New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details
Socket
Book a DemoSign in
Socket

@chakra-ui/descendant

Package Overview
Dependencies
Maintainers
4
Versions
175
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@chakra-ui/descendant - npm Package Compare versions

Comparing version
1.1.3
to
2.0.0
+183
dist/cjs/descendant.js
"use strict";
exports.__esModule = true;
exports.DescendantsManager = void 0;
var _utils = require("./utils");
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
/**
* @internal
*
* Class to manage descendants and their relative indices in the DOM.
* It uses `node.compareDocumentPosition(...)` under the hood
*/
var DescendantsManager = function DescendantsManager() {
var _this = this;
_defineProperty(this, "descendants", new Map());
_defineProperty(this, "register", function (nodeOrOptions) {
if (nodeOrOptions == null) return;
if ((0, _utils.isElement)(nodeOrOptions)) {
return _this.registerNode(nodeOrOptions);
}
return function (node) {
_this.registerNode(node, nodeOrOptions);
};
});
_defineProperty(this, "unregister", function (node) {
_this.descendants["delete"](node);
var sorted = (0, _utils.sortNodes)(Array.from(_this.descendants.keys()));
_this.assignIndex(sorted);
});
_defineProperty(this, "destroy", function () {
_this.descendants.clear();
});
_defineProperty(this, "assignIndex", function (descendants) {
_this.descendants.forEach(function (descendant) {
var index = descendants.indexOf(descendant.node);
descendant.index = index;
descendant.node.dataset.index = descendant.index.toString();
});
});
_defineProperty(this, "count", function () {
return _this.descendants.size;
});
_defineProperty(this, "enabledCount", function () {
return _this.enabledValues().length;
});
_defineProperty(this, "values", function () {
var values = Array.from(_this.descendants.values());
return values.sort(function (a, b) {
return a.index - b.index;
});
});
_defineProperty(this, "enabledValues", function () {
return _this.values().filter(function (descendant) {
return !descendant.disabled;
});
});
_defineProperty(this, "item", function (index) {
if (_this.count() === 0) return undefined;
return _this.values()[index];
});
_defineProperty(this, "enabledItem", function (index) {
if (_this.enabledCount() === 0) return undefined;
return _this.enabledValues()[index];
});
_defineProperty(this, "first", function () {
return _this.item(0);
});
_defineProperty(this, "firstEnabled", function () {
return _this.enabledItem(0);
});
_defineProperty(this, "last", function () {
return _this.item(_this.descendants.size - 1);
});
_defineProperty(this, "lastEnabled", function () {
var lastIndex = _this.enabledValues().length - 1;
return _this.enabledItem(lastIndex);
});
_defineProperty(this, "indexOf", function (node) {
var _this$descendants$get, _this$descendants$get2;
if (!node) return -1;
return (_this$descendants$get = (_this$descendants$get2 = _this.descendants.get(node)) == null ? void 0 : _this$descendants$get2.index) != null ? _this$descendants$get : -1;
});
_defineProperty(this, "enabledIndexOf", function (node) {
if (node == null) return -1;
return _this.enabledValues().findIndex(function (i) {
return i.node.isSameNode(node);
});
});
_defineProperty(this, "next", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var next = (0, _utils.getNextIndex)(index, _this.count(), loop);
return _this.item(next);
});
_defineProperty(this, "nextEnabled", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var item = _this.item(index);
if (!item) return;
var enabledIndex = _this.enabledIndexOf(item.node);
var nextEnabledIndex = (0, _utils.getNextIndex)(enabledIndex, _this.enabledCount(), loop);
return _this.enabledItem(nextEnabledIndex);
});
_defineProperty(this, "prev", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var prev = (0, _utils.getPrevIndex)(index, _this.count() - 1, loop);
return _this.item(prev);
});
_defineProperty(this, "prevEnabled", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var item = _this.item(index);
if (!item) return;
var enabledIndex = _this.enabledIndexOf(item.node);
var prevEnabledIndex = (0, _utils.getPrevIndex)(enabledIndex, _this.enabledCount() - 1, loop);
return _this.enabledItem(prevEnabledIndex);
});
_defineProperty(this, "registerNode", function (node, options) {
if (options === void 0) {
options = {};
}
if (!node || _this.descendants.has(node)) return;
var keys = Array.from(_this.descendants.keys()).concat(node);
var sorted = (0, _utils.sortNodes)(keys);
_this.descendants.set(node, {
node: node,
index: -1,
disabled: !!options.disabled
});
_this.assignIndex(sorted);
});
};
exports.DescendantsManager = DescendantsManager;
//# sourceMappingURL=descendant.js.map
{"version":3,"sources":["../../src/descendant.ts"],"names":["DescendantsManager","Map","nodeOrOptions","registerNode","node","descendants","sorted","Array","from","keys","assignIndex","clear","forEach","descendant","index","indexOf","dataset","toString","size","enabledValues","length","values","sort","a","b","filter","disabled","count","undefined","enabledCount","item","enabledItem","lastIndex","get","findIndex","i","isSameNode","loop","next","enabledIndex","enabledIndexOf","nextEnabledIndex","prev","prevEnabledIndex","options","has","concat","set"],"mappings":"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","sourcesContent":["import { sortNodes, isElement, getNextIndex, getPrevIndex } from \"./utils\"\n\nexport interface DescendantOptions {\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 interface Descendant<T> extends DescendantOptions {\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<T extends HTMLElement, K = {}> {\n private descendants = new Map<T, Descendant<T>>()\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 = {}) => {\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 this.descendants.set(node, {\n node,\n index: -1,\n disabled: !!options.disabled,\n })\n\n this.assignIndex(sorted)\n }\n}\n"],"file":"descendant.js"}
"use strict";
exports.__esModule = true;
exports.sortNodes = sortNodes;
exports.getNextIndex = getNextIndex;
exports.getPrevIndex = getPrevIndex;
exports.cast = exports.useSafeLayoutEffect = exports.isElement = void 0;
var _react = require("react");
/**
* Sort an array of DOM nodes according to the HTML tree order
* @see http://www.w3.org/TR/html5/infrastructure.html#tree-order
*/
function sortNodes(nodes) {
return nodes.sort(function (a, b) {
var compare = a.compareDocumentPosition(b);
if (compare & Node.DOCUMENT_POSITION_FOLLOWING || compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {
// a < b
return -1;
}
if (compare & Node.DOCUMENT_POSITION_PRECEDING || compare & Node.DOCUMENT_POSITION_CONTAINS) {
// a > b
return 1;
}
if (compare & Node.DOCUMENT_POSITION_DISCONNECTED || compare & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) {
throw Error("Cannot sort the given nodes.");
} else {
return 0;
}
});
}
var isElement = function isElement(el) {
return typeof el == "object" && "nodeType" in el && el.nodeType === Node.ELEMENT_NODE;
};
exports.isElement = isElement;
function getNextIndex(current, max, loop) {
var next = current + 1;
if (loop && next >= max) next = 0;
return next;
}
function getPrevIndex(current, max, loop) {
var next = current - 1;
if (loop && next < 0) next = max;
return next;
}
var useSafeLayoutEffect = typeof window !== "undefined" ? _react.useLayoutEffect : _react.useEffect;
exports.useSafeLayoutEffect = useSafeLayoutEffect;
var cast = function cast(value) {
return value;
};
exports.cast = cast;
//# sourceMappingURL=utils.js.map
{"version":3,"sources":["../../src/utils.ts"],"names":["sortNodes","nodes","sort","a","b","compare","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_CONTAINED_BY","DOCUMENT_POSITION_PRECEDING","DOCUMENT_POSITION_CONTAINS","DOCUMENT_POSITION_DISCONNECTED","DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC","Error","isElement","el","nodeType","ELEMENT_NODE","getNextIndex","current","max","loop","next","getPrevIndex","useSafeLayoutEffect","window","useLayoutEffect","useEffect","cast","value"],"mappings":";;;;;;;;AAAA;;AAEA;AACA;AACA;AACA;AACO,SAASA,SAAT,CAAmBC,KAAnB,EAAkC;AACvC,SAAOA,KAAK,CAACC,IAAN,CAAW,UAACC,CAAD,EAAIC,CAAJ,EAAU;AAC1B,QAAMC,OAAO,GAAGF,CAAC,CAACG,uBAAF,CAA0BF,CAA1B,CAAhB;;AAEA,QACEC,OAAO,GAAGE,IAAI,CAACC,2BAAf,IACAH,OAAO,GAAGE,IAAI,CAACE,8BAFjB,EAGE;AACA;AACA,aAAO,CAAC,CAAR;AACD;;AAED,QACEJ,OAAO,GAAGE,IAAI,CAACG,2BAAf,IACAL,OAAO,GAAGE,IAAI,CAACI,0BAFjB,EAGE;AACA;AACA,aAAO,CAAP;AACD;;AAED,QACEN,OAAO,GAAGE,IAAI,CAACK,8BAAf,IACAP,OAAO,GAAGE,IAAI,CAACM,yCAFjB,EAGE;AACA,YAAMC,KAAK,CAAC,8BAAD,CAAX;AACD,KALD,MAKO;AACL,aAAO,CAAP;AACD;AACF,GA3BM,CAAP;AA4BD;;AAEM,IAAMC,SAAS,GAAG,SAAZA,SAAY,CAACC,EAAD;AAAA,SACvB,OAAOA,EAAP,IAAa,QAAb,IAAyB,cAAcA,EAAvC,IAA6CA,EAAE,CAACC,QAAH,KAAgBV,IAAI,CAACW,YAD3C;AAAA,CAAlB;;;;AAGA,SAASC,YAAT,CAAsBC,OAAtB,EAAuCC,GAAvC,EAAoDC,IAApD,EAAmE;AACxE,MAAIC,IAAI,GAAGH,OAAO,GAAG,CAArB;AACA,MAAIE,IAAI,IAAIC,IAAI,IAAIF,GAApB,EAAyBE,IAAI,GAAG,CAAP;AACzB,SAAOA,IAAP;AACD;;AAEM,SAASC,YAAT,CAAsBJ,OAAtB,EAAuCC,GAAvC,EAAoDC,IAApD,EAAmE;AACxE,MAAIC,IAAI,GAAGH,OAAO,GAAG,CAArB;AACA,MAAIE,IAAI,IAAIC,IAAI,GAAG,CAAnB,EAAsBA,IAAI,GAAGF,GAAP;AACtB,SAAOE,IAAP;AACD;;AAEM,IAAME,mBAAmB,GAC9B,OAAOC,MAAP,KAAkB,WAAlB,GAAgCC,sBAAhC,GAAkDC,gBAD7C;;;AAGA,IAAMC,IAAI,GAAG,SAAPA,IAAO,CAAIC,KAAJ;AAAA,SAAmBA,KAAnB;AAAA,CAAb","sourcesContent":["import { useEffect, useLayoutEffect } from \"react\"\n\n/**\n * Sort an array of DOM nodes according to the HTML tree order\n * @see http://www.w3.org/TR/html5/infrastructure.html#tree-order\n */\nexport function sortNodes(nodes: Node[]) {\n return nodes.sort((a, b) => {\n const compare = a.compareDocumentPosition(b)\n\n if (\n compare & Node.DOCUMENT_POSITION_FOLLOWING ||\n compare & Node.DOCUMENT_POSITION_CONTAINED_BY\n ) {\n // a < b\n return -1\n }\n\n if (\n compare & Node.DOCUMENT_POSITION_PRECEDING ||\n compare & Node.DOCUMENT_POSITION_CONTAINS\n ) {\n // a > b\n return 1\n }\n\n if (\n compare & Node.DOCUMENT_POSITION_DISCONNECTED ||\n compare & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC\n ) {\n throw Error(\"Cannot sort the given nodes.\")\n } else {\n return 0\n }\n })\n}\n\nexport const isElement = (el: any): el is HTMLElement =>\n typeof el == \"object\" && \"nodeType\" in el && el.nodeType === Node.ELEMENT_NODE\n\nexport function getNextIndex(current: number, max: number, loop: boolean) {\n let next = current + 1\n if (loop && next >= max) next = 0\n return next\n}\n\nexport function getPrevIndex(current: number, max: number, loop: boolean) {\n let next = current - 1\n if (loop && next < 0) next = max\n return next\n}\n\nexport const useSafeLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect\n\nexport const cast = <T>(value: any) => value as T\n"],"file":"utils.js"}
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
import { sortNodes, isElement, getNextIndex, getPrevIndex } from "./utils";
/**
* @internal
*
* Class to manage descendants and their relative indices in the DOM.
* It uses `node.compareDocumentPosition(...)` under the hood
*/
export class DescendantsManager {
constructor() {
var _this = this;
_defineProperty(this, "descendants", new Map());
_defineProperty(this, "register", nodeOrOptions => {
if (nodeOrOptions == null) return;
if (isElement(nodeOrOptions)) {
return this.registerNode(nodeOrOptions);
}
return node => {
this.registerNode(node, nodeOrOptions);
};
});
_defineProperty(this, "unregister", node => {
this.descendants.delete(node);
var sorted = sortNodes(Array.from(this.descendants.keys()));
this.assignIndex(sorted);
});
_defineProperty(this, "destroy", () => {
this.descendants.clear();
});
_defineProperty(this, "assignIndex", descendants => {
this.descendants.forEach(descendant => {
var index = descendants.indexOf(descendant.node);
descendant.index = index;
descendant.node.dataset.index = descendant.index.toString();
});
});
_defineProperty(this, "count", () => this.descendants.size);
_defineProperty(this, "enabledCount", () => this.enabledValues().length);
_defineProperty(this, "values", () => {
var values = Array.from(this.descendants.values());
return values.sort((a, b) => a.index - b.index);
});
_defineProperty(this, "enabledValues", () => {
return this.values().filter(descendant => !descendant.disabled);
});
_defineProperty(this, "item", index => {
if (this.count() === 0) return undefined;
return this.values()[index];
});
_defineProperty(this, "enabledItem", index => {
if (this.enabledCount() === 0) return undefined;
return this.enabledValues()[index];
});
_defineProperty(this, "first", () => this.item(0));
_defineProperty(this, "firstEnabled", () => this.enabledItem(0));
_defineProperty(this, "last", () => this.item(this.descendants.size - 1));
_defineProperty(this, "lastEnabled", () => {
var lastIndex = this.enabledValues().length - 1;
return this.enabledItem(lastIndex);
});
_defineProperty(this, "indexOf", node => {
var _this$descendants$get, _this$descendants$get2;
if (!node) return -1;
return (_this$descendants$get = (_this$descendants$get2 = this.descendants.get(node)) == null ? void 0 : _this$descendants$get2.index) != null ? _this$descendants$get : -1;
});
_defineProperty(this, "enabledIndexOf", node => {
if (node == null) return -1;
return this.enabledValues().findIndex(i => i.node.isSameNode(node));
});
_defineProperty(this, "next", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var next = getNextIndex(index, _this.count(), loop);
return _this.item(next);
});
_defineProperty(this, "nextEnabled", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var item = _this.item(index);
if (!item) return;
var enabledIndex = _this.enabledIndexOf(item.node);
var nextEnabledIndex = getNextIndex(enabledIndex, _this.enabledCount(), loop);
return _this.enabledItem(nextEnabledIndex);
});
_defineProperty(this, "prev", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var prev = getPrevIndex(index, _this.count() - 1, loop);
return _this.item(prev);
});
_defineProperty(this, "prevEnabled", function (index, loop) {
if (loop === void 0) {
loop = true;
}
var item = _this.item(index);
if (!item) return;
var enabledIndex = _this.enabledIndexOf(item.node);
var prevEnabledIndex = getPrevIndex(enabledIndex, _this.enabledCount() - 1, loop);
return _this.enabledItem(prevEnabledIndex);
});
_defineProperty(this, "registerNode", function (node, options) {
if (options === void 0) {
options = {};
}
if (!node || _this.descendants.has(node)) return;
var keys = Array.from(_this.descendants.keys()).concat(node);
var sorted = sortNodes(keys);
_this.descendants.set(node, {
node,
index: -1,
disabled: !!options.disabled
});
_this.assignIndex(sorted);
});
}
}
//# sourceMappingURL=descendant.js.map
{"version":3,"sources":["../../src/descendant.ts"],"names":["sortNodes","isElement","getNextIndex","getPrevIndex","DescendantsManager","Map","nodeOrOptions","registerNode","node","descendants","delete","sorted","Array","from","keys","assignIndex","clear","forEach","descendant","index","indexOf","dataset","toString","size","enabledValues","length","values","sort","a","b","filter","disabled","count","undefined","enabledCount","item","enabledItem","lastIndex","get","findIndex","i","isSameNode","loop","next","enabledIndex","enabledIndexOf","nextEnabledIndex","prev","prevEnabledIndex","options","has","concat","set"],"mappings":"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","sourcesContent":["import { sortNodes, isElement, getNextIndex, getPrevIndex } from \"./utils\"\n\nexport interface DescendantOptions {\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 interface Descendant<T> extends DescendantOptions {\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<T extends HTMLElement, K = {}> {\n private descendants = new Map<T, Descendant<T>>()\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 = {}) => {\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 this.descendants.set(node, {\n node,\n index: -1,\n disabled: !!options.disabled,\n })\n\n this.assignIndex(sorted)\n }\n}\n"],"file":"descendant.js"}
import { useEffect, useLayoutEffect } from "react";
/**
* Sort an array of DOM nodes according to the HTML tree order
* @see http://www.w3.org/TR/html5/infrastructure.html#tree-order
*/
export function sortNodes(nodes) {
return nodes.sort((a, b) => {
var compare = a.compareDocumentPosition(b);
if (compare & Node.DOCUMENT_POSITION_FOLLOWING || compare & Node.DOCUMENT_POSITION_CONTAINED_BY) {
// a < b
return -1;
}
if (compare & Node.DOCUMENT_POSITION_PRECEDING || compare & Node.DOCUMENT_POSITION_CONTAINS) {
// a > b
return 1;
}
if (compare & Node.DOCUMENT_POSITION_DISCONNECTED || compare & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC) {
throw Error("Cannot sort the given nodes.");
} else {
return 0;
}
});
}
export var isElement = el => typeof el == "object" && "nodeType" in el && el.nodeType === Node.ELEMENT_NODE;
export function getNextIndex(current, max, loop) {
var next = current + 1;
if (loop && next >= max) next = 0;
return next;
}
export function getPrevIndex(current, max, loop) {
var next = current - 1;
if (loop && next < 0) next = max;
return next;
}
export var useSafeLayoutEffect = typeof window !== "undefined" ? useLayoutEffect : useEffect;
export var cast = value => value;
//# sourceMappingURL=utils.js.map
{"version":3,"sources":["../../src/utils.ts"],"names":["useEffect","useLayoutEffect","sortNodes","nodes","sort","a","b","compare","compareDocumentPosition","Node","DOCUMENT_POSITION_FOLLOWING","DOCUMENT_POSITION_CONTAINED_BY","DOCUMENT_POSITION_PRECEDING","DOCUMENT_POSITION_CONTAINS","DOCUMENT_POSITION_DISCONNECTED","DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC","Error","isElement","el","nodeType","ELEMENT_NODE","getNextIndex","current","max","loop","next","getPrevIndex","useSafeLayoutEffect","window","cast","value"],"mappings":"AAAA,SAASA,SAAT,EAAoBC,eAApB,QAA2C,OAA3C;AAEA;AACA;AACA;AACA;;AACA,OAAO,SAASC,SAAT,CAAmBC,KAAnB,EAAkC;AACvC,SAAOA,KAAK,CAACC,IAAN,CAAW,CAACC,CAAD,EAAIC,CAAJ,KAAU;AAC1B,QAAMC,OAAO,GAAGF,CAAC,CAACG,uBAAF,CAA0BF,CAA1B,CAAhB;;AAEA,QACEC,OAAO,GAAGE,IAAI,CAACC,2BAAf,IACAH,OAAO,GAAGE,IAAI,CAACE,8BAFjB,EAGE;AACA;AACA,aAAO,CAAC,CAAR;AACD;;AAED,QACEJ,OAAO,GAAGE,IAAI,CAACG,2BAAf,IACAL,OAAO,GAAGE,IAAI,CAACI,0BAFjB,EAGE;AACA;AACA,aAAO,CAAP;AACD;;AAED,QACEN,OAAO,GAAGE,IAAI,CAACK,8BAAf,IACAP,OAAO,GAAGE,IAAI,CAACM,yCAFjB,EAGE;AACA,YAAMC,KAAK,CAAC,8BAAD,CAAX;AACD,KALD,MAKO;AACL,aAAO,CAAP;AACD;AACF,GA3BM,CAAP;AA4BD;AAED,OAAO,IAAMC,SAAS,GAAIC,EAAD,IACvB,OAAOA,EAAP,IAAa,QAAb,IAAyB,cAAcA,EAAvC,IAA6CA,EAAE,CAACC,QAAH,KAAgBV,IAAI,CAACW,YAD7D;AAGP,OAAO,SAASC,YAAT,CAAsBC,OAAtB,EAAuCC,GAAvC,EAAoDC,IAApD,EAAmE;AACxE,MAAIC,IAAI,GAAGH,OAAO,GAAG,CAArB;AACA,MAAIE,IAAI,IAAIC,IAAI,IAAIF,GAApB,EAAyBE,IAAI,GAAG,CAAP;AACzB,SAAOA,IAAP;AACD;AAED,OAAO,SAASC,YAAT,CAAsBJ,OAAtB,EAAuCC,GAAvC,EAAoDC,IAApD,EAAmE;AACxE,MAAIC,IAAI,GAAGH,OAAO,GAAG,CAArB;AACA,MAAIE,IAAI,IAAIC,IAAI,GAAG,CAAnB,EAAsBA,IAAI,GAAGF,GAAP;AACtB,SAAOE,IAAP;AACD;AAED,OAAO,IAAME,mBAAmB,GAC9B,OAAOC,MAAP,KAAkB,WAAlB,GAAgC3B,eAAhC,GAAkDD,SAD7C;AAGP,OAAO,IAAM6B,IAAI,GAAOC,KAAJ,IAAmBA,KAAhC","sourcesContent":["import { useEffect, useLayoutEffect } from \"react\"\n\n/**\n * Sort an array of DOM nodes according to the HTML tree order\n * @see http://www.w3.org/TR/html5/infrastructure.html#tree-order\n */\nexport function sortNodes(nodes: Node[]) {\n return nodes.sort((a, b) => {\n const compare = a.compareDocumentPosition(b)\n\n if (\n compare & Node.DOCUMENT_POSITION_FOLLOWING ||\n compare & Node.DOCUMENT_POSITION_CONTAINED_BY\n ) {\n // a < b\n return -1\n }\n\n if (\n compare & Node.DOCUMENT_POSITION_PRECEDING ||\n compare & Node.DOCUMENT_POSITION_CONTAINS\n ) {\n // a > b\n return 1\n }\n\n if (\n compare & Node.DOCUMENT_POSITION_DISCONNECTED ||\n compare & Node.DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC\n ) {\n throw Error(\"Cannot sort the given nodes.\")\n } else {\n return 0\n }\n })\n}\n\nexport const isElement = (el: any): el is HTMLElement =>\n typeof el == \"object\" && \"nodeType\" in el && el.nodeType === Node.ELEMENT_NODE\n\nexport function getNextIndex(current: number, max: number, loop: boolean) {\n let next = current + 1\n if (loop && next >= max) next = 0\n return next\n}\n\nexport function getPrevIndex(current: number, max: number, loop: boolean) {\n let next = current - 1\n if (loop && next < 0) next = max\n return next\n}\n\nexport const useSafeLayoutEffect =\n typeof window !== \"undefined\" ? useLayoutEffect : useEffect\n\nexport const cast = <T>(value: any) => value as T\n"],"file":"utils.js"}
export interface DescendantOptions {
/**
* If `true`, the item will be registered in all nodes map
* but omitted from enabled nodes map
*/
disabled?: boolean;
/**
* The id of the item
*/
id?: string;
}
export interface Descendant<T> extends DescendantOptions {
/**
* DOM element of the item
*/
node: T;
/**
* index of item in all nodes map and enabled nodes map
*/
index: number;
}
/**
* @internal
*
* Class to manage descendants and their relative indices in the DOM.
* It uses `node.compareDocumentPosition(...)` under the hood
*/
export declare class DescendantsManager<T extends HTMLElement, K = {}> {
private descendants;
register: (nodeOrOptions: T | null | (DescendantOptions & K)) => void | ((node: T | null) => void);
unregister: (node: T) => void;
destroy: () => void;
private assignIndex;
count: () => number;
enabledCount: () => number;
values: () => Descendant<T>[];
enabledValues: () => Descendant<T>[];
item: (index: number) => Descendant<T> | undefined;
enabledItem: (index: number) => Descendant<T> | undefined;
first: () => Descendant<T> | undefined;
firstEnabled: () => Descendant<T> | undefined;
last: () => Descendant<T> | undefined;
lastEnabled: () => Descendant<T> | undefined;
indexOf: (node: T | null) => number;
enabledIndexOf: (node: T | null) => number;
next: (index: number, loop?: boolean) => Descendant<T> | undefined;
nextEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
prev: (index: number, loop?: boolean) => Descendant<T> | undefined;
prevEnabled: (index: number, loop?: boolean) => Descendant<T> | undefined;
private registerNode;
}
//# sourceMappingURL=descendant.d.ts.map
{"version":3,"file":"descendant.d.ts","sourceRoot":"","sources":["../../src/descendant.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,iBAAiB;IAChC;;;OAGG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;OAEG;IACH,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,UAAU,CAAC,CAAC,CAAE,SAAQ,iBAAiB;IACtD;;OAEG;IACH,IAAI,EAAE,CAAC,CAAA;IACP;;OAEG;IACH,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;GAKG;AACH,qBAAa,kBAAkB,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,GAAG,EAAE;IAC3D,OAAO,CAAC,WAAW,CAA8B;IAEjD,QAAQ,kBAAmB,CAAC,GAAG,IAAI,GAAG,CAAC,iBAAiB,GAAG,CAAC,CAAC,oBAO7C,CAAC,GAAG,IAAI,WAGvB;IAED,UAAU,SAAU,CAAC,UAIpB;IAED,OAAO,aAEN;IAED,OAAO,CAAC,WAAW,CAMlB;IAED,KAAK,eAA8B;IAEnC,YAAY,eAAoC;IAEhD,MAAM,wBAGL;IAED,aAAa,wBAEZ;IAED,IAAI,UAAW,MAAM,+BAGpB;IAED,WAAW,UAAW,MAAM,+BAG3B;IAED,KAAK,kCAAqB;IAE1B,YAAY,kCAA4B;IAExC,IAAI,kCAA6C;IAEjD,WAAW,kCAGV;IAED,OAAO,SAAU,CAAC,GAAG,IAAI,YAGxB;IAED,cAAc,SAAU,CAAC,GAAG,IAAI,YAG/B;IAED,IAAI,UAAW,MAAM,+CAGpB;IAED,WAAW,UAAW,MAAM,+CAU3B;IAED,IAAI,UAAW,MAAM,+CAGpB;IAED,WAAW,UAAW,MAAM,+CAU3B;IAED,OAAO,CAAC,YAAY,CAanB;CACF"}
import { useLayoutEffect } from "react";
/**
* Sort an array of DOM nodes according to the HTML tree order
* @see http://www.w3.org/TR/html5/infrastructure.html#tree-order
*/
export declare function sortNodes(nodes: Node[]): Node[];
export declare const isElement: (el: any) => el is HTMLElement;
export declare function getNextIndex(current: number, max: number, loop: boolean): number;
export declare function getPrevIndex(current: number, max: number, loop: boolean): number;
export declare const useSafeLayoutEffect: typeof useLayoutEffect;
export declare const cast: <T>(value: any) => T;
//# sourceMappingURL=utils.d.ts.map
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,eAAe,EAAE,MAAM,OAAO,CAAA;AAElD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,UA6BtC;AAED,eAAO,MAAM,SAAS,OAAQ,GAAG,sBAC+C,CAAA;AAEhF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,UAIvE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,UAIvE;AAED,eAAO,MAAM,mBAAmB,wBAC6B,CAAA;AAE7D,eAAO,MAAM,IAAI,aAAc,GAAG,MAAe,CAAA"}
+20
-0
# Change Log
## 2.0.0
### Major Changes
- [`82f08867f`](https://github.com/chakra-ui/chakra-ui/commit/82f08867fa4825d647a3b9cc805220d9364f2f3f)
[#3864](https://github.com/chakra-ui/chakra-ui/pull/3864) Thanks
[@segunadebayo](https://github.com/segunadebayo)! - > Note: This is an
internal package.
Improve performance of registering, filtering and finding the index of
descendants in a disclosure(open/close) widget.
Mostly used by the accordion, menu, tabs and pin-input components.
### Patch Changes
- Updated dependencies
[[`82f08867f`](https://github.com/chakra-ui/chakra-ui/commit/82f08867fa4825d647a3b9cc805220d9364f2f3f)]:
- @chakra-ui/react-utils@1.1.2
## 1.1.3

@@ -4,0 +24,0 @@

@@ -12,2 +12,10 @@ "use strict";

});
var _descendant = require("./descendant");
Object.keys(_descendant).forEach(function (key) {
if (key === "default" || key === "__esModule") return;
if (key in exports && exports[key] === _descendant[key]) return;
exports[key] = _descendant[key];
});
//# sourceMappingURL=index.js.map
+1
-1

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export * from \"./use-descendant\"\n"],"file":"index.js"}
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":";;;;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;;AACA;;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["export * from \"./use-descendant\"\nexport * from \"./descendant\"\n"],"file":"index.js"}
"use strict";
exports.__esModule = true;
exports.useDescendants = useDescendants;
exports.useDescendant = useDescendant;
exports.useDescendants = useDescendants;
exports.createDescendantContext = createDescendantContext;
exports.useDescendantsContext = exports.DescendantsContextProvider = void 0;
var _reactUtils = require("@chakra-ui/react-utils");
var _react = require("react");
var _hooks = require("@chakra-ui/hooks");
var _descendant = require("./descendant");
function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _utils = require("./utils");
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
/**
* @internal
* React hook that initializes the DescendantsManager
*/
function useDescendants() {
var _useState = (0, _react.useState)(function () {
return new _descendant.DescendantsManager();
}),
descendants = _useState[0];
function useDescendant(props) {
var context = props.context,
element = props.element,
indexProp = props.index,
disabled = props.disabled,
focusable = props.focusable,
rest = _objectWithoutPropertiesLoose(props, ["context", "element", "index", "disabled", "focusable"]);
(0, _utils.useSafeLayoutEffect)(function () {
return function () {
return descendants.destroy();
};
});
return descendants;
}
var forceUpdate = (0, _hooks.useForceUpdate)();
var register = context.register,
unregister = context.unregister,
descendants = context.descendants;
(0, _hooks.useSafeLayoutEffect)(function () {
if (!element) {
forceUpdate();
}
/**
* Don't register this descendant if it is disabled and not focusable
*/
/* -------------------------------------------------------------------------------------------------
* Descendants context to be used in component-land.
- Mount the `DescendantsContextProvider` at the root of the component
- Call `useDescendantsContext` anywhere you need access to the descendants information
NB: I recommend using `createDescendantContext` below
* -----------------------------------------------------------------------------------------------*/
var _createContext = (0, _reactUtils.createContext)({
name: "DescendantsProvider",
errorMessage: "useDescendantsContext must be used within DescendantsProvider"
}),
DescendantsContextProvider = _createContext[0],
useDescendantsContext = _createContext[1];
/**
* @internal
* This hook provides information a descendant such as:
* - Its index compared to other descendants
* - ref callback to register the descendant
* - Its enabled index compared to other enabled descendants
*/
if (disabled && !focusable) return undefined;
/**
* else, register the descendant
*/
register(_extends({
element: element,
disabled: disabled,
focusable: focusable
}, rest));
/**
* when it unmounts, unregister the descendant
*/
exports.useDescendantsContext = useDescendantsContext;
exports.DescendantsContextProvider = DescendantsContextProvider;
function useDescendant(options) {
var descendants = useDescendantsContext();
var _useState2 = (0, _react.useState)(-1),
index = _useState2[0],
setIndex = _useState2[1];
var ref = (0, _react.useRef)(null);
(0, _utils.useSafeLayoutEffect)(function () {
return function () {
if (element) {
unregister(element);
}
}; // eslint-disable-next-line
}, [element, disabled, focusable].concat(Object.values(rest)));
var index = indexProp != null ? indexProp : descendants.findIndex(function (descendant) {
return descendant.element === element;
if (!ref.current) return;
descendants.unregister(ref.current);
};
}, []);
(0, _utils.useSafeLayoutEffect)(function () {
if (!ref.current) return;
var dataIndex = Number(ref.current.dataset.index);
if (index != dataIndex && !Number.isNaN(dataIndex)) {
setIndex(dataIndex);
}
});
return index;
var refCallback = options ? (0, _utils.cast)(descendants.register(options)) : (0, _utils.cast)(descendants.register);
return {
descendants: descendants,
index: index,
enabledIndex: descendants.enabledIndexOf(ref.current),
register: (0, _reactUtils.mergeRefs)(refCallback, ref)
};
}
/* -------------------------------------------------------------------------------------------------
* Function that provides strongly typed versions of the context provider and hooks above.
To be used in component-land
* -----------------------------------------------------------------------------------------------*/
function useDescendants() {
var _useState = (0, _react.useState)([]),
descendants = _useState[0],
setDescendants = _useState[1];
var register = (0, _react.useCallback)(function (_ref) {
var element = _ref.element,
rest = _objectWithoutPropertiesLoose(_ref, ["element"]);
function createDescendantContext() {
var ContextProvider = (0, _utils.cast)(DescendantsContextProvider);
if (!element) return; // @ts-ignore
var _useDescendantsContext = function _useDescendantsContext() {
return (0, _utils.cast)(useDescendantsContext());
};
setDescendants(function (prevDescendants) {
if (prevDescendants.find(function (item) {
return item.element === element;
}) == null) {
var index = prevDescendants.findIndex(function (item) {
if (!item.element || !element) return false;
return Boolean(item.element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING);
});
var _useDescendant = function _useDescendant(options) {
return useDescendant(options);
};
var newItem = _extends({
element: element
}, rest);
var _useDescendants = function _useDescendants() {
return useDescendants();
};
if (index === -1) {
return [].concat(prevDescendants, [newItem]);
}
return [].concat(prevDescendants.slice(0, index), [newItem], prevDescendants.slice(index));
}
return prevDescendants;
});
}, []);
var unregister = (0, _react.useCallback)(function (element) {
if (!element) return;
setDescendants(function (descendants) {
return descendants.filter(function (descendant) {
return element !== descendant.element;
});
});
}, []);
var context = (0, _react.useMemo)(function () {
return {
descendants: descendants,
register: register,
unregister: unregister
};
}, [descendants, register, unregister]);
return context;
return [// context provider
ContextProvider, // call this when you need to read from context
_useDescendantsContext, // descendants state information, to be called and passed to `ContextProvider`
_useDescendants, // descendant index information
_useDescendant];
}
//# sourceMappingURL=use-descendant.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/use-descendant.ts"],"names":["useDescendant","props","context","element","indexProp","index","disabled","focusable","rest","forceUpdate","register","unregister","descendants","undefined","Object","values","findIndex","descendant","useDescendants","setDescendants","prevDescendants","find","item","Boolean","compareDocumentPosition","Node","DOCUMENT_POSITION_PRECEDING","newItem","slice","filter"],"mappings":"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","sourcesContent":["import { useCallback, useMemo, useState } from \"react\"\nimport { useSafeLayoutEffect, useForceUpdate } from \"@chakra-ui/hooks\"\n\nexport type Descendant<T extends HTMLElement, P = {}> = P & {\n element: T | null\n index?: number\n disabled?: boolean\n focusable?: boolean\n}\n\nexport interface DescendantContext<T extends HTMLElement, P = {}> {\n descendants: Descendant<T, P>[]\n register: (descendant: Descendant<T, P>) => void\n unregister: (element: T) => void\n}\n\nexport type UseDescendantProps<T extends HTMLElement, P> = {\n context: DescendantContext<T, P>\n} & Descendant<T, P>\n\nexport function useDescendant<T extends HTMLElement, P>(\n props: UseDescendantProps<T, P>,\n) {\n const {\n context,\n element,\n index: indexProp,\n disabled,\n focusable,\n ...rest\n } = props\n\n const forceUpdate = useForceUpdate()\n const { register, unregister, descendants } = context\n\n useSafeLayoutEffect(() => {\n if (!element) {\n forceUpdate()\n }\n\n /**\n * Don't register this descendant if it is disabled and not focusable\n */\n if (disabled && !focusable) return undefined\n\n /**\n * else, register the descendant\n */\n register({ element, disabled, focusable, ...rest } as any)\n\n /**\n * when it unmounts, unregister the descendant\n */\n return () => {\n if (element) {\n unregister(element)\n }\n }\n // eslint-disable-next-line\n }, [element, disabled, focusable, ...Object.values(rest)])\n\n const index =\n indexProp ??\n descendants.findIndex((descendant) => descendant.element === element)\n\n return index\n}\n\nexport function useDescendants<T extends HTMLElement, P>() {\n const [descendants, setDescendants] = useState<Descendant<T, P>[]>([])\n\n const register = useCallback(({ element, ...rest }: Descendant<T, P>) => {\n if (!element) return\n\n // @ts-ignore\n setDescendants((prevDescendants) => {\n if (prevDescendants.find((item) => item.element === element) == null) {\n const index = prevDescendants.findIndex((item) => {\n if (!item.element || !element) return false\n\n return Boolean(\n item.element.compareDocumentPosition(element) &\n Node.DOCUMENT_POSITION_PRECEDING,\n )\n })\n\n const newItem = { element, ...rest }\n\n if (index === -1) {\n return [...prevDescendants, newItem]\n }\n return [\n ...prevDescendants.slice(0, index),\n newItem,\n ...prevDescendants.slice(index),\n ]\n }\n return prevDescendants\n })\n }, [])\n\n const unregister = useCallback((element: T) => {\n if (!element) return\n setDescendants((descendants) =>\n descendants.filter((descendant) => element !== descendant.element),\n )\n }, [])\n\n const context = useMemo(() => ({ descendants, register, unregister }), [\n descendants,\n register,\n unregister,\n ])\n\n return context\n}\n"],"file":"use-descendant.js"}
{"version":3,"sources":["../../src/use-descendant.ts"],"names":["useDescendants","DescendantsManager","descendants","destroy","name","errorMessage","DescendantsContextProvider","useDescendantsContext","useDescendant","options","index","setIndex","ref","current","unregister","dataIndex","Number","dataset","isNaN","refCallback","register","enabledIndex","enabledIndexOf","createDescendantContext","ContextProvider","_useDescendantsContext","_useDescendant","_useDescendants"],"mappings":";;;;;;;;AAAA;;AACA;;AACA;;AACA;;AAEA;AACA;AACA;AACA;AACO,SAASA,cAAT,GAAuE;AAAA,kBACtD,qBAAS;AAAA,WAAM,IAAIC,8BAAJ,EAAN;AAAA,GAAT,CADsD;AAAA,MACrEC,WADqE;;AAE5E,kCAAoB,YAAM;AACxB,WAAO;AAAA,aAAMA,WAAW,CAACC,OAAZ,EAAN;AAAA,KAAP;AACD,GAFD;AAGA,SAAOD,WAAP;AACD;;AAKD;AACA;AACA;AACA;AACA;AACA;AACA;qBAKI,+BAAoC;AACtCE,EAAAA,IAAI,EAAE,qBADgC;AAEtCC,EAAAA,YAAY,EAAE;AAFwB,CAApC,C;IAFFC,0B;IACAC,qB;AAMF;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;AACO,SAASC,aAAT,CACLC,OADK,EAEL;AACA,MAAMP,WAAW,GAAGK,qBAAqB,EAAzC;;AADA,mBAE0B,qBAAS,CAAC,CAAV,CAF1B;AAAA,MAEOG,KAFP;AAAA,MAEcC,QAFd;;AAGA,MAAMC,GAAG,GAAG,mBAAU,IAAV,CAAZ;AAEA,kCAAoB,YAAM;AACxB,WAAO,YAAM;AACX,UAAI,CAACA,GAAG,CAACC,OAAT,EAAkB;AAClBX,MAAAA,WAAW,CAACY,UAAZ,CAAuBF,GAAG,CAACC,OAA3B;AACD,KAHD;AAID,GALD,EAKG,EALH;AAOA,kCAAoB,YAAM;AACxB,QAAI,CAACD,GAAG,CAACC,OAAT,EAAkB;AAClB,QAAME,SAAS,GAAGC,MAAM,CAACJ,GAAG,CAACC,OAAJ,CAAYI,OAAZ,CAAoBP,KAArB,CAAxB;;AACA,QAAIA,KAAK,IAAIK,SAAT,IAAsB,CAACC,MAAM,CAACE,KAAP,CAAaH,SAAb,CAA3B,EAAoD;AAClDJ,MAAAA,QAAQ,CAACI,SAAD,CAAR;AACD;AACF,GAND;AAQA,MAAMI,WAAW,GAAGV,OAAO,GACvB,iBAAqBP,WAAW,CAACkB,QAAZ,CAAqBX,OAArB,CAArB,CADuB,GAEvB,iBAAqBP,WAAW,CAACkB,QAAjC,CAFJ;AAIA,SAAO;AACLlB,IAAAA,WAAW,EAAXA,WADK;AAELQ,IAAAA,KAAK,EAALA,KAFK;AAGLW,IAAAA,YAAY,EAAEnB,WAAW,CAACoB,cAAZ,CAA2BV,GAAG,CAACC,OAA/B,CAHT;AAILO,IAAAA,QAAQ,EAAE,2BAAUD,WAAV,EAAuBP,GAAvB;AAJL,GAAP;AAMD;AAED;AACA;AACA;AACA;;;AAEO,SAASW,uBAAT,GAGH;AAEF,MAAMC,eAAe,GAAG,iBAA0BlB,0BAA1B,CAAxB;;AAEA,MAAMmB,sBAAsB,GAAG,SAAzBA,sBAAyB;AAAA,WAC7B,iBAA+BlB,qBAAqB,EAApD,CAD6B;AAAA,GAA/B;;AAGA,MAAMmB,cAAc,GAAG,SAAjBA,cAAiB,CAACjB,OAAD;AAAA,WACrBD,aAAa,CAAOC,OAAP,CADQ;AAAA,GAAvB;;AAGA,MAAMkB,eAAe,GAAG,SAAlBA,eAAkB;AAAA,WAAM3B,cAAc,EAApB;AAAA,GAAxB;;AAEA,SAAO,CACL;AACAwB,EAAAA,eAFK,EAGL;AACAC,EAAAA,sBAJK,EAKL;AACAE,EAAAA,eANK,EAOL;AACAD,EAAAA,cARK,CAAP;AAUD","sourcesContent":["import { createContext, mergeRefs } from \"@chakra-ui/react-utils\"\nimport { RefCallback, useRef, useState } from \"react\"\nimport { DescendantsManager, DescendantOptions } from \"./descendant\"\nimport { useSafeLayoutEffect, cast } from \"./utils\"\n\n/**\n * @internal\n * React hook that initializes the DescendantsManager\n */\nexport function useDescendants<T extends HTMLElement = HTMLElement, K = {}>() {\n const [descendants] = useState(() => new DescendantsManager<T, K>())\n useSafeLayoutEffect(() => {\n return () => descendants.destroy()\n })\n return descendants\n}\n\nexport interface UseDescendantsReturn\n extends ReturnType<typeof useDescendants> {}\n\n/* -------------------------------------------------------------------------------------------------\n * Descendants context to be used in component-land.\n - Mount the `DescendantsContextProvider` at the root of the component\n - Call `useDescendantsContext` anywhere you need access to the descendants information\n\n NB: I recommend using `createDescendantContext` below\n * -----------------------------------------------------------------------------------------------*/\n\nexport const [\n DescendantsContextProvider,\n useDescendantsContext,\n] = createContext<UseDescendantsReturn>({\n name: \"DescendantsProvider\",\n errorMessage: \"useDescendantsContext must be used within DescendantsProvider\",\n})\n\n/**\n * @internal\n * This hook provides information a descendant such as:\n * - Its index compared to other descendants\n * - ref callback to register the descendant\n * - Its enabled index compared to other enabled descendants\n */\nexport function useDescendant<T extends HTMLElement = HTMLElement, K = {}>(\n options?: DescendantOptions & K,\n) {\n const descendants = useDescendantsContext()\n const [index, setIndex] = useState(-1)\n const ref = useRef<T>(null)\n\n useSafeLayoutEffect(() => {\n return () => {\n if (!ref.current) return\n descendants.unregister(ref.current)\n }\n }, [])\n\n useSafeLayoutEffect(() => {\n if (!ref.current) return\n const dataIndex = Number(ref.current.dataset.index)\n if (index != dataIndex && !Number.isNaN(dataIndex)) {\n setIndex(dataIndex)\n }\n })\n\n const refCallback = options\n ? cast<RefCallback<T>>(descendants.register(options))\n : cast<RefCallback<T>>(descendants.register)\n\n return {\n descendants,\n index,\n enabledIndex: descendants.enabledIndexOf(ref.current),\n register: mergeRefs(refCallback, ref),\n }\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Function that provides strongly typed versions of the context provider and hooks above.\n To be used in component-land\n * -----------------------------------------------------------------------------------------------*/\n\nexport function createDescendantContext<\n T extends HTMLElement = HTMLElement,\n K = {}\n>() {\n type ContextProviderType = React.Provider<DescendantsManager<T, K>>\n const ContextProvider = cast<ContextProviderType>(DescendantsContextProvider)\n\n const _useDescendantsContext = () =>\n cast<DescendantsManager<T, K>>(useDescendantsContext())\n\n const _useDescendant = (options?: DescendantOptions & K) =>\n useDescendant<T, K>(options)\n\n const _useDescendants = () => useDescendants<T, K>()\n\n return [\n // context provider\n ContextProvider,\n // call this when you need to read from context\n _useDescendantsContext,\n // descendants state information, to be called and passed to `ContextProvider`\n _useDescendants,\n // descendant index information\n _useDescendant,\n ] as const\n}\n"],"file":"use-descendant.js"}
export * from "./use-descendant";
export * from "./descendant";
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAd","sourcesContent":["export * from \"./use-descendant\"\n"],"file":"index.js"}
{"version":3,"sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAd;AACA,cAAc,cAAd","sourcesContent":["export * from \"./use-descendant\"\nexport * from \"./descendant\"\n"],"file":"index.js"}

@@ -1,97 +0,83 @@

function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
import { createContext, mergeRefs } from "@chakra-ui/react-utils";
import { useRef, useState } from "react";
import { DescendantsManager } from "./descendant";
import { useSafeLayoutEffect, cast } from "./utils";
/**
* @internal
* React hook that initializes the DescendantsManager
*/
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
import { useCallback, useMemo, useState } from "react";
import { useSafeLayoutEffect, useForceUpdate } from "@chakra-ui/hooks";
export function useDescendant(props) {
var {
context,
element,
index: indexProp,
disabled,
focusable
} = props,
rest = _objectWithoutPropertiesLoose(props, ["context", "element", "index", "disabled", "focusable"]);
var forceUpdate = useForceUpdate();
var {
register,
unregister,
descendants
} = context;
export function useDescendants() {
var [descendants] = useState(() => new DescendantsManager());
useSafeLayoutEffect(() => {
if (!element) {
forceUpdate();
}
/**
* Don't register this descendant if it is disabled and not focusable
*/
return () => descendants.destroy();
});
return descendants;
}
/* -------------------------------------------------------------------------------------------------
* Descendants context to be used in component-land.
- Mount the `DescendantsContextProvider` at the root of the component
- Call `useDescendantsContext` anywhere you need access to the descendants information
if (disabled && !focusable) return undefined;
/**
* else, register the descendant
*/
NB: I recommend using `createDescendantContext` below
* -----------------------------------------------------------------------------------------------*/
export var [DescendantsContextProvider, useDescendantsContext] = createContext({
name: "DescendantsProvider",
errorMessage: "useDescendantsContext must be used within DescendantsProvider"
});
/**
* @internal
* This hook provides information a descendant such as:
* - Its index compared to other descendants
* - ref callback to register the descendant
* - Its enabled index compared to other enabled descendants
*/
register(_extends({
element,
disabled,
focusable
}, rest));
/**
* when it unmounts, unregister the descendant
*/
export function useDescendant(options) {
var descendants = useDescendantsContext();
var [index, setIndex] = useState(-1);
var ref = useRef(null);
useSafeLayoutEffect(() => {
return () => {
if (!ref.current) return;
descendants.unregister(ref.current);
};
}, []);
useSafeLayoutEffect(() => {
if (!ref.current) return;
var dataIndex = Number(ref.current.dataset.index);
return () => {
if (element) {
unregister(element);
}
}; // eslint-disable-next-line
}, [element, disabled, focusable, ...Object.values(rest)]);
var index = indexProp != null ? indexProp : descendants.findIndex(descendant => descendant.element === element);
return index;
if (index != dataIndex && !Number.isNaN(dataIndex)) {
setIndex(dataIndex);
}
});
var refCallback = options ? cast(descendants.register(options)) : cast(descendants.register);
return {
descendants,
index,
enabledIndex: descendants.enabledIndexOf(ref.current),
register: mergeRefs(refCallback, ref)
};
}
export function useDescendants() {
var [descendants, setDescendants] = useState([]);
var register = useCallback((_ref) => {
var {
element
} = _ref,
rest = _objectWithoutPropertiesLoose(_ref, ["element"]);
/* -------------------------------------------------------------------------------------------------
* Function that provides strongly typed versions of the context provider and hooks above.
To be used in component-land
* -----------------------------------------------------------------------------------------------*/
if (!element) return; // @ts-ignore
export function createDescendantContext() {
var ContextProvider = cast(DescendantsContextProvider);
setDescendants(prevDescendants => {
if (prevDescendants.find(item => item.element === element) == null) {
var index = prevDescendants.findIndex(item => {
if (!item.element || !element) return false;
return Boolean(item.element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING);
});
var _useDescendantsContext = () => cast(useDescendantsContext());
var newItem = _extends({
element
}, rest);
var _useDescendant = options => useDescendant(options);
if (index === -1) {
return [...prevDescendants, newItem];
}
var _useDescendants = () => useDescendants();
return [...prevDescendants.slice(0, index), newItem, ...prevDescendants.slice(index)];
}
return prevDescendants;
});
}, []);
var unregister = useCallback(element => {
if (!element) return;
setDescendants(descendants => descendants.filter(descendant => element !== descendant.element));
}, []);
var context = useMemo(() => ({
descendants,
register,
unregister
}), [descendants, register, unregister]);
return context;
return [// context provider
ContextProvider, // call this when you need to read from context
_useDescendantsContext, // descendants state information, to be called and passed to `ContextProvider`
_useDescendants, // descendant index information
_useDescendant];
}
//# sourceMappingURL=use-descendant.js.map

@@ -1,1 +0,1 @@

{"version":3,"sources":["../../src/use-descendant.ts"],"names":["useCallback","useMemo","useState","useSafeLayoutEffect","useForceUpdate","useDescendant","props","context","element","index","indexProp","disabled","focusable","rest","forceUpdate","register","unregister","descendants","undefined","Object","values","findIndex","descendant","useDescendants","setDescendants","prevDescendants","find","item","Boolean","compareDocumentPosition","Node","DOCUMENT_POSITION_PRECEDING","newItem","slice","filter"],"mappings":"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","sourcesContent":["import { useCallback, useMemo, useState } from \"react\"\nimport { useSafeLayoutEffect, useForceUpdate } from \"@chakra-ui/hooks\"\n\nexport type Descendant<T extends HTMLElement, P = {}> = P & {\n element: T | null\n index?: number\n disabled?: boolean\n focusable?: boolean\n}\n\nexport interface DescendantContext<T extends HTMLElement, P = {}> {\n descendants: Descendant<T, P>[]\n register: (descendant: Descendant<T, P>) => void\n unregister: (element: T) => void\n}\n\nexport type UseDescendantProps<T extends HTMLElement, P> = {\n context: DescendantContext<T, P>\n} & Descendant<T, P>\n\nexport function useDescendant<T extends HTMLElement, P>(\n props: UseDescendantProps<T, P>,\n) {\n const {\n context,\n element,\n index: indexProp,\n disabled,\n focusable,\n ...rest\n } = props\n\n const forceUpdate = useForceUpdate()\n const { register, unregister, descendants } = context\n\n useSafeLayoutEffect(() => {\n if (!element) {\n forceUpdate()\n }\n\n /**\n * Don't register this descendant if it is disabled and not focusable\n */\n if (disabled && !focusable) return undefined\n\n /**\n * else, register the descendant\n */\n register({ element, disabled, focusable, ...rest } as any)\n\n /**\n * when it unmounts, unregister the descendant\n */\n return () => {\n if (element) {\n unregister(element)\n }\n }\n // eslint-disable-next-line\n }, [element, disabled, focusable, ...Object.values(rest)])\n\n const index =\n indexProp ??\n descendants.findIndex((descendant) => descendant.element === element)\n\n return index\n}\n\nexport function useDescendants<T extends HTMLElement, P>() {\n const [descendants, setDescendants] = useState<Descendant<T, P>[]>([])\n\n const register = useCallback(({ element, ...rest }: Descendant<T, P>) => {\n if (!element) return\n\n // @ts-ignore\n setDescendants((prevDescendants) => {\n if (prevDescendants.find((item) => item.element === element) == null) {\n const index = prevDescendants.findIndex((item) => {\n if (!item.element || !element) return false\n\n return Boolean(\n item.element.compareDocumentPosition(element) &\n Node.DOCUMENT_POSITION_PRECEDING,\n )\n })\n\n const newItem = { element, ...rest }\n\n if (index === -1) {\n return [...prevDescendants, newItem]\n }\n return [\n ...prevDescendants.slice(0, index),\n newItem,\n ...prevDescendants.slice(index),\n ]\n }\n return prevDescendants\n })\n }, [])\n\n const unregister = useCallback((element: T) => {\n if (!element) return\n setDescendants((descendants) =>\n descendants.filter((descendant) => element !== descendant.element),\n )\n }, [])\n\n const context = useMemo(() => ({ descendants, register, unregister }), [\n descendants,\n register,\n unregister,\n ])\n\n return context\n}\n"],"file":"use-descendant.js"}
{"version":3,"sources":["../../src/use-descendant.ts"],"names":["createContext","mergeRefs","useRef","useState","DescendantsManager","useSafeLayoutEffect","cast","useDescendants","descendants","destroy","DescendantsContextProvider","useDescendantsContext","name","errorMessage","useDescendant","options","index","setIndex","ref","current","unregister","dataIndex","Number","dataset","isNaN","refCallback","register","enabledIndex","enabledIndexOf","createDescendantContext","ContextProvider","_useDescendantsContext","_useDescendant","_useDescendants"],"mappings":"AAAA,SAASA,aAAT,EAAwBC,SAAxB,QAAyC,wBAAzC;AACA,SAAsBC,MAAtB,EAA8BC,QAA9B,QAA8C,OAA9C;AACA,SAASC,kBAAT,QAAsD,cAAtD;AACA,SAASC,mBAAT,EAA8BC,IAA9B,QAA0C,SAA1C;AAEA;AACA;AACA;AACA;;AACA,OAAO,SAASC,cAAT,GAAuE;AAC5E,MAAM,CAACC,WAAD,IAAgBL,QAAQ,CAAC,MAAM,IAAIC,kBAAJ,EAAP,CAA9B;AACAC,EAAAA,mBAAmB,CAAC,MAAM;AACxB,WAAO,MAAMG,WAAW,CAACC,OAAZ,EAAb;AACD,GAFkB,CAAnB;AAGA,SAAOD,WAAP;AACD;;AAKD;AACA;AACA;AACA;AACA;AACA;AACA;AAEA,OAAO,IAAM,CACXE,0BADW,EAEXC,qBAFW,IAGTX,aAAa,CAAuB;AACtCY,EAAAA,IAAI,EAAE,qBADgC;AAEtCC,EAAAA,YAAY,EAAE;AAFwB,CAAvB,CAHV;AAQP;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,SAASC,aAAT,CACLC,OADK,EAEL;AACA,MAAMP,WAAW,GAAGG,qBAAqB,EAAzC;AACA,MAAM,CAACK,KAAD,EAAQC,QAAR,IAAoBd,QAAQ,CAAC,CAAC,CAAF,CAAlC;AACA,MAAMe,GAAG,GAAGhB,MAAM,CAAI,IAAJ,CAAlB;AAEAG,EAAAA,mBAAmB,CAAC,MAAM;AACxB,WAAO,MAAM;AACX,UAAI,CAACa,GAAG,CAACC,OAAT,EAAkB;AAClBX,MAAAA,WAAW,CAACY,UAAZ,CAAuBF,GAAG,CAACC,OAA3B;AACD,KAHD;AAID,GALkB,EAKhB,EALgB,CAAnB;AAOAd,EAAAA,mBAAmB,CAAC,MAAM;AACxB,QAAI,CAACa,GAAG,CAACC,OAAT,EAAkB;AAClB,QAAME,SAAS,GAAGC,MAAM,CAACJ,GAAG,CAACC,OAAJ,CAAYI,OAAZ,CAAoBP,KAArB,CAAxB;;AACA,QAAIA,KAAK,IAAIK,SAAT,IAAsB,CAACC,MAAM,CAACE,KAAP,CAAaH,SAAb,CAA3B,EAAoD;AAClDJ,MAAAA,QAAQ,CAACI,SAAD,CAAR;AACD;AACF,GANkB,CAAnB;AAQA,MAAMI,WAAW,GAAGV,OAAO,GACvBT,IAAI,CAAiBE,WAAW,CAACkB,QAAZ,CAAqBX,OAArB,CAAjB,CADmB,GAEvBT,IAAI,CAAiBE,WAAW,CAACkB,QAA7B,CAFR;AAIA,SAAO;AACLlB,IAAAA,WADK;AAELQ,IAAAA,KAFK;AAGLW,IAAAA,YAAY,EAAEnB,WAAW,CAACoB,cAAZ,CAA2BV,GAAG,CAACC,OAA/B,CAHT;AAILO,IAAAA,QAAQ,EAAEzB,SAAS,CAACwB,WAAD,EAAcP,GAAd;AAJd,GAAP;AAMD;AAED;AACA;AACA;AACA;;AAEA,OAAO,SAASW,uBAAT,GAGH;AAEF,MAAMC,eAAe,GAAGxB,IAAI,CAAsBI,0BAAtB,CAA5B;;AAEA,MAAMqB,sBAAsB,GAAG,MAC7BzB,IAAI,CAA2BK,qBAAqB,EAAhD,CADN;;AAGA,MAAMqB,cAAc,GAAIjB,OAAD,IACrBD,aAAa,CAAOC,OAAP,CADf;;AAGA,MAAMkB,eAAe,GAAG,MAAM1B,cAAc,EAA5C;;AAEA,SAAO,CACL;AACAuB,EAAAA,eAFK,EAGL;AACAC,EAAAA,sBAJK,EAKL;AACAE,EAAAA,eANK,EAOL;AACAD,EAAAA,cARK,CAAP;AAUD","sourcesContent":["import { createContext, mergeRefs } from \"@chakra-ui/react-utils\"\nimport { RefCallback, useRef, useState } from \"react\"\nimport { DescendantsManager, DescendantOptions } from \"./descendant\"\nimport { useSafeLayoutEffect, cast } from \"./utils\"\n\n/**\n * @internal\n * React hook that initializes the DescendantsManager\n */\nexport function useDescendants<T extends HTMLElement = HTMLElement, K = {}>() {\n const [descendants] = useState(() => new DescendantsManager<T, K>())\n useSafeLayoutEffect(() => {\n return () => descendants.destroy()\n })\n return descendants\n}\n\nexport interface UseDescendantsReturn\n extends ReturnType<typeof useDescendants> {}\n\n/* -------------------------------------------------------------------------------------------------\n * Descendants context to be used in component-land.\n - Mount the `DescendantsContextProvider` at the root of the component\n - Call `useDescendantsContext` anywhere you need access to the descendants information\n\n NB: I recommend using `createDescendantContext` below\n * -----------------------------------------------------------------------------------------------*/\n\nexport const [\n DescendantsContextProvider,\n useDescendantsContext,\n] = createContext<UseDescendantsReturn>({\n name: \"DescendantsProvider\",\n errorMessage: \"useDescendantsContext must be used within DescendantsProvider\",\n})\n\n/**\n * @internal\n * This hook provides information a descendant such as:\n * - Its index compared to other descendants\n * - ref callback to register the descendant\n * - Its enabled index compared to other enabled descendants\n */\nexport function useDescendant<T extends HTMLElement = HTMLElement, K = {}>(\n options?: DescendantOptions & K,\n) {\n const descendants = useDescendantsContext()\n const [index, setIndex] = useState(-1)\n const ref = useRef<T>(null)\n\n useSafeLayoutEffect(() => {\n return () => {\n if (!ref.current) return\n descendants.unregister(ref.current)\n }\n }, [])\n\n useSafeLayoutEffect(() => {\n if (!ref.current) return\n const dataIndex = Number(ref.current.dataset.index)\n if (index != dataIndex && !Number.isNaN(dataIndex)) {\n setIndex(dataIndex)\n }\n })\n\n const refCallback = options\n ? cast<RefCallback<T>>(descendants.register(options))\n : cast<RefCallback<T>>(descendants.register)\n\n return {\n descendants,\n index,\n enabledIndex: descendants.enabledIndexOf(ref.current),\n register: mergeRefs(refCallback, ref),\n }\n}\n\n/* -------------------------------------------------------------------------------------------------\n * Function that provides strongly typed versions of the context provider and hooks above.\n To be used in component-land\n * -----------------------------------------------------------------------------------------------*/\n\nexport function createDescendantContext<\n T extends HTMLElement = HTMLElement,\n K = {}\n>() {\n type ContextProviderType = React.Provider<DescendantsManager<T, K>>\n const ContextProvider = cast<ContextProviderType>(DescendantsContextProvider)\n\n const _useDescendantsContext = () =>\n cast<DescendantsManager<T, K>>(useDescendantsContext())\n\n const _useDescendant = (options?: DescendantOptions & K) =>\n useDescendant<T, K>(options)\n\n const _useDescendants = () => useDescendants<T, K>()\n\n return [\n // context provider\n ContextProvider,\n // call this when you need to read from context\n _useDescendantsContext,\n // descendants state information, to be called and passed to `ContextProvider`\n _useDescendants,\n // descendant index information\n _useDescendant,\n ] as const\n}\n"],"file":"use-descendant.js"}
export * from "./use-descendant";
export * from "./descendant";
//# sourceMappingURL=index.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA"}
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAA;AAChC,cAAc,cAAc,CAAA"}

@@ -1,21 +0,30 @@

export declare type Descendant<T extends HTMLElement, P = {}> = P & {
element: T | null;
index?: number;
disabled?: boolean;
focusable?: boolean;
};
export interface DescendantContext<T extends HTMLElement, P = {}> {
descendants: Descendant<T, P>[];
register: (descendant: Descendant<T, P>) => void;
unregister: (element: T) => void;
/// <reference types="react" />
import { DescendantsManager, DescendantOptions } from "./descendant";
/**
* @internal
* React hook that initializes the DescendantsManager
*/
export declare function useDescendants<T extends HTMLElement = HTMLElement, K = {}>(): DescendantsManager<T, K>;
export interface UseDescendantsReturn extends ReturnType<typeof useDescendants> {
}
export declare type UseDescendantProps<T extends HTMLElement, P> = {
context: DescendantContext<T, P>;
} & Descendant<T, P>;
export declare function useDescendant<T extends HTMLElement, P>(props: UseDescendantProps<T, P>): number;
export declare function useDescendants<T extends HTMLElement, P>(): {
descendants: Descendant<T, P>[];
register: ({ element, ...rest }: Descendant<T, P>) => void;
unregister: (element: T) => void;
export declare const DescendantsContextProvider: import("react").Provider<UseDescendantsReturn>, useDescendantsContext: () => UseDescendantsReturn;
/**
* @internal
* This hook provides information a descendant such as:
* - Its index compared to other descendants
* - ref callback to register the descendant
* - Its enabled index compared to other enabled descendants
*/
export declare function useDescendant<T extends HTMLElement = HTMLElement, K = {}>(options?: DescendantOptions & K): {
descendants: UseDescendantsReturn;
index: number;
enabledIndex: number;
register: (node: T | null) => void;
};
export declare function createDescendantContext<T extends HTMLElement = HTMLElement, K = {}>(): readonly [import("react").Provider<DescendantsManager<T, K>>, () => DescendantsManager<T, K>, () => DescendantsManager<T, K>, (options?: (DescendantOptions & K) | undefined) => {
descendants: UseDescendantsReturn;
index: number;
enabledIndex: number;
register: (node: T | null) => void;
}];
//# sourceMappingURL=use-descendant.d.ts.map

@@ -1,1 +0,1 @@

{"version":3,"file":"use-descendant.d.ts","sourceRoot":"","sources":["../../src/use-descendant.ts"],"names":[],"mappings":"AAGA,oBAAY,UAAU,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG;IAC1D,OAAO,EAAE,CAAC,GAAG,IAAI,CAAA;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,SAAS,CAAC,EAAE,OAAO,CAAA;CACpB,CAAA;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,GAAG,EAAE;IAC9D,WAAW,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAA;IAC/B,QAAQ,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,IAAI,CAAA;IAChD,UAAU,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA;CACjC;AAED,oBAAY,kBAAkB,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,IAAI;IACzD,OAAO,EAAE,iBAAiB,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;CACjC,GAAG,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;AAEpB,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC,EACpD,KAAK,EAAE,kBAAkB,CAAC,CAAC,EAAE,CAAC,CAAC,UA6ChC;AAED,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,EAAE,CAAC;;qCAGD,WAAW,CAAC,EAAE,CAAC,CAAC;0BA8B3B,CAAC;EAc3C"}
{"version":3,"file":"use-descendant.d.ts","sourceRoot":"","sources":["../../src/use-descendant.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAGpE;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,CAAC,GAAG,EAAE,8BAMzE;AAED,MAAM,WAAW,oBACf,SAAQ,UAAU,CAAC,OAAO,cAAc,CAAC;CAAG;AAU9C,eAAO,MACL,0BAA0B,kDAC1B,qBAAqB,4BAIrB,CAAA;AAEF;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAAE,CAAC,GAAG,EAAE,EACvE,OAAO,CAAC,EAAE,iBAAiB,GAAG,CAAC;;;;;EA+BhC;AAOD,wBAAgB,uBAAuB,CACrC,CAAC,SAAS,WAAW,GAAG,WAAW,EACnC,CAAC,GAAG,EAAE;;;;;GAuBP"}
{
"name": "@chakra-ui/descendant",
"version": "1.1.3",
"version": "2.0.0",
"description": "Register child nodes of a react element for better accessibility",

@@ -57,3 +57,3 @@ "keywords": [

"dependencies": {
"@chakra-ui/hooks": "1.5.0"
"@chakra-ui/react-utils": "^1.1.2"
},

@@ -60,0 +60,0 @@ "peerDependencies": {

+130
-2
# Descendant
Keep track of descendant components and their relative indices.
A descendant index solution for better accessibility support in compound

@@ -12,7 +14,133 @@ components.

```sh
yarn add @chakra-ui/descendants
yarn add @chakra-ui/descendant
# or
npm i @chakra-ui/descendants
npm i @chakra-ui/descendant
```
## Motivation
Descendants observer is an utility hook for keeping track of descendant elements
and their relative indices.
In short, this package allows each item in a list to know it's relative index
and the parent of the list can keep track of each child, without needing to
render in a loop and pass each component an index.
This enables component composition:
```jsx
<List>
<Item /> // I'm index 0
<Item /> // I'm index 1<div>
<div>
<Item /> // I'm arbitrarily nested, but still know that I'm index 2
</div>
</div>
</List>
```
### Usage
```jsx
import { createDescendantContext } from "@descendants/react"
import * as React from "react"
const [
DescendantsProvider,
useDescendantsContext,
useDescendants,
useDescendant,
] = createDescendantContext()
const MenuContext = React.createContext({})
function Menu({ children }) {
// 1. Call the `useDescendants` hook
const descendants = useDescendants()
const [selected, setSelected] = React.useState(1)
const context = React.useMemo(() => ({ selected, setSelected }), [selected])
return (
// 2. Add the descendants context
<DescendantsProvider value={descendants}>
<MenuContext.Provider value={context}>
<div role="menu" style={{ maxWidth: 320 }}>
<button
onClick={() => {
const prev = descendants.prev(selected)
prev.node.focus()
setSelected(prev.index)
}}
>
Prev
</button>
<button
onClick={() => {
const next = descendants.next(selected)
next.node.focus()
setSelected(next.index)
}}
>
Next
</button>
{children}
</div>
</MenuContext.Provider>
</DescendantsProvider>
)
}
const MenuItem = ({ children }) => {
const { selected, setSelected } = React.useContext(MenuContext)
// 3. Read from descendant context
const { index, register } = useDescendant()
const isSelected = index === selected
return (
<div
role="menuitem"
ref={register}
aria-selected={isSelected}
onMouseMove={() => setSelected(index)}
style={{ color: isSelected ? "red" : "black" }}
>
{children} - {index}
</div>
)
}
const Example = () => {
const [show, setShow] = React.useState(false)
const [show2, setShow2] = React.useState(false)
const toggle = () => {
setShow(!show)
if (!show === true) {
setTimeout(() => {
setShow2(true)
}, 1000)
}
}
return (
<div>
<button onClick={toggle}>Toggle</button>
<Menu>
<MenuItem>One</MenuItem>
{show && <MenuItem>Two</MenuItem>}
<MenuItem>Three</MenuItem>
<MenuItem>Four</MenuItem>
<div>
{show2 && <MenuItem>Testing 🌟</MenuItem>}
<MenuItem>Five</MenuItem>
</div>
</Menu>
</div>
)
}
```