Skip to content

Commit 8b5cb6f

Browse files
committed
feat: tweaks layout
1 parent 063980e commit 8b5cb6f

1 file changed

Lines changed: 148 additions & 52 deletions

File tree

app/pages/package/[[org]]/[name]/versions.vue

Lines changed: 148 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ const orgName = computed(() => {
2525
// ─── Mock data ────────────────────────────────────────────────────────────────
2626
// TODO: Replace distTags with pkg['dist-tags'] from usePackage()
2727
// TODO: Replace versionHistory with data from useAllPackageVersions()
28+
// TODO: Replace mockChangelogs with real changelog data (e.g. GitHub releases or CHANGELOG.md)
2829
2930
const distTags: Record<string, string> = {
3031
'latest': '7.26.3',
@@ -82,14 +83,51 @@ const versionHistory: PackageVersionInfo[] = [
8283
},
8384
]
8485
86+
// Changelog entries keyed by version. In production this would come from GitHub
87+
// releases or a CHANGELOG.md parsed from the package files.
88+
const mockChangelogs: Record<string, string[]> = {
89+
'8.0.0-alpha.16': [
90+
'Added support for TypeScript 5.x type imports in builder helpers',
91+
'Improved error messages for invalid AST node transformations',
92+
'Fixed incorrect location tracking for template literals inside tagged expressions',
93+
'Resolved memory leak in recursive type visitor traversal',
94+
],
95+
'7.26.3': [
96+
'Fixed edge case in identifier validation for private class fields (#16421)',
97+
'Corrected span calculation for async generator function expressions',
98+
],
99+
'7.26.0': [
100+
'Added assert keyword support for import assertions (Stage 3 proposal)',
101+
'New createTypeAnnotation builder helper for programmatic AST construction',
102+
'Fixed inconsistent behavior in optional chaining type narrowing',
103+
'Corrected position data for JSX fragment children with whitespace',
104+
],
105+
'7.25.0': [
106+
'Introduced satisfies operator support (TypeScript 4.9)',
107+
'Added experimental decorator metadata helpers behind a flag',
108+
'Removed deprecated isType aliases — use isTSType instead',
109+
'Improved clone performance for large ASTs by ~18%',
110+
],
111+
'7.0.0': [
112+
'Package renamed from babel-types to @babel/types',
113+
'All APIs now use ES module syntax',
114+
'Dropped support for Node.js < 6',
115+
'Removed all deprecated v5 builder aliases',
116+
],
117+
}
118+
85119
// ─── Derived data ─────────────────────────────────────────────────────────────
86120
87121
const versionToTagsMap = computed(() => buildVersionToTagsMap(distTags))
88122
89123
const sortedVersions = computed(() =>
90124
[...versionHistory]
91125
.sort((a, b) => compare(b.version, a.version))
92-
.map(v => ({ ...v, tags: versionToTagsMap.value.get(v.version) })),
126+
.map(v => ({
127+
...v,
128+
tags: versionToTagsMap.value.get(v.version),
129+
changelog: mockChangelogs[v.version] ?? null,
130+
})),
93131
)
94132
95133
const tagRows = computed(() => buildTaggedVersionRows(distTags))
@@ -98,6 +136,19 @@ function getVersionTime(version: string): string | undefined {
98136
return versionHistory.find(v => v.version === version)?.time
99137
}
100138
139+
// ─── Changelog expand/collapse ────────────────────────────────────────────────
140+
141+
const expandedChangelogs = ref<Set<string>>(new Set())
142+
143+
function toggleChangelog(version: string) {
144+
if (expandedChangelogs.value.has(version)) {
145+
expandedChangelogs.value.delete(version)
146+
} else {
147+
expandedChangelogs.value.add(version)
148+
}
149+
expandedChangelogs.value = new Set(expandedChangelogs.value)
150+
}
151+
101152
// ─── Jump to version ──────────────────────────────────────────────────────────
102153
103154
const jumpVersion = ref('')
@@ -137,26 +188,26 @@ function navigateToVersion() {
137188
</header>
138189

139190
<!-- Content -->
140-
<div class="container max-w-3xl py-8">
191+
<div class="container py-8 flex flex-col lg:flex-row gap-8 items-start">
141192
<!-- ── Current Tags ─────────────────────────────────────────────────── -->
142-
<section class="mb-10">
193+
<section class="w-full lg:w-72 shrink-0">
143194
<h2 class="text-xs text-fg-subtle uppercase tracking-wider mb-3 ps-1">Current Tags</h2>
144195
<div class="rounded-lg border border-border overflow-hidden">
145196
<table class="w-full">
146197
<thead>
147198
<tr class="border-b border-border bg-bg-subtle">
148199
<th
149-
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider w-1/3"
200+
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider"
150201
>
151202
Tag
152203
</th>
153204
<th
154-
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider w-1/3"
205+
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider"
155206
>
156207
Version
157208
</th>
158209
<th
159-
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider hidden sm:table-cell"
210+
class="text-start px-4 py-2.5 text-xs text-fg-subtle font-medium uppercase tracking-wider hidden sm:table-cell lg:hidden xl:table-cell"
160211
>
161212
Published
162213
</th>
@@ -189,7 +240,7 @@ function navigateToVersion() {
189240
{{ row.version }}
190241
</LinkBase>
191242
</td>
192-
<td class="px-4 py-3 hidden sm:table-cell">
243+
<td class="px-4 py-3 hidden sm:table-cell lg:hidden xl:table-cell">
193244
<DateTime
194245
v-if="getVersionTime(row.version)"
195246
:datetime="getVersionTime(row.version)!"
@@ -207,7 +258,7 @@ function navigateToVersion() {
207258
</section>
208259

209260
<!-- ── Version History ──────────────────────────────────────────────── -->
210-
<section>
261+
<section class="flex-1 min-w-0">
211262
<!-- Header + jump-to-version -->
212263
<div class="flex flex-wrap items-center justify-between gap-3 mb-4 ps-1">
213264
<h2 class="text-xs text-fg-subtle uppercase tracking-wider">
@@ -246,59 +297,104 @@ function navigateToVersion() {
246297
<div
247298
v-for="v in sortedVersions"
248299
:key="v.version"
249-
class="flex items-center gap-3 px-4 py-2.5 border-b border-border last:border-0 hover:bg-bg-subtle transition-colors group relative"
300+
class="border-b border-border last:border-0"
250301
>
251-
<!-- Version + badges -->
252-
<div class="flex-1 min-w-0 flex items-center gap-2 flex-wrap">
253-
<LinkBase
254-
:to="packageRoute(packageName, v.version)"
255-
class="font-mono text-sm after:absolute after:inset-0 after:content-['']"
256-
:class="v.deprecated ? 'text-red-700 dark:text-red-400' : ''"
257-
:classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined"
258-
dir="ltr"
259-
>
260-
{{ v.version }}
261-
</LinkBase>
302+
<!-- Version row -->
303+
<div
304+
class="flex items-center gap-3 px-4 py-2.5 hover:bg-bg-subtle transition-colors group relative"
305+
>
306+
<!-- Version + badges -->
307+
<div class="flex-1 min-w-0 flex items-center gap-2 flex-wrap">
308+
<LinkBase
309+
:to="packageRoute(packageName, v.version)"
310+
class="font-mono text-sm after:absolute after:inset-0 after:content-['']"
311+
:class="v.deprecated ? 'text-red-700 dark:text-red-400' : ''"
312+
:classicon="v.deprecated ? 'i-lucide:octagon-alert' : undefined"
313+
dir="ltr"
314+
>
315+
{{ v.version }}
316+
</LinkBase>
262317

263-
<!-- Dist-tags -->
264-
<div v-if="v.tags?.length" class="flex items-center gap-1 flex-wrap relative z-10">
318+
<!-- Dist-tags -->
319+
<div v-if="v.tags?.length" class="flex items-center gap-1 flex-wrap relative z-10">
320+
<span
321+
v-for="tag in v.tags"
322+
:key="tag"
323+
class="text-4xs font-semibold uppercase tracking-wide"
324+
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
325+
>
326+
{{ tag }}
327+
</span>
328+
</div>
329+
330+
<!-- Deprecated label -->
265331
<span
266-
v-for="tag in v.tags"
267-
:key="tag"
268-
class="text-4xs font-semibold uppercase tracking-wide"
269-
:class="tag === 'latest' ? 'text-accent' : 'text-fg-subtle'"
332+
v-if="v.deprecated"
333+
class="text-3xs font-medium text-red-700 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-1.5 py-0.5 rounded relative z-10"
334+
:title="v.deprecated"
270335
>
271-
{{ tag }}
336+
deprecated
272337
</span>
273338
</div>
274339

275-
<!-- Deprecated label -->
276-
<span
277-
v-if="v.deprecated"
278-
class="text-3xs font-medium text-red-700 dark:text-red-400 bg-red-100 dark:bg-red-900/30 px-1.5 py-0.5 rounded relative z-10"
279-
:title="v.deprecated"
280-
>
281-
deprecated
282-
</span>
340+
<!-- Right side: date + provenance + changelog toggle -->
341+
<div class="flex items-center gap-3 shrink-0 relative z-10">
342+
<DateTime
343+
v-if="v.time"
344+
:datetime="v.time"
345+
class="text-xs text-fg-subtle hidden sm:block"
346+
year="numeric"
347+
month="short"
348+
day="numeric"
349+
/>
350+
<ProvenanceBadge
351+
v-if="v.hasProvenance"
352+
:package-name="packageName"
353+
:version="v.version"
354+
compact
355+
:linked="false"
356+
/>
357+
<!-- Changelog toggle button -->
358+
<button
359+
v-if="v.changelog"
360+
type="button"
361+
class="flex items-center gap-1 text-xs text-fg-subtle hover:text-fg transition-colors rounded focus-visible:outline-accent/70"
362+
:aria-expanded="expandedChangelogs.has(v.version)"
363+
@click.stop="toggleChangelog(v.version)"
364+
>
365+
<span
366+
class="i-lucide:chevron-right w-3 h-3 transition-transform duration-200 motion-reduce:transition-none"
367+
:class="{ 'rotate-90': expandedChangelogs.has(v.version) }"
368+
aria-hidden="true"
369+
/>
370+
<span class="hidden sm:inline">Changelog</span>
371+
</button>
372+
</div>
283373
</div>
284374

285-
<!-- Right side: date + provenance -->
286-
<div class="flex items-center gap-3 shrink-0 relative z-10">
287-
<DateTime
288-
v-if="v.time"
289-
:datetime="v.time"
290-
class="text-xs text-fg-subtle hidden sm:block"
291-
year="numeric"
292-
month="short"
293-
day="numeric"
294-
/>
295-
<ProvenanceBadge
296-
v-if="v.hasProvenance"
297-
:package-name="packageName"
298-
:version="v.version"
299-
compact
300-
:linked="false"
301-
/>
375+
<!-- Changelog expansion -->
376+
<div
377+
v-if="v.changelog"
378+
class="grid transition-[grid-template-rows] duration-200 ease-out motion-reduce:transition-none"
379+
:class="expandedChangelogs.has(v.version) ? 'grid-rows-[1fr]' : 'grid-rows-[0fr]'"
380+
>
381+
<div class="overflow-hidden min-h-0">
382+
<div class="px-4 pb-4 pt-3 border-t border-border bg-bg-subtle">
383+
<ul class="space-y-1.5 list-none m-0 p-0">
384+
<li
385+
v-for="(entry, i) in v.changelog"
386+
:key="i"
387+
class="flex items-start gap-2 text-sm text-fg-muted"
388+
>
389+
<span
390+
class="i-lucide:minus w-3.5 h-3.5 mt-0.5 text-fg-subtle shrink-0"
391+
aria-hidden="true"
392+
/>
393+
{{ entry }}
394+
</li>
395+
</ul>
396+
</div>
397+
</div>
302398
</div>
303399
</div>
304400
</div>

0 commit comments

Comments
 (0)