Skip to content

Commit b1ee806

Browse files
committed
feat: show loading state for dependencies download option
1 parent b0de596 commit b1ee806

File tree

2 files changed

+32
-20
lines changed

2 files changed

+32
-20
lines changed

app/components/Package/DownloadButton.vue

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ const props = withDefaults(
77
packageName: string
88
version: SlimPackumentVersion
99
dependencies: DependencySize[] | null
10+
dependenciesLoading?: boolean
1011
size?: 'small' | 'medium'
1112
}>(),
1213
{
14+
dependenciesLoading: false,
1315
size: 'medium',
1416
},
1517
)
@@ -21,16 +23,14 @@ const highlightedIndex = shallowRef(-1)
2123
const dropdownPosition = shallowRef<{ top: number; left: number } | null>(null)
2224
2325
const menuId = 'download-menu'
24-
const menuItems = computed(() => {
25-
const items = [{ id: 'package', icon: 'i-lucide:package' }]
26-
if (props.dependencies?.length) {
27-
items.push({
28-
id: 'dependencies',
29-
icon: 'i-lucide:list-tree',
30-
})
31-
}
32-
return items
33-
})
26+
const menuItems = computed(() => [
27+
{ id: 'package', icon: 'i-lucide:package', disabled: false },
28+
{
29+
id: 'dependencies',
30+
icon: props.dependenciesLoading ? 'i-lucide:loader-circle' : 'i-lucide:list-tree',
31+
disabled: props.dependenciesLoading || !props.dependencies?.length,
32+
},
33+
])
3434
3535
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)')
3636
@@ -87,7 +87,7 @@ function handleKeydown(event: KeyboardEvent) {
8787
case 'Enter':
8888
case ' ':
8989
event.preventDefault()
90-
handleAction(menuItems.value[highlightedIndex.value]?.id)
90+
handleAction(menuItems.value[highlightedIndex.value])
9191
break
9292
case 'Escape':
9393
event.preventDefault()
@@ -100,10 +100,11 @@ function handleKeydown(event: KeyboardEvent) {
100100
}
101101
}
102102
103-
function handleAction(id: string | undefined) {
104-
if (id === 'package') {
103+
function handleAction(item: (typeof menuItems.value)[number] | undefined) {
104+
if (!item || item.disabled) return
105+
if (item.id === 'package') {
105106
downloadPackage()
106-
} else if (id === 'dependencies') {
107+
} else if (item.id === 'dependencies') {
107108
downloadDependenciesScript()
108109
}
109110
close()
@@ -233,16 +234,26 @@ defineOptions({
233234
v-for="(item, index) in menuItems"
234235
:key="item.id"
235236
role="menuitem"
236-
class="cursor-pointer flex items-center gap-2 px-3 py-1.5 text-sm text-fg-muted transition-colors duration-150"
237+
:aria-disabled="item.disabled || undefined"
238+
class="flex items-center gap-2 px-3 py-1.5 text-sm transition-colors duration-150"
237239
:class="[
238-
highlightedIndex === index
239-
? 'bg-bg-elevated text-fg'
240-
: 'hover:bg-bg-elevated hover:text-fg',
240+
item.disabled
241+
? 'cursor-default text-fg-muted/50'
242+
: highlightedIndex === index
243+
? 'cursor-pointer bg-bg-elevated text-fg'
244+
: 'cursor-pointer text-fg-muted hover:bg-bg-elevated hover:text-fg',
241245
]"
242-
@click="handleAction(item.id)"
246+
@click="handleAction(item)"
243247
@mouseenter="highlightedIndex = index"
244248
>
245-
<span :class="item.icon" class="w-4 h-4" aria-hidden="true" />
249+
<span
250+
:class="[
251+
item.icon,
252+
{ 'animate-spin': item.id === 'dependencies' && dependenciesLoading },
253+
]"
254+
class="w-4 h-4"
255+
aria-hidden="true"
256+
/>
246257
{{
247258
item.id === 'package'
248259
? $t('package.download.package')

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ const showSkeleton = shallowRef(false)
778778
:package-name="pkg.name"
779779
:version="displayVersion"
780780
:dependencies="installSize?.dependencies ?? null"
781+
:dependencies-loading="installSizeStatus === 'pending'"
781782
size="small"
782783
/>
783784
<PackageManagerSelect />

0 commit comments

Comments
 (0)