Skip to content
UI

Focus Trap

FocusTrap keeps Tab and Shift+Tab navigation inside its content. It is useful for custom dialogs, drawers, and other temporary interfaces that must prevent focus from escaping.

<script setup lang="ts">
import { FocusTrap } from '@destyler-ui/vue'
</script>
import { FocusTrap } from '@destyler-ui/react'
import { FocusTrap } from '@destyler-ui/solid'
<script lang="ts">
import { FocusTrap } from '@destyler-ui/svelte/focus-trap'
</script>
<script setup lang="ts">
import { FocusTrap } from '@destyler-ui/vue'
import { ref } from 'vue'
const trapped = ref(false)
</script>
<template>
<button type="button" @click="trapped = true">Start trap</button>
<FocusTrap :disabled="!trapped" return-focus-on-deactivate>
<input aria-label="Name" />
<button type="button" @click="trapped = false">End trap</button>
</FocusTrap>
</template>
import { FocusTrap } from '@destyler-ui/react'
import { useState } from 'react'
export function Example() {
const [trapped, setTrapped] = useState(false)
return (
<>
<button type="button" onClick={() => setTrapped(true)}>Start trap</button>
<FocusTrap disabled={!trapped} returnFocusOnDeactivate>
<input aria-label="Name" />
<button type="button" onClick={() => setTrapped(false)}>End trap</button>
</FocusTrap>
</>
)
}
import { FocusTrap } from '@destyler-ui/solid'
import { createSignal } from 'solid-js'
export function Example() {
const [trapped, setTrapped] = createSignal(false)
return (
<>
<button type="button" onClick={() => setTrapped(true)}>Start trap</button>
<FocusTrap disabled={!trapped()} returnFocusOnDeactivate>
<input aria-label="Name" />
<button type="button" onClick={() => setTrapped(false)}>End trap</button>
</FocusTrap>
</>
)
}
<script lang="ts">
import { FocusTrap } from '@destyler-ui/svelte/focus-trap'
let trapped = $state(false)
</script>
<button type="button" onclick={() => (trapped = true)}>Start trap</button>
<FocusTrap disabled={!trapped} returnFocusOnDeactivate>
<label>
Name
<input />
</label>
<button type="button" onclick={() => (trapped = false)}>End trap</button>
</FocusTrap>

The component renders a div and accepts normal div attributes in addition to the options below. Always provide at least one focusable child, or set fallbackFocus to a focusable target.

PropTypeDefaultDescription
disabledbooleanfalseStops trapping focus while preserving the rendered content.
initialFocusFocusTarget | falseFirst tabbable elementChooses the target focused when the trap activates.
fallbackFocusFocusTargetTarget used when the trap contains no tabbable element.
returnFocusOnDeactivatebooleantrueReturns focus to the previously focused element when disabled or removed.
setReturnFocusFocusTarget | falsePreviously focused elementOverrides the target that receives returned focus.
onActivate() => voidRuns before focus moves into the trap.
onDeactivate() => voidRuns when the trap is deactivated.
refElementBindable reference to the rendered element.

FocusTarget can be an element, a selector, or a function returning either one.