UNPKG

element-plus

Version:

A Component Library for Vue 3

1 lines 3.53 kB
{"version":3,"file":"index.mjs","sources":["../../../../../packages/directives/trap-focus/index.ts"],"sourcesContent":["import { nextTick } from 'vue'\nimport { on, off } from '@element-plus/utils/dom'\nimport {\n obtainAllFocusableElements,\n EVENT_CODE,\n} from '@element-plus/utils/aria'\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 ITrapFocusElement extends HTMLElement {\n [FOCUSABLE_CHILDREN]: HTMLElement[]\n [TRAP_FOCUS_HANDLER]: (e: KeyboardEvent) => void\n}\n\nconst FOCUS_STACK = []\n\nconst FOCUS_HANDLER = (e: KeyboardEvent) => {\n // Getting the top layer.\n if (FOCUS_STACK.length === 0) return\n const focusableElement =\n FOCUS_STACK[FOCUS_STACK.length - 1][FOCUSABLE_CHILDREN]\n if (focusableElement.length > 0 && e.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.findIndex(\n (element: Element) => element === e.target\n )\n if (index !== -1) {\n focusableElement[goingBackward ? index - 1 : index + 1]?.focus()\n }\n }\n }\n}\n\nconst TrapFocus: ObjectDirective = {\n beforeMount(el: ITrapFocusElement) {\n el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\n FOCUS_STACK.push(el)\n if (FOCUS_STACK.length <= 1) {\n on(document, 'keydown', FOCUS_HANDLER)\n }\n },\n updated(el: ITrapFocusElement) {\n nextTick(() => {\n el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\n })\n },\n unmounted() {\n FOCUS_STACK.shift()\n if (FOCUS_STACK.length === 0) {\n off(document, 'keydown', FOCUS_HANDLER)\n }\n },\n}\n\nexport default TrapFocus\n"],"names":[],"mappings":";;;;MASa,qBAAqB;MACrB,qBAAqB;AAOlC,MAAM,cAAc;AAEpB,MAAM,gBAAgB,CAAC,MAAqB;AAnB5C;AAqBE,MAAI,YAAY,WAAW;AAAG;AAC9B,QAAM,mBACJ,YAAY,YAAY,SAAS,GAAG;AACtC,MAAI,iBAAiB,SAAS,KAAK,EAAE,SAAS,WAAW,KAAK;AAC5D,QAAI,iBAAiB,WAAW,GAAG;AACjC,QAAE;AACF,UAAI,SAAS,kBAAkB,iBAAiB,IAAI;AAClD,yBAAiB,GAAG;AAAA;AAEtB;AAAA;AAEF,UAAM,gBAAgB,EAAE;AACxB,UAAM,UAAU,EAAE,WAAW,iBAAiB;AAC9C,UAAM,SAAS,EAAE,WAAW,iBAAiB,iBAAiB,SAAS;AACvE,QAAI,WAAW,eAAe;AAC5B,QAAE;AACF,uBAAiB,iBAAiB,SAAS,GAAG;AAAA;AAEhD,QAAI,UAAU,CAAC,eAAe;AAC5B,QAAE;AACF,uBAAiB,GAAG;AAAA;AAKtB,QAAI,QAAQ,IAAI,aAAa,QAAQ;AACnC,YAAM,QAAQ,iBAAiB,UAC7B,CAAC,YAAqB,YAAY,EAAE;AAEtC,UAAI,UAAU,IAAI;AAChB,+BAAiB,gBAAgB,QAAQ,IAAI,QAAQ,OAArD,mBAAyD;AAAA;AAAA;AAAA;AAAA;MAM3D,YAA6B;AAAA,EACjC,YAAY,IAAuB;AACjC,OAAG,sBAAsB,2BAA2B;AACpD,gBAAY,KAAK;AACjB,QAAI,YAAY,UAAU,GAAG;AAC3B,SAAG,UAAU,WAAW;AAAA;AAAA;AAAA,EAG5B,QAAQ,IAAuB;AAC7B,aAAS,MAAM;AACb,SAAG,sBAAsB,2BAA2B;AAAA;AAAA;AAAA,EAGxD,YAAY;AACV,gBAAY;AACZ,QAAI,YAAY,WAAW,GAAG;AAC5B,UAAI,UAAU,WAAW;AAAA;AAAA;AAAA;;;;"}