index.mjs 1.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152
  1. import { obtainAllFocusableElements } from "../../utils/dom/aria.mjs";
  2. import { EVENT_CODE } from "../../constants/aria.mjs";
  3. import { getEventCode } from "../../utils/dom/event.mjs";
  4. import { nextTick } from "vue";
  5. //#region ../../packages/directives/trap-focus/index.ts
  6. const FOCUSABLE_CHILDREN = "_trap-focus-children";
  7. const TRAP_FOCUS_HANDLER = "_trap-focus-handler";
  8. const FOCUS_STACK = [];
  9. const FOCUS_HANDLER = (e) => {
  10. if (FOCUS_STACK.length === 0) return;
  11. const code = getEventCode(e);
  12. const focusableElement = FOCUS_STACK[FOCUS_STACK.length - 1][FOCUSABLE_CHILDREN];
  13. if (focusableElement.length > 0 && code === EVENT_CODE.tab) {
  14. if (focusableElement.length === 1) {
  15. e.preventDefault();
  16. if (document.activeElement !== focusableElement[0]) focusableElement[0].focus();
  17. return;
  18. }
  19. const goingBackward = e.shiftKey;
  20. const isFirst = e.target === focusableElement[0];
  21. const isLast = e.target === focusableElement[focusableElement.length - 1];
  22. if (isFirst && goingBackward) {
  23. e.preventDefault();
  24. focusableElement[focusableElement.length - 1].focus();
  25. }
  26. if (isLast && !goingBackward) {
  27. e.preventDefault();
  28. focusableElement[0].focus();
  29. }
  30. }
  31. };
  32. const TrapFocus = {
  33. beforeMount(el) {
  34. el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el);
  35. FOCUS_STACK.push(el);
  36. if (FOCUS_STACK.length <= 1) document.addEventListener("keydown", FOCUS_HANDLER);
  37. },
  38. updated(el) {
  39. nextTick(() => {
  40. el[FOCUSABLE_CHILDREN] = obtainAllFocusableElements(el);
  41. });
  42. },
  43. unmounted() {
  44. FOCUS_STACK.shift();
  45. if (FOCUS_STACK.length === 0) document.removeEventListener("keydown", FOCUS_HANDLER);
  46. }
  47. };
  48. //#endregion
  49. export { FOCUSABLE_CHILDREN, TRAP_FOCUS_HANDLER, TrapFocus as default };
  50. //# sourceMappingURL=index.mjs.map