UNPKG

wix-style-react

Version:
80 lines 2.84 kB
import React from 'react'; const readItemNodesRecursively = (parentItemNode, children) => { if (!children) { return; } React.Children.toArray(children).forEach(child => { if (!React.isValidElement(child)) { return; } const itemKey = child?.props?.itemKey; const itemChildren = child?.props?.children; if (typeof itemKey === 'string' && itemKey !== parentItemNode.itemKey) { const itemNode = { itemKey }; (parentItemNode.items ??= []).push(itemNode); readItemNodesRecursively(itemNode, itemChildren); } else { readItemNodesRecursively(parentItemNode, itemChildren); } }); }; const readParentKeysRecursively = (keyToParentKey, itemNodes, parentItemKey) => { for (const { itemKey, items } of itemNodes) { keyToParentKey[itemKey] = parentItemKey; if (items) { readParentKeysRecursively(keyToParentKey, items, itemKey); } } }; /** * Recursively walks react children to create a tree of sidebar item nodes and * their parent-child relationships. */ export const extractItemNodes = (children) => { const rootNode = { itemKey: 'rootMenu' }; // TODO: use a symbol readItemNodesRecursively(rootNode, children); const items = rootNode.items ?? []; const keyToParentKey = Object.create(null); readParentKeysRecursively(keyToParentKey, items); return { items, keyToParentKey }; }; export const getItemPath = (keyToParentKey, itemKey) => { const path = []; while (itemKey !== undefined) { path.unshift(itemKey); itemKey = keyToParentKey[itemKey]; } return path; }; export const isMenu = (keyToParentKey, itemKey) => Object.values(keyToParentKey).includes(itemKey); export const getMenuPath = (keyToParentKey, itemKey) => { const path = getItemPath(keyToParentKey, itemKey); if (path.length > 0 && !isMenu(keyToParentKey, path[path.length - 1])) { path.pop(); } return path; }; export const getMaxDepth = (items) => { let maxDepth = 0; if (items?.length) { for (const item of items) { maxDepth = Math.max(maxDepth, getMaxDepth(item.items) + 1); } } return maxDepth; }; export function pick(object, keys) { // Probably should use `lodash.pick` but it's too smart with its key handing ( // lodash keys can be paths like `a.b.c`). Since we're using this to pick // keys from a record which gets created from consumer input, we can't be sure // that consumers won't use keys that look like paths. const result = {}; for (const key of keys) { if (Object.prototype.hasOwnProperty.call(object, key)) { result[key] = object[key]; } } return result; } //# sourceMappingURL=utils.js.map