{"id":15108,"library":"focus-trap-vue","title":"Vue Focus Trap Component","description":"focus-trap-vue is a Vue component designed to enhance web accessibility by programmatically trapping keyboard focus within a specified DOM element. This is crucial for UI patterns like modals, dialogs, and sidebars, preventing users of assistive technologies from accidentally tabbing out of the active context. The current stable version is 4.1.0, last published in August 2025, with regular patch and minor releases, indicating active maintenance and a stable API. It acts as a Vue-specific wrapper around the robust `focus-trap` library, inheriting its extensive focus management capabilities. Key differentiators include its seamless integration into Vue applications, support for both Vue 2 (via `@legacy` package) and Vue 3, and flexible control mechanisms via `active` prop, `v-model:active`, or direct method calls, while enforcing best practices for accessibility by leveraging its underlying peer dependency.","status":"active","version":"4.1.0","language":"javascript","source_language":"en","source_url":"https://github.com/posva/focus-trap-vue","tags":["javascript","focus","trap","a11y","accessibility","modal","component","block","lock","typescript"],"install":[{"cmd":"npm install focus-trap-vue","lang":"bash","label":"npm"},{"cmd":"yarn add focus-trap-vue","lang":"bash","label":"yarn"},{"cmd":"pnpm add focus-trap-vue","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Provides the core focus trapping logic; required as a peer dependency.","package":"focus-trap","optional":false},{"reason":"The foundational Vue.js framework, required for the component to function.","package":"vue","optional":false}],"imports":[{"note":"This is the primary named export for the component. CommonJS `require` is generally incorrect in modern Vue 3 ESM projects.","wrong":"const FocusTrap = require('focus-trap-vue').FocusTrap;","symbol":"FocusTrap","correct":"import { FocusTrap } from 'focus-trap-vue';"},{"note":"Import types explicitly for type-checking when using TypeScript, particularly for advanced prop configurations like `tabbableOptions`.","symbol":"FocusTrapTabbableOptions","correct":"import type { FocusTrapTabbableOptions } from 'focus-trap-vue';"}],"quickstart":{"code":"import { createApp, ref } from 'vue';\nimport { FocusTrap } from 'focus-trap-vue';\n\nconst app = createApp({\n  components: {\n    FocusTrap,\n  },\n  setup() {\n    const isActive = ref(false);\n    const nameInput = ref<HTMLInputElement | null>(null);\n\n    return {\n      isActive,\n      nameInput,\n      acceptCookies: () => {\n        alert('Cookies accepted!');\n        isActive.value = false;\n      },\n    };\n  },\n  template: `\n    <div>\n      <button @click=\"isActive = true\">Open Cookie Consent</button>\n\n      <focus-trap v-model:active=\"isActive\" :initial-focus=\"() => nameInput.value\">\n        <div v-if=\"isActive\" style=\"border: 1px solid #ccc; padding: 20px; background: #f9f9f9; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 1000; width: 300px; text-align: center;\">\n          <p>Do you accept our use of cookies?</p>\n          <label>Your Name: <input ref=\"nameInput\" type=\"text\" /></label>\n          <div style=\"margin-top: 15px;\">\n            <button @click=\"acceptCookies\" style=\"margin-right: 10px;\">Yes, I accept</button>\n            <button @click=\"isActive = false\">No, thank you</button>\n          </div>\n        </div>\n      </focus-trap>\n\n      <p style=\"margin-top: 200px;\">Content behind the modal.</p>\n      <button>Another button</button>\n    </div>\n  `,\n});\n\napp.mount('#app');","lang":"typescript","description":"Demonstrates a basic focus trap using `v-model:active` to control visibility and setting `initialFocus` to an input field within a modal-like cookie consent dialog for improved accessibility."},"warnings":[{"fix":"Review the `CHANGELOG.md` for `focus-trap-vue` and `focus-trap` to understand necessary code adaptations, especially if migrating from pre-4.0.0 versions or if IE support is critical. Ensure `focus-trap` v7 is installed.","message":"Version 4.0.0 introduced breaking changes, primarily due to upgrading its underlying `focus-trap` dependency to v7. This includes dropping support for Internet Explorer browsers and other behavioral changes in the core focus trapping logic. Refer to the `focus-trap` changelog for full details.","severity":"breaking","affected_versions":">=4.0.0"},{"fix":"Ensure `npm install focus-trap vue` (for Vue 3) or `npm install focus-trap vue@^2 focus-trap-vue@legacy` (for Vue 2) is run.","message":"The `focus-trap` and `vue` packages are peer dependencies and must be installed separately alongside `focus-trap-vue`. Failure to do so will result in runtime errors.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Ensure the `FocusTrap` component directly contains only a single HTML element or Vue component as its immediate child.","message":"The `FocusTrap` component is designed to wrap exactly one child element. Providing multiple root children will lead to undefined behavior or errors.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"Always provide a valid CSS selector or a function returning a focusable DOM `Element` for the `initialFocus` prop. If targeting a container, ensure it has `tabindex=\"-1\"`.","message":"When setting `initialFocus`, the target element should be a focusable and ideally interactable element (e.g., an input, button, or an element with `tabindex=\"-1\"` if it's a container). If a non-focusable element is targeted, the trap might not behave as expected.","severity":"gotcha","affected_versions":">=3.0.0"},{"fix":"For Vue 2 projects, install `focus-trap-vue@legacy`. For Vue 3 projects, install `focus-trap-vue` (without `@legacy`).","message":"Different versions of `focus-trap-vue` are required for Vue 2 vs. Vue 3. The main package (`focus-trap-vue`) is for Vue 3, while Vue 2 requires `focus-trap-vue@legacy`.","severity":"gotcha","affected_versions":">=2.0.0"}],"env_vars":null,"last_verified":"2026-04-21T00:00:00.000Z","next_check":"2026-07-20T00:00:00.000Z","problems":[{"fix":"Verify installation with `npm install focus-trap-vue` (or `@legacy`) and ensure correct import statement: `import { FocusTrap } from 'focus-trap-vue';`.","cause":"The package or its types were not installed correctly, or the import path is wrong.","error":"Cannot find module 'focus-trap-vue' or 'Cannot find name 'FocusTrap'."},{"fix":"Wrap all content within the `FocusTrap` component inside a single container `<div>` or custom component.","cause":"The `FocusTrap` component has more than one root child element in its slot.","error":"The FocusTrap component expects a single child element."},{"fix":"Ensure `FocusTrap` is either imported and registered locally in a component's `components` option, or globally registered via `app.component('FocusTrap', FocusTrap)` for Vue 3.","cause":"The `FocusTrap` component was used in a template but not properly registered with Vue.","error":"[Vue warn]: Failed to resolve component: FocusTrap"},{"fix":"For Vue 2 projects, use `npm install focus-trap-vue@legacy`. For Vue 3 projects, ensure `focus-trap-vue` is installed without `@legacy` and that your `vue` version meets the peer dependency requirement (e.g., `^3.0.0`).","cause":"An incorrect version of `focus-trap-vue` was installed for the corresponding Vue version in the project.","error":"Vue packages version mismatch: - focus-trap-vue requires Vue '^3.0.0' but Vue version is '2.x.x'."}],"ecosystem":"npm"}