UNPKG

@chakra-ui/descendant

Version:

Register child nodes of a react element for better accessibility

1 lines 6.89 kB
{"version":3,"sources":["../src/descendant.ts"],"sourcesContent":["import { sortNodes, isElement, getNextIndex, getPrevIndex } from \"./utils\"\n\nexport type DescendantOptions<T = {}> = T & {\n /**\n * If `true`, the item will be registered in all nodes map\n * but omitted from enabled nodes map\n */\n disabled?: boolean\n /**\n * The id of the item\n */\n id?: string\n}\n\nexport type Descendant<T, K> = DescendantOptions<K> & {\n /**\n * DOM element of the item\n */\n node: T\n /**\n * index of item in all nodes map and enabled nodes map\n */\n index: number\n}\n\n/**\n * @internal\n *\n * Class to manage descendants and their relative indices in the DOM.\n * It uses `node.compareDocumentPosition(...)` under the hood\n */\nexport class DescendantsManager<\n T extends HTMLElement,\n K extends Record<string, any> = {},\n> {\n private descendants = new Map<T, Descendant<T, K>>()\n\n register = (nodeOrOptions: T | null | DescendantOptions<K>) => {\n if (nodeOrOptions == null) return\n\n if (isElement(nodeOrOptions)) {\n return this.registerNode(nodeOrOptions)\n }\n\n return (node: T | null) => {\n this.registerNode(node, nodeOrOptions)\n }\n }\n\n unregister = (node: T) => {\n this.descendants.delete(node)\n const sorted = sortNodes(Array.from(this.descendants.keys()))\n this.assignIndex(sorted)\n }\n\n destroy = () => {\n this.descendants.clear()\n }\n\n private assignIndex = (descendants: Node[]) => {\n this.descendants.forEach((descendant) => {\n const index = descendants.indexOf(descendant.node)\n descendant.index = index\n descendant.node.dataset[\"index\"] = descendant.index.toString()\n })\n }\n\n count = () => this.descendants.size\n\n enabledCount = () => this.enabledValues().length\n\n values = () => {\n const values = Array.from(this.descendants.values())\n return values.sort((a, b) => a.index - b.index)\n }\n\n enabledValues = () => {\n return this.values().filter((descendant) => !descendant.disabled)\n }\n\n item = (index: number) => {\n if (this.count() === 0) return undefined\n return this.values()[index]\n }\n\n enabledItem = (index: number) => {\n if (this.enabledCount() === 0) return undefined\n return this.enabledValues()[index]\n }\n\n first = () => this.item(0)\n\n firstEnabled = () => this.enabledItem(0)\n\n last = () => this.item(this.descendants.size - 1)\n\n lastEnabled = () => {\n const lastIndex = this.enabledValues().length - 1\n return this.enabledItem(lastIndex)\n }\n\n indexOf = (node: T | null) => {\n if (!node) return -1\n return this.descendants.get(node)?.index ?? -1\n }\n\n enabledIndexOf = (node: T | null) => {\n if (node == null) return -1\n return this.enabledValues().findIndex((i) => i.node.isSameNode(node))\n }\n\n next = (index: number, loop = true) => {\n const next = getNextIndex(index, this.count(), loop)\n return this.item(next)\n }\n\n nextEnabled = (index: number, loop = true) => {\n const item = this.item(index)\n if (!item) return\n const enabledIndex = this.enabledIndexOf(item.node)\n const nextEnabledIndex = getNextIndex(\n enabledIndex,\n this.enabledCount(),\n loop,\n )\n return this.enabledItem(nextEnabledIndex)\n }\n\n prev = (index: number, loop = true) => {\n const prev = getPrevIndex(index, this.count() - 1, loop)\n return this.item(prev)\n }\n\n prevEnabled = (index: number, loop = true) => {\n const item = this.item(index)\n if (!item) return\n const enabledIndex = this.enabledIndexOf(item.node)\n const prevEnabledIndex = getPrevIndex(\n enabledIndex,\n this.enabledCount() - 1,\n loop,\n )\n return this.enabledItem(prevEnabledIndex)\n }\n\n private registerNode = (node: T | null, options?: DescendantOptions<K>) => {\n if (!node || this.descendants.has(node)) return\n\n const keys = Array.from(this.descendants.keys()).concat(node)\n const sorted = sortNodes(keys)\n\n if (options?.disabled) {\n options.disabled = !!options.disabled\n }\n\n const descendant = { node, index: -1, ...options }\n\n this.descendants.set(node, descendant as Descendant<T, K>)\n\n this.assignIndex(sorted)\n }\n}\n"],"mappings":"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","names":[]}