UNPKG

@mantine/hooks

Version:

A collection of 50+ hooks for state and UI management

1 lines 3 kB
{"version":3,"file":"tabbable.mjs","names":[],"sources":["../../src/use-focus-trap/tabbable.ts"],"sourcesContent":["const TABBABLE_NODES = /input|select|textarea|button|object/;\nexport const FOCUS_SELECTOR = 'a, input, select, textarea, button, object, [tabindex]';\n\nfunction hidden(element: HTMLElement) {\n if (process.env.NODE_ENV === 'test') {\n return false;\n }\n\n return element.style.display === 'none';\n}\n\nfunction visible(element: HTMLElement) {\n const isHidden =\n element.getAttribute('aria-hidden') ||\n element.getAttribute('hidden') ||\n element.getAttribute('type') === 'hidden';\n\n if (isHidden) {\n return false;\n }\n\n let parentElement: HTMLElement = element;\n while (parentElement) {\n if (parentElement === document.body || parentElement.nodeType === 11) {\n break;\n }\n\n if (hidden(parentElement)) {\n return false;\n }\n\n parentElement = parentElement.parentNode as HTMLElement;\n }\n\n return true;\n}\n\nfunction getElementTabIndex(element: HTMLElement) {\n let tabIndex: string | null | undefined = element.getAttribute('tabindex');\n if (tabIndex === null) {\n tabIndex = undefined;\n }\n return parseInt(tabIndex as string, 10);\n}\n\nexport function focusable(element: HTMLElement) {\n const nodeName = element.nodeName.toLowerCase();\n const isTabIndexNotNaN = !Number.isNaN(getElementTabIndex(element));\n const res =\n // @ts-expect-error function accepts any html element but if it is a button, it should not be disabled to trigger the condition\n (TABBABLE_NODES.test(nodeName) && !element.disabled) ||\n (element instanceof HTMLAnchorElement ? element.href || isTabIndexNotNaN : isTabIndexNotNaN);\n\n return res && visible(element);\n}\n\nexport function tabbable(element: HTMLElement) {\n const tabIndex = getElementTabIndex(element);\n const isTabIndexNaN = Number.isNaN(tabIndex);\n return (isTabIndexNaN || tabIndex >= 0) && focusable(element);\n}\n\nexport function findTabbableDescendants(element: HTMLElement): HTMLElement[] {\n return Array.from(element.querySelectorAll<HTMLElement>(FOCUS_SELECTOR)).filter(tabbable);\n}\n"],"mappings":";;AAAA,MAAM,iBAAiB;AACvB,MAAa,iBAAiB;AAE9B,SAAS,OAAO,SAAsB;AAKpC,QAAO,QAAQ,MAAM,YAAY;;AAGnC,SAAS,QAAQ,SAAsB;AAMrC,KAJE,QAAQ,aAAa,cAAc,IACnC,QAAQ,aAAa,SAAS,IAC9B,QAAQ,aAAa,OAAO,KAAK,SAGjC,QAAO;CAGT,IAAI,gBAA6B;AACjC,QAAO,eAAe;AACpB,MAAI,kBAAkB,SAAS,QAAQ,cAAc,aAAa,GAChE;AAGF,MAAI,OAAO,cAAc,CACvB,QAAO;AAGT,kBAAgB,cAAc;;AAGhC,QAAO;;AAGT,SAAS,mBAAmB,SAAsB;CAChD,IAAI,WAAsC,QAAQ,aAAa,WAAW;AAC1E,KAAI,aAAa,KACf,YAAW,KAAA;AAEb,QAAO,SAAS,UAAoB,GAAG;;AAGzC,SAAgB,UAAU,SAAsB;CAC9C,MAAM,WAAW,QAAQ,SAAS,aAAa;CAC/C,MAAM,mBAAmB,CAAC,OAAO,MAAM,mBAAmB,QAAQ,CAAC;AAMnE,SAHG,eAAe,KAAK,SAAS,IAAI,CAAC,QAAQ,aAC1C,mBAAmB,oBAAoB,QAAQ,QAAQ,mBAAmB,sBAE/D,QAAQ,QAAQ;;AAGhC,SAAgB,SAAS,SAAsB;CAC7C,MAAM,WAAW,mBAAmB,QAAQ;AAE5C,SADsB,OAAO,MAAM,SAAS,IACnB,YAAY,MAAM,UAAU,QAAQ;;AAG/D,SAAgB,wBAAwB,SAAqC;AAC3E,QAAO,MAAM,KAAK,QAAQ,iBAA8B,eAAe,CAAC,CAAC,OAAO,SAAS"}