@zag-js/tabbable
Advanced tools
Comparing version 0.0.1 to 0.1.0
@@ -20,5 +20,24 @@ type IncludeContainerType = boolean | "if-empty"; | ||
declare function isTabbable(el: HTMLElement | null): el is HTMLElement; | ||
/** | ||
* Returns the first focusable element within the element | ||
*/ | ||
declare function getFirstTabbable(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement; | ||
/** | ||
* Returns the last focusable element within the element | ||
*/ | ||
declare function getLastTabbable(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement; | ||
/** | ||
* Returns the first and last focusable elements within the element | ||
*/ | ||
declare function getTabbableEdges(container: HTMLElement | null, includeContainer?: IncludeContainerType): HTMLElement[]; | ||
/** | ||
* Returns the next tabbable element after the current element | ||
*/ | ||
declare function getNextTabbable(container: HTMLElement | null, current?: HTMLElement | null): HTMLElement | null; | ||
/** | ||
* Proxies tab focus within a container to a reference element | ||
* when the container is rendered in a portal | ||
*/ | ||
declare function proxyTabFocus(container: HTMLElement | null, reference: HTMLElement | null, cb: (elementToFocus: HTMLElement) => void): () => void; | ||
export { focusableSelector, getFirstFocusable, getFirstTabbable, getFocusables, getLastTabbable, getTabbables, isFocusable, isTabbable }; | ||
export { focusableSelector, getFirstFocusable, getFirstTabbable, getFocusables, getLastTabbable, getNextTabbable, getTabbableEdges, getTabbables, isFocusable, isTabbable, proxyTabFocus }; |
@@ -28,5 +28,8 @@ "use strict"; | ||
getLastTabbable: () => getLastTabbable, | ||
getNextTabbable: () => getNextTabbable, | ||
getTabbableEdges: () => getTabbableEdges, | ||
getTabbables: () => getTabbables, | ||
isFocusable: () => isFocusable, | ||
isTabbable: () => isTabbable | ||
isTabbable: () => isTabbable, | ||
proxyTabFocus: () => proxyTabFocus | ||
}); | ||
@@ -103,2 +106,42 @@ module.exports = __toCommonJS(src_exports); | ||
} | ||
function getTabbableEdges(container, includeContainer) { | ||
const elements = getTabbables(container, includeContainer); | ||
const first = elements[0] || null; | ||
const last = elements[elements.length - 1] || null; | ||
return [first, last]; | ||
} | ||
function getNextTabbable(container, current) { | ||
const tabbables = getTabbables(container); | ||
const doc = container?.ownerDocument || document; | ||
const currentElement = current ?? doc.activeElement; | ||
if (!currentElement) | ||
return null; | ||
const index = tabbables.indexOf(currentElement); | ||
return tabbables[index + 1] || null; | ||
} | ||
function proxyTabFocus(container, reference, cb) { | ||
const doc = container?.ownerDocument || document; | ||
const body = doc.body; | ||
function onKeyDown(event) { | ||
if (event.key !== "Tab") | ||
return; | ||
let elementToFocus = null; | ||
const [firstTabbable, lastTabbable] = getTabbableEdges(container); | ||
if (event.shiftKey && doc.activeElement === firstTabbable) { | ||
elementToFocus = reference; | ||
} else if (!event.shiftKey && doc.activeElement === reference) { | ||
elementToFocus = firstTabbable; | ||
} else if (!event.shiftKey && doc.activeElement === lastTabbable) { | ||
elementToFocus = getNextTabbable(body, reference); | ||
} | ||
if (!elementToFocus) | ||
return; | ||
event.preventDefault(); | ||
cb(elementToFocus); | ||
} | ||
doc?.addEventListener("keydown", onKeyDown, true); | ||
return () => { | ||
doc?.removeEventListener("keydown", onKeyDown, true); | ||
}; | ||
} | ||
// Annotate the CommonJS export names for ESM import in node: | ||
@@ -111,5 +154,8 @@ 0 && (module.exports = { | ||
getLastTabbable, | ||
getNextTabbable, | ||
getTabbableEdges, | ||
getTabbables, | ||
isFocusable, | ||
isTabbable | ||
isTabbable, | ||
proxyTabFocus | ||
}); |
{ | ||
"name": "@zag-js/tabbable", | ||
"version": "0.0.1", | ||
"version": "0.1.0", | ||
"description": "Small utility that returns an array of all* tabbable DOM nodes within a containing node.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
Sorry, the diff of this file is not supported yet
15461
323