@zag-js/tree-view
Version:
Core logic for the tree-view widget implemented as a state machine
813 lines (807 loc) • 28.9 kB
JavaScript
import { createAnatomy } from '@zag-js/anatomy';
import { TreeCollection, filePathToTree } from '@zag-js/collection';
import { getByTypeahead, dataAttr, isComposingEvent, getEventTarget, isEditableElement, getEventKey, isModifierKey } from '@zag-js/dom-query';
import { first, uniq, addOrRemove, remove, add, isEqual, createSplitProps } from '@zag-js/utils';
import { createGuards, createMachine } from '@zag-js/core';
import { createProps } from '@zag-js/types';
// src/tree-view.anatomy.ts
var anatomy = createAnatomy("tree-view").parts(
"root",
"label",
"tree",
"item",
"itemIndicator",
"itemText",
"branch",
"branchControl",
"branchTrigger",
"branchContent",
"branchText",
"branchIndicator",
"branchIndentGuide"
);
var parts = anatomy.build();
var collection = (options) => {
return new TreeCollection(options);
};
collection.empty = () => {
return new TreeCollection({ rootNode: { children: [] } });
};
function filePathCollection(paths) {
return filePathToTree(paths);
}
// src/tree-view.dom.ts
var getRootId = (ctx) => ctx.ids?.root ?? `tree:${ctx.id}:root`;
var getLabelId = (ctx) => ctx.ids?.label ?? `tree:${ctx.id}:label`;
var getNodeId = (ctx, value) => ctx.ids?.node?.(value) ?? `tree:${ctx.id}:node:${value}`;
var getTreeId = (ctx) => ctx.ids?.tree ?? `tree:${ctx.id}:tree`;
var focusNode = (ctx, value) => {
if (value == null) return;
const nodeId = getNodeId(ctx, value);
ctx.getById(nodeId)?.focus({ preventScroll: true });
};
// src/tree-view.utils.ts
function skipFn(params) {
const { prop, context } = params;
return function skip({ indexPath }) {
const paths = prop("collection").getValuePath(indexPath).slice(0, -1);
return paths.some((value) => !context.get("expandedValue").includes(value));
};
}
function getVisibleNodes(params) {
const { prop } = params;
const nodes = [];
prop("collection").visit({
skip: skipFn(params),
onEnter: (node, indexPath) => {
nodes.push({ node, indexPath });
}
});
return nodes;
}
// src/tree-view.connect.ts
function connect(service, normalize) {
const { context, scope, computed, prop, send } = service;
const collection2 = prop("collection");
const expandedValue = Array.from(context.get("expandedValue"));
const selectedValue = Array.from(context.get("selectedValue"));
const isTypingAhead = computed("isTypingAhead");
const focusedValue = context.get("focusedValue");
function getNodeState(props2) {
const { node, indexPath } = props2;
const value = collection2.getNodeValue(node);
return {
value,
valuePath: collection2.getValuePath(indexPath),
disabled: Boolean(node.disabled),
focused: focusedValue == null ? isEqual(indexPath, [0]) : focusedValue === value,
selected: selectedValue.includes(value),
expanded: expandedValue.includes(value),
depth: indexPath.length,
isBranch: collection2.isBranchNode(node)
};
}
return {
collection: collection2,
expandedValue,
selectedValue,
expand(value) {
if (!value) return send({ type: "EXPANDED.ALL" });
const _expandedValue = uniq(expandedValue.concat(...value));
send({ type: "EXPANDED.SET", value: _expandedValue, src: "expand" });
},
collapse(value) {
if (!value) return send({ type: "EXPANDED.SET", value: [], src: "collapseAll" });
const _expandedValue = uniq(remove(expandedValue, ...value));
send({ type: "EXPANDED.SET", value: _expandedValue, src: "collapse" });
},
deselect(value) {
if (!value) return send({ type: "SELECTED.SET", value: [], src: "deselectAll" });
const _selectedValue = uniq(remove(selectedValue, ...value));
send({ type: "SELECTED.SET", value: _selectedValue, src: "deselect" });
},
select(value) {
if (!value) return send({ type: "SELECTED.ALL" });
const nextValue = [];
if (prop("selectionMode") === "single") {
if (value.length > 0) nextValue.push(value[value.length - 1]);
} else {
nextValue.push(...selectedValue, ...value);
}
send({ type: "SELECTED.SET", value: nextValue, src: "select" });
},
getVisibleNodes() {
return getVisibleNodes(service);
},
focus(value) {
focusNode(scope, value);
},
selectParent(value) {
const parentNode = collection2.getParentNode(value);
if (!parentNode) return;
const _selectedValue = add(selectedValue, collection2.getNodeValue(parentNode));
send({ type: "SELECTED.SET", value: _selectedValue, src: "select.parent" });
},
expandParent(value) {
const parentNode = collection2.getParentNode(value);
if (!parentNode) return;
const _expandedValue = add(expandedValue, collection2.getNodeValue(parentNode));
send({ type: "EXPANDED.SET", value: _expandedValue, src: "expand.parent" });
},
setExpandedValue(value) {
const _expandedValue = uniq(value);
send({ type: "EXPANDED.SET", value: _expandedValue });
},
setSelectedValue(value) {
const _selectedValue = uniq(value);
send({ type: "SELECTED.SET", value: _selectedValue });
},
getRootProps() {
return normalize.element({
...parts.root.attrs,
id: getRootId(scope),
dir: prop("dir")
});
},
getLabelProps() {
return normalize.element({
...parts.label.attrs,
id: getLabelId(scope),
dir: prop("dir")
});
},
getTreeProps() {
return normalize.element({
...parts.tree.attrs,
id: getTreeId(scope),
dir: prop("dir"),
role: "tree",
"aria-label": "Tree View",
"aria-labelledby": getLabelId(scope),
"aria-multiselectable": prop("selectionMode") === "multiple" || void 0,
tabIndex: -1,
onKeyDown(event) {
if (event.defaultPrevented) return;
if (isComposingEvent(event)) return;
const target = getEventTarget(event);
if (isEditableElement(target)) return;
const node = target?.closest("[data-part=branch-control], [data-part=item]");
if (!node) return;
const nodeId = node.dataset.value;
if (nodeId == null) {
console.warn(`[zag-js/tree-view] Node id not found for node`, node);
return;
}
const isBranchNode = node.matches("[data-part=branch-control]");
const keyMap = {
ArrowDown(event2) {
if (isModifierKey(event2)) return;
event2.preventDefault();
send({ type: "NODE.ARROW_DOWN", id: nodeId, shiftKey: event2.shiftKey });
},
ArrowUp(event2) {
if (isModifierKey(event2)) return;
event2.preventDefault();
send({ type: "NODE.ARROW_UP", id: nodeId, shiftKey: event2.shiftKey });
},
ArrowLeft(event2) {
if (isModifierKey(event2) || node.dataset.disabled) return;
event2.preventDefault();
send({ type: isBranchNode ? "BRANCH_NODE.ARROW_LEFT" : "NODE.ARROW_LEFT", id: nodeId });
},
ArrowRight(event2) {
if (!isBranchNode || node.dataset.disabled) return;
event2.preventDefault();
send({ type: "BRANCH_NODE.ARROW_RIGHT", id: nodeId });
},
Home(event2) {
if (isModifierKey(event2)) return;
event2.preventDefault();
send({ type: "NODE.HOME", id: nodeId, shiftKey: event2.shiftKey });
},
End(event2) {
if (isModifierKey(event2)) return;
event2.preventDefault();
send({ type: "NODE.END", id: nodeId, shiftKey: event2.shiftKey });
},
Space(event2) {
if (node.dataset.disabled) return;
if (isTypingAhead) {
send({ type: "TREE.TYPEAHEAD", key: event2.key });
} else {
keyMap.Enter?.(event2);
}
},
Enter(event2) {
if (node.dataset.disabled) return;
const isLink = target?.closest("a[href]");
if (!isLink) event2.preventDefault();
send({ type: isBranchNode ? "BRANCH_NODE.CLICK" : "NODE.CLICK", id: nodeId, src: "keyboard" });
},
"*"(event2) {
if (node.dataset.disabled) return;
event2.preventDefault();
send({ type: "SIBLINGS.EXPAND", id: nodeId });
},
a(event2) {
if (!event2.metaKey || node.dataset.disabled) return;
event2.preventDefault();
send({ type: "SELECTED.ALL", moveFocus: true });
}
};
const key = getEventKey(event, { dir: prop("dir") });
const exec = keyMap[key];
if (exec) {
exec(event);
return;
}
if (!isTypingAhead) return;
const isValidTypeahead = event.key.length === 1 && !isModifierKey(event);
if (!isValidTypeahead) return;
send({ type: "TREE.TYPEAHEAD", key: event.key, id: nodeId });
event.preventDefault();
}
});
},
getNodeState,
getItemProps(props2) {
const itemState = getNodeState(props2);
return normalize.element({
...parts.item.attrs,
id: getNodeId(scope, itemState.value),
dir: prop("dir"),
"data-ownedby": getTreeId(scope),
"data-path": props2.indexPath.join("/"),
"data-value": itemState.value,
tabIndex: itemState.focused ? 0 : -1,
"data-focus": dataAttr(itemState.focused),
role: "treeitem",
"aria-current": itemState.selected ? "true" : void 0,
"aria-selected": itemState.disabled ? void 0 : itemState.selected,
"data-selected": dataAttr(itemState.selected),
"aria-disabled": itemState.disabled,
"data-disabled": dataAttr(itemState.disabled),
"aria-level": itemState.depth,
"data-depth": itemState.depth,
style: {
"--depth": itemState.depth
},
onFocus(event) {
event.stopPropagation();
send({ type: "NODE.FOCUS", id: itemState.value });
},
onClick(event) {
if (itemState.disabled) return;
const isMetaKey = event.metaKey || event.ctrlKey;
send({ type: "NODE.CLICK", id: itemState.value, shiftKey: event.shiftKey, ctrlKey: isMetaKey });
event.stopPropagation();
const isLink = event.currentTarget.matches("a[href]");
if (!isLink) event.preventDefault();
}
});
},
getItemTextProps(props2) {
const itemState = getNodeState(props2);
return normalize.element({
...parts.itemText.attrs,
"data-disabled": dataAttr(itemState.disabled),
"data-selected": dataAttr(itemState.selected),
"data-focus": dataAttr(itemState.focused)
});
},
getItemIndicatorProps(props2) {
const itemState = getNodeState(props2);
return normalize.element({
...parts.itemIndicator.attrs,
"aria-hidden": true,
"data-disabled": dataAttr(itemState.disabled),
"data-selected": dataAttr(itemState.selected),
"data-focus": dataAttr(itemState.focused),
hidden: !itemState.selected
});
},
getBranchProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branch.attrs,
"data-depth": nodeState.depth,
dir: prop("dir"),
"data-branch": nodeState.value,
role: "treeitem",
"data-ownedby": getTreeId(scope),
"data-value": nodeState.value,
"aria-level": nodeState.depth,
"aria-selected": nodeState.disabled ? void 0 : nodeState.selected,
"data-path": props2.indexPath.join("/"),
"data-selected": dataAttr(nodeState.selected),
"aria-expanded": nodeState.expanded,
"data-state": nodeState.expanded ? "open" : "closed",
"aria-disabled": nodeState.disabled,
"data-disabled": dataAttr(nodeState.disabled),
style: {
"--depth": nodeState.depth
}
});
},
getBranchIndicatorProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchIndicator.attrs,
"aria-hidden": true,
"data-state": nodeState.expanded ? "open" : "closed",
"data-disabled": dataAttr(nodeState.disabled),
"data-selected": dataAttr(nodeState.selected),
"data-focus": dataAttr(nodeState.focused)
});
},
getBranchTriggerProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchTrigger.attrs,
role: "button",
dir: prop("dir"),
"data-disabled": dataAttr(nodeState.disabled),
"data-state": nodeState.expanded ? "open" : "closed",
"data-value": nodeState.value,
onClick(event) {
if (nodeState.disabled) return;
send({ type: "BRANCH_TOGGLE.CLICK", id: nodeState.value });
event.stopPropagation();
}
});
},
getBranchControlProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchControl.attrs,
role: "button",
id: getNodeId(scope, nodeState.value),
dir: prop("dir"),
tabIndex: nodeState.focused ? 0 : -1,
"data-path": props2.indexPath.join("/"),
"data-state": nodeState.expanded ? "open" : "closed",
"data-disabled": dataAttr(nodeState.disabled),
"data-selected": dataAttr(nodeState.selected),
"data-focus": dataAttr(nodeState.focused),
"data-value": nodeState.value,
"data-depth": nodeState.depth,
onFocus(event) {
send({ type: "NODE.FOCUS", id: nodeState.value });
event.stopPropagation();
},
onClick(event) {
if (nodeState.disabled) return;
const isMetaKey = event.metaKey || event.ctrlKey;
send({ type: "BRANCH_NODE.CLICK", id: nodeState.value, shiftKey: event.shiftKey, ctrlKey: isMetaKey });
event.stopPropagation();
}
});
},
getBranchTextProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchText.attrs,
dir: prop("dir"),
"data-disabled": dataAttr(nodeState.disabled),
"data-state": nodeState.expanded ? "open" : "closed"
});
},
getBranchContentProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchContent.attrs,
role: "group",
dir: prop("dir"),
"data-state": nodeState.expanded ? "open" : "closed",
"data-depth": nodeState.depth,
"data-path": props2.indexPath.join("/"),
"data-value": nodeState.value,
hidden: !nodeState.expanded
});
},
getBranchIndentGuideProps(props2) {
const nodeState = getNodeState(props2);
return normalize.element({
...parts.branchIndentGuide.attrs,
"data-depth": nodeState.depth
});
}
};
}
var { and } = createGuards();
var machine = createMachine({
props({ props: props2 }) {
return {
selectionMode: "single",
collection: collection.empty(),
typeahead: true,
expandOnClick: true,
defaultExpandedValue: [],
defaultSelectedValue: [],
...props2
};
},
initialState() {
return "idle";
},
context({ prop, bindable, getContext }) {
return {
expandedValue: bindable(() => ({
defaultValue: prop("defaultExpandedValue"),
value: prop("expandedValue"),
isEqual: isEqual,
onChange(value) {
const ctx = getContext();
const focusedValue = ctx.get("focusedValue");
prop("onExpandedChange")?.({ expandedValue: value, focusedValue });
}
})),
selectedValue: bindable(() => ({
defaultValue: prop("defaultSelectedValue"),
value: prop("selectedValue"),
isEqual: isEqual,
onChange(value) {
const ctx = getContext();
const focusedValue = ctx.get("focusedValue");
prop("onSelectionChange")?.({ selectedValue: value, focusedValue });
}
})),
focusedValue: bindable(() => ({
defaultValue: prop("focusedValue"),
onChange(value) {
prop("onFocusChange")?.({ focusedValue: value });
}
}))
};
},
refs() {
return {
typeaheadState: { ...getByTypeahead.defaultOptions }
};
},
computed: {
isMultipleSelection: ({ prop }) => prop("selectionMode") === "multiple",
isTypingAhead: ({ refs }) => refs.get("typeaheadState").keysSoFar.length > 0
},
on: {
"EXPANDED.SET": {
actions: ["setExpanded"]
},
"SELECTED.SET": {
actions: ["setSelected"]
},
"SELECTED.ALL": [
{
guard: and("isMultipleSelection", "moveFocus"),
actions: ["selectAllNodes", "focusTreeLastNode"]
},
{
guard: "isMultipleSelection",
actions: ["selectAllNodes"]
}
],
"EXPANDED.ALL": {
actions: ["expandAllBranches"]
}
},
states: {
idle: {
on: {
"NODE.FOCUS": {
actions: ["setFocusedNode"]
},
"NODE.ARROW_DOWN": [
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["focusTreeNextNode", "extendSelectionToNextNode"]
},
{
actions: ["focusTreeNextNode"]
}
],
"NODE.ARROW_UP": [
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["focusTreePrevNode", "extendSelectionToPrevNode"]
},
{
actions: ["focusTreePrevNode"]
}
],
"NODE.ARROW_LEFT": {
actions: ["focusBranchNode"]
},
"BRANCH_NODE.ARROW_LEFT": [
{
guard: "isBranchExpanded",
actions: ["collapseBranch"]
},
{
actions: ["focusBranchNode"]
}
],
"BRANCH_NODE.ARROW_RIGHT": [
{
guard: and("isBranchFocused", "isBranchExpanded"),
actions: ["focusBranchFirstNode"]
},
{
actions: ["expandBranch"]
}
],
"SIBLINGS.EXPAND": {
actions: ["expandSiblingBranches"]
},
"NODE.HOME": [
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["extendSelectionToFirstNode", "focusTreeFirstNode"]
},
{
actions: ["focusTreeFirstNode"]
}
],
"NODE.END": [
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["extendSelectionToLastNode", "focusTreeLastNode"]
},
{
actions: ["focusTreeLastNode"]
}
],
"NODE.CLICK": [
{
guard: and("isCtrlKey", "isMultipleSelection"),
actions: ["toggleNodeSelection"]
},
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["extendSelectionToNode"]
},
{
actions: ["selectNode"]
}
],
"BRANCH_NODE.CLICK": [
{
guard: and("isCtrlKey", "isMultipleSelection"),
actions: ["toggleNodeSelection"]
},
{
guard: and("isShiftKey", "isMultipleSelection"),
actions: ["extendSelectionToNode"]
},
{
guard: "openOnClick",
actions: ["selectNode", "toggleBranchNode"]
},
{
actions: ["selectNode"]
}
],
"BRANCH_TOGGLE.CLICK": {
actions: ["toggleBranchNode"]
},
"TREE.TYPEAHEAD": {
actions: ["focusMatchedNode"]
}
}
}
},
implementations: {
guards: {
isBranchFocused: ({ context, event }) => context.get("focusedValue") === event.id,
isBranchExpanded: ({ context, event }) => context.get("expandedValue").includes(event.id),
isShiftKey: ({ event }) => event.shiftKey,
isCtrlKey: ({ event }) => event.ctrlKey,
hasSelectedItems: ({ context }) => context.get("selectedValue").length > 0,
isMultipleSelection: ({ prop }) => prop("selectionMode") === "multiple",
moveFocus: ({ event }) => !!event.moveFocus,
openOnClick: ({ prop }) => !!prop("expandOnClick")
},
actions: {
selectNode({ context, event }) {
context.set("selectedValue", [event.id]);
},
setFocusedNode({ context, event }) {
context.set("focusedValue", event.id);
},
clearFocusedNode({ context }) {
context.set("focusedValue", null);
},
clearSelectedItem({ context }) {
context.set("selectedValue", []);
},
toggleBranchNode({ context, event }) {
context.set("expandedValue", (prev) => addOrRemove(prev, event.id));
},
expandBranch({ context, event }) {
context.set("expandedValue", (prev) => add(prev, event.id));
},
collapseBranch({ context, event }) {
context.set("expandedValue", (prev) => remove(prev, event.id));
},
setExpanded({ context, event }) {
context.set("expandedValue", event.value);
},
setSelected({ context, event }) {
context.set("selectedValue", event.value);
},
focusTreeFirstNode({ prop, scope }) {
const collection2 = prop("collection");
const firstNode = collection2.getFirstNode();
const firstValue = collection2.getNodeValue(firstNode);
focusNode(scope, firstValue);
},
focusTreeLastNode({ prop, scope }) {
const collection2 = prop("collection");
const lastNode = collection2.getLastNode();
const lastValue = collection2.getNodeValue(lastNode);
focusNode(scope, lastValue);
},
focusBranchFirstNode({ event, prop, scope }) {
const collection2 = prop("collection");
const branchNode = collection2.findNode(event.id);
const firstNode = collection2.getFirstNode(branchNode);
const firstValue = collection2.getNodeValue(firstNode);
focusNode(scope, firstValue);
},
focusTreeNextNode(params) {
const { event, prop, scope } = params;
const collection2 = prop("collection");
const nextNode = collection2.getNextNode(event.id, { skip: skipFn(params) });
if (!nextNode) return;
const nextValue = collection2.getNodeValue(nextNode);
focusNode(scope, nextValue);
},
focusTreePrevNode(params) {
const { event, prop, scope } = params;
const collection2 = prop("collection");
const prevNode = collection2.getPreviousNode(event.id, { skip: skipFn(params) });
if (!prevNode) return;
const prevValue = collection2.getNodeValue(prevNode);
focusNode(scope, prevValue);
},
focusBranchNode({ event, prop, scope }) {
const collection2 = prop("collection");
const parentNode = collection2.getParentNode(event.id);
const parentValue = parentNode ? collection2.getNodeValue(parentNode) : void 0;
focusNode(scope, parentValue);
},
selectAllNodes({ context, prop }) {
context.set("selectedValue", prop("collection").getValues());
},
focusMatchedNode(params) {
const { context, prop, refs, event, scope } = params;
const nodes = getVisibleNodes(params);
const elements = nodes.map(({ node: node2 }) => ({
textContent: prop("collection").stringifyNode(node2),
id: prop("collection").getNodeValue(node2)
}));
const node = getByTypeahead(elements, {
state: refs.get("typeaheadState"),
activeId: context.get("focusedValue"),
key: event.key
});
focusNode(scope, node?.id);
},
toggleNodeSelection({ context, event }) {
const selectedValue = addOrRemove(context.get("selectedValue"), event.id);
context.set("selectedValue", selectedValue);
},
expandAllBranches({ context, prop }) {
const nextValue = prop("collection").getBranchValues();
context.set("expandedValue", nextValue);
},
expandSiblingBranches({ context, event, prop }) {
const collection2 = prop("collection");
const indexPath = collection2.getIndexPath(event.id);
if (!indexPath) return;
const nodes = collection2.getSiblingNodes(indexPath);
const values = nodes.map((node) => collection2.getNodeValue(node));
context.set("expandedValue", uniq(values));
},
extendSelectionToNode(params) {
const { context, event, prop } = params;
const collection2 = prop("collection");
const anchorValue = first(context.get("selectedValue")) || collection2.getNodeValue(collection2.getFirstNode());
const targetValue = event.id;
let values = [anchorValue, targetValue];
let hits = 0;
const visibleNodes = getVisibleNodes(params);
visibleNodes.forEach(({ node }) => {
const nodeValue = collection2.getNodeValue(node);
if (hits === 1) values.push(nodeValue);
if (nodeValue === anchorValue || nodeValue === targetValue) hits++;
});
context.set("selectedValue", uniq(values));
},
extendSelectionToNextNode(params) {
const { context, event, prop } = params;
const collection2 = prop("collection");
const nextNode = collection2.getNextNode(event.id, { skip: skipFn(params) });
if (!nextNode) return;
const values = new Set(context.get("selectedValue"));
const nextValue = collection2.getNodeValue(nextNode);
if (nextValue == null) return;
if (values.has(event.id) && values.has(nextValue)) {
values.delete(event.id);
} else if (!values.has(nextValue)) {
values.add(nextValue);
}
context.set("selectedValue", Array.from(values));
},
extendSelectionToPrevNode(params) {
const { context, event, prop } = params;
const collection2 = prop("collection");
const prevNode = collection2.getPreviousNode(event.id, { skip: skipFn(params) });
if (!prevNode) return;
const values = new Set(context.get("selectedValue"));
const prevValue = collection2.getNodeValue(prevNode);
if (prevValue == null) return;
if (values.has(event.id) && values.has(prevValue)) {
values.delete(event.id);
} else if (!values.has(prevValue)) {
values.add(prevValue);
}
context.set("selectedValue", Array.from(values));
},
extendSelectionToFirstNode(params) {
const { context, prop } = params;
const collection2 = prop("collection");
const currentSelection = first(context.get("selectedValue"));
const values = [];
collection2.visit({
skip: skipFn(params),
onEnter: (node) => {
const nodeValue = collection2.getNodeValue(node);
values.push(nodeValue);
if (nodeValue === currentSelection) {
return "stop";
}
}
});
context.set("selectedValue", values);
},
extendSelectionToLastNode(params) {
const { context, prop } = params;
const collection2 = prop("collection");
const currentSelection = first(context.get("selectedValue"));
const values = [];
let current = false;
collection2.visit({
skip: skipFn(params),
onEnter: (node) => {
const nodeValue = collection2.getNodeValue(node);
if (nodeValue === currentSelection) current = true;
if (current) values.push(nodeValue);
}
});
context.set("selectedValue", values);
}
}
}
});
var props = createProps()([
"ids",
"collection",
"dir",
"expandedValue",
"expandOnClick",
"focusedValue",
"getRootNode",
"id",
"onExpandedChange",
"onFocusChange",
"onSelectionChange",
"selectedValue",
"selectionMode",
"typeahead",
"defaultExpandedValue",
"defaultSelectedValue"
]);
var splitProps = createSplitProps(props);
var itemProps = createProps()(["node", "indexPath"]);
var splitItemProps = createSplitProps(itemProps);
export { anatomy, collection, connect, filePathCollection, itemProps, machine, props, splitItemProps, splitProps };