Skip to content

Commit 66e9fcd

Browse files
committed
feat: add proper loading and error state to readme
1 parent 0d9b25b commit 66e9fcd

6 files changed

Lines changed: 47 additions & 11 deletions

File tree

app/components/Package/Readme.vue

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,11 @@ const props = defineProps<{
88
}>()
99
1010
// Fetch README for specific version if requested, otherwise latest
11-
const { data } = useLazyFetch<ReadmeResponse>(
12-
() => {
13-
const base = `/api/registry/readme/${props.packageName}`
14-
const version = props.requestedVersion
15-
return version ? `${base}/v/${version}` : base
16-
},
17-
{ default: () => ({ html: '', md: '', playgroundLinks: [], toc: [] }) },
18-
)
11+
const { data, status, error } = useLazyFetch<ReadmeResponse>(() => {
12+
const base = `/api/registry/readme/${props.packageName}`
13+
const version = props.requestedVersion
14+
return version ? `${base}/v/${version}` : base
15+
})
1916
2017
// Track active TOC item based on scroll position
2118
const tocItems = computed(() => data.value?.toc ?? [])
@@ -37,12 +34,17 @@ const { copied: copiedReadme, copy: copyReadme } = useClipboard({
3734
</h2>
3835
<div class="flex gap-2">
3936
<!-- Copy readme as Markdown button -->
40-
<TooltipApp v-if="data?.md" :text="$t('package.readme.copy_as_markdown')" position="bottom">
37+
<TooltipApp
38+
v-if="data?.md || status === 'pending' || status === 'idle'"
39+
:text="$t('package.readme.copy_as_markdown')"
40+
position="bottom"
41+
>
4142
<ButtonBase
4243
@click="copyReadme()"
4344
:aria-pressed="copiedReadme"
4445
:aria-label="copiedReadme ? $t('common.copied') : $t('package.readme.copy_as_markdown')"
4546
:classicon="copiedReadme ? 'i-carbon:checkmark' : 'i-simple-icons:markdown'"
47+
:disabled="status === 'pending' || status === 'idle'"
4648
>
4749
{{ copiedReadme ? $t('common.copied') : $t('common.copy') }}
4850
</ButtonBase>
@@ -51,12 +53,41 @@ const { copied: copiedReadme, copy: copyReadme } = useClipboard({
5153
v-if="data?.toc && data.toc.length > 1"
5254
:toc="data.toc"
5355
:active-id="activeTocId"
56+
:disabled="!data || !data.toc"
5457
/>
58+
<ButtonBase
59+
v-else-if="status === 'pending' || status === 'idle'"
60+
disabled
61+
classicon="i-carbon:list"
62+
block
63+
>
64+
<span class="i-carbon:chevron-down w-3 h-3" aria-hidden="true" />
65+
</ButtonBase>
5566
</div>
5667
</div>
5768

5869
<!-- eslint-disable vue/no-v-html -- HTML is sanitized server-side -->
59-
<Readme v-if="data?.html" :html="data.html" />
70+
<Readme v-if="status === 'success' && data?.html" :html="data.html" />
71+
<div class="space-y-4" v-else-if="status === 'pending' || status === 'idle'">
72+
<!-- Heading -->
73+
<SkeletonBlock class="h-7 w-2/3" />
74+
<!-- Paragraphs -->
75+
<SkeletonBlock class="h-4 w-full" />
76+
<SkeletonBlock class="h-4 w-full" />
77+
<SkeletonBlock class="h-4 w-4/5" />
78+
<!-- Gap for section break -->
79+
<SkeletonBlock class="h-6 w-1/2 mt-6" />
80+
<SkeletonBlock class="h-4 w-full" />
81+
<SkeletonBlock class="h-4 w-full" />
82+
<SkeletonBlock class="h-4 w-3/4" />
83+
<!-- Code block placeholder -->
84+
<SkeletonBlock class="h-24 w-full rounded-lg mt-4" />
85+
<SkeletonBlock class="h-4 w-full" />
86+
<SkeletonBlock class="h-4 w-5/6" />
87+
</div>
88+
<div v-else-if="status === 'error'" class="text-red-500">
89+
{{ $t('package.readme.load_error') }}
90+
</div>
6091
<p v-else class="text-fg-muted italic">
6192
{{ $t('package.readme.no_readme') }}
6293
<a

app/components/ReadmeTocDropdown.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,6 @@ function handleKeydown(event: KeyboardEvent) {
152152
@click="toggle"
153153
@keydown="handleKeydown"
154154
classicon="i-carbon:list"
155-
class="px-2.5"
156155
block
157156
>
158157
<span

i18n/locales/en.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,7 @@
236236
"no_readme": "No README available.",
237237
"view_on_github": "View on GitHub",
238238
"toc_title": "Outline",
239+
"load_error": "Failed to load README",
239240
"callout": {
240241
"note": "Note",
241242
"tip": "Tip",

i18n/schema.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -712,6 +712,9 @@
712712
"toc_title": {
713713
"type": "string"
714714
},
715+
"load_error": {
716+
"type": "string"
717+
},
715718
"callout": {
716719
"type": "object",
717720
"properties": {

lunaria/files/en-GB.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
"no_readme": "No README available.",
236236
"view_on_github": "View on GitHub",
237237
"toc_title": "Outline",
238+
"load_error": "Failed to load README",
238239
"callout": {
239240
"note": "Note",
240241
"tip": "Tip",

lunaria/files/en-US.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@
235235
"no_readme": "No README available.",
236236
"view_on_github": "View on GitHub",
237237
"toc_title": "Outline",
238+
"load_error": "Failed to load README",
238239
"callout": {
239240
"note": "Note",
240241
"tip": "Tip",

0 commit comments

Comments
 (0)