modal.js 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637
  1. import { getTabbableElements } from '../internal/tabbable';
  2. let activeModals = [];
  3. export default class Modal {
  4. constructor(element) {
  5. this.tabDirection = 'forward';
  6. this.element = element;
  7. this.handleFocusIn = this.handleFocusIn.bind(this);
  8. this.handleKeyDown = this.handleKeyDown.bind(this);
  9. }
  10. activate() {
  11. activeModals.push(this.element);
  12. document.addEventListener('focusin', this.handleFocusIn);
  13. document.addEventListener('keydown', this.handleKeyDown);
  14. }
  15. deactivate() {
  16. activeModals = activeModals.filter(modal => modal !== this.element);
  17. document.removeEventListener('focusin', this.handleFocusIn);
  18. document.removeEventListener('keydown', this.handleKeyDown);
  19. }
  20. isActive() {
  21. return activeModals[activeModals.length - 1] === this.element;
  22. }
  23. handleFocusIn(event) {
  24. const path = event.composedPath();
  25. if (this.isActive() && !path.includes(this.element)) {
  26. const tabbableElements = getTabbableElements(this.element);
  27. const index = this.tabDirection === 'backward' ? tabbableElements.length - 1 : 0;
  28. tabbableElements[index].focus({ preventScroll: true });
  29. }
  30. }
  31. handleKeyDown(event) {
  32. if (event.key === 'Tab' && event.shiftKey) {
  33. this.tabDirection = 'backward';
  34. setTimeout(() => (this.tabDirection = 'forward'));
  35. }
  36. }
  37. }