@@ -253,16 +253,43 @@ watch(status, (status) => {
253253 }
254254})
255255
256+ // Keyboard accessibility: dispatch the configured trigger event on Enter/Space
257+ // so users navigating via keyboard can activate the placeholder.
258+ const keyboardTriggerable = computed (() => {
259+ if (ready .value )
260+ return false
261+ const triggers = Array .isArray (props .trigger ) ? props .trigger : [props .trigger ]
262+ return triggers .some (t => typeof t === ' string' && ! [' immediate' , ' onNuxtReady' , ' visibility' , ' visible' ].includes (t ))
263+ })
264+
265+ function onPlaceholderKeydown(e : KeyboardEvent ) {
266+ if (e .key !== ' Enter' && e .key !== ' ' )
267+ return
268+ e .preventDefault ()
269+ if (! rootEl .value )
270+ return
271+ const triggers = (Array .isArray (props .trigger ) ? props .trigger : [props .trigger ]).filter (Boolean ) as string []
272+ for (const t of triggers ) {
273+ if (typeof t !== ' string' )
274+ continue
275+ if ([' immediate' , ' onNuxtReady' , ' visibility' , ' visible' ].includes (t ))
276+ continue
277+ rootEl .value .dispatchEvent (new Event (t , { bubbles: false }))
278+ }
279+ }
280+
256281const rootAttrs = computed (() => {
282+ const interactive = keyboardTriggerable .value
257283 return defu (props .rootAttrs , {
258284 ' aria-busy' : status .value === ' loading' ,
259285 ' aria-label' : status .value === ' awaitingLoad'
260- ? ' Vimeo Player - Placeholder'
286+ ? ( interactive ? ' Play video ' : ' Vimeo Player - Placeholder' )
261287 : status .value === ' loading'
262288 ? ' Vimeo Player - Loading'
263289 : ' Vimeo Player - Loaded' ,
264290 ' aria-live' : ' polite' ,
265- ' role' : ' application' ,
291+ ' role' : interactive ? ' button' : ' application' ,
292+ ' tabindex' : interactive ? 0 : undefined ,
266293 ' style' : {
267294 ' --vimeo-ratio' : props .ratio ,
268295 ' maxWidth' : ' 100%' ,
@@ -279,7 +306,7 @@ const rootAttrs = computed(() => {
279306const placeholderAttrs = computed (() => {
280307 return defu (props .placeholderAttrs , {
281308 src: placeholder .value ,
282- alt: ' ' ,
309+ alt: ' Play video ' ,
283310 loading: props .aboveTheFold ? ' eager' : ' lazy' ,
284311 // @ts-expect-error untyped
285312 fetchpriority: props .aboveTheFold ? ' high' : undefined ,
@@ -296,7 +323,7 @@ onBeforeUnmount(() => player?.unload())
296323 </script >
297324
298325<template >
299- <div ref =" rootEl" v-bind =" rootAttrs" >
326+ <div ref =" rootEl" v-bind =" rootAttrs" @keydown = " keyboardTriggerable ? onPlaceholderKeydown($event) : undefined " >
300327 <div v-show =" ready" ref =" elVimeo" class =" vimeo-player" />
301328 <slot v-if =" !ready" v-bind =" payload" :placeholder =" placeholder" name =" placeholder" >
302329 <img v-if =" placeholder" v-bind =" placeholderAttrs" >
0 commit comments