{"version":3,"file":"index.mjs","sources":["../../../../packages/directives/trap-focus/index.ts"],"sourcesContent":["import { nextTick } from 'vue'\nimport { on, off, obtainAllFocusableElements } from '@element-ultra/utils'\nimport { EVENT_CODE } from '@element-ultra/shared'\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":";;;;;;;AAKO,MAAM,kBAAqB,GAAA,uBAAA;AAC3B,MAAM,kBAAqB,GAAA,sBAAA;AAOlC,MAAM,cAAc,EAAC,CAAA;AAErB,MAAM,aAAA,GAAgB,CAAC,CAAqB,KAAA;AAf5C,EAAA,IAAA,EAAA,CAAA;AAiBE,EAAA,IAAI,YAAY,MAAW,KAAA,CAAA;AAAG,IAAA,OAAA;AAC9B,EAAA,MAAM,mBACJ,WAAY,CAAA,WAAA,CAAY,MAAS,GAAA,CAAC,EAAE,kBAAkB,CAAA,CAAA;AACxD,EAAA,IAAI,iBAAiB,MAAS,GAAA,CAAA,IAAK,CAAE,CAAA,IAAA,KAAS,WAAW,GAAK,EAAA;AAC5D,IAAI,IAAA,gBAAA,CAAiB,WAAW,CAAG,EAAA;AACjC,MAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,MAAA,IAAI,QAAS,CAAA,aAAA,KAAkB,gBAAiB,CAAA,CAAC,CAAG,EAAA;AAClD,QAAiB,gBAAA,CAAA,CAAC,EAAE,KAAM,EAAA,CAAA;AAAA,OAC5B;AACA,MAAA,OAAA;AAAA,KACF;AACA,IAAA,MAAM,gBAAgB,CAAE,CAAA,QAAA,CAAA;AACxB,IAAA,MAAM,OAAU,GAAA,CAAA,CAAE,MAAW,KAAA,gBAAA,CAAiB,CAAC,CAAA,CAAA;AAC/C,IAAA,MAAM,SAAS,CAAE,CAAA,MAAA,KAAW,gBAAiB,CAAA,gBAAA,CAAiB,SAAS,CAAC,CAAA,CAAA;AACxE,IAAA,IAAI,WAAW,aAAe,EAAA;AAC5B,MAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,MAAA,gBAAA,CAAiB,gBAAiB,CAAA,MAAA,GAAS,CAAC,CAAA,CAAE,KAAM,EAAA,CAAA;AAAA,KACtD;AACA,IAAI,IAAA,MAAA,IAAU,CAAC,aAAe,EAAA;AAC5B,MAAA,CAAA,CAAE,cAAe,EAAA,CAAA;AACjB,MAAiB,gBAAA,CAAA,CAAC,EAAE,KAAM,EAAA,CAAA;AAAA,KAC5B;AAIA,IAAI,IAAA,OAAA,CAAQ,GAAI,CAAA,QAAA,KAAa,MAAQ,EAAA;AACnC,MAAA,MAAM,QAAQ,gBAAiB,CAAA,SAAA;AAAA,QAC7B,CAAC,OAAqB,KAAA,OAAA,KAAY,CAAE,CAAA,MAAA;AAAA,OACtC,CAAA;AACA,MAAA,IAAI,UAAU,CAAI,CAAA,EAAA;AAChB,QAAA,CAAA,EAAA,GAAA,gBAAA,CAAiB,gBAAgB,KAAQ,GAAA,CAAA,GAAI,KAAQ,GAAA,CAAC,MAAtD,IAAyD,GAAA,KAAA,CAAA,GAAA,EAAA,CAAA,KAAA,EAAA,CAAA;AAAA,OAC3D;AAAA,KACF;AAAA,GACF;AACF,CAAA,CAAA;AAEA,MAAM,SAA6B,GAAA;AAAA,EACjC,YAAY,EAAuB,EAAA;AACjC,IAAG,EAAA,CAAA,kBAAkB,CAAI,GAAA,0BAAA,CAA2B,EAAE,CAAA,CAAA;AACtD,IAAA,WAAA,CAAY,KAAK,EAAE,CAAA,CAAA;AACnB,IAAI,IAAA,WAAA,CAAY,UAAU,CAAG,EAAA;AAC3B,MAAG,EAAA,CAAA,QAAA,EAAU,WAAW,aAAa,CAAA,CAAA;AAAA,KACvC;AAAA,GACF;AAAA,EACA,QAAQ,EAAuB,EAAA;AAC7B,IAAA,QAAA,CAAS,MAAM;AACb,MAAG,EAAA,CAAA,kBAAkB,CAAI,GAAA,0BAAA,CAA2B,EAAE,CAAA,CAAA;AAAA,KACvD,CAAA,CAAA;AAAA,GACH;AAAA,EACA,SAAY,GAAA;AACV,IAAA,WAAA,CAAY,KAAM,EAAA,CAAA;AAClB,IAAI,IAAA,WAAA,CAAY,WAAW,CAAG,EAAA;AAC5B,MAAI,GAAA,CAAA,QAAA,EAAU,WAAW,aAAa,CAAA,CAAA;AAAA,KACxC;AAAA,GACF;AACF;;;;"}