Skip to content

Commit 18e2f54

Browse files
committed
refactor: Extract reusable Skeleton components
1 parent 136872f commit 18e2f54

10 files changed

Lines changed: 108 additions & 92 deletions

File tree

app/components/PackageSkeleton.vue

Lines changed: 53 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -12,20 +12,20 @@
1212
<div class="flex-1 min-w-0">
1313
<!-- Package name: h1 font-mono text-2xl sm:text-3xl font-medium mb-2 -->
1414
<h1 class="font-mono text-2xl sm:text-3xl font-medium mb-2">
15-
<span class="skeleton inline-block h-9 w-48" />
15+
<SkeletonInline class="h-9 w-48" />
1616
</h1>
1717
<!-- Description: fixed height container matching min-h-[4.5rem] (72px) to prevent CLS -->
1818
<div class="relative max-w-2xl min-h-[4.5rem]">
1919
<div class="space-y-2">
20-
<span class="skeleton block h-5 w-full" />
21-
<span class="skeleton block h-5 w-4/5" />
22-
<span class="skeleton block h-5 w-3/5" />
20+
<SkeletonBlock class="h-5 w-full" />
21+
<SkeletonBlock class="h-5 w-4/5" />
22+
<SkeletonBlock class="h-5 w-3/5" />
2323
</div>
2424
</div>
2525
</div>
2626

2727
<!-- Version badge: shrink-0 px-3 py-1 font-mono text-sm bg-bg-muted border border-border rounded-md -->
28-
<span class="skeleton shrink-0 h-8 w-20 rounded-md" />
28+
<SkeletonInline class="shrink-0 h-8 w-20 rounded-md" />
2929
</div>
3030

3131
<!-- Stats grid: grid grid-cols-2 sm:grid-cols-3 md:grid-cols-6 gap-4 mt-6 -->
@@ -36,7 +36,7 @@
3636
{{ $t('package.skeleton.license') }}
3737
</dt>
3838
<dd class="font-mono text-sm">
39-
<span class="skeleton inline-block h-5 w-12" />
39+
<SkeletonInline class="h-5 w-12" />
4040
</dd>
4141
</div>
4242

@@ -46,7 +46,7 @@
4646
{{ $t('package.skeleton.weekly') }}
4747
</dt>
4848
<dd class="font-mono text-sm">
49-
<span class="skeleton inline-block h-5 w-20" />
49+
<SkeletonInline class="h-5 w-20" />
5050
</dd>
5151
</div>
5252

@@ -56,7 +56,7 @@
5656
{{ $t('package.skeleton.size') }}
5757
</dt>
5858
<dd class="font-mono text-sm">
59-
<span class="skeleton inline-block h-5 w-16" />
59+
<SkeletonInline class="h-5 w-16" />
6060
</dd>
6161
</div>
6262

@@ -66,7 +66,7 @@
6666
{{ $t('package.skeleton.deps') }}
6767
</dt>
6868
<dd class="font-mono text-sm">
69-
<span class="skeleton inline-block h-5 w-8" />
69+
<SkeletonInline class="h-5 w-8" />
7070
</dd>
7171
</div>
7272

@@ -76,7 +76,7 @@
7676
{{ $t('package.skeleton.updated') }}
7777
</dt>
7878
<dd class="font-mono text-sm">
79-
<span class="skeleton inline-block h-5 w-28" />
79+
<SkeletonInline class="h-5 w-28" />
8080
</dd>
8181
</div>
8282
</dl>
@@ -85,16 +85,16 @@
8585
<nav aria-label="Package links" class="mt-6">
8686
<ul class="flex flex-wrap items-center gap-4 list-none m-0 p-0">
8787
<li>
88-
<span class="skeleton inline-block h-5 w-14" />
88+
<SkeletonInline class="h-5 w-14" />
8989
</li>
9090
<li>
91-
<span class="skeleton inline-block h-5 w-20" />
91+
<SkeletonInline class="h-5 w-20" />
9292
</li>
9393
<li>
94-
<span class="skeleton inline-block h-5 w-16" />
94+
<SkeletonInline class="h-5 w-16" />
9595
</li>
9696
<li>
97-
<span class="skeleton inline-block h-5 w-12" />
97+
<SkeletonInline class="h-5 w-12" />
9898
</li>
9999
</ul>
100100
</nav>
@@ -113,9 +113,9 @@
113113
<div
114114
class="bg-bg-muted border border-border rounded-md p-4 font-mono text-sm overflow-x-auto pe-16"
115115
>
116-
<span class="skeleton inline-block h-5 w-52" />
116+
<SkeletonInline class="h-5 w-52" />
117117
</div>
118-
<span class="skeleton absolute top-3 inset-ie-3 h-6 w-12 rounded" />
118+
<SkeletonInline class="absolute top-3 inset-ie-3 h-6 w-12 rounded" />
119119
</div>
120120
</section>
121121

@@ -133,20 +133,20 @@
133133
<!-- Simulated README content -->
134134
<div class="space-y-4">
135135
<!-- Heading -->
136-
<span class="skeleton block h-7 w-2/3" />
136+
<SkeletonBlock class="h-7 w-2/3" />
137137
<!-- Paragraphs -->
138-
<span class="skeleton block h-4 w-full" />
139-
<span class="skeleton block h-4 w-full" />
140-
<span class="skeleton block h-4 w-4/5" />
138+
<SkeletonBlock class="h-4 w-full" />
139+
<SkeletonBlock class="h-4 w-full" />
140+
<SkeletonBlock class="h-4 w-4/5" />
141141
<!-- Gap for section break -->
142-
<span class="skeleton block h-6 w-1/2 mt-6" />
143-
<span class="skeleton block h-4 w-full" />
144-
<span class="skeleton block h-4 w-full" />
145-
<span class="skeleton block h-4 w-3/4" />
142+
<SkeletonBlock class="h-6 w-1/2 mt-6" />
143+
<SkeletonBlock class="h-4 w-full" />
144+
<SkeletonBlock class="h-4 w-full" />
145+
<SkeletonBlock class="h-4 w-3/4" />
146146
<!-- Code block placeholder -->
147-
<div class="skeleton h-24 w-full rounded-lg mt-4" />
148-
<span class="skeleton block h-4 w-full" />
149-
<span class="skeleton block h-4 w-5/6" />
147+
<SkeletonBlock class="h-24 w-full rounded-lg mt-4" />
148+
<SkeletonBlock class="h-4 w-full" />
149+
<SkeletonBlock class="h-4 w-5/6" />
150150
</div>
151151
</section>
152152
</div>
@@ -163,10 +163,10 @@
163163
</h2>
164164
<ul class="space-y-2 list-none m-0 p-0">
165165
<li>
166-
<span class="skeleton inline-block h-5 w-28" />
166+
<SkeletonInline class="h-5 w-28" />
167167
</li>
168168
<li>
169-
<span class="skeleton inline-block h-5 w-24" />
169+
<SkeletonInline class="h-5 w-24" />
170170
</li>
171171
</ul>
172172
</section>
@@ -181,12 +181,12 @@
181181
</h2>
182182
<!-- flex flex-wrap gap-1.5 -->
183183
<ul class="flex flex-wrap gap-1.5 list-none m-0 p-0">
184-
<li><span class="skeleton inline-block h-6 w-16 rounded" /></li>
185-
<li><span class="skeleton inline-block h-6 w-12 rounded" /></li>
186-
<li><span class="skeleton inline-block h-6 w-20 rounded" /></li>
187-
<li><span class="skeleton inline-block h-6 w-14 rounded" /></li>
188-
<li><span class="skeleton inline-block h-6 w-18 rounded" /></li>
189-
<li><span class="skeleton inline-block h-6 w-10 rounded" /></li>
184+
<li><SkeletonInline class="h-6 w-16 rounded" /></li>
185+
<li><SkeletonInline class="h-6 w-12 rounded" /></li>
186+
<li><SkeletonInline class="h-6 w-20 rounded" /></li>
187+
<li><SkeletonInline class="h-6 w-14 rounded" /></li>
188+
<li><SkeletonInline class="h-6 w-18 rounded" /></li>
189+
<li><SkeletonInline class="h-6 w-10 rounded" /></li>
190190
</ul>
191191
</section>
192192

@@ -201,24 +201,24 @@
201201
<!-- space-y-1, each row: flex items-center justify-between py-1.5 text-sm -->
202202
<div class="space-y-1">
203203
<div class="flex items-center justify-between py-1.5 text-sm">
204-
<span class="skeleton inline-block h-4 w-16" />
205-
<span class="skeleton inline-block h-4 w-24" />
204+
<SkeletonInline class="h-4 w-16" />
205+
<SkeletonInline class="h-4 w-24" />
206206
</div>
207207
<div class="flex items-center justify-between py-1.5 text-sm">
208-
<span class="skeleton inline-block h-4 w-14" />
209-
<span class="skeleton inline-block h-4 w-24" />
208+
<SkeletonInline class="h-4 w-14" />
209+
<SkeletonInline class="h-4 w-24" />
210210
</div>
211211
<div class="flex items-center justify-between py-1.5 text-sm">
212-
<span class="skeleton inline-block h-4 w-18" />
213-
<span class="skeleton inline-block h-4 w-24" />
212+
<SkeletonInline class="h-4 w-18" />
213+
<SkeletonInline class="h-4 w-24" />
214214
</div>
215215
<div class="flex items-center justify-between py-1.5 text-sm">
216-
<span class="skeleton inline-block h-4 w-14" />
217-
<span class="skeleton inline-block h-4 w-24" />
216+
<SkeletonInline class="h-4 w-14" />
217+
<SkeletonInline class="h-4 w-24" />
218218
</div>
219219
<div class="flex items-center justify-between py-1.5 text-sm">
220-
<span class="skeleton inline-block h-4 w-16" />
221-
<span class="skeleton inline-block h-4 w-24" />
220+
<SkeletonInline class="h-4 w-16" />
221+
<SkeletonInline class="h-4 w-24" />
222222
</div>
223223
</div>
224224
</section>
@@ -234,20 +234,20 @@
234234
<!-- space-y-1, each: flex items-center justify-between py-1 text-sm -->
235235
<ul class="space-y-1 list-none m-0 p-0">
236236
<li class="flex items-center justify-between py-1 text-sm">
237-
<span class="skeleton inline-block h-4 w-24" />
238-
<span class="skeleton inline-block h-4 w-12" />
237+
<SkeletonInline class="h-4 w-24" />
238+
<SkeletonInline class="h-4 w-12" />
239239
</li>
240240
<li class="flex items-center justify-between py-1 text-sm">
241-
<span class="skeleton inline-block h-4 w-32" />
242-
<span class="skeleton inline-block h-4 w-10" />
241+
<SkeletonInline class="h-4 w-32" />
242+
<SkeletonInline class="h-4 w-10" />
243243
</li>
244244
<li class="flex items-center justify-between py-1 text-sm">
245-
<span class="skeleton inline-block h-4 w-20" />
246-
<span class="skeleton inline-block h-4 w-14" />
245+
<SkeletonInline class="h-4 w-20" />
246+
<SkeletonInline class="h-4 w-14" />
247247
</li>
248248
<li class="flex items-center justify-between py-1 text-sm">
249-
<span class="skeleton inline-block h-4 w-28" />
250-
<span class="skeleton inline-block h-4 w-12" />
249+
<SkeletonInline class="h-4 w-28" />
250+
<SkeletonInline class="h-4 w-12" />
251251
</li>
252252
</ul>
253253
</section>

app/components/PackageWeeklyDownloadStats.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -217,20 +217,20 @@ const config = computed(() => {
217217
<div class="min-h-[75.195px]">
218218
<!-- Title row: date range (24px height) -->
219219
<div class="h-6 flex items-center ps-3">
220-
<span class="skeleton h-3 w-36" />
220+
<SkeletonInline class="h-3 w-36" />
221221
</div>
222222
<!-- Chart area: data label left, sparkline right -->
223223
<div class="aspect-[500/80] flex items-center">
224224
<!-- Data label (covers ~42% width) -->
225225
<div class="w-[42%] flex items-center ps-0.5">
226-
<span class="skeleton h-7 w-24" />
226+
<SkeletonInline class="h-7 w-24" />
227227
</div>
228228
<!-- Sparkline area (~58% width) -->
229229
<div class="flex-1 flex items-end gap-0.5 h-4/5 pe-3">
230-
<span
230+
<SkeletonInline
231231
v-for="i in 16"
232232
:key="i"
233-
class="skeleton flex-1 rounded-sm"
233+
class="flex-1 rounded-sm"
234234
:style="{ height: `${25 + ((i * 7) % 50)}%` }"
235235
/>
236236
</div>

app/components/SkeletonBlock.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!-- Vue component that only takes a class as prop and adds `bg-bg-elevated rounded animate-skeleton-pulse` to that class -->
2+
<script setup lang="ts">
3+
const props = defineProps<{
4+
class?: string
5+
}>()
6+
</script>
7+
8+
<template>
9+
<div :class="`bg-bg-elevated rounded animate-skeleton-pulse ${props.class ?? ''}`" />
10+
</template>

app/components/SkeletonInline.vue

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!-- Vue component that only takes a class as prop and adds `bg-bg-elevated rounded animate-skeleton-pulse` to that class -->
2+
<script setup lang="ts">
3+
const props = defineProps<{
4+
class?: string
5+
}>()
6+
</script>
7+
8+
<template>
9+
<span
10+
:class="`inline-block bg-bg-elevated rounded animate-skeleton-pulse ${props.class ?? ''}`"
11+
/>
12+
</template>

app/components/Toggle.server.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ defineProps<{
1010
<span v-if="label" class="text-sm text-fg font-medium text-start">
1111
{{ label }}
1212
</span>
13-
<span class="skeleton block h-6 w-11 shrink-0 rounded-full" />
13+
<SkeletonBlock class="h-6 w-11 shrink-0 rounded-full" />
1414
</div>
1515
<p v-if="description" class="text-sm text-fg-muted">
1616
{{ description }}

app/pages/[...package].vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -455,10 +455,10 @@ function handleClick(event: MouseEvent) {
455455
class="self-baseline ms-1 sm:ms-2"
456456
/>
457457
<template #fallback>
458-
<ul class="flex items-center gap-1.5 self-baseline ms-1 sm:ms-2">
459-
<li class="skeleton w-8 h-5 rounded" />
460-
<li class="skeleton w-12 h-5 rounded" />
461-
</ul>
458+
<div class="flex items-center gap-1.5 self-baseline ms-1 sm:ms-2">
459+
<SkeletonBlock class="w-8 h-5 rounded" />
460+
<SkeletonBlock class="w-12 h-5 rounded" />
461+
</div>
462462
</template>
463463
</ClientOnly>
464464

app/pages/code/[...path].vue

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -482,31 +482,31 @@ defineOgImageComponent('Default', {
482482
<!-- Fake line numbers column -->
483483
<div class="shrink-0 bg-bg-subtle border-ie border-border w-14 py-0">
484484
<div v-for="n in 20" :key="n" class="px-3 h-6 flex items-center justify-end">
485-
<span class="skeleton w-4 h-3 rounded-sm" />
485+
<SkeletonInline class="w-4 h-3 rounded-sm" />
486486
</div>
487487
</div>
488488
<!-- Fake code content -->
489489
<div class="flex-1 p-4 space-y-1.5">
490-
<div class="skeleton h-4 w-32 rounded-sm" />
491-
<div class="skeleton h-4 w-48 rounded-sm" />
492-
<div class="skeleton h-4 w-24 rounded-sm" />
490+
<SkeletonBlock class="h-4 w-32 rounded-sm" />
491+
<SkeletonBlock class="h-4 w-48 rounded-sm" />
492+
<SkeletonBlock class="h-4 w-24 rounded-sm" />
493493
<div class="h-4" />
494-
<div class="skeleton h-4 w-64 rounded-sm" />
495-
<div class="skeleton h-4 w-56 rounded-sm" />
496-
<div class="skeleton h-4 w-40 rounded-sm" />
497-
<div class="skeleton h-4 w-72 rounded-sm" />
494+
<SkeletonBlock class="h-4 w-64 rounded-sm" />
495+
<SkeletonBlock class="h-4 w-56 rounded-sm" />
496+
<SkeletonBlock class="h-4 w-40 rounded-sm" />
497+
<SkeletonBlock class="h-4 w-72 rounded-sm" />
498498
<div class="h-4" />
499-
<div class="skeleton h-4 w-36 rounded-sm" />
500-
<div class="skeleton h-4 w-52 rounded-sm" />
501-
<div class="skeleton h-4 w-44 rounded-sm" />
502-
<div class="skeleton h-4 w-28 rounded-sm" />
499+
<SkeletonBlock class="h-4 w-36 rounded-sm" />
500+
<SkeletonBlock class="h-4 w-52 rounded-sm" />
501+
<SkeletonBlock class="h-4 w-44 rounded-sm" />
502+
<SkeletonBlock class="h-4 w-28 rounded-sm" />
503503
<div class="h-4" />
504-
<div class="skeleton h-4 w-60 rounded-sm" />
505-
<div class="skeleton h-4 w-48 rounded-sm" />
506-
<div class="skeleton h-4 w-32 rounded-sm" />
507-
<div class="skeleton h-4 w-56 rounded-sm" />
508-
<div class="skeleton h-4 w-40 rounded-sm" />
509-
<div class="skeleton h-4 w-24 rounded-sm" />
504+
<SkeletonBlock class="h-4 w-60 rounded-sm" />
505+
<SkeletonBlock class="h-4 w-48 rounded-sm" />
506+
<SkeletonBlock class="h-4 w-32 rounded-sm" />
507+
<SkeletonBlock class="h-4 w-56 rounded-sm" />
508+
<SkeletonBlock class="h-4 w-40 rounded-sm" />
509+
<SkeletonBlock class="h-4 w-24 rounded-sm" />
510510
</div>
511511
</div>
512512

app/pages/docs/[...path].vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -165,10 +165,10 @@ const showEmptyState = computed(() => docsData.value?.status !== 'ok')
165165
<!-- Main content -->
166166
<main class="flex-1 min-w-0">
167167
<div v-if="showLoading" class="p-6 sm:p-8 lg:p-12 space-y-4">
168-
<div class="skeleton h-8 w-64 rounded" />
169-
<div class="skeleton h-4 w-full max-w-2xl rounded" />
170-
<div class="skeleton h-4 w-5/6 max-w-2xl rounded" />
171-
<div class="skeleton h-4 w-3/4 max-w-2xl rounded" />
168+
<SkeletonBlock class="h-8 w-64 rounded" />
169+
<SkeletonBlock class="h-4 w-full max-w-2xl rounded" />
170+
<SkeletonBlock class="h-4 w-5/6 max-w-2xl rounded" />
171+
<SkeletonBlock class="h-4 w-3/4 max-w-2xl rounded" />
172172
</div>
173173

174174
<div v-else-if="showEmptyState" class="p-6 sm:p-8 lg:p-12">

app/pages/~[username]/orgs.vue

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,7 @@ defineOgImageComponent('Default', {
216216
>
217217
{{ org.role }}
218218
</span>
219-
<span
220-
v-else-if="org.isLoadingDetails"
221-
class="skeleton inline-block mt-1 h-5 w-16 rounded"
222-
/>
219+
<SkeletonInline v-else-if="org.isLoadingDetails" class="mt-1 h-5 w-16 rounded" />
223220
</div>
224221
</div>
225222

@@ -236,7 +233,7 @@ defineOgImageComponent('Default', {
236233
)
237234
}}
238235
</span>
239-
<span v-else-if="org.isLoadingDetails" class="skeleton inline-block h-4 w-20" />
236+
<SkeletonInline v-else-if="org.isLoadingDetails" class="h-4 w-20" />
240237
<span v-else class="text-fg-subtle">—</span>
241238
</div>
242239
</div>

0 commit comments

Comments
 (0)