@fluentui/react-tree 9.0.0-beta.25 → 9.0.0-beta.26
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.json +73 -1
- package/CHANGELOG.md +18 -2
- package/dist/index.d.ts +123 -9
- package/lib/components/Tree/Tree.types.js.map +1 -1
- package/lib/components/Tree/useRootTree.js +24 -8
- package/lib/components/Tree/useRootTree.js.map +1 -1
- package/lib/components/Tree/useSubtree.js +4 -0
- package/lib/components/Tree/useSubtree.js.map +1 -1
- package/lib/components/Tree/useTreeContextValues.js +4 -2
- package/lib/components/Tree/useTreeContextValues.js.map +1 -1
- package/lib/components/TreeItem/TreeItem.types.js.map +1 -1
- package/lib/components/TreeItem/useTreeItem.js +48 -4
- package/lib/components/TreeItem/useTreeItem.js.map +1 -1
- package/lib/components/TreeItem/useTreeItemContextValues.js +5 -3
- package/lib/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib/components/TreeItemLayout/TreeItemLayout.types.js.map +1 -1
- package/lib/components/TreeItemLayout/renderTreeItemLayout.js +1 -1
- package/lib/components/TreeItemLayout/renderTreeItemLayout.js.map +1 -1
- package/lib/components/TreeItemLayout/useTreeItemLayout.js +10 -5
- package/lib/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib/components/TreeItemLayout/useTreeItemLayoutStyles.styles.js +15 -8
- package/lib/components/TreeItemLayout/useTreeItemLayoutStyles.styles.js.map +1 -1
- package/lib/contexts/treeContext.js +3 -0
- package/lib/contexts/treeContext.js.map +1 -1
- package/lib/contexts/treeItemSlotsContext.js.map +1 -1
- package/lib/hooks/index.js +2 -0
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useFlatControllableCheckedItems.js +76 -0
- package/lib/hooks/useFlatControllableCheckedItems.js.map +1 -0
- package/lib/hooks/useFlatTree.js +16 -5
- package/lib/hooks/useFlatTree.js.map +1 -1
- package/lib/hooks/useNestedControllableCheckedItems.js +107 -0
- package/lib/hooks/useNestedControllableCheckedItems.js.map +1 -0
- package/lib/index.js.map +1 -1
- package/lib/utils/ImmutableMap.js +37 -0
- package/lib/utils/ImmutableMap.js.map +1 -0
- package/lib/utils/ImmutableSet.js +3 -2
- package/lib/utils/ImmutableSet.js.map +1 -1
- package/lib/utils/createFlatTreeItems.js +60 -8
- package/lib/utils/createFlatTreeItems.js.map +1 -1
- package/lib/utils/tokens.js +2 -1
- package/lib/utils/tokens.js.map +1 -1
- package/lib-commonjs/components/Tree/useRootTree.js +23 -7
- package/lib-commonjs/components/Tree/useRootTree.js.map +1 -1
- package/lib-commonjs/components/Tree/useSubtree.js +4 -0
- package/lib-commonjs/components/Tree/useSubtree.js.map +1 -1
- package/lib-commonjs/components/Tree/useTreeContextValues.js +4 -2
- package/lib-commonjs/components/Tree/useTreeContextValues.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItem.js +48 -4
- package/lib-commonjs/components/TreeItem/useTreeItem.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js +5 -3
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/renderTreeItemLayout.js +1 -1
- package/lib-commonjs/components/TreeItemLayout/renderTreeItemLayout.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayout.js +11 -6
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayoutStyles.styles.js +12 -8
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayoutStyles.styles.js.map +1 -1
- package/lib-commonjs/contexts/treeContext.js +3 -0
- package/lib-commonjs/contexts/treeContext.js.map +1 -1
- package/lib-commonjs/hooks/index.js +2 -0
- package/lib-commonjs/hooks/index.js.map +1 -1
- package/lib-commonjs/hooks/useFlatControllableCheckedItems.js +91 -0
- package/lib-commonjs/hooks/useFlatControllableCheckedItems.js.map +1 -0
- package/lib-commonjs/hooks/useFlatTree.js +14 -3
- package/lib-commonjs/hooks/useFlatTree.js.map +1 -1
- package/lib-commonjs/hooks/useNestedControllableCheckedItems.js +116 -0
- package/lib-commonjs/hooks/useNestedControllableCheckedItems.js.map +1 -0
- package/lib-commonjs/utils/ImmutableMap.js +45 -0
- package/lib-commonjs/utils/ImmutableMap.js.map +1 -0
- package/lib-commonjs/utils/ImmutableSet.js +3 -2
- package/lib-commonjs/utils/ImmutableSet.js.map +1 -1
- package/lib-commonjs/utils/createFlatTreeItems.js +60 -8
- package/lib-commonjs/utils/createFlatTreeItems.js.map +1 -1
- package/lib-commonjs/utils/tokens.js +2 -1
- package/lib-commonjs/utils/tokens.js.map +1 -1
- package/package.json +9 -7
package/lib/hooks/useFlatTree.js
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import { createFlatTreeItems
|
|
3
|
+
import { createFlatTreeItems } from '../utils/createFlatTreeItems';
|
|
4
4
|
import { treeDataTypes } from '../utils/tokens';
|
|
5
5
|
import { useFlatTreeNavigation } from './useFlatTreeNavigation';
|
|
6
|
-
import { useControllableOpenItems } from './useControllableOpenItems';
|
|
6
|
+
import { createNextOpenItems, useControllableOpenItems } from './useControllableOpenItems';
|
|
7
7
|
import { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement';
|
|
8
|
+
import { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './useFlatControllableCheckedItems';
|
|
8
9
|
/**
|
|
9
10
|
* this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems
|
|
10
11
|
* in multiple scenarios including virtualization.
|
|
@@ -21,16 +22,22 @@ import { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement'
|
|
|
21
22
|
flatTreeItemProps
|
|
22
23
|
]);
|
|
23
24
|
const [openItems, setOpenItems] = useControllableOpenItems(options);
|
|
25
|
+
const [checkedItems, setCheckedItems] = useFlatControllableCheckedItems(options);
|
|
24
26
|
const [navigate, navigationRef] = useFlatTreeNavigation(flatTreeItems);
|
|
25
27
|
const treeRef = React.useRef(null);
|
|
26
28
|
const handleOpenChange = useEventCallback((event, data)=>{
|
|
27
29
|
var _options_onOpenChange;
|
|
28
30
|
(_options_onOpenChange = options.onOpenChange) === null || _options_onOpenChange === void 0 ? void 0 : _options_onOpenChange.call(options, event, data);
|
|
29
31
|
if (!event.isDefaultPrevented()) {
|
|
30
|
-
setOpenItems(data
|
|
32
|
+
setOpenItems(createNextOpenItems(data, openItems));
|
|
31
33
|
}
|
|
32
34
|
event.preventDefault();
|
|
33
35
|
});
|
|
36
|
+
const handleCheckedChange = useEventCallback((event, data)=>{
|
|
37
|
+
var _options_onCheckedChange;
|
|
38
|
+
(_options_onCheckedChange = options.onCheckedChange) === null || _options_onCheckedChange === void 0 ? void 0 : _options_onCheckedChange.call(options, event, data);
|
|
39
|
+
setCheckedItems(createNextFlatCheckedItems(data, checkedItems, flatTreeItems));
|
|
40
|
+
});
|
|
34
41
|
const handleNavigation = useEventCallback((event, data)=>{
|
|
35
42
|
var _options_onNavigation_unstable;
|
|
36
43
|
(_options_onNavigation_unstable = options.onNavigation_unstable) === null || _options_onNavigation_unstable === void 0 ? void 0 : _options_onNavigation_unstable.call(options, event, data);
|
|
@@ -68,14 +75,18 @@ import { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement'
|
|
|
68
75
|
const getTreeProps = React.useCallback(()=>({
|
|
69
76
|
ref,
|
|
70
77
|
openItems,
|
|
78
|
+
selectionMode: options.selectionMode,
|
|
79
|
+
checkedItems,
|
|
71
80
|
onOpenChange: handleOpenChange,
|
|
81
|
+
onCheckedChange: handleCheckedChange,
|
|
72
82
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
73
83
|
onNavigation_unstable: handleNavigation
|
|
74
84
|
}), // eslint-disable-next-line react-hooks/exhaustive-deps
|
|
75
85
|
[
|
|
76
|
-
openItems
|
|
86
|
+
openItems,
|
|
87
|
+
checkedItems
|
|
77
88
|
]);
|
|
78
|
-
const items = React.useCallback(()=>
|
|
89
|
+
const items = React.useCallback(()=>flatTreeItems.visibleItems(openItems), [
|
|
79
90
|
openItems,
|
|
80
91
|
flatTreeItems
|
|
81
92
|
]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useFlatTree.ts"],"sourcesContent":["import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { createFlatTreeItems, VisibleFlatTreeItemGenerator } from '../utils/createFlatTreeItems';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useFlatTreeNavigation } from './useFlatTreeNavigation';\nimport { useControllableOpenItems } from './useControllableOpenItems';\nimport type {\n TreeNavigationData_unstable,\n TreeNavigationEvent_unstable,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeProps,\n} from '../Tree';\nimport type { TreeItemProps, TreeItemValue } from '../TreeItem';\nimport { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement';\nimport { ImmutableSet } from '../utils/ImmutableSet';\n\nexport type FlatTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> &\n Partial<Pick<TreeItemProps, 'itemType'>> & {\n value: TreeItemValue;\n parentValue?: TreeItemValue;\n };\n\n/**\n * The item that is returned by `useFlatTree`, it represents a wrapper around the properties provided to\n * `useFlatTree` but with extra information that might be useful on flat tree scenarios\n */\nexport type FlatTreeItem<Props extends FlatTreeItemProps = FlatTreeItemProps> = {\n index: number;\n level: number;\n childrenSize: number;\n value: TreeItemValue;\n parentValue: TreeItemValue | undefined;\n getTreeItemProps(): Required<Pick<Props, 'value' | 'aria-setsize' | 'aria-level' | 'aria-posinset' | 'itemType'>> &\n Omit<Props, 'parentId'>;\n};\n\nexport type FlatTreeProps = Required<Pick<TreeProps, 'openItems' | 'onOpenChange' | 'onNavigation_unstable'>> & {\n ref: React.Ref<HTMLDivElement>;\n openItems: ImmutableSet<TreeItemValue>;\n};\n\n/**\n * FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n *\n * On simple scenarios it is advised to simply use a nested structure instead.\n */\nexport type FlatTree<Props extends FlatTreeItemProps = FlatTreeItemProps> = {\n /**\n * returns the properties required for the Tree component to work properly.\n * That includes:\n * `openItems`, `onOpenChange`, `onNavigation_unstable` and `ref`\n */\n getTreeProps(): FlatTreeProps;\n /**\n * internal method used to react to an `onNavigation` event.\n * This method ensures proper navigation on keyboard and mouse interaction.\n * In case of virtualization it might be required to cancel default provided `onNavigation`\n * event and then call this method manually.\n *\n * @example\n * ```ts\n * // react-window\n * const handleNavigation = (event, data) => {\n * event.preventDefault();\n * const nextItem = tree.getNextNavigableItem(data);\n * // scroll to item using virtualization scroll mechanism\n * if (nextItem && tree.getElementFromItem(nextItem)) {\n * listRef.current.scrollToItem(nextItem.index);\n * }\n * // wait for scrolling to happen and then invoke navigate method\n * requestAnimationFrame(() => {\n * tree.navigate(data);\n * });\n * };\n *```\n */\n navigate(data: TreeNavigationData_unstable): void;\n /**\n * returns next item to be focused on a navigation.\n * This method is provided to decouple the element that needs to be focused from\n * the action of focusing it itself.\n *\n * On the case of TypeAhead navigation this method returns the current item.\n */\n getNextNavigableItem(\n visibleItems: FlatTreeItem<Props>[],\n data: TreeNavigationData_unstable,\n ): FlatTreeItem<Props> | undefined;\n /**\n * similar to getElementById but for FlatTreeItems\n */\n getElementFromItem(item: FlatTreeItem<Props>): HTMLElement | null;\n /**\n * an iterable containing all visually available flat tree items\n */\n items(): IterableIterator<FlatTreeItem<Props>>;\n};\n\ntype FlatTreeOptions = Pick<TreeProps, 'openItems' | 'defaultOpenItems' | 'onOpenChange' | 'onNavigation_unstable'>;\n\n/**\n * this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n * On simple scenarios it is advised to simply use a nested structure instead.\n *\n * @param flatTreeItemProps - a list of tree items\n * @param options - in case control over the internal openItems is required\n */\nexport function useFlatTree_unstable<Props extends FlatTreeItemProps = FlatTreeItemProps>(\n flatTreeItemProps: Props[],\n options: FlatTreeOptions = {},\n): FlatTree<Props> {\n const flatTreeItems = React.useMemo(() => createFlatTreeItems(flatTreeItemProps), [flatTreeItemProps]);\n const [openItems, setOpenItems] = useControllableOpenItems(options);\n const [navigate, navigationRef] = useFlatTreeNavigation(flatTreeItems);\n const treeRef = React.useRef<HTMLDivElement>(null);\n\n const handleOpenChange = useEventCallback((event: TreeOpenChangeEvent, data: TreeOpenChangeData) => {\n options.onOpenChange?.(event, data);\n if (!event.isDefaultPrevented()) {\n setOpenItems(data.openItems);\n }\n event.preventDefault();\n });\n\n const handleNavigation = useEventCallback(\n (event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable) => {\n options.onNavigation_unstable?.(event, data);\n if (!event.isDefaultPrevented()) {\n navigate(data);\n }\n event.preventDefault();\n },\n );\n\n const getNextNavigableItem = useEventCallback(\n (visibleItems: FlatTreeItem<Props>[], data: TreeNavigationData_unstable) => {\n const item = flatTreeItems.get(data.value);\n if (item) {\n switch (data.type) {\n case treeDataTypes.TypeAhead:\n return item;\n case treeDataTypes.ArrowLeft:\n return flatTreeItems.get(item.parentValue!);\n case treeDataTypes.ArrowRight:\n return visibleItems[item.index + 1];\n case treeDataTypes.End:\n return visibleItems[visibleItems.length - 1];\n case treeDataTypes.Home:\n return visibleItems[0];\n case treeDataTypes.ArrowDown:\n return visibleItems[item.index + 1];\n case treeDataTypes.ArrowUp:\n return visibleItems[item.index - 1];\n }\n }\n },\n );\n\n const getElementFromItem = React.useCallback((item: FlatTreeItem<Props>) => {\n return treeRef.current?.querySelector(`[${dataTreeItemValueAttrName}=\"${item.value}\"]`) as HTMLElement | null;\n }, []);\n\n const ref = useMergedRefs(treeRef, navigationRef as React.Ref<HTMLDivElement>);\n\n const getTreeProps = React.useCallback(\n () => ({\n ref,\n openItems,\n onOpenChange: handleOpenChange,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onNavigation_unstable: handleNavigation,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [openItems],\n );\n\n const items = React.useCallback(\n () => VisibleFlatTreeItemGenerator(openItems, flatTreeItems),\n [openItems, flatTreeItems],\n );\n\n return React.useMemo(\n () => ({ navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items }),\n [navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items],\n );\n}\n"],"names":["useEventCallback","useMergedRefs","React","createFlatTreeItems","VisibleFlatTreeItemGenerator","treeDataTypes","useFlatTreeNavigation","useControllableOpenItems","dataTreeItemValueAttrName","useFlatTree_unstable","flatTreeItemProps","options","flatTreeItems","useMemo","openItems","setOpenItems","navigate","navigationRef","treeRef","useRef","handleOpenChange","event","data","onOpenChange","isDefaultPrevented","preventDefault","handleNavigation","onNavigation_unstable","getNextNavigableItem","visibleItems","item","get","value","type","TypeAhead","ArrowLeft","parentValue","ArrowRight","index","End","length","Home","ArrowDown","ArrowUp","getElementFromItem","useCallback","current","querySelector","ref","getTreeProps","items"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["useFlatTree.ts"],"sourcesContent":["import { useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport { createFlatTreeItems } from '../utils/createFlatTreeItems';\nimport { treeDataTypes } from '../utils/tokens';\nimport { useFlatTreeNavigation } from './useFlatTreeNavigation';\nimport { createNextOpenItems, useControllableOpenItems } from './useControllableOpenItems';\nimport type {\n TreeCheckedChangeData,\n TreeCheckedChangeEvent,\n TreeNavigationData_unstable,\n TreeNavigationEvent_unstable,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeProps,\n} from '../Tree';\nimport type { TreeItemProps, TreeItemValue } from '../TreeItem';\nimport { dataTreeItemValueAttrName } from '../utils/getTreeItemValueFromElement';\nimport { ImmutableSet } from '../utils/ImmutableSet';\nimport { createNextFlatCheckedItems, useFlatControllableCheckedItems } from './useFlatControllableCheckedItems';\n\nexport type FlatTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> &\n Partial<Pick<TreeItemProps, 'itemType'>> & {\n value: TreeItemValue;\n parentValue?: TreeItemValue;\n };\n\n/**\n * The item that is returned by `useFlatTree`, it represents a wrapper around the properties provided to\n * `useFlatTree` but with extra information that might be useful on flat tree scenarios\n */\nexport type FlatTreeItem<Props extends FlatTreeItemProps = FlatTreeItemProps> = {\n index: number;\n level: number;\n childrenValues: TreeItemValue[];\n value: TreeItemValue;\n parentValue: TreeItemValue | undefined;\n getTreeItemProps(): Required<Pick<Props, 'value' | 'aria-setsize' | 'aria-level' | 'aria-posinset' | 'itemType'>> &\n Omit<Props, 'parentId'>;\n};\n\nexport type FlatTreeProps = Required<\n Pick<TreeProps, 'openItems' | 'onOpenChange' | 'onNavigation_unstable' | 'checkedItems' | 'onCheckedChange'>\n> & {\n ref: React.Ref<HTMLDivElement>;\n openItems: ImmutableSet<TreeItemValue>;\n};\n\n/**\n * FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n *\n * On simple scenarios it is advised to simply use a nested structure instead.\n */\nexport type FlatTree<Props extends FlatTreeItemProps = FlatTreeItemProps> = {\n /**\n * returns the properties required for the Tree component to work properly.\n * That includes:\n * `openItems`, `onOpenChange`, `onNavigation_unstable` and `ref`\n */\n getTreeProps(): FlatTreeProps;\n /**\n * internal method used to react to an `onNavigation` event.\n * This method ensures proper navigation on keyboard and mouse interaction.\n * In case of virtualization it might be required to cancel default provided `onNavigation`\n * event and then call this method manually.\n *\n * @example\n * ```ts\n * // react-window\n * const handleNavigation = (event, data) => {\n * event.preventDefault();\n * const nextItem = tree.getNextNavigableItem(data);\n * // scroll to item using virtualization scroll mechanism\n * if (nextItem && tree.getElementFromItem(nextItem)) {\n * listRef.current.scrollToItem(nextItem.index);\n * }\n * // wait for scrolling to happen and then invoke navigate method\n * requestAnimationFrame(() => {\n * tree.navigate(data);\n * });\n * };\n *```\n */\n navigate(data: TreeNavigationData_unstable): void;\n /**\n * returns next item to be focused on a navigation.\n * This method is provided to decouple the element that needs to be focused from\n * the action of focusing it itself.\n *\n * On the case of TypeAhead navigation this method returns the current item.\n */\n getNextNavigableItem(\n visibleItems: FlatTreeItem<Props>[],\n data: TreeNavigationData_unstable,\n ): FlatTreeItem<Props> | undefined;\n /**\n * similar to getElementById but for FlatTreeItems\n */\n getElementFromItem(item: FlatTreeItem<Props>): HTMLElement | null;\n /**\n * an iterable containing all visually available flat tree items\n */\n items(): IterableIterator<FlatTreeItem<Props>>;\n};\n\nexport type FlatTreeOptions = Pick<\n TreeProps,\n | 'openItems'\n | 'defaultOpenItems'\n | 'onOpenChange'\n | 'onNavigation_unstable'\n | 'selectionMode'\n | 'checkedItems'\n | 'defaultCheckedItems'\n | 'onCheckedChange'\n>;\n\n/**\n * this hook provides FlatTree API to manage all required mechanisms to convert a list of items into renderable TreeItems\n * in multiple scenarios including virtualization.\n *\n * !!A flat tree is an unofficial spec for tree!!\n *\n * It should be used on cases where more complex interactions with a Tree is required.\n * On simple scenarios it is advised to simply use a nested structure instead.\n *\n * @param flatTreeItemProps - a list of tree items\n * @param options - in case control over the internal openItems is required\n */\nexport function useFlatTree_unstable<Props extends FlatTreeItemProps = FlatTreeItemProps>(\n flatTreeItemProps: Props[],\n options: FlatTreeOptions = {},\n): FlatTree<Props> {\n const flatTreeItems = React.useMemo(() => createFlatTreeItems(flatTreeItemProps), [flatTreeItemProps]);\n const [openItems, setOpenItems] = useControllableOpenItems(options);\n const [checkedItems, setCheckedItems] = useFlatControllableCheckedItems(options);\n const [navigate, navigationRef] = useFlatTreeNavigation(flatTreeItems);\n const treeRef = React.useRef<HTMLDivElement>(null);\n const handleOpenChange = useEventCallback((event: TreeOpenChangeEvent, data: TreeOpenChangeData) => {\n options.onOpenChange?.(event, data);\n if (!event.isDefaultPrevented()) {\n setOpenItems(createNextOpenItems(data, openItems));\n }\n event.preventDefault();\n });\n\n const handleCheckedChange = useEventCallback((event: TreeCheckedChangeEvent, data: TreeCheckedChangeData) => {\n options.onCheckedChange?.(event, data);\n setCheckedItems(createNextFlatCheckedItems(data, checkedItems, flatTreeItems));\n });\n\n const handleNavigation = useEventCallback(\n (event: TreeNavigationEvent_unstable, data: TreeNavigationData_unstable) => {\n options.onNavigation_unstable?.(event, data);\n if (!event.isDefaultPrevented()) {\n navigate(data);\n }\n event.preventDefault();\n },\n );\n\n const getNextNavigableItem = useEventCallback(\n (visibleItems: FlatTreeItem<Props>[], data: TreeNavigationData_unstable) => {\n const item = flatTreeItems.get(data.value);\n if (item) {\n switch (data.type) {\n case treeDataTypes.TypeAhead:\n return item;\n case treeDataTypes.ArrowLeft:\n return flatTreeItems.get(item.parentValue!);\n case treeDataTypes.ArrowRight:\n return visibleItems[item.index + 1];\n case treeDataTypes.End:\n return visibleItems[visibleItems.length - 1];\n case treeDataTypes.Home:\n return visibleItems[0];\n case treeDataTypes.ArrowDown:\n return visibleItems[item.index + 1];\n case treeDataTypes.ArrowUp:\n return visibleItems[item.index - 1];\n }\n }\n },\n );\n\n const getElementFromItem = React.useCallback((item: FlatTreeItem<Props>) => {\n return treeRef.current?.querySelector(`[${dataTreeItemValueAttrName}=\"${item.value}\"]`) as HTMLElement | null;\n }, []);\n\n const ref = useMergedRefs(treeRef, navigationRef as React.Ref<HTMLDivElement>);\n\n const getTreeProps = React.useCallback(\n () => ({\n ref,\n openItems,\n selectionMode: options.selectionMode,\n checkedItems,\n onOpenChange: handleOpenChange,\n onCheckedChange: handleCheckedChange,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n onNavigation_unstable: handleNavigation,\n }),\n // eslint-disable-next-line react-hooks/exhaustive-deps\n [openItems, checkedItems],\n );\n\n const items = React.useCallback(() => flatTreeItems.visibleItems(openItems), [openItems, flatTreeItems]);\n\n return React.useMemo(\n () => ({ navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items }),\n [navigate, getTreeProps, getNextNavigableItem, getElementFromItem, items],\n );\n}\n"],"names":["useEventCallback","useMergedRefs","React","createFlatTreeItems","treeDataTypes","useFlatTreeNavigation","createNextOpenItems","useControllableOpenItems","dataTreeItemValueAttrName","createNextFlatCheckedItems","useFlatControllableCheckedItems","useFlatTree_unstable","flatTreeItemProps","options","flatTreeItems","useMemo","openItems","setOpenItems","checkedItems","setCheckedItems","navigate","navigationRef","treeRef","useRef","handleOpenChange","event","data","onOpenChange","isDefaultPrevented","preventDefault","handleCheckedChange","onCheckedChange","handleNavigation","onNavigation_unstable","getNextNavigableItem","visibleItems","item","get","value","type","TypeAhead","ArrowLeft","parentValue","ArrowRight","index","End","length","Home","ArrowDown","ArrowUp","getElementFromItem","useCallback","current","querySelector","ref","getTreeProps","selectionMode","items"],"mappings":"AAAA,SAASA,gBAAgB,EAAEC,aAAa,QAAQ,4BAA4B;AAC5E,YAAYC,WAAW,QAAQ;AAC/B,SAASC,mBAAmB,QAAQ,+BAA+B;AACnE,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,qBAAqB,QAAQ,0BAA0B;AAChE,SAASC,mBAAmB,EAAEC,wBAAwB,QAAQ,6BAA6B;AAW3F,SAASC,yBAAyB,QAAQ,uCAAuC;AAEjF,SAASC,0BAA0B,EAAEC,+BAA+B,QAAQ,oCAAoC;AAuGhH;;;;;;;;;;;CAWC,GACD,OAAO,SAASC,qBACdC,iBAA0B,EAC1BC,UAA2B,CAAC,CAAC,EACZ;IACjB,MAAMC,gBAAgBZ,MAAMa,OAAO,CAAC,IAAMZ,oBAAoBS,oBAAoB;QAACA;KAAkB;IACrG,MAAM,CAACI,WAAWC,aAAa,GAAGV,yBAAyBM;IAC3D,MAAM,CAACK,cAAcC,gBAAgB,GAAGT,gCAAgCG;IACxE,MAAM,CAACO,UAAUC,cAAc,GAAGhB,sBAAsBS;IACxD,MAAMQ,UAAUpB,MAAMqB,MAAM,CAAiB,IAAI;IACjD,MAAMC,mBAAmBxB,iBAAiB,CAACyB,OAA4BC,OAA6B;YAClGb;QAAAA,CAAAA,wBAAAA,QAAQc,YAAY,cAApBd,mCAAAA,KAAAA,IAAAA,sBAAAA,KAAAA,SAAuBY,OAAOC;QAC9B,IAAI,CAACD,MAAMG,kBAAkB,IAAI;YAC/BX,aAAaX,oBAAoBoB,MAAMV;QACzC,CAAC;QACDS,MAAMI,cAAc;IACtB;IAEA,MAAMC,sBAAsB9B,iBAAiB,CAACyB,OAA+BC,OAAgC;YAC3Gb;QAAAA,CAAAA,2BAAAA,QAAQkB,eAAe,cAAvBlB,sCAAAA,KAAAA,IAAAA,yBAAAA,KAAAA,SAA0BY,OAAOC;QACjCP,gBAAgBV,2BAA2BiB,MAAMR,cAAcJ;IACjE;IAEA,MAAMkB,mBAAmBhC,iBACvB,CAACyB,OAAqCC,OAAsC;YAC1Eb;QAAAA,CAAAA,iCAAAA,QAAQoB,qBAAqB,cAA7BpB,4CAAAA,KAAAA,IAAAA,+BAAAA,KAAAA,SAAgCY,OAAOC;QACvC,IAAI,CAACD,MAAMG,kBAAkB,IAAI;YAC/BR,SAASM;QACX,CAAC;QACDD,MAAMI,cAAc;IACtB;IAGF,MAAMK,uBAAuBlC,iBAC3B,CAACmC,cAAqCT,OAAsC;QAC1E,MAAMU,OAAOtB,cAAcuB,GAAG,CAACX,KAAKY,KAAK;QACzC,IAAIF,MAAM;YACR,OAAQV,KAAKa,IAAI;gBACf,KAAKnC,cAAcoC,SAAS;oBAC1B,OAAOJ;gBACT,KAAKhC,cAAcqC,SAAS;oBAC1B,OAAO3B,cAAcuB,GAAG,CAACD,KAAKM,WAAW;gBAC3C,KAAKtC,cAAcuC,UAAU;oBAC3B,OAAOR,YAAY,CAACC,KAAKQ,KAAK,GAAG,EAAE;gBACrC,KAAKxC,cAAcyC,GAAG;oBACpB,OAAOV,YAAY,CAACA,aAAaW,MAAM,GAAG,EAAE;gBAC9C,KAAK1C,cAAc2C,IAAI;oBACrB,OAAOZ,YAAY,CAAC,EAAE;gBACxB,KAAK/B,cAAc4C,SAAS;oBAC1B,OAAOb,YAAY,CAACC,KAAKQ,KAAK,GAAG,EAAE;gBACrC,KAAKxC,cAAc6C,OAAO;oBACxB,OAAOd,YAAY,CAACC,KAAKQ,KAAK,GAAG,EAAE;YACvC;QACF,CAAC;IACH;IAGF,MAAMM,qBAAqBhD,MAAMiD,WAAW,CAAC,CAACf,OAA8B;YACnEd;QAAP,OAAOA,CAAAA,mBAAAA,QAAQ8B,OAAO,cAAf9B,8BAAAA,KAAAA,IAAAA,iBAAiB+B,cAAc,CAAC,CAAC,EAAE7C,0BAA0B,EAAE,EAAE4B,KAAKE,KAAK,CAAC,EAAE,CAAC;IACxF,GAAG,EAAE;IAEL,MAAMgB,MAAMrD,cAAcqB,SAASD;IAEnC,MAAMkC,eAAerD,MAAMiD,WAAW,CACpC,IAAO,CAAA;YACLG;YACAtC;YACAwC,eAAe3C,QAAQ2C,aAAa;YACpCtC;YACAS,cAAcH;YACdO,iBAAiBD;YACjB,gEAAgE;YAChEG,uBAAuBD;QACzB,CAAA,GACA,uDAAuD;IACvD;QAAChB;QAAWE;KAAa;IAG3B,MAAMuC,QAAQvD,MAAMiD,WAAW,CAAC,IAAMrC,cAAcqB,YAAY,CAACnB,YAAY;QAACA;QAAWF;KAAc;IAEvG,OAAOZ,MAAMa,OAAO,CAClB,IAAO,CAAA;YAAEK;YAAUmC;YAAcrB;YAAsBgB;YAAoBO;QAAM,CAAA,GACjF;QAACrC;QAAUmC;QAAcrB;QAAsBgB;QAAoBO;KAAM;AAE7E,CAAC"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { useControllableState } from '@fluentui/react-utilities';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { ImmutableMap } from '../utils/ImmutableMap';
|
|
4
|
+
function initializeMap(iterable) {
|
|
5
|
+
const map = new Map();
|
|
6
|
+
if (iterable === undefined) {
|
|
7
|
+
return ImmutableMap.empty;
|
|
8
|
+
}
|
|
9
|
+
for (const item of iterable){
|
|
10
|
+
if (Array.isArray(item)) {
|
|
11
|
+
map.set(item[0], item[1]);
|
|
12
|
+
} else {
|
|
13
|
+
map.set(item, true);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
return ImmutableMap.dangerouslyCreate_unstable(map);
|
|
17
|
+
}
|
|
18
|
+
export function useNestedControllableCheckedItems(props) {
|
|
19
|
+
return useControllableState({
|
|
20
|
+
initialState: ImmutableMap.empty,
|
|
21
|
+
state: React.useMemo(()=>props.checkedItems && initializeMap(props.checkedItems), [
|
|
22
|
+
props.checkedItems
|
|
23
|
+
]),
|
|
24
|
+
defaultState: ()=>initializeMap(props.defaultCheckedItems)
|
|
25
|
+
});
|
|
26
|
+
} // export function useCheckedItemsState(props: Pick<TreeProps, 'checkedItems' | 'defaultCheckedItems' | 'selectionMode'>) {
|
|
27
|
+
// const [walkerRef, rootRef] = useHTMLElementWalkerRef(treeItemFilter);
|
|
28
|
+
// const selections = React.useMemo(() => initializeSelection(props.checkedItems ?? []), [props.checkedItems]);
|
|
29
|
+
// const defaultSelections = React.useMemo(
|
|
30
|
+
// () => initializeSelection(props.defaultCheckedItems ?? []),
|
|
31
|
+
// [props.defaultCheckedItems],
|
|
32
|
+
// );
|
|
33
|
+
// const [checkedSelection, checkedSelectionManager] = useSelection<TreeItemValue>({
|
|
34
|
+
// selectionMode: props.selectionMode ?? 'single',
|
|
35
|
+
// selectedItems: selections.checkedSelection,
|
|
36
|
+
// defaultSelectedItems: defaultSelections.checkedSelection,
|
|
37
|
+
// });
|
|
38
|
+
// const [mixedSelection, setMixedSelection] = useControllableState({
|
|
39
|
+
// initialState: ImmutableSet.empty,
|
|
40
|
+
// defaultState: React.useMemo(
|
|
41
|
+
// () => ImmutableSet.create(defaultSelections.mixedSelection),
|
|
42
|
+
// [defaultSelections.mixedSelection],
|
|
43
|
+
// ),
|
|
44
|
+
// state: React.useMemo(() => ImmutableSet.create(selections.mixedSelection), [selections.mixedSelection]),
|
|
45
|
+
// });
|
|
46
|
+
// const updateCheckedItems = useEventCallback((data: TreeCheckedChangeData) => {
|
|
47
|
+
// if (props.selectionMode === 'single') {
|
|
48
|
+
// checkedSelectionManager.selectItem(data.value);
|
|
49
|
+
// return;
|
|
50
|
+
// }
|
|
51
|
+
// if (walkerRef.current === null) {
|
|
52
|
+
// return;
|
|
53
|
+
// }
|
|
54
|
+
// const nextSelectedState = !checkedSelectionManager.isSelected(data.value);
|
|
55
|
+
// let treeItemValues = getAllSubTreeItemValues(data).add(data.value);
|
|
56
|
+
// let mixedValues: ImmutableSet<TreeItemValue> = ImmutableSet.empty;
|
|
57
|
+
// walkerRef.current.currentElement = data.event.currentTarget;
|
|
58
|
+
// while (walkerRef.current.parentElement() !== null) {
|
|
59
|
+
// const descendants = Array.from(
|
|
60
|
+
// walkerRef.current.currentElement.querySelectorAll<HTMLElement>('[role="treeitem"]'),
|
|
61
|
+
// ).filter(item => item.getAttribute(dataTreeItemValueAttrName) !== data.value);
|
|
62
|
+
// const isAllSiblingsEqualSelectionState = descendants.every(item => {
|
|
63
|
+
// return (
|
|
64
|
+
// (item.getAttribute('aria-selected') === 'true') === nextSelectedState ||
|
|
65
|
+
// treeItemValues.has(item.getAttribute(dataTreeItemValueAttrName) as TreeItemValue)
|
|
66
|
+
// );
|
|
67
|
+
// });
|
|
68
|
+
// if (isAllSiblingsEqualSelectionState) {
|
|
69
|
+
// treeItemValues = treeItemValues.add(
|
|
70
|
+
// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,
|
|
71
|
+
// );
|
|
72
|
+
// mixedValues = mixedValues.delete(
|
|
73
|
+
// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,
|
|
74
|
+
// );
|
|
75
|
+
// } else {
|
|
76
|
+
// treeItemValues = treeItemValues
|
|
77
|
+
// .delete(walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue)
|
|
78
|
+
// .add(data.value);
|
|
79
|
+
// mixedValues = mixedValues.add(
|
|
80
|
+
// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,
|
|
81
|
+
// );
|
|
82
|
+
// }
|
|
83
|
+
// }
|
|
84
|
+
// unstable_batchedUpdates(() => {
|
|
85
|
+
// nextSelectedState
|
|
86
|
+
// ? checkedSelectionManager.selectItems(treeItemValues)
|
|
87
|
+
// : checkedSelectionManager.deselectItems(treeItemValues);
|
|
88
|
+
// let nextMixedSelection = ImmutableSet.create(mixedSelection);
|
|
89
|
+
// for (const value of mixedValues) {
|
|
90
|
+
// nextMixedSelection = nextMixedSelection.add(value);
|
|
91
|
+
// }
|
|
92
|
+
// for (const value of treeItemValues) {
|
|
93
|
+
// nextMixedSelection = nextMixedSelection.delete(value);
|
|
94
|
+
// }
|
|
95
|
+
// setMixedSelection(nextMixedSelection);
|
|
96
|
+
// });
|
|
97
|
+
// });
|
|
98
|
+
// return [checkedSelection, mixedSelection, updateCheckedItems, rootRef] as const;
|
|
99
|
+
// }
|
|
100
|
+
// function getAllSubTreeItemValues(data: TreeCheckedChangeData) {
|
|
101
|
+
// const subTreeItems = Array.from(data.event.currentTarget.querySelectorAll('[role="treeitem"]'));
|
|
102
|
+
// const values = new Set<TreeItemValue>();
|
|
103
|
+
// for (const item of subTreeItems) {
|
|
104
|
+
// values.add(item.getAttribute(dataTreeItemValueAttrName) as TreeItemValue);
|
|
105
|
+
// }
|
|
106
|
+
// return ImmutableSet.dangerouslyCreate(values);
|
|
107
|
+
// }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["useNestedControllableCheckedItems.ts"],"sourcesContent":["import { useControllableState } from '@fluentui/react-utilities';\nimport * as React from 'react';\nimport type { TreeProps } from '../Tree';\nimport { TreeItemValue } from '../TreeItem';\nimport { ImmutableMap } from '../utils/ImmutableMap';\n\nfunction initializeMap(iterable?: Iterable<TreeItemValue | [TreeItemValue, 'mixed' | boolean]>) {\n const map = new Map<TreeItemValue, 'mixed' | boolean>();\n if (iterable === undefined) {\n return ImmutableMap.empty;\n }\n for (const item of iterable) {\n if (Array.isArray(item)) {\n map.set(item[0], item[1]);\n } else {\n map.set(item, true);\n }\n }\n return ImmutableMap.dangerouslyCreate_unstable(map);\n}\n\nexport function useNestedControllableCheckedItems(\n props: Pick<TreeProps, 'checkedItems' | 'defaultCheckedItems' | 'selectionMode'>,\n) {\n return useControllableState({\n initialState: ImmutableMap.empty,\n state: React.useMemo(() => props.checkedItems && initializeMap(props.checkedItems), [props.checkedItems]),\n defaultState: () => initializeMap(props.defaultCheckedItems),\n });\n}\n\n// export function useCheckedItemsState(props: Pick<TreeProps, 'checkedItems' | 'defaultCheckedItems' | 'selectionMode'>) {\n// const [walkerRef, rootRef] = useHTMLElementWalkerRef(treeItemFilter);\n// const selections = React.useMemo(() => initializeSelection(props.checkedItems ?? []), [props.checkedItems]);\n// const defaultSelections = React.useMemo(\n// () => initializeSelection(props.defaultCheckedItems ?? []),\n// [props.defaultCheckedItems],\n// );\n// const [checkedSelection, checkedSelectionManager] = useSelection<TreeItemValue>({\n// selectionMode: props.selectionMode ?? 'single',\n// selectedItems: selections.checkedSelection,\n// defaultSelectedItems: defaultSelections.checkedSelection,\n// });\n// const [mixedSelection, setMixedSelection] = useControllableState({\n// initialState: ImmutableSet.empty,\n// defaultState: React.useMemo(\n// () => ImmutableSet.create(defaultSelections.mixedSelection),\n// [defaultSelections.mixedSelection],\n// ),\n// state: React.useMemo(() => ImmutableSet.create(selections.mixedSelection), [selections.mixedSelection]),\n// });\n\n// const updateCheckedItems = useEventCallback((data: TreeCheckedChangeData) => {\n// if (props.selectionMode === 'single') {\n// checkedSelectionManager.selectItem(data.value);\n// return;\n// }\n// if (walkerRef.current === null) {\n// return;\n// }\n// const nextSelectedState = !checkedSelectionManager.isSelected(data.value);\n\n// let treeItemValues = getAllSubTreeItemValues(data).add(data.value);\n\n// let mixedValues: ImmutableSet<TreeItemValue> = ImmutableSet.empty;\n\n// walkerRef.current.currentElement = data.event.currentTarget;\n// while (walkerRef.current.parentElement() !== null) {\n// const descendants = Array.from(\n// walkerRef.current.currentElement.querySelectorAll<HTMLElement>('[role=\"treeitem\"]'),\n// ).filter(item => item.getAttribute(dataTreeItemValueAttrName) !== data.value);\n// const isAllSiblingsEqualSelectionState = descendants.every(item => {\n// return (\n// (item.getAttribute('aria-selected') === 'true') === nextSelectedState ||\n// treeItemValues.has(item.getAttribute(dataTreeItemValueAttrName) as TreeItemValue)\n// );\n// });\n// if (isAllSiblingsEqualSelectionState) {\n// treeItemValues = treeItemValues.add(\n// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,\n// );\n// mixedValues = mixedValues.delete(\n// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,\n// );\n// } else {\n// treeItemValues = treeItemValues\n// .delete(walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue)\n// .add(data.value);\n// mixedValues = mixedValues.add(\n// walkerRef.current.currentElement.getAttribute(dataTreeItemValueAttrName) as TreeItemValue,\n// );\n// }\n// }\n// unstable_batchedUpdates(() => {\n// nextSelectedState\n// ? checkedSelectionManager.selectItems(treeItemValues)\n// : checkedSelectionManager.deselectItems(treeItemValues);\n// let nextMixedSelection = ImmutableSet.create(mixedSelection);\n// for (const value of mixedValues) {\n// nextMixedSelection = nextMixedSelection.add(value);\n// }\n// for (const value of treeItemValues) {\n// nextMixedSelection = nextMixedSelection.delete(value);\n// }\n// setMixedSelection(nextMixedSelection);\n// });\n// });\n// return [checkedSelection, mixedSelection, updateCheckedItems, rootRef] as const;\n// }\n\n// function getAllSubTreeItemValues(data: TreeCheckedChangeData) {\n// const subTreeItems = Array.from(data.event.currentTarget.querySelectorAll('[role=\"treeitem\"]'));\n// const values = new Set<TreeItemValue>();\n// for (const item of subTreeItems) {\n// values.add(item.getAttribute(dataTreeItemValueAttrName) as TreeItemValue);\n// }\n// return ImmutableSet.dangerouslyCreate(values);\n// }\n"],"names":["useControllableState","React","ImmutableMap","initializeMap","iterable","map","Map","undefined","empty","item","Array","isArray","set","dangerouslyCreate_unstable","useNestedControllableCheckedItems","props","initialState","state","useMemo","checkedItems","defaultState","defaultCheckedItems"],"mappings":"AAAA,SAASA,oBAAoB,QAAQ,4BAA4B;AACjE,YAAYC,WAAW,QAAQ;AAG/B,SAASC,YAAY,QAAQ,wBAAwB;AAErD,SAASC,cAAcC,QAAuE,EAAE;IAC9F,MAAMC,MAAM,IAAIC;IAChB,IAAIF,aAAaG,WAAW;QAC1B,OAAOL,aAAaM,KAAK;IAC3B,CAAC;IACD,KAAK,MAAMC,QAAQL,SAAU;QAC3B,IAAIM,MAAMC,OAAO,CAACF,OAAO;YACvBJ,IAAIO,GAAG,CAACH,IAAI,CAAC,EAAE,EAAEA,IAAI,CAAC,EAAE;QAC1B,OAAO;YACLJ,IAAIO,GAAG,CAACH,MAAM,IAAI;QACpB,CAAC;IACH;IACA,OAAOP,aAAaW,0BAA0B,CAACR;AACjD;AAEA,OAAO,SAASS,kCACdC,KAAgF,EAChF;IACA,OAAOf,qBAAqB;QAC1BgB,cAAcd,aAAaM,KAAK;QAChCS,OAAOhB,MAAMiB,OAAO,CAAC,IAAMH,MAAMI,YAAY,IAAIhB,cAAcY,MAAMI,YAAY,GAAG;YAACJ,MAAMI,YAAY;SAAC;QACxGC,cAAc,IAAMjB,cAAcY,MAAMM,mBAAmB;IAC7D;AACF,CAAC,CAED,2HAA2H;CAC3H,0EAA0E;CAC1E,iHAAiH;CACjH,6CAA6C;CAC7C,kEAAkE;CAClE,mCAAmC;CACnC,OAAO;CACP,sFAAsF;CACtF,sDAAsD;CACtD,kDAAkD;CAClD,gEAAgE;CAChE,QAAQ;CACR,uEAAuE;CACvE,wCAAwC;CACxC,mCAAmC;CACnC,qEAAqE;CACrE,4CAA4C;CAC5C,SAAS;CACT,+GAA+G;CAC/G,QAAQ;CAER,mFAAmF;CACnF,8CAA8C;CAC9C,wDAAwD;CACxD,gBAAgB;CAChB,QAAQ;CACR,wCAAwC;CACxC,gBAAgB;CAChB,QAAQ;CACR,iFAAiF;CAEjF,0EAA0E;CAE1E,yEAAyE;CAEzE,mEAAmE;CACnE,2DAA2D;CAC3D,wCAAwC;CACxC,+FAA+F;CAC/F,uFAAuF;CACvF,6EAA6E;CAC7E,mBAAmB;CACnB,qFAAqF;CACrF,8FAA8F;CAC9F,aAAa;CACb,YAAY;CACZ,gDAAgD;CAChD,+CAA+C;CAC/C,uGAAuG;CACvG,aAAa;CACb,4CAA4C;CAC5C,uGAAuG;CACvG,aAAa;CACb,iBAAiB;CACjB,0CAA0C;CAC1C,+GAA+G;CAC/G,8BAA8B;CAC9B,yCAAyC;CACzC,uGAAuG;CACvG,aAAa;CACb,UAAU;CACV,QAAQ;CACR,sCAAsC;CACtC,0BAA0B;CAC1B,gEAAgE;CAChE,mEAAmE;CACnE,sEAAsE;CACtE,2CAA2C;CAC3C,8DAA8D;CAC9D,UAAU;CACV,8CAA8C;CAC9C,iEAAiE;CACjE,UAAU;CACV,+CAA+C;CAC/C,UAAU;CACV,QAAQ;CACR,qFAAqF;CACrF,IAAI;CAEJ,kEAAkE;CAClE,qGAAqG;CACrG,6CAA6C;CAC7C,uCAAuC;CACvC,iFAAiF;CACjF,MAAM;CACN,mDAAmD;CACnD,IAAI"}
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["index.ts"],"sourcesContent":["export {\n Tree,\n treeClassNames,\n renderTree_unstable,\n useTreeStyles_unstable,\n useTree_unstable,\n useTreeContextValues_unstable,\n} from './Tree';\nexport type {\n TreeProps,\n TreeState,\n TreeSlots,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeNavigationEvent_unstable,\n TreeNavigationData_unstable,\n} from './Tree';\n\nexport { TreeProvider, useTreeContext_unstable, useTreeItemContext_unstable, TreeItemProvider } from './contexts';\nexport type { TreeContextValue } from './contexts';\n\nexport { treeItemLevelToken } from './utils/tokens';\n\nexport {\n TreeItem,\n treeItemClassNames,\n renderTreeItem_unstable,\n useTreeItemStyles_unstable,\n useTreeItemContextValues_unstable,\n useTreeItem_unstable,\n} from './TreeItem';\nexport type { TreeItemProps, TreeItemState, TreeItemSlots, TreeItemValue } from './TreeItem';\n\nexport {\n TreeItemLayout,\n treeItemLayoutClassNames,\n renderTreeItemLayout_unstable,\n useTreeItemLayoutStyles_unstable,\n useTreeItemLayout_unstable,\n} from './TreeItemLayout';\nexport type { TreeItemLayoutProps, TreeItemLayoutSlots, TreeItemLayoutState } from './TreeItemLayout';\n\nexport {\n TreeItemPersonaLayout,\n treeItemPersonaLayoutClassNames,\n renderTreeItemPersonaLayout_unstable,\n useTreeItemPersonaLayoutStyles_unstable,\n useTreeItemPersonaLayout_unstable,\n} from './TreeItemPersonaLayout';\nexport type {\n TreeItemPersonaLayoutProps,\n TreeItemPersonaLayoutSlots,\n TreeItemPersonaLayoutState,\n} from './TreeItemPersonaLayout';\n\nexport { useFlatTree_unstable } from './hooks/index';\nexport type { FlatTreeItem, FlatTreeItemProps, FlatTreeProps, FlatTree } from './hooks/index';\n\nexport { flattenTree_unstable } from './utils/flattenTree';\nexport type { NestedTreeItem } from './utils/flattenTree';\n"],"names":["Tree","treeClassNames","renderTree_unstable","useTreeStyles_unstable","useTree_unstable","useTreeContextValues_unstable","TreeProvider","useTreeContext_unstable","useTreeItemContext_unstable","TreeItemProvider","treeItemLevelToken","TreeItem","treeItemClassNames","renderTreeItem_unstable","useTreeItemStyles_unstable","useTreeItemContextValues_unstable","useTreeItem_unstable","TreeItemLayout","treeItemLayoutClassNames","renderTreeItemLayout_unstable","useTreeItemLayoutStyles_unstable","useTreeItemLayout_unstable","TreeItemPersonaLayout","treeItemPersonaLayoutClassNames","renderTreeItemPersonaLayout_unstable","useTreeItemPersonaLayoutStyles_unstable","useTreeItemPersonaLayout_unstable","useFlatTree_unstable","flattenTree_unstable"],"mappings":"AAAA,SACEA,IAAI,EACJC,cAAc,EACdC,mBAAmB,EACnBC,sBAAsB,EACtBC,gBAAgB,EAChBC,6BAA6B,QACxB,SAAS;
|
|
1
|
+
{"version":3,"sources":["index.ts"],"sourcesContent":["export {\n Tree,\n treeClassNames,\n renderTree_unstable,\n useTreeStyles_unstable,\n useTree_unstable,\n useTreeContextValues_unstable,\n} from './Tree';\nexport type {\n TreeProps,\n TreeState,\n TreeSlots,\n TreeSelectionValue,\n TreeOpenChangeData,\n TreeOpenChangeEvent,\n TreeCheckedChangeData,\n TreeCheckedChangeEvent,\n TreeNavigationEvent_unstable,\n TreeNavigationData_unstable,\n} from './Tree';\n\nexport { TreeProvider, useTreeContext_unstable, useTreeItemContext_unstable, TreeItemProvider } from './contexts';\nexport type { TreeContextValue } from './contexts';\n\nexport { treeItemLevelToken } from './utils/tokens';\n\nexport {\n TreeItem,\n treeItemClassNames,\n renderTreeItem_unstable,\n useTreeItemStyles_unstable,\n useTreeItemContextValues_unstable,\n useTreeItem_unstable,\n} from './TreeItem';\nexport type { TreeItemProps, TreeItemState, TreeItemSlots, TreeItemValue } from './TreeItem';\n\nexport {\n TreeItemLayout,\n treeItemLayoutClassNames,\n renderTreeItemLayout_unstable,\n useTreeItemLayoutStyles_unstable,\n useTreeItemLayout_unstable,\n} from './TreeItemLayout';\nexport type { TreeItemLayoutProps, TreeItemLayoutSlots, TreeItemLayoutState } from './TreeItemLayout';\n\nexport {\n TreeItemPersonaLayout,\n treeItemPersonaLayoutClassNames,\n renderTreeItemPersonaLayout_unstable,\n useTreeItemPersonaLayoutStyles_unstable,\n useTreeItemPersonaLayout_unstable,\n} from './TreeItemPersonaLayout';\nexport type {\n TreeItemPersonaLayoutProps,\n TreeItemPersonaLayoutSlots,\n TreeItemPersonaLayoutState,\n} from './TreeItemPersonaLayout';\n\nexport { useFlatTree_unstable } from './hooks/index';\nexport type { FlatTreeItem, FlatTreeItemProps, FlatTreeProps, FlatTree } from './hooks/index';\n\nexport { flattenTree_unstable } from './utils/flattenTree';\nexport type { NestedTreeItem } from './utils/flattenTree';\n"],"names":["Tree","treeClassNames","renderTree_unstable","useTreeStyles_unstable","useTree_unstable","useTreeContextValues_unstable","TreeProvider","useTreeContext_unstable","useTreeItemContext_unstable","TreeItemProvider","treeItemLevelToken","TreeItem","treeItemClassNames","renderTreeItem_unstable","useTreeItemStyles_unstable","useTreeItemContextValues_unstable","useTreeItem_unstable","TreeItemLayout","treeItemLayoutClassNames","renderTreeItemLayout_unstable","useTreeItemLayoutStyles_unstable","useTreeItemLayout_unstable","TreeItemPersonaLayout","treeItemPersonaLayoutClassNames","renderTreeItemPersonaLayout_unstable","useTreeItemPersonaLayoutStyles_unstable","useTreeItemPersonaLayout_unstable","useFlatTree_unstable","flattenTree_unstable"],"mappings":"AAAA,SACEA,IAAI,EACJC,cAAc,EACdC,mBAAmB,EACnBC,sBAAsB,EACtBC,gBAAgB,EAChBC,6BAA6B,QACxB,SAAS;AAchB,SAASC,YAAY,EAAEC,uBAAuB,EAAEC,2BAA2B,EAAEC,gBAAgB,QAAQ,aAAa;AAGlH,SAASC,kBAAkB,QAAQ,iBAAiB;AAEpD,SACEC,QAAQ,EACRC,kBAAkB,EAClBC,uBAAuB,EACvBC,0BAA0B,EAC1BC,iCAAiC,EACjCC,oBAAoB,QACf,aAAa;AAGpB,SACEC,cAAc,EACdC,wBAAwB,EACxBC,6BAA6B,EAC7BC,gCAAgC,EAChCC,0BAA0B,QACrB,mBAAmB;AAG1B,SACEC,qBAAqB,EACrBC,+BAA+B,EAC/BC,oCAAoC,EACpCC,uCAAuC,EACvCC,iCAAiC,QAC5B,0BAA0B;AAOjC,SAASC,oBAAoB,QAAQ,gBAAgB;AAGrD,SAASC,oBAAoB,QAAQ,sBAAsB"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const emptyImmutableMap = createImmutableMap();
|
|
2
|
+
/**
|
|
3
|
+
* properly creates an ImmutableMap instance from an iterable
|
|
4
|
+
*/ function createImmutableMap(iterable) {
|
|
5
|
+
const internalMap = new Map(iterable);
|
|
6
|
+
return dangerouslyCreateImmutableMap(internalMap);
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Avoid using *dangerouslyCreateImmutableMap*, since this method will expose internally used set, use createImmutableMap instead,
|
|
10
|
+
* @param internalMap - a set that is used internally to store values.
|
|
11
|
+
*/ function dangerouslyCreateImmutableMap(internalMap) {
|
|
12
|
+
return {
|
|
13
|
+
size: internalMap.size,
|
|
14
|
+
set: (key, value)=>{
|
|
15
|
+
const nextSet = new Map(internalMap);
|
|
16
|
+
nextSet.set(key, value);
|
|
17
|
+
return dangerouslyCreateImmutableMap(nextSet);
|
|
18
|
+
},
|
|
19
|
+
get: (key)=>internalMap.get(key),
|
|
20
|
+
clear: ()=>emptyImmutableMap,
|
|
21
|
+
delete (value) {
|
|
22
|
+
const nextSet = new Map(internalMap);
|
|
23
|
+
nextSet.delete(value);
|
|
24
|
+
return dangerouslyCreateImmutableMap(nextSet);
|
|
25
|
+
},
|
|
26
|
+
has: (value)=>internalMap.has(value),
|
|
27
|
+
[Symbol.iterator]: ()=>internalMap[Symbol.iterator](),
|
|
28
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
29
|
+
dangerouslyGetInternalMap_unstable: ()=>internalMap
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export const ImmutableMap = {
|
|
33
|
+
empty: emptyImmutableMap,
|
|
34
|
+
create: createImmutableMap,
|
|
35
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
36
|
+
dangerouslyCreate_unstable: dangerouslyCreateImmutableMap
|
|
37
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["ImmutableMap.ts"],"sourcesContent":["export interface ImmutableMap<Key, Value> {\n clear(): ImmutableMap<Key, Value>;\n delete(key: Key): ImmutableMap<Key, Value>;\n /**\n * Returns a specified element from the Map object. If the value that is associated to the provided key is an object, then you will get a reference to that object and any change made to that object will effectively modify it inside the Map.\n * @returns Returns the element associated with the specified key. If no element is associated with the specified key, undefined is returned.\n */\n get(key: Key): Value | undefined;\n /**\n * @returns boolean indicating whether an element with the specified key exists or not.\n */\n has(key: Key): boolean;\n /**\n * Adds a new element with a specified key and value to the Map. If an element with the same key already exists, the element will be updated.\n */\n set(key: Key, value: Value): ImmutableMap<Key, Value>;\n /**\n * @returns the number of elements in the Map.\n */\n readonly size: number;\n /** Iterates over entries in the Map. */\n [Symbol.iterator](): IterableIterator<[Key, Value]>;\n /**\n * @internal\n * Exposes the internal map used to store values.\n * This is an internal API and should not be used directly.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyGetInternalMap_unstable(): Map<Key, Value>;\n}\n\nconst emptyImmutableMap = createImmutableMap<never, never>();\n\n/**\n * properly creates an ImmutableMap instance from an iterable\n */\nfunction createImmutableMap<Key, Value>(iterable?: Iterable<[Key, Value]>): ImmutableMap<Key, Value> {\n const internalMap = new Map(iterable);\n return dangerouslyCreateImmutableMap(internalMap);\n}\n/**\n * Avoid using *dangerouslyCreateImmutableMap*, since this method will expose internally used set, use createImmutableMap instead,\n * @param internalMap - a set that is used internally to store values.\n */\nfunction dangerouslyCreateImmutableMap<Key, Value>(internalMap: Map<Key, Value>): ImmutableMap<Key, Value> {\n return {\n size: internalMap.size,\n set: (key, value) => {\n const nextSet = new Map(internalMap);\n nextSet.set(key, value);\n return dangerouslyCreateImmutableMap(nextSet);\n },\n get: key => internalMap.get(key),\n clear: () => emptyImmutableMap,\n delete(value) {\n const nextSet = new Map(internalMap);\n nextSet.delete(value);\n return dangerouslyCreateImmutableMap(nextSet);\n },\n has: value => internalMap.has(value),\n [Symbol.iterator]: () => internalMap[Symbol.iterator](),\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyGetInternalMap_unstable: () => internalMap,\n };\n}\n\nexport const ImmutableMap = {\n empty: emptyImmutableMap,\n create: createImmutableMap,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyCreate_unstable: dangerouslyCreateImmutableMap,\n};\n"],"names":["emptyImmutableMap","createImmutableMap","iterable","internalMap","Map","dangerouslyCreateImmutableMap","size","set","key","value","nextSet","get","clear","delete","has","Symbol","iterator","dangerouslyGetInternalMap_unstable","ImmutableMap","empty","create","dangerouslyCreate_unstable"],"mappings":"AA+BA,MAAMA,oBAAoBC;AAE1B;;CAEC,GACD,SAASA,mBAA+BC,QAAiC,EAA4B;IACnG,MAAMC,cAAc,IAAIC,IAAIF;IAC5B,OAAOG,8BAA8BF;AACvC;AACA;;;CAGC,GACD,SAASE,8BAA0CF,WAA4B,EAA4B;IACzG,OAAO;QACLG,MAAMH,YAAYG,IAAI;QACtBC,KAAK,CAACC,KAAKC,QAAU;YACnB,MAAMC,UAAU,IAAIN,IAAID;YACxBO,QAAQH,GAAG,CAACC,KAAKC;YACjB,OAAOJ,8BAA8BK;QACvC;QACAC,KAAKH,CAAAA,MAAOL,YAAYQ,GAAG,CAACH;QAC5BI,OAAO,IAAMZ;QACba,QAAOJ,KAAK,EAAE;YACZ,MAAMC,UAAU,IAAIN,IAAID;YACxBO,QAAQG,MAAM,CAACJ;YACf,OAAOJ,8BAA8BK;QACvC;QACAI,KAAKL,CAAAA,QAASN,YAAYW,GAAG,CAACL;QAC9B,CAACM,OAAOC,QAAQ,CAAC,EAAE,IAAMb,WAAW,CAACY,OAAOC,QAAQ,CAAC;QACrD,gEAAgE;QAChEC,oCAAoC,IAAMd;IAC5C;AACF;AAEA,OAAO,MAAMe,eAAe;IAC1BC,OAAOnB;IACPoB,QAAQnB;IACR,gEAAgE;IAChEoB,4BAA4BhB;AAC9B,EAAE"}
|
|
@@ -25,7 +25,7 @@ const emptyImmutableSet = createImmutableSet();
|
|
|
25
25
|
return internalSet[Symbol.iterator]();
|
|
26
26
|
},
|
|
27
27
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
28
|
-
|
|
28
|
+
dangerouslyGetInternalSet_unstable: ()=>internalSet
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
@@ -37,5 +37,6 @@ const emptyImmutableSet = createImmutableSet();
|
|
|
37
37
|
export const ImmutableSet = {
|
|
38
38
|
empty: emptyImmutableSet,
|
|
39
39
|
create: createImmutableSet,
|
|
40
|
-
|
|
40
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
41
|
+
dangerouslyCreate_unstable: dangerouslyCreateImmutableSet
|
|
41
42
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["ImmutableSet.ts"],"sourcesContent":["export interface ImmutableSet<Value> {\n /**\n * The number of (unique) elements in a ImmutableSet.\n */\n readonly size: number;\n /**\n * Creates a new ImmutableSet containing all previous element plus the one provided as argument\n * @param value - new value to be included in the new ImmutableSet instance\n */\n add(value: Value): ImmutableSet<Value>;\n /**\n * Returns a reference to ImmutableSet.emptySet\n */\n clear(): ImmutableSet<Value>;\n /**\n * Creates a new ImmutableSet with the original items and removes a specified value from the new ImmutableSet.\n */\n delete(value: Value): ImmutableSet<Value>;\n /**\n * @returns a boolean indicating whether an element with the specified value exists in the ImmutableSet or not.\n */\n has(value: Value): boolean;\n /** Iterates over values in the ImmutableSet. */\n [Symbol.iterator](): IterableIterator<Value>;\n /**\n * @internal\n * Exposes the internal set used to store values.\n * This is an internal API and should not be used directly.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n
|
|
1
|
+
{"version":3,"sources":["ImmutableSet.ts"],"sourcesContent":["export interface ImmutableSet<Value> {\n /**\n * The number of (unique) elements in a ImmutableSet.\n */\n readonly size: number;\n /**\n * Creates a new ImmutableSet containing all previous element plus the one provided as argument\n * @param value - new value to be included in the new ImmutableSet instance\n */\n add(value: Value): ImmutableSet<Value>;\n /**\n * Returns a reference to ImmutableSet.emptySet\n */\n clear(): ImmutableSet<Value>;\n /**\n * Creates a new ImmutableSet with the original items and removes a specified value from the new ImmutableSet.\n */\n delete(value: Value): ImmutableSet<Value>;\n /**\n * @returns a boolean indicating whether an element with the specified value exists in the ImmutableSet or not.\n */\n has(value: Value): boolean;\n /** Iterates over values in the ImmutableSet. */\n [Symbol.iterator](): IterableIterator<Value>;\n /**\n * @internal\n * Exposes the internal set used to store values.\n * This is an internal API and should not be used directly.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyGetInternalSet_unstable(): Set<Value>;\n}\n\nconst emptyImmutableSet = createImmutableSet<never>();\n\n/**\n * Avoid using *dangerouslyCreateImmutableSet*, since this method will expose internally used set, use createImmutableSet instead,\n * @param internalSet - a set that is used internally to store values.\n */\nfunction dangerouslyCreateImmutableSet<Value>(internalSet: Set<Value>): ImmutableSet<Value> {\n return {\n size: internalSet.size,\n add(value) {\n const nextSet = new Set(internalSet);\n nextSet.add(value);\n return dangerouslyCreateImmutableSet(nextSet);\n },\n clear() {\n return emptyImmutableSet;\n },\n delete(value) {\n const nextSet = new Set(internalSet);\n nextSet.delete(value);\n return dangerouslyCreateImmutableSet(nextSet);\n },\n has(value) {\n return internalSet.has(value);\n },\n [Symbol.iterator]() {\n return internalSet[Symbol.iterator]();\n },\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyGetInternalSet_unstable: () => internalSet,\n };\n}\n\n/**\n * properly creates an ImmutableSet instance from an iterable\n */\nfunction createImmutableSet<Value>(iterable?: Iterable<Value>): ImmutableSet<Value> {\n const internalSet = new Set(iterable);\n return dangerouslyCreateImmutableSet(internalSet);\n}\n\nexport const ImmutableSet = {\n empty: emptyImmutableSet,\n create: createImmutableSet,\n // eslint-disable-next-line @typescript-eslint/naming-convention\n dangerouslyCreate_unstable: dangerouslyCreateImmutableSet,\n};\n"],"names":["emptyImmutableSet","createImmutableSet","dangerouslyCreateImmutableSet","internalSet","size","add","value","nextSet","Set","clear","delete","has","Symbol","iterator","dangerouslyGetInternalSet_unstable","iterable","ImmutableSet","empty","create","dangerouslyCreate_unstable"],"mappings":"AAiCA,MAAMA,oBAAoBC;AAE1B;;;CAGC,GACD,SAASC,8BAAqCC,WAAuB,EAAuB;IAC1F,OAAO;QACLC,MAAMD,YAAYC,IAAI;QACtBC,KAAIC,KAAK,EAAE;YACT,MAAMC,UAAU,IAAIC,IAAIL;YACxBI,QAAQF,GAAG,CAACC;YACZ,OAAOJ,8BAA8BK;QACvC;QACAE,SAAQ;YACN,OAAOT;QACT;QACAU,QAAOJ,KAAK,EAAE;YACZ,MAAMC,UAAU,IAAIC,IAAIL;YACxBI,QAAQG,MAAM,CAACJ;YACf,OAAOJ,8BAA8BK;QACvC;QACAI,KAAIL,KAAK,EAAE;YACT,OAAOH,YAAYQ,GAAG,CAACL;QACzB;QACA,CAACM,OAAOC,QAAQ,CAAC,IAAG;YAClB,OAAOV,WAAW,CAACS,OAAOC,QAAQ,CAAC;QACrC;QACA,gEAAgE;QAChEC,oCAAoC,IAAMX;IAC5C;AACF;AAEA;;CAEC,GACD,SAASF,mBAA0Bc,QAA0B,EAAuB;IAClF,MAAMZ,cAAc,IAAIK,IAAIO;IAC5B,OAAOb,8BAA8BC;AACvC;AAEA,OAAO,MAAMa,eAAe;IAC1BC,OAAOjB;IACPkB,QAAQjB;IACR,gEAAgE;IAChEkB,4BAA4BjB;AAC9B,EAAE"}
|
|
@@ -25,30 +25,38 @@
|
|
|
25
25
|
const itemType = (_treeItemProps_itemType = treeItemProps.itemType) !== null && _treeItemProps_itemType !== void 0 ? _treeItemProps_itemType : treeItemProps.value === undefined || (nextItemProps === null || nextItemProps === void 0 ? void 0 : nextItemProps.parentValue) !== treeItemProps.value ? 'leaf' : 'branch';
|
|
26
26
|
var _currentParent_level;
|
|
27
27
|
const currentLevel = ((_currentParent_level = currentParent.level) !== null && _currentParent_level !== void 0 ? _currentParent_level : 0) + 1;
|
|
28
|
-
const currentChildrenSize = ++currentParent.childrenSize;
|
|
29
28
|
const flatTreeItem = {
|
|
30
29
|
value: treeItemProps.value,
|
|
31
30
|
getTreeItemProps: ()=>({
|
|
32
31
|
...treeItemProps,
|
|
33
32
|
'aria-level': currentLevel,
|
|
34
33
|
'aria-posinset': currentChildrenSize,
|
|
35
|
-
'aria-setsize': currentParent.
|
|
34
|
+
'aria-setsize': currentParent.childrenValues.length,
|
|
36
35
|
itemType
|
|
37
36
|
}),
|
|
38
37
|
level: currentLevel,
|
|
39
38
|
parentValue,
|
|
40
|
-
|
|
39
|
+
childrenValues: [],
|
|
41
40
|
index: -1
|
|
42
41
|
};
|
|
42
|
+
const currentChildrenSize = currentParent.childrenValues.push(flatTreeItem.value);
|
|
43
43
|
itemsPerValue.set(flatTreeItem.value, flatTreeItem);
|
|
44
44
|
items.push(flatTreeItem);
|
|
45
45
|
}
|
|
46
|
+
var _itemsPerValue_get_parentValue, _itemsPerValue_get;
|
|
46
47
|
const flatTreeItems = {
|
|
47
48
|
root,
|
|
48
49
|
size: items.length,
|
|
49
50
|
getByIndex: (index)=>items[index],
|
|
51
|
+
getParent: (key)=>{
|
|
52
|
+
var _itemsPerValue_get1;
|
|
53
|
+
return (_itemsPerValue_get = itemsPerValue.get((_itemsPerValue_get_parentValue = (_itemsPerValue_get1 = itemsPerValue.get(key)) === null || _itemsPerValue_get1 === void 0 ? void 0 : _itemsPerValue_get1.parentValue) !== null && _itemsPerValue_get_parentValue !== void 0 ? _itemsPerValue_get_parentValue : root.value)) !== null && _itemsPerValue_get !== void 0 ? _itemsPerValue_get : root;
|
|
54
|
+
},
|
|
50
55
|
get: (key)=>itemsPerValue.get(key),
|
|
51
|
-
|
|
56
|
+
subtree: (key)=>FlatTreeSubtreeGenerator(key, flatTreeItems),
|
|
57
|
+
children: (key)=>FlatTreeChildrenGenerator(key, flatTreeItems),
|
|
58
|
+
ancestors: (key)=>FlatTreeAncestorsGenerator(key, flatTreeItems),
|
|
59
|
+
visibleItems: (openItems)=>VisibleFlatTreeItemGenerator(openItems, flatTreeItems)
|
|
52
60
|
};
|
|
53
61
|
return flatTreeItems;
|
|
54
62
|
}
|
|
@@ -71,7 +79,7 @@ function createFlatTreeRootItem() {
|
|
|
71
79
|
itemType: 'branch'
|
|
72
80
|
};
|
|
73
81
|
},
|
|
74
|
-
|
|
82
|
+
childrenValues: [],
|
|
75
83
|
get index () {
|
|
76
84
|
if (process.env.NODE_ENV !== 'production') {
|
|
77
85
|
// eslint-disable-next-line no-console
|
|
@@ -82,8 +90,52 @@ function createFlatTreeRootItem() {
|
|
|
82
90
|
level: 0
|
|
83
91
|
};
|
|
84
92
|
}
|
|
85
|
-
|
|
86
|
-
|
|
93
|
+
/**
|
|
94
|
+
* Generator that returns all subtree of a given flat tree item
|
|
95
|
+
* @param key the key of the item to get the subtree from
|
|
96
|
+
*/ // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
97
|
+
function* FlatTreeSubtreeGenerator(key, flatTreeItems) {
|
|
98
|
+
const item = flatTreeItems.get(key);
|
|
99
|
+
if (!item || item.childrenValues.length === 0) {
|
|
100
|
+
return [];
|
|
101
|
+
}
|
|
102
|
+
let counter = item.childrenValues.length;
|
|
103
|
+
let index = item.index;
|
|
104
|
+
while(counter > 0){
|
|
105
|
+
const children = flatTreeItems.getByIndex(++index);
|
|
106
|
+
yield children;
|
|
107
|
+
counter += children.childrenValues.length - 1;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Generator that returns all children of a given flat tree item
|
|
112
|
+
* @param key the key of the item to get the children from
|
|
113
|
+
*/ // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
114
|
+
function* FlatTreeChildrenGenerator(key, flatTreeItems) {
|
|
115
|
+
const item = flatTreeItems.get(key);
|
|
116
|
+
if (!item || item.childrenValues.length === 0) {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
for (const childValue of item.childrenValues){
|
|
120
|
+
yield flatTreeItems.get(childValue);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Generator that returns all ancestors of a given flat tree item
|
|
125
|
+
* @param key the key of the item to get the children from
|
|
126
|
+
*/ // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
127
|
+
function* FlatTreeAncestorsGenerator(key, flatTreeItems) {
|
|
128
|
+
let parent = flatTreeItems.getParent(key);
|
|
129
|
+
while(parent !== flatTreeItems.root){
|
|
130
|
+
yield parent;
|
|
131
|
+
parent = flatTreeItems.getParent(parent.value);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Generator that returns all visible items of a given flat tree
|
|
136
|
+
* @param openItems the open items of the tree
|
|
137
|
+
*/ // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
138
|
+
function* VisibleFlatTreeItemGenerator(openItems, flatTreeItems) {
|
|
87
139
|
for(let index = 0, visibleIndex = 0; index < flatTreeItems.size; index++){
|
|
88
140
|
const item = flatTreeItems.getByIndex(index);
|
|
89
141
|
if (isItemVisible(item, openItems, flatTreeItems)) {
|
|
@@ -91,7 +143,7 @@ export function* VisibleFlatTreeItemGenerator(openItems, flatTreeItems) {
|
|
|
91
143
|
yield item;
|
|
92
144
|
} else {
|
|
93
145
|
// Jump the amount of children the current item has, since those items will also be hidden
|
|
94
|
-
index += item.
|
|
146
|
+
index += item.childrenValues.length;
|
|
95
147
|
}
|
|
96
148
|
}
|
|
97
149
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["createFlatTreeItems.ts"],"sourcesContent":["import type { FlatTreeItem, FlatTreeItemProps } from '../hooks/useFlatTree';\nimport { TreeItemValue } from '../TreeItem';\nimport { ImmutableSet } from './ImmutableSet';\n\n/**\n * @internal\n */\nexport type FlatTreeItems<Props extends FlatTreeItemProps> = {\n size: number;\n root: FlatTreeItem;\n get(key: TreeItemValue): FlatTreeItem<Props> | undefined;\n set(key: TreeItemValue, value: FlatTreeItem<Props>): void;\n getByIndex(index: number): FlatTreeItem<Props>;\n};\n\n/**\n * creates a list of flat tree items\n * and provides a map to access each item by id\n */\nexport function createFlatTreeItems<Props extends FlatTreeItemProps>(flatTreeItemProps: Props[]): FlatTreeItems<Props> {\n const root = createFlatTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, FlatTreeItem<FlatTreeItemProps>>([[root.value, root]]);\n const items: FlatTreeItem<FlatTreeItemProps>[] = [];\n\n for (let index = 0; index < flatTreeItemProps.length; index++) {\n const { parentValue = flatTreeRootId, ...treeItemProps } = flatTreeItemProps[index];\n\n const nextItemProps: Props | undefined = flatTreeItemProps[index + 1];\n const currentParent = itemsPerValue.get(parentValue);\n if (!currentParent) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(\n `useFlatTree: item ${flatTreeItemProps[index].value} is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized`,\n );\n }\n break;\n }\n const itemType =\n treeItemProps.itemType ??\n (treeItemProps.value === undefined || nextItemProps?.parentValue !== treeItemProps.value ? 'leaf' : 'branch');\n const currentLevel = (currentParent.level ?? 0) + 1;\n const currentChildrenSize = ++currentParent.childrenSize;\n\n const flatTreeItem: FlatTreeItem<FlatTreeItemProps> = {\n value: treeItemProps.value,\n getTreeItemProps: () => ({\n ...treeItemProps,\n 'aria-level': currentLevel,\n 'aria-posinset': currentChildrenSize,\n 'aria-setsize': currentParent.childrenSize,\n itemType,\n }),\n level: currentLevel,\n parentValue,\n childrenSize: 0,\n index: -1,\n };\n itemsPerValue.set(flatTreeItem.value, flatTreeItem);\n items.push(flatTreeItem);\n }\n\n const flatTreeItems: FlatTreeItems<FlatTreeItemProps> = {\n root,\n size: items.length,\n getByIndex: index => items[index],\n get: key => itemsPerValue.get(key),\n set: (key, value) => itemsPerValue.set(key, value),\n };\n\n return flatTreeItems as FlatTreeItems<Props>;\n}\n\nexport const flatTreeRootId = '__fuiFlatTreeRoot';\n\nfunction createFlatTreeRootItem(): FlatTreeItem {\n return {\n parentValue: undefined,\n value: flatTreeRootId,\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('useFlatTree: internal error, trying to access treeitem props from invalid root element');\n }\n return {\n id: flatTreeRootId,\n value: flatTreeRootId,\n 'aria-setsize': -1,\n 'aria-level': -1,\n 'aria-posinset': -1,\n itemType: 'branch',\n };\n },\n childrenSize: 0,\n get index() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('useFlatTree: internal error, trying to access treeitem props from invalid root element');\n }\n return -1;\n },\n level: 0,\n };\n}\n\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport function* VisibleFlatTreeItemGenerator<Props extends FlatTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n flatTreeItems: FlatTreeItems<Props>,\n) {\n for (let index = 0, visibleIndex = 0; index < flatTreeItems.size; index++) {\n const item = flatTreeItems.getByIndex(index) as FlatTreeItem<Props>;\n if (isItemVisible(item, openItems, flatTreeItems)) {\n item.index = visibleIndex++;\n yield item;\n } else {\n // Jump the amount of children the current item has, since those items will also be hidden\n index += item.childrenSize;\n }\n }\n}\n\nfunction isItemVisible(\n item: FlatTreeItem<FlatTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n flatTreeItems: FlatTreeItems<FlatTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== flatTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = flatTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createFlatTreeItems","flatTreeItemProps","root","createFlatTreeRootItem","itemsPerValue","Map","value","items","index","length","parentValue","flatTreeRootId","treeItemProps","nextItemProps","currentParent","get","process","env","NODE_ENV","console","error","itemType","undefined","currentLevel","level","currentChildrenSize","childrenSize","flatTreeItem","getTreeItemProps","set","push","flatTreeItems","size","getByIndex","key","id","VisibleFlatTreeItemGenerator","openItems","visibleIndex","item","isItemVisible","has","parent"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["createFlatTreeItems.ts"],"sourcesContent":["import type { FlatTreeItem, FlatTreeItemProps } from '../hooks/useFlatTree';\nimport { TreeItemValue } from '../TreeItem';\nimport { ImmutableSet } from './ImmutableSet';\n\n/**\n * @internal\n */\nexport type FlatTreeItems<Props extends FlatTreeItemProps> = {\n size: number;\n root: FlatTreeItem;\n get(key: TreeItemValue): FlatTreeItem<Props> | undefined;\n getParent(key: TreeItemValue): FlatTreeItem<Props>;\n getByIndex(index: number): FlatTreeItem<Props>;\n subtree(key: TreeItemValue): IterableIterator<FlatTreeItem<Props>>;\n children(key: TreeItemValue): IterableIterator<FlatTreeItem<Props>>;\n visibleItems(openItems: ImmutableSet<TreeItemValue>): IterableIterator<FlatTreeItem<Props>>;\n ancestors(key: TreeItemValue): IterableIterator<FlatTreeItem<Props>>;\n};\n\n/**\n * creates a list of flat tree items\n * and provides a map to access each item by id\n */\nexport function createFlatTreeItems<Props extends FlatTreeItemProps>(flatTreeItemProps: Props[]): FlatTreeItems<Props> {\n const root = createFlatTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, FlatTreeItem<FlatTreeItemProps>>([[root.value, root]]);\n const items: FlatTreeItem<FlatTreeItemProps>[] = [];\n\n for (let index = 0; index < flatTreeItemProps.length; index++) {\n const { parentValue = flatTreeRootId, ...treeItemProps } = flatTreeItemProps[index];\n\n const nextItemProps: Props | undefined = flatTreeItemProps[index + 1];\n const currentParent = itemsPerValue.get(parentValue);\n if (!currentParent) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(\n `useFlatTree: item ${flatTreeItemProps[index].value} is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized`,\n );\n }\n break;\n }\n const itemType =\n treeItemProps.itemType ??\n (treeItemProps.value === undefined || nextItemProps?.parentValue !== treeItemProps.value ? 'leaf' : 'branch');\n const currentLevel = (currentParent.level ?? 0) + 1;\n\n const flatTreeItem: FlatTreeItem<FlatTreeItemProps> = {\n value: treeItemProps.value,\n getTreeItemProps: () => ({\n ...treeItemProps,\n 'aria-level': currentLevel,\n 'aria-posinset': currentChildrenSize,\n 'aria-setsize': currentParent.childrenValues.length,\n itemType,\n }),\n level: currentLevel,\n parentValue,\n childrenValues: [],\n index: -1,\n };\n const currentChildrenSize = currentParent.childrenValues.push(flatTreeItem.value);\n itemsPerValue.set(flatTreeItem.value, flatTreeItem);\n items.push(flatTreeItem);\n }\n\n const flatTreeItems: FlatTreeItems<FlatTreeItemProps> = {\n root,\n size: items.length,\n getByIndex: index => items[index],\n getParent: key => itemsPerValue.get(itemsPerValue.get(key)?.parentValue ?? root.value) ?? root,\n get: key => itemsPerValue.get(key),\n subtree: key => FlatTreeSubtreeGenerator(key, flatTreeItems),\n children: key => FlatTreeChildrenGenerator(key, flatTreeItems),\n ancestors: key => FlatTreeAncestorsGenerator(key, flatTreeItems),\n visibleItems: openItems => VisibleFlatTreeItemGenerator(openItems, flatTreeItems),\n };\n\n return flatTreeItems as FlatTreeItems<Props>;\n}\n\nexport const flatTreeRootId = '__fuiFlatTreeRoot';\n\nfunction createFlatTreeRootItem(): FlatTreeItem {\n return {\n parentValue: undefined,\n value: flatTreeRootId,\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('useFlatTree: internal error, trying to access treeitem props from invalid root element');\n }\n return {\n id: flatTreeRootId,\n value: flatTreeRootId,\n 'aria-setsize': -1,\n 'aria-level': -1,\n 'aria-posinset': -1,\n itemType: 'branch',\n };\n },\n childrenValues: [],\n get index() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('useFlatTree: internal error, trying to access treeitem props from invalid root element');\n }\n return -1;\n },\n level: 0,\n };\n}\n\n/**\n * Generator that returns all subtree of a given flat tree item\n * @param key the key of the item to get the subtree from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* FlatTreeSubtreeGenerator<Props extends FlatTreeItemProps>(\n key: TreeItemValue,\n flatTreeItems: FlatTreeItems<Props>,\n) {\n const item = flatTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return [];\n }\n let counter = item.childrenValues.length;\n let index = item.index;\n while (counter > 0) {\n const children = flatTreeItems.getByIndex(++index);\n yield children;\n counter += children.childrenValues.length - 1;\n }\n}\n\n/**\n * Generator that returns all children of a given flat tree item\n * @param key the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* FlatTreeChildrenGenerator<Props extends FlatTreeItemProps>(\n key: TreeItemValue,\n flatTreeItems: FlatTreeItems<Props>,\n) {\n const item = flatTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield flatTreeItems.get(childValue)!;\n }\n}\n\n/**\n * Generator that returns all ancestors of a given flat tree item\n * @param key the key of the item to get the children from\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* FlatTreeAncestorsGenerator<Props extends FlatTreeItemProps>(\n key: TreeItemValue,\n flatTreeItems: FlatTreeItems<Props>,\n) {\n let parent = flatTreeItems.getParent(key);\n while (parent !== flatTreeItems.root) {\n yield parent;\n parent = flatTreeItems.getParent(parent.value);\n }\n}\n\n/**\n * Generator that returns all visible items of a given flat tree\n * @param openItems the open items of the tree\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* VisibleFlatTreeItemGenerator<Props extends FlatTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n flatTreeItems: FlatTreeItems<Props>,\n) {\n for (let index = 0, visibleIndex = 0; index < flatTreeItems.size; index++) {\n const item = flatTreeItems.getByIndex(index) as FlatTreeItem<Props>;\n if (isItemVisible(item, openItems, flatTreeItems)) {\n item.index = visibleIndex++;\n yield item;\n } else {\n // Jump the amount of children the current item has, since those items will also be hidden\n index += item.childrenValues.length;\n }\n }\n}\n\nfunction isItemVisible(\n item: FlatTreeItem<FlatTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n flatTreeItems: FlatTreeItems<FlatTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== flatTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = flatTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createFlatTreeItems","flatTreeItemProps","root","createFlatTreeRootItem","itemsPerValue","Map","value","items","index","length","parentValue","flatTreeRootId","treeItemProps","nextItemProps","currentParent","get","process","env","NODE_ENV","console","error","itemType","undefined","currentLevel","level","flatTreeItem","getTreeItemProps","currentChildrenSize","childrenValues","push","set","flatTreeItems","size","getByIndex","getParent","key","subtree","FlatTreeSubtreeGenerator","children","FlatTreeChildrenGenerator","ancestors","FlatTreeAncestorsGenerator","visibleItems","openItems","VisibleFlatTreeItemGenerator","id","item","counter","childValue","parent","visibleIndex","isItemVisible","has"],"mappings":"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"}
|
package/lib/utils/tokens.js
CHANGED
package/lib/utils/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["tokens.ts"],"sourcesContent":["import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Home, Enter } from '@fluentui/keyboard-keys';\nimport { TreeNavigationData_unstable, TreeOpenChangeData } from '../Tree';\n\nexport const treeItemLevelToken = '--fluent-TreeItem--level' as const;\n\nexport const treeAvatarSize = {\n medium: 32,\n small: 24,\n} as const;\n\nexport const treeDataTypes: {\n readonly [K in TreeOpenChangeData['type'] | TreeNavigationData_unstable['type']]: K;\n} = {\n ArrowLeft,\n ArrowRight,\n Enter,\n Click: 'Click',\n ExpandIconClick: 'ExpandIconClick',\n End,\n Home,\n ArrowUp,\n ArrowDown,\n TypeAhead: 'TypeAhead',\n};\n"],"names":["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","End","Home","Enter","treeItemLevelToken","treeAvatarSize","medium","small","treeDataTypes","Click","ExpandIconClick","TypeAhead"],"mappings":"AAAA,SAASA,SAAS,EAAEC,SAAS,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,EAAEC,KAAK,QAAQ,0BAA0B;AAGtG,OAAO,MAAMC,qBAAqB,2BAAoC;AAEtE,OAAO,MAAMC,iBAAiB;IAC5BC,QAAQ;IACRC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,gBAET;IACFV;IACAC;IACAI;IACAM,OAAO;IACPC,iBAAiB;IACjBT;IACAC;IACAF;IACAH;IACAc,WAAW;
|
|
1
|
+
{"version":3,"sources":["tokens.ts"],"sourcesContent":["import { ArrowDown, ArrowLeft, ArrowRight, ArrowUp, End, Home, Enter } from '@fluentui/keyboard-keys';\nimport { TreeCheckedChangeData, TreeNavigationData_unstable, TreeOpenChangeData } from '../Tree';\n\nexport const treeItemLevelToken = '--fluent-TreeItem--level' as const;\n\nexport const treeAvatarSize = {\n medium: 32,\n small: 24,\n} as const;\n\nexport const treeDataTypes: {\n readonly [K in TreeOpenChangeData['type'] | TreeNavigationData_unstable['type'] | TreeCheckedChangeData['type']]: K;\n} = {\n ArrowLeft,\n ArrowRight,\n Enter,\n Click: 'Click',\n ExpandIconClick: 'ExpandIconClick',\n End,\n Home,\n ArrowUp,\n ArrowDown,\n TypeAhead: 'TypeAhead',\n Change: 'Change',\n};\n"],"names":["ArrowDown","ArrowLeft","ArrowRight","ArrowUp","End","Home","Enter","treeItemLevelToken","treeAvatarSize","medium","small","treeDataTypes","Click","ExpandIconClick","TypeAhead","Change"],"mappings":"AAAA,SAASA,SAAS,EAAEC,SAAS,EAAEC,UAAU,EAAEC,OAAO,EAAEC,GAAG,EAAEC,IAAI,EAAEC,KAAK,QAAQ,0BAA0B;AAGtG,OAAO,MAAMC,qBAAqB,2BAAoC;AAEtE,OAAO,MAAMC,iBAAiB;IAC5BC,QAAQ;IACRC,OAAO;AACT,EAAW;AAEX,OAAO,MAAMC,gBAET;IACFV;IACAC;IACAI;IACAM,OAAO;IACPC,iBAAiB;IACjBT;IACAC;IACAF;IACAH;IACAc,WAAW;IACXC,QAAQ;AACV,EAAE"}
|
|
@@ -14,20 +14,24 @@ const _hooks = require("../../hooks");
|
|
|
14
14
|
const _tokens = require("../../utils/tokens");
|
|
15
15
|
function useRootTree(props, ref) {
|
|
16
16
|
warnIfNoProperPropsRootTree(props);
|
|
17
|
-
const { appearance ='subtle' , size ='medium' } = props;
|
|
17
|
+
const { appearance ='subtle' , size ='medium' , selectionMode ='none' } = props;
|
|
18
18
|
const [openItems, setOpenItems] = (0, _hooks.useControllableOpenItems)(props);
|
|
19
|
+
const [checkedItems] = (0, _hooks.useNestedControllableCheckedItems)(props);
|
|
19
20
|
const [navigate, navigationRef] = (0, _hooks.useNestedTreeNavigation)();
|
|
20
21
|
const requestOpenChange = (data)=>{
|
|
21
22
|
var _props_onOpenChange;
|
|
22
|
-
|
|
23
|
-
(_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, data.event, {
|
|
24
|
-
...data,
|
|
25
|
-
openItems: nextOpenItems
|
|
26
|
-
});
|
|
23
|
+
(_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, data.event, data);
|
|
27
24
|
if (data.event.isDefaultPrevented()) {
|
|
28
25
|
return;
|
|
29
26
|
}
|
|
30
|
-
return setOpenItems(
|
|
27
|
+
return setOpenItems((0, _hooks.createNextOpenItems)(data, openItems));
|
|
28
|
+
};
|
|
29
|
+
const requestCheckedChange = (data)=>{
|
|
30
|
+
var _props_onCheckedChange;
|
|
31
|
+
(_props_onCheckedChange = props.onCheckedChange) === null || _props_onCheckedChange === void 0 ? void 0 : _props_onCheckedChange.call(props, data.event, data);
|
|
32
|
+
// TODO:
|
|
33
|
+
// we should implement the logic for nested tree selection
|
|
34
|
+
// return setCheckedItems(checkedItems);
|
|
31
35
|
};
|
|
32
36
|
const requestNavigation = (data)=>{
|
|
33
37
|
var _props_onNavigation_unstable;
|
|
@@ -102,21 +106,33 @@ function useRootTree(props, ref) {
|
|
|
102
106
|
...request,
|
|
103
107
|
target: request.event.currentTarget
|
|
104
108
|
});
|
|
109
|
+
case _tokens.treeDataTypes.Change:
|
|
110
|
+
{
|
|
111
|
+
const previousCheckedValue = checkedItems.get(request.value);
|
|
112
|
+
return requestCheckedChange({
|
|
113
|
+
...request,
|
|
114
|
+
selectionMode: selectionMode,
|
|
115
|
+
checked: previousCheckedValue === 'mixed' ? true : !previousCheckedValue
|
|
116
|
+
});
|
|
117
|
+
}
|
|
105
118
|
}
|
|
106
119
|
});
|
|
107
120
|
return {
|
|
108
121
|
components: {
|
|
109
122
|
root: 'div'
|
|
110
123
|
},
|
|
124
|
+
selectionMode,
|
|
111
125
|
open: true,
|
|
112
126
|
appearance,
|
|
113
127
|
size,
|
|
114
128
|
level: 1,
|
|
115
129
|
openItems,
|
|
130
|
+
checkedItems,
|
|
116
131
|
requestTreeResponse,
|
|
117
132
|
root: (0, _reactUtilities.getNativeElementProps)('div', {
|
|
118
133
|
ref: (0, _reactUtilities.useMergedRefs)(navigationRef, ref),
|
|
119
134
|
role: 'tree',
|
|
135
|
+
'aria-multiselectable': selectionMode === 'multiselect' ? true : undefined,
|
|
120
136
|
...props
|
|
121
137
|
})
|
|
122
138
|
};
|