Skip to content

Commit 70f9d59

Browse files
Adebesin-Cellclaude
andcommitted
fix: make DownloadButton SSR-safe with useId and CSS reduced motion
Replace JS-based useMediaQuery with CSS motion-reduce: variants to eliminate hydration mismatches during prerender. Add useId() for unique menu IDs matching PackageManagerSelect pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent e98977e commit 70f9d59

File tree

1 file changed

+6
-9
lines changed

1 file changed

+6
-9
lines changed

app/components/Package/DownloadButton.vue

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const highlightedIndex = shallowRef(-1)
2121
const dropdownPosition = shallowRef<{ top: number; right: number } | null>(null)
2222
2323
const { t } = useI18n()
24-
const menuId = 'download-menu'
24+
const menuId = `${useId()}-download-menu`
2525
const menuItems = computed(() => {
2626
const items = [{ id: 'package', label: t('package.download.package'), icon: 'i-lucide:package' }]
2727
if (props.installSize) {
@@ -177,8 +177,6 @@ function downloadDependenciesScript() {
177177
URL.revokeObjectURL(url)
178178
}
179179
180-
const prefersReducedMotion = useMediaQuery('(prefers-reduced-motion: reduce)')
181-
182180
useEventListener('scroll', () => isOpen.value && close(), { passive: true })
183181
184182
defineOptions({
@@ -202,24 +200,23 @@ defineOptions({
202200
>
203201
{{ $t('package.download.button') }}
204202
<span
205-
class="i-lucide:chevron-down ms-1"
203+
class="i-lucide:chevron-down ms-1 transition-transform duration-200 motion-reduce:transition-none"
206204
:class="[
207205
size === 'small' ? 'w-3 h-3' : 'w-3.5 h-3.5',
208206
{ 'rotate-180': isOpen },
209-
prefersReducedMotion ? '' : 'transition-transform duration-200',
210207
]"
211208
aria-hidden="true"
212209
/>
213210
</ButtonBase>
214211

215212
<Teleport to="body">
216213
<Transition
217-
:enter-active-class="prefersReducedMotion ? '' : 'transition-opacity duration-150'"
218-
:enter-from-class="prefersReducedMotion ? '' : 'opacity-0'"
214+
enter-active-class="transition-opacity duration-150 motion-reduce:duration-0"
215+
enter-from-class="opacity-0"
219216
enter-to-class="opacity-100"
220-
:leave-active-class="prefersReducedMotion ? '' : 'transition-opacity duration-100'"
217+
leave-active-class="transition-opacity duration-100 motion-reduce:duration-0"
221218
leave-from-class="opacity-100"
222-
:leave-to-class="prefersReducedMotion ? '' : 'opacity-0'"
219+
leave-to-class="opacity-0"
223220
>
224221
<div
225222
v-if="isOpen"

0 commit comments

Comments
 (0)