11<script setup lang="ts">
22import type { SlimPackumentVersion , InstallSizeResult } from ' #shared/types'
3- import { onClickOutside , useEventListener } from ' @vueuse/core'
3+ import { onClickOutside , useEventListener , useMediaQuery } from ' @vueuse/core'
44
55const props = withDefaults (
66 defineProps <{
@@ -18,10 +18,10 @@ const triggerRef = useTemplateRef('triggerRef')
1818const listRef = useTemplateRef (' listRef' )
1919const isOpen = shallowRef (false )
2020const highlightedIndex = shallowRef (- 1 )
21- const dropdownPosition = shallowRef <{ top: number ; right : number } | null >(null )
21+ const dropdownPosition = shallowRef <{ top: number ; left : number } | null >(null )
2222
2323const { t } = useI18n ()
24- const menuId = ` ${ useId ()}- download-menu`
24+ const menuId = ' download-menu'
2525const menuItems = computed (() => {
2626 const items = [{ id: ' package' , label: t (' package.download.package' ), icon: ' i-lucide:package' }]
2727 if (props .installSize ) {
@@ -34,11 +34,13 @@ const menuItems = computed(() => {
3434 return items
3535})
3636
37+ const prefersReducedMotion = useMediaQuery (' (prefers-reduced-motion: reduce)' )
38+
3739function getDropdownStyle(): Record <string , string > {
3840 if (! dropdownPosition .value ) return {}
3941 return {
4042 top: ` ${dropdownPosition .value .top }px ` ,
41- right : ` ${document . documentElement . clientWidth - dropdownPosition .value .right }px ` ,
43+ left : ` ${dropdownPosition .value .left }px ` ,
4244 }
4345}
4446
@@ -50,7 +52,7 @@ function toggle() {
5052 if (rect ) {
5153 dropdownPosition .value = {
5254 top: rect .bottom + 4 ,
53- right : rect .right ,
55+ left : rect .left ,
5456 }
5557 }
5658 isOpen .value = true
@@ -200,36 +202,40 @@ defineOptions({
200202 >
201203 {{ $t('package.download.button') }}
202204 <span
203- class =" i-lucide:chevron-down ms-1 transition-transform duration-200 motion-reduce:transition-none"
204- :class =" [size === 'small' ? 'w-3 h-3' : 'w-3.5 h-3.5', { 'rotate-180': isOpen }]"
205+ class =" i-lucide:chevron-down ms-1"
206+ :class =" [
207+ size === 'small' ? 'w-3 h-3' : 'w-3.5 h-3.5',
208+ { 'rotate-180': isOpen },
209+ prefersReducedMotion ? '' : 'transition-transform duration-200',
210+ ]"
205211 aria-hidden =" true"
206212 />
207213 </ButtonBase >
208214
209215 <Teleport to =" body" >
210216 <Transition
211- enter-active-class =" transition-opacity duration-150 motion-reduce:duration-0 "
212- enter-from-class =" opacity-0"
217+ : enter-active-class =" prefersReducedMotion ? '' : ' transition-opacity duration-150' "
218+ : enter-from-class =" prefersReducedMotion ? '' : ' opacity-0' "
213219 enter-to-class =" opacity-100"
214- leave-active-class =" transition-opacity duration-100 motion-reduce:duration-0 "
220+ : leave-active-class =" prefersReducedMotion ? '' : ' transition-opacity duration-100' "
215221 leave-from-class =" opacity-100"
216- leave-to-class =" opacity-0"
222+ : leave-to-class =" prefersReducedMotion ? '' : ' opacity-0' "
217223 >
218- <div
224+ <ul
219225 v-if =" isOpen"
220226 :id =" menuId"
221227 ref =" listRef"
222228 role =" menu"
229+ :aria-label =" $t('package.download.button')"
223230 :style =" getDropdownStyle()"
224- class =" fixed bg-bg-subtle border border-border rounded-md shadow-lg z-50 py-1 w-64 overscroll-contain "
231+ class =" fixed bg-bg-subtle border border-border rounded-md shadow-lg z-50"
225232 @keydown =" handleKeydown"
226233 >
227- <button
234+ <li
228235 v-for =" (item, index) in menuItems"
229236 :key =" item.id"
230237 role =" menuitem"
231- type =" button"
232- class =" w-full flex items-center gap-2 px-3 py-2 text-sm text-fg-muted transition-colors duration-150"
238+ class =" cursor-pointer flex items-center gap-2 px-3 py-1.5 text-sm text-fg-muted transition-colors duration-150"
233239 :class =" [
234240 highlightedIndex === index
235241 ? 'bg-bg-elevated text-fg'
@@ -240,8 +246,8 @@ defineOptions({
240246 >
241247 <span :class =" item.icon" class =" w-4 h-4" aria-hidden =" true" />
242248 {{ item.label }}
243- </button >
244- </div >
249+ </li >
250+ </ul >
245251 </Transition >
246252 </Teleport >
247253</template >
0 commit comments