Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
3bf1ff1
feat: add basic version page with mock data
ShroXd Mar 13, 2026
1373fdf
feat: update page layout
ShroXd Mar 11, 2026
ff2c7a8
feat: tweaks layout
ShroXd Mar 11, 2026
55c8117
refactor: tweaks the layout
ShroXd Mar 11, 2026
16833e0
refactor: tweaks layout
ShroXd Mar 11, 2026
cdc2b3e
feat: use sticky card
ShroXd Mar 11, 2026
2a4a4e8
chore: clean up mock changelog
ShroXd Mar 12, 2026
793ee16
feat: fetch versions data
ShroXd Mar 12, 2026
71a566c
feat: grouped versions
ShroXd Mar 12, 2026
5343fac
feat: use map to avoid O(n) searching
ShroXd Mar 13, 2026
5d305d1
perf: init loading for basic data, and lazy full loading when expanding
ShroXd Mar 13, 2026
016f47b
feat: use virtual rendering
ShroXd Mar 13, 2026
0361273
perf: use shallowRef for deep data structure
ShroXd Mar 13, 2026
bdffaf3
feat: fallback for ssr
ShroXd Mar 13, 2026
879a7d4
feat: support filtering
ShroXd Mar 13, 2026
7589471
feat: tweaks versions' order
ShroXd Mar 13, 2026
fede892
chore: clean up
ShroXd Mar 13, 2026
7aa08d5
test: fix test of PackageVersions
ShroXd Mar 13, 2026
4a816e7
fix: fix virtual window rendering issue
ShroXd Mar 14, 2026
a233df6
fix: fix hltml lint errors
ShroXd Mar 14, 2026
c39d591
refactor: optimize type and css
ShroXd Mar 14, 2026
9b7412c
feat: searching animation and transition
ShroXd Mar 14, 2026
35919a0
test: add tests for package version page
ShroXd Mar 14, 2026
cba049c
chore: move hard coded text to i18n file
ShroXd Mar 14, 2026
f069028
feat: use debounce for filtering
ShroXd Mar 14, 2026
6f5c1b8
test: use data-testid
ShroXd Mar 14, 2026
bba4380
chore: remove all changelog related code
ShroXd Mar 14, 2026
98dbb71
chore: explain why we cant disable fething in package/[name].vue page
ShroXd Mar 15, 2026
bab8140
fix: remove unnecessary aria-label
ShroXd Mar 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 29 additions & 9 deletions app/components/Package/Versions.vue
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,14 @@ function versionRoute(version: string): RouteLocationRaw {
return packageRoute(props.packageName, version)
}

// Route to the full versions history page
const versionsPageRoute = computed((): RouteLocationRaw => {
const [org, name = ''] = props.packageName.startsWith('@')
? props.packageName.split('/')
: ['', props.packageName]
return { name: 'package-versions', params: { org, name } }
})

// Version to tags lookup (supports multiple tags per version)
const versionToTags = computed(() => buildVersionToTagsMap(props.distTags))

Expand Down Expand Up @@ -521,15 +529,27 @@ function majorGroupContainsCurrent(group: (typeof otherMajorGroups.value)[0]): b
id="versions"
>
<template #actions>
<ButtonBase
variant="secondary"
class="text-fg-subtle hover:text-fg transition-colors min-w-6 min-h-6 -m-1 p-1 rounded"
:title="$t('package.downloads.community_distribution')"
classicon="i-lucide:file-stack"
@click="openDistributionModal"
>
<span class="sr-only">{{ $t('package.downloads.community_distribution') }}</span>
</ButtonBase>
<div class="flex items-center gap-3">
<LinkBase
:to="versionsPageRoute"
variant="button-secondary"
class="text-fg-subtle hover:text-fg transition-colors min-w-6 min-h-6 p-1 rounded"
:title="$t('package.versions.view_all_versions')"
classicon="i-lucide:history"
data-testid="view-all-versions-link"
>
<span class="sr-only">{{ $t('package.versions.view_all_versions') }}</span>
</LinkBase>
<ButtonBase
variant="secondary"
class="text-fg-subtle hover:text-fg transition-colors min-w-6 min-h-6 -m-1 p-1 rounded"
:title="$t('package.downloads.community_distribution')"
classicon="i-lucide:file-stack"
@click="openDistributionModal"
>
<span class="sr-only">{{ $t('package.downloads.community_distribution') }}</span>
</ButtonBase>
</div>
</template>
<div class="space-y-0.5 min-w-0">
<!-- Semver range filter -->
Expand Down
8 changes: 6 additions & 2 deletions app/pages/package/[[org]]/[name].vue
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ const { diff: sizeDiff } = useInstallSizeDiff(packageName, resolvedVersion, pkg,
// β†’ Preserve the server-rendered DOM, don't flash to skeleton.
const nuxtApp = useNuxtApp()
const route = useRoute()
// Gates template rendering only β€” data fetches intentionally still run.
// immediate is set once at mount β€” skipped requests won't re-fire on navigation, leaving data permanently missing.
const isVersionsRoute = computed(() => route.name === 'package-versions')
const hasEmptyPayload =
import.meta.client &&
nuxtApp.payload.serverRendered &&
Expand Down Expand Up @@ -516,7 +519,8 @@ const showSkeleton = shallowRef(false)
</script>

<template>
<DevOnly>
<NuxtPage v-if="isVersionsRoute" />
<DevOnly v-else>
<ButtonBase
class="fixed bottom-4 inset-is-4 z-50 shadow-lg rounded-full! px-3! py-2!"
classicon="i-simple-icons:skeleton"
Expand All @@ -528,7 +532,7 @@ const showSkeleton = shallowRef(false)
<span class="text-xs">Skeleton</span>
</ButtonBase>
</DevOnly>
<main class="flex-1 pb-8">
<main v-if="!isVersionsRoute" class="flex-1 pb-8">
<!-- Scenario 1: SPA fallback β€” show skeleton (no real content to preserve) -->
<!-- Scenario 2: SSR with missing payload β€” preserve server DOM, skip skeleton -->
<PackageSkeleton
Expand Down
Loading
Loading