@augment-vir/web
Version:
A collection of augments, helpers types, functions, and classes only for web (frontend) JavaScript environments.
97 lines (96 loc) • 3.58 kB
JavaScript
/**
* Gets all deeply nested elements contained within the given element, flattened into a single
* array. Shadow DOMs are traversed.
*
* Note that `<slot>` elements are included, as well as their nested elements (even if a slot filler
* is provided by the parent) and the slot filler itself (if provided).
*
* Optionally define a second "depth" input to control how far nestings should be pursued. Omit
* depth or set it to `undefined` or `0` to allow full depth search.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getNestedChildren(startingElement, depth) {
return recursivelyGetNestedChildren({
startingElement,
maxDepth: depth ?? 0,
currentDepth: 0,
});
}
function recursivelyGetNestedChildren({ startingElement, maxDepth, currentDepth, }) {
const children = getDirectChildren(startingElement);
return children.flatMap((child) => {
const nextDepth = currentDepth + 1;
const nested = maxDepth && nextDepth >= maxDepth
? []
: recursivelyGetNestedChildren({
startingElement: child,
maxDepth,
currentDepth: nextDepth,
});
return [
child,
nested,
].flat();
});
}
/**
* Gets all deeply nested elements contained within the given element in a tree. Shadow DOMs are
* traversed.
*
* Note that `<slot>` elements are included, as well as their nested elements (even if a slot filler
* is provided by the parent) and the slot filler itself (if provided).
*
* Optionally define a second "depth" input to control how far nestings should be pursued. Omit
* depth or set it to `undefined` or `0` to allow full depth search.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getNestedChildrenTree(startingElement, depth) {
return {
element: startingElement,
children: recursivelyGetNestedChildrenTree({
startingElement,
maxDepth: depth ?? 0,
currentDepth: 0,
}),
};
}
function recursivelyGetNestedChildrenTree({ startingElement, maxDepth, currentDepth, }) {
return getDirectChildren(startingElement).map((child) => {
const nextDepth = currentDepth + 1;
const nested = maxDepth && nextDepth >= Math.abs(maxDepth)
? []
: recursivelyGetNestedChildrenTree({
startingElement: child,
maxDepth,
currentDepth: nextDepth,
});
return {
element: child,
children: nested,
};
});
}
/**
* Gets an element's direct children. Includes slotted elements, direct `<slot>` children
* themselves, and all direct children of a shadow DOM. Default `<slot>` children are not included
* (since they're not "direct" children as they are nested under `<slot>`).
*
* Note that that slotted elements and light dom elements will always be shown above shadow dom
* elements. Besides that, the order of children is preserved.
*
* @category Web : Elements
* @category Package : @augment-vir/web
* @package [`@augment-vir/web`](https://www.npmjs.com/package/@augment-vir/web)
*/
export function getDirectChildren(startingElement) {
return [
...startingElement.children,
...(startingElement.shadowRoot?.children ?? []),
];
}