element-plus
Version:
A Component Library for Vue 3
1 lines • 4.62 kB
Source Map (JSON)
{"version":3,"file":"index.mjs","sources":["../../../../../packages/directives/trap-focus/index.ts"],"sourcesContent":["import { nextTick } from 'vue'\nimport { getEventCode, obtainAllFocusableElements } from '@element-plus/utils'\nimport { EVENT_CODE } from '@element-plus/constants'\n\nimport type { ObjectDirective } from 'vue'\n\nexport const FOCUSABLE_CHILDREN = '_trap-focus-children'\nexport const TRAP_FOCUS_HANDLER = '_trap-focus-handler'\n\nexport interface TrapFocusElement extends HTMLElement {\n [FOCUSABLE_CHILDREN]: HTMLElement[]\n [TRAP_FOCUS_HANDLER]: (e: KeyboardEvent) => void\n}\n\nconst FOCUS_STACK: TrapFocusElement[] = []\n\nconst FOCUS_HANDLER = (e: KeyboardEvent) => {\n // Getting the top layer.\n if (FOCUS_STACK.length === 0) return\n const code = getEventCode(e)\n const focusableElement =\n FOCUS_STACK[FOCUS_STACK.length - 1][FOCUSABLE_CHILDREN]\n if (focusableElement.length > 0 && code === EVENT_CODE.tab) {\n if (focusableElement.length === 1) {\n e.preventDefault()\n if (document.activeElement !== focusableElement[0]) {\n focusableElement[0].focus()\n }\n return\n }\n const goingBackward = e.shiftKey\n const isFirst = e.target === focusableElement[0]\n const isLast = e.target === focusableElement[focusableElement.length - 1]\n if (isFirst && goingBackward) {\n e.preventDefault()\n focusableElement[focusableElement.length - 1].focus()\n }\n if (isLast && !goingBackward) {\n e.preventDefault()\n focusableElement[0].focus()\n }\n\n // the is critical since jsdom did not implement user actions, you can only mock it\n // DELETE ME: when testing env switches to puppeteer\n if (process.env.NODE_ENV === 'test') {\n const index = focusableElement.indexOf(e.target as HTMLElement)\n if (index !== -1) {\n focusableElement[goingBackward ? index - 1 : index + 1]?.focus()\n }\n }\n }\n}\n\nconst TrapFocus: ObjectDirective = {\n beforeMount(el: TrapFocusElement) {\n el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\n FOCUS_STACK.push(el)\n if (FOCUS_STACK.length <= 1) {\n document.addEventListener('keydown', FOCUS_HANDLER)\n }\n },\n updated(el: TrapFocusElement) {\n nextTick(() => {\n el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\n })\n },\n unmounted() {\n FOCUS_STACK.shift()\n if (FOCUS_STACK.length === 0) {\n document.removeEventListener('keydown', FOCUS_HANDLER)\n }\n },\n}\n\nexport default TrapFocus\n"],"names":[],"mappings":"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"}