chunk.DVN52LS5.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. // src/internal/tabbable.ts
  2. function isTabbable(el) {
  3. const tag = el.tagName.toLowerCase();
  4. if (el.getAttribute("tabindex") === "-1") {
  5. return false;
  6. }
  7. if (el.hasAttribute("disabled")) {
  8. return false;
  9. }
  10. if (el.hasAttribute("aria-disabled") && el.getAttribute("aria-disabled") !== "false") {
  11. return false;
  12. }
  13. if (el.hasAttribute("tabindex")) {
  14. return true;
  15. }
  16. if (el.hasAttribute("contenteditable") && el.getAttribute("contenteditable") !== "false") {
  17. return true;
  18. }
  19. if ((tag === "audio" || tag === "video") && el.hasAttribute("controls")) {
  20. return true;
  21. }
  22. if (tag === "input" && el.getAttribute("type") === "radio" && !el.hasAttribute("checked")) {
  23. return false;
  24. }
  25. if (!el.offsetParent) {
  26. return false;
  27. }
  28. if (window.getComputedStyle(el).visibility === "hidden") {
  29. return false;
  30. }
  31. return ["button", "input", "select", "textarea", "a", "audio", "video", "summary"].includes(tag);
  32. }
  33. function getTabbableElements(root) {
  34. const tabbableElements = [];
  35. if (root instanceof HTMLElement) {
  36. if (isTabbable(root)) {
  37. tabbableElements.push(root);
  38. }
  39. if (root.shadowRoot && root.shadowRoot.mode === "open") {
  40. getTabbableElements(root.shadowRoot).map((el) => tabbableElements.push(el));
  41. }
  42. if (root instanceof HTMLSlotElement) {
  43. root.assignedElements().map((slottedEl) => {
  44. getTabbableElements(slottedEl).map((el) => tabbableElements.push(el));
  45. });
  46. }
  47. }
  48. [...root.querySelectorAll("*")].map((el) => {
  49. getTabbableElements(el).map((el2) => tabbableElements.push(el2));
  50. });
  51. return tabbableElements;
  52. }
  53. function getNearestTabbableElement(el) {
  54. const tabbableElements = getTabbableElements(el);
  55. return tabbableElements.length ? tabbableElements[0] : null;
  56. }
  57. export {
  58. getTabbableElements,
  59. getNearestTabbableElement
  60. };