{"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;;;;"}