{"version":3,"file":"index.mjs","sources":["../../../../../packages/directives/trap-focus/index.ts"],"sourcesContent":["import { nextTick } from 'vue'\r\nimport {\r\n  obtainAllFocusableElements,\r\n  EVENT_CODE,\r\n} from '@sgui-plus/utils/aria'\r\n\r\nimport type { ObjectDirective } from 'vue'\r\n\r\nexport const FOCUSABLE_CHILDREN = '_trap-focus-children'\r\nexport const TRAP_FOCUS_HANDLER = '_trap-focus-handler'\r\n\r\nexport interface ITrapFocusElement extends HTMLElement {\r\n  [FOCUSABLE_CHILDREN]: HTMLElement[]\r\n  [TRAP_FOCUS_HANDLER]: (e: KeyboardEvent) => void\r\n}\r\n\r\nconst FOCUS_STACK: ITrapFocusElement[] = []\r\n\r\nconst FOCUS_HANDLER = (e: KeyboardEvent) => {\r\n  // Getting the top layer.\r\n  if (FOCUS_STACK.length === 0) return\r\n  const focusableElement =\r\n    FOCUS_STACK[FOCUS_STACK.length - 1][FOCUSABLE_CHILDREN]\r\n  if (focusableElement.length > 0 && e.code === EVENT_CODE.tab) {\r\n    if (focusableElement.length === 1) {\r\n      e.preventDefault()\r\n      if (document.activeElement !== focusableElement[0]) {\r\n        focusableElement[0].focus()\r\n      }\r\n      return\r\n    }\r\n    const goingBackward = e.shiftKey\r\n    const isFirst = e.target === focusableElement[0]\r\n    const isLast = e.target === focusableElement[focusableElement.length - 1]\r\n    if (isFirst && goingBackward) {\r\n      e.preventDefault()\r\n      focusableElement[focusableElement.length - 1].focus()\r\n    }\r\n    if (isLast && !goingBackward) {\r\n      e.preventDefault()\r\n      focusableElement[0].focus()\r\n    }\r\n\r\n    // the is critical since jsdom did not implement user actions, you can only mock it\r\n    // DELETE ME: when testing env switches to puppeteer\r\n    if (process.env.NODE_ENV === 'test') {\r\n      const index = focusableElement.findIndex(\r\n        (element: Element) => element === e.target\r\n      )\r\n      if (index !== -1) {\r\n        focusableElement[goingBackward ? index - 1 : index + 1]?.focus()\r\n      }\r\n    }\r\n  }\r\n}\r\n\r\nconst TrapFocus: ObjectDirective = {\r\n  beforeMount(el: ITrapFocusElement) {\r\n    el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\r\n    FOCUS_STACK.push(el)\r\n    if (FOCUS_STACK.length <= 1) {\r\n      document.addEventListener('keydown', FOCUS_HANDLER)\r\n    }\r\n  },\r\n  updated(el: ITrapFocusElement) {\r\n    nextTick(() => {\r\n      el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el)\r\n    })\r\n  },\r\n  unmounted() {\r\n    FOCUS_STACK.shift()\r\n    if (FOCUS_STACK.length === 0) {\r\n      document.removeEventListener('keydown', FOCUS_HANDLER)\r\n    }\r\n  },\r\n}\r\n\r\nexport default TrapFocus\r\n"],"names":[],"mappings":";;;AAKY,MAAC,kBAAkB,GAAG,uBAAuB;AAC7C,MAAC,kBAAkB,GAAG,sBAAsB;AACxD,MAAM,WAAW,GAAG,EAAE,CAAC;AACvB,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK;AAC7B,EAAE,IAAI,EAAE,CAAC;AACT,EAAE,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;AAC9B,IAAI,OAAO;AACX,EAAE,MAAM,gBAAgB,GAAG,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC;AACnF,EAAE,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,CAAC,GAAG,EAAE;AAChE,IAAI,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE;AACvC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC;AACzB,MAAM,IAAI,QAAQ,CAAC,aAAa,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE;AAC1D,QAAQ,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AACpC,OAAO;AACP,MAAM,OAAO;AACb,KAAK;AACL,IAAI,MAAM,aAAa,GAAG,CAAC,CAAC,QAAQ,CAAC;AACrC,IAAI,MAAM,OAAO,GAAG,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,CAAC,CAAC,CAAC;AACrD,IAAI,MAAM,MAAM,GAAG,CAAC,CAAC,MAAM,KAAK,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC9E,IAAI,IAAI,OAAO,IAAI,aAAa,EAAE;AAClC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC;AACzB,MAAM,gBAAgB,CAAC,gBAAgB,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AAC5D,KAAK;AACL,IAAI,IAAI,MAAM,IAAI,CAAC,aAAa,EAAE;AAClC,MAAM,CAAC,CAAC,cAAc,EAAE,CAAC;AACzB,MAAM,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC;AAClC,KAAK;AACL,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM,EAAE;AACzC,MAAM,MAAM,KAAK,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,OAAO,KAAK,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC;AAClF,MAAM,IAAI,KAAK,KAAK,CAAC,CAAC,EAAE;AACxB,QAAQ,CAAC,EAAE,GAAG,gBAAgB,CAAC,aAAa,GAAG,KAAK,GAAG,CAAC,GAAG,KAAK,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,EAAE,CAAC;AACrG,OAAO;AACP,KAAK;AACL,GAAG;AACH,CAAC,CAAC;AACG,MAAC,SAAS,GAAG;AAClB,EAAE,WAAW,CAAC,EAAE,EAAE;AAClB,IAAI,EAAE,CAAC,kBAAkB,CAAC,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC;AAC5D,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACzB,IAAI,IAAI,WAAW,CAAC,MAAM,IAAI,CAAC,EAAE;AACjC,MAAM,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAC1D,KAAK;AACL,GAAG;AACH,EAAE,OAAO,CAAC,EAAE,EAAE;AACd,IAAI,QAAQ,CAAC,MAAM;AACnB,MAAM,EAAE,CAAC,kBAAkB,CAAC,GAAG,0BAA0B,CAAC,EAAE,CAAC,CAAC;AAC9D,KAAK,CAAC,CAAC;AACP,GAAG;AACH,EAAE,SAAS,GAAG;AACd,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;AACxB,IAAI,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,EAAE;AAClC,MAAM,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;AAC7D,KAAK;AACL,GAAG;AACH;;;;"}