Skip to content

feat(useFocusTrap): expose updateContainerElements for dynamic contai… #4849

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jul 28, 2025
Merged
35 changes: 35 additions & 0 deletions packages/integrations/useFocusTrap/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,41 @@ const { hasFocus, activate, deactivate } = useFocusTrap([targetOne, targetTwo])
</template>
```

**Dynamic Focus Target**

```vue
<script setup lang="ts">
import { useFocusTrap } from '@vueuse/integrations/useFocusTrap'
import { computed, shallowRef, useTemplateRef } from 'vue'

const left = useTemplateRef('left')
const right = useTemplateRef('right')
const currentRef = shallowRef<'left' | 'right'>('left')

const target = computed(() => {
return currentRef.value === 'left' ? left : currentRef.value === 'right' ? right : null
})
const { hasFocus, activate } = useFocusTrap(target)

activate()

setTimeout(() => {
currentRef.value = 'right'
}, 3000)
</script>

<template>
<div>
<div ref="left" class="left">
...
</div>
<div ref="right" class="right">
...
</div>
</div>
</template>
```

**Automatically Focus**

```vue
Expand Down
60 changes: 37 additions & 23 deletions packages/integrations/useFocusTrap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export interface UseFocusTrapReturn {
* @see https://vueuse.org/useFocusTrap
*/
export function useFocusTrap(
target: Arrayable<MaybeRefOrGetter<string> | MaybeComputedElementRef>,
target: MaybeRefOrGetter<Arrayable<MaybeRefOrGetter<string> | MaybeComputedElementRef>>,
options: UseFocusTrapOptions = {},
): UseFocusTrapReturn {
let trap: undefined | FocusTrap
Expand Down Expand Up @@ -102,28 +102,42 @@ export function useFocusTrap(
(els) => {
if (!els.length)
return

trap = createFocusTrap(els, {
...focusTrapOptions,
onActivate() {
hasFocus.value = true

// Apply if user provided onActivate option
if (options.onActivate)
options.onActivate()
},
onDeactivate() {
hasFocus.value = false

// Apply if user provided onDeactivate option
if (options.onDeactivate)
options.onDeactivate()
},
})

// Focus if immediate is set to true
if (immediate)
activate()
if (!trap) {
// create the trap
trap = createFocusTrap(els, {
...focusTrapOptions,
onActivate() {
hasFocus.value = true

// Apply if user provided onActivate option
if (options.onActivate)
options.onActivate()
},
onDeactivate() {
hasFocus.value = false

// Apply if user provided onDeactivate option
if (options.onDeactivate)
options.onDeactivate()
},
})

// Focus if immediate is set to true
if (immediate)
activate()
}
else {
// get the active state of the trap
const isActive = trap?.active

// update the container elements
trap?.updateContainerElements(els)

// if the trap is not active and immediate is set to true, activate the trap
if (!isActive && immediate) {
activate()
}
}
},
{ flush: 'post' },
)
Expand Down
Loading
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy