@fluentui/react-tree 9.0.0-beta.28 → 9.0.0-beta.29
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 +70 -1
- package/CHANGELOG.md +20 -2
- package/dist/index.d.ts +9 -4
- package/lib/components/FlatTree/useFlatTreeNavigation.js +22 -25
- package/lib/components/FlatTree/useFlatTreeNavigation.js.map +1 -1
- package/lib/components/FlatTree/useFlatTreeStyles.styles.js +3 -13
- package/lib/components/FlatTree/useFlatTreeStyles.styles.js.map +1 -1
- package/lib/components/FlatTree/useHeadlessFlatTree.js +30 -13
- package/lib/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
- package/lib/components/Tree/Tree.types.js.map +1 -1
- package/lib/components/Tree/useTree.js +16 -3
- package/lib/components/Tree/useTree.js.map +1 -1
- package/lib/components/Tree/useTreeNavigation.js +7 -14
- package/lib/components/Tree/useTreeNavigation.js.map +1 -1
- package/lib/components/Tree/useTreeStyles.styles.js +4 -10
- package/lib/components/Tree/useTreeStyles.styles.js.map +1 -1
- package/lib/components/TreeItem/useTreeItem.js +12 -5
- package/lib/components/TreeItem/useTreeItem.js.map +1 -1
- package/lib/components/TreeItem/useTreeItemContextValues.js +2 -1
- package/lib/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib/components/TreeItemLayout/useTreeItemLayout.js +2 -3
- package/lib/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib/contexts/treeContext.js.map +1 -1
- package/lib/contexts/treeItemContext.js +4 -2
- package/lib/contexts/treeItemContext.js.map +1 -1
- package/lib/hooks/useRootTree.js +14 -11
- package/lib/hooks/useRootTree.js.map +1 -1
- package/lib/hooks/useRovingTabIndexes.js +8 -28
- package/lib/hooks/useRovingTabIndexes.js.map +1 -1
- package/lib/hooks/useSubtree.js +3 -3
- package/lib/hooks/useSubtree.js.map +1 -1
- package/lib/{hooks/useHTMLElementWalker.js → utils/createHTMLElementWalker.js} +0 -15
- package/lib/utils/createHTMLElementWalker.js.map +1 -0
- package/lib/utils/createHeadlessTree.js +85 -62
- package/lib/utils/createHeadlessTree.js.map +1 -1
- package/lib/utils/nextTypeAheadElement.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTreeNavigation.js +21 -24
- package/lib-commonjs/components/FlatTree/useFlatTreeNavigation.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTreeStyles.styles.js +2 -19
- package/lib-commonjs/components/FlatTree/useFlatTreeStyles.styles.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js +29 -12
- package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
- package/lib-commonjs/components/Tree/useTree.js +16 -3
- package/lib-commonjs/components/Tree/useTree.js.map +1 -1
- package/lib-commonjs/components/Tree/useTreeNavigation.js +7 -14
- package/lib-commonjs/components/Tree/useTreeNavigation.js.map +1 -1
- package/lib-commonjs/components/Tree/useTreeStyles.styles.js +3 -15
- package/lib-commonjs/components/Tree/useTreeStyles.styles.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItem.js +11 -4
- package/lib-commonjs/components/TreeItem/useTreeItem.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js +2 -1
- package/lib-commonjs/components/TreeItem/useTreeItemContextValues.js.map +1 -1
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayout.js +2 -3
- package/lib-commonjs/components/TreeItemLayout/useTreeItemLayout.js.map +1 -1
- package/lib-commonjs/contexts/treeItemContext.js +4 -2
- package/lib-commonjs/contexts/treeItemContext.js.map +1 -1
- package/lib-commonjs/hooks/useRootTree.js +11 -8
- package/lib-commonjs/hooks/useRootTree.js.map +1 -1
- package/lib-commonjs/hooks/useRovingTabIndexes.js +8 -28
- package/lib-commonjs/hooks/useRovingTabIndexes.js.map +1 -1
- package/lib-commonjs/hooks/useSubtree.js.map +1 -1
- package/lib-commonjs/{hooks/useHTMLElementWalker.js → utils/createHTMLElementWalker.js} +3 -25
- package/lib-commonjs/utils/createHTMLElementWalker.js.map +1 -0
- package/lib-commonjs/utils/createHeadlessTree.js +86 -63
- package/lib-commonjs/utils/createHeadlessTree.js.map +1 -1
- package/package.json +8 -8
- package/lib/hooks/useHTMLElementWalker.js.map +0 -1
- package/lib-commonjs/hooks/useHTMLElementWalker.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useSubtree.ts"],"sourcesContent":["import * as React from 'react';\nimport { TreeProps, TreeState } from '../Tree';\nimport { useTreeContext_unstable, useTreeItemContext_unstable } from '../contexts/index';\nimport { getNativeElementProps, useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render a sub-level
|
|
1
|
+
{"version":3,"sources":["useSubtree.ts"],"sourcesContent":["import * as React from 'react';\nimport { TreeProps, TreeState } from '../Tree';\nimport { useTreeContext_unstable, useTreeItemContext_unstable } from '../contexts/index';\nimport { getNativeElementProps, useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render a sub-level tree.\n *\n * @param props - props from this instance of tree\n * @param ref - reference to root HTMLElement of tree\n */\nexport function useSubtree(props: Pick<TreeProps, 'appearance' | 'size'>, ref: React.Ref<HTMLElement>): TreeState {\n const contextAppearance = useTreeContext_unstable(ctx => ctx.appearance);\n const contextSize = useTreeContext_unstable(ctx => ctx.size);\n const subtreeRef = useTreeItemContext_unstable(ctx => ctx.subtreeRef);\n const value = useTreeItemContext_unstable(ctx => ctx.value);\n\n const { appearance = contextAppearance ?? 'subtle', size = contextSize ?? 'medium' } = props;\n\n const parentLevel = useTreeContext_unstable(ctx => ctx.level);\n const selectionMode = useTreeContext_unstable(ctx => ctx.selectionMode);\n const openItems = useTreeContext_unstable(ctx => ctx.openItems);\n const checkedItems = useTreeContext_unstable(ctx => ctx.checkedItems);\n const requestTreeResponse = useTreeContext_unstable(ctx => ctx.requestTreeResponse);\n\n const open = openItems.has(value);\n\n return {\n open,\n components: {\n root: 'div',\n },\n appearance,\n size,\n selectionMode,\n level: parentLevel + 1,\n root: getNativeElementProps('div', {\n ref: useMergedRefs(ref, subtreeRef),\n role: 'group',\n ...props,\n }),\n openItems,\n checkedItems,\n requestTreeResponse,\n };\n}\n"],"names":["React","useTreeContext_unstable","useTreeItemContext_unstable","getNativeElementProps","useMergedRefs","useSubtree","props","ref","contextAppearance","ctx","appearance","contextSize","size","subtreeRef","value","parentLevel","level","selectionMode","openItems","checkedItems","requestTreeResponse","open","has","components","root","role"],"mappings":"AAAA,YAAYA,WAAW,QAAQ;AAE/B,SAASC,uBAAuB,EAAEC,2BAA2B,QAAQ,oBAAoB;AACzF,SAASC,qBAAqB,EAAEC,aAAa,QAAQ,4BAA4B;AAEjF;;;;;CAKC,GACD,OAAO,SAASC,WAAWC,KAA6C,EAAEC,GAA2B,EAAa;IAChH,MAAMC,oBAAoBP,wBAAwBQ,CAAAA,MAAOA,IAAIC,UAAU;IACvE,MAAMC,cAAcV,wBAAwBQ,CAAAA,MAAOA,IAAIG,IAAI;IAC3D,MAAMC,aAAaX,4BAA4BO,CAAAA,MAAOA,IAAII,UAAU;IACpE,MAAMC,QAAQZ,4BAA4BO,CAAAA,MAAOA,IAAIK,KAAK;IAE1D,MAAM,EAAEJ,YAAaF,8BAAAA,+BAAAA,oBAAqB,QAAQ,CAAA,EAAEI,MAAOD,wBAAAA,yBAAAA,cAAe,QAAQ,CAAA,EAAE,GAAGL;IAEvF,MAAMS,cAAcd,wBAAwBQ,CAAAA,MAAOA,IAAIO,KAAK;IAC5D,MAAMC,gBAAgBhB,wBAAwBQ,CAAAA,MAAOA,IAAIQ,aAAa;IACtE,MAAMC,YAAYjB,wBAAwBQ,CAAAA,MAAOA,IAAIS,SAAS;IAC9D,MAAMC,eAAelB,wBAAwBQ,CAAAA,MAAOA,IAAIU,YAAY;IACpE,MAAMC,sBAAsBnB,wBAAwBQ,CAAAA,MAAOA,IAAIW,mBAAmB;IAElF,MAAMC,OAAOH,UAAUI,GAAG,CAACR;IAE3B,OAAO;QACLO;QACAE,YAAY;YACVC,MAAM;QACR;QACAd;QACAE;QACAK;QACAD,OAAOD,cAAc;QACrBS,MAAMrB,sBAAsB,OAAO;YACjCI,KAAKH,cAAcG,KAAKM;YACxBY,MAAM;YACN,GAAGnB,KAAK;QACV;QACAY;QACAC;QACAC;IACF;AACF,CAAC"}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { isHTMLElement } from '@fluentui/react-utilities';
|
|
2
|
-
import * as React from 'react';
|
|
3
2
|
export function createHTMLElementWalker(root, filter = ()=>NodeFilter.FILTER_ACCEPT) {
|
|
4
3
|
let temporaryFilter;
|
|
5
4
|
const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
|
|
@@ -66,17 +65,3 @@ export function createHTMLElementWalker(root, filter = ()=>NodeFilter.FILTER_ACC
|
|
|
66
65
|
}
|
|
67
66
|
};
|
|
68
67
|
}
|
|
69
|
-
export const useHTMLElementWalkerRef = (filter)=>{
|
|
70
|
-
const walkerRef = React.useRef();
|
|
71
|
-
const rootRefCallback = (element1)=>{
|
|
72
|
-
if (!element1) {
|
|
73
|
-
walkerRef.current = undefined;
|
|
74
|
-
return;
|
|
75
|
-
}
|
|
76
|
-
walkerRef.current = createHTMLElementWalker(element1, filter);
|
|
77
|
-
};
|
|
78
|
-
return [
|
|
79
|
-
walkerRef,
|
|
80
|
-
rootRefCallback
|
|
81
|
-
];
|
|
82
|
-
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["createHTMLElementWalker.ts"],"sourcesContent":["import { isHTMLElement } from '@fluentui/react-utilities';\n\nexport interface HTMLElementWalker {\n readonly root: HTMLElement;\n currentElement: HTMLElement;\n firstChild(filter?: HTMLElementFilter): HTMLElement | null;\n lastChild(filter?: HTMLElementFilter): HTMLElement | null;\n nextElement(filter?: HTMLElementFilter): HTMLElement | null;\n nextSibling(filter?: HTMLElementFilter): HTMLElement | null;\n parentElement(filter?: HTMLElementFilter): HTMLElement | null;\n previousElement(filter?: HTMLElementFilter): HTMLElement | null;\n previousSibling(filter?: HTMLElementFilter): HTMLElement | null;\n}\n\nexport type HTMLElementFilter = (element: HTMLElement) => number;\n\nexport function createHTMLElementWalker(\n root: HTMLElement,\n filter: HTMLElementFilter = () => NodeFilter.FILTER_ACCEPT,\n): HTMLElementWalker {\n let temporaryFilter: HTMLElementFilter | undefined;\n const treeWalker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {\n acceptNode(node: Node) {\n if (!isHTMLElement(node)) {\n return NodeFilter.FILTER_REJECT;\n }\n const filterResult = filter(node);\n return filterResult === NodeFilter.FILTER_ACCEPT ? temporaryFilter?.(node) ?? filterResult : filterResult;\n },\n });\n return {\n get root() {\n return treeWalker.root as HTMLElement;\n },\n get currentElement() {\n return treeWalker.currentNode as HTMLElement;\n },\n set currentElement(element) {\n treeWalker.currentNode = element;\n },\n firstChild: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.firstChild() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n lastChild: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.lastChild() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n nextElement: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.nextNode() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n nextSibling: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.nextSibling() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n parentElement: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.parentNode() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n previousElement: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.previousNode() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n previousSibling: localFilter => {\n temporaryFilter = localFilter;\n const result = treeWalker.previousSibling() as HTMLElement | null;\n temporaryFilter = undefined;\n return result;\n },\n };\n}\n"],"names":["isHTMLElement","createHTMLElementWalker","root","filter","NodeFilter","FILTER_ACCEPT","temporaryFilter","treeWalker","document","createTreeWalker","SHOW_ELEMENT","acceptNode","node","FILTER_REJECT","filterResult","currentElement","currentNode","element","firstChild","localFilter","result","undefined","lastChild","nextElement","nextNode","nextSibling","parentElement","parentNode","previousElement","previousNode","previousSibling"],"mappings":"AAAA,SAASA,aAAa,QAAQ,4BAA4B;AAgB1D,OAAO,SAASC,wBACdC,IAAiB,EACjBC,SAA4B,IAAMC,WAAWC,aAAa,EACvC;IACnB,IAAIC;IACJ,MAAMC,aAAaC,SAASC,gBAAgB,CAACP,MAAME,WAAWM,YAAY,EAAE;QAC1EC,YAAWC,IAAU,EAAE;YACrB,IAAI,CAACZ,cAAcY,OAAO;gBACxB,OAAOR,WAAWS,aAAa;YACjC,CAAC;YACD,MAAMC,eAAeX,OAAOS;gBACuBN;YAAnD,OAAOQ,iBAAiBV,WAAWC,aAAa,GAAGC,CAAAA,mBAAAA,4BAAAA,6BAAAA,KAAAA,IAAAA,gBAAkBM,mBAAlBN,8BAAAA,mBAA2BQ,YAAY,GAAGA,YAAY;QAC3G;IACF;IACA,OAAO;QACL,IAAIZ,QAAO;YACT,OAAOK,WAAWL,IAAI;QACxB;QACA,IAAIa,kBAAiB;YACnB,OAAOR,WAAWS,WAAW;QAC/B;QACA,IAAID,gBAAeE,QAAS;YAC1BV,WAAWS,WAAW,GAAGC;QAC3B;QACAC,YAAYC,CAAAA,cAAe;YACzBb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWW,UAAU;YACpCZ,kBAAkBe;YAClB,OAAOD;QACT;QACAE,WAAWH,CAAAA,cAAe;YACxBb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWe,SAAS;YACnChB,kBAAkBe;YAClB,OAAOD;QACT;QACAG,aAAaJ,CAAAA,cAAe;YAC1Bb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWiB,QAAQ;YAClClB,kBAAkBe;YAClB,OAAOD;QACT;QACAK,aAAaN,CAAAA,cAAe;YAC1Bb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWkB,WAAW;YACrCnB,kBAAkBe;YAClB,OAAOD;QACT;QACAM,eAAeP,CAAAA,cAAe;YAC5Bb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWoB,UAAU;YACpCrB,kBAAkBe;YAClB,OAAOD;QACT;QACAQ,iBAAiBT,CAAAA,cAAe;YAC9Bb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWsB,YAAY;YACtCvB,kBAAkBe;YAClB,OAAOD;QACT;QACAU,iBAAiBX,CAAAA,cAAe;YAC9Bb,kBAAkBa;YAClB,MAAMC,SAASb,WAAWuB,eAAe;YACzCxB,kBAAkBe;YAClB,OAAOD;QACT;IACF;AACF,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* creates a list of virtual tree items
|
|
3
3
|
* and provides a map to access each item by id
|
|
4
|
-
*/ export function createHeadlessTree(
|
|
4
|
+
*/ export function createHeadlessTree(initialProps = []) {
|
|
5
5
|
const root = createHeadlessTreeRootItem();
|
|
6
6
|
const itemsPerValue = new Map([
|
|
7
7
|
[
|
|
@@ -9,70 +9,92 @@
|
|
|
9
9
|
root
|
|
10
10
|
]
|
|
11
11
|
]);
|
|
12
|
-
const items = [];
|
|
13
|
-
for(let index = 0; index < virtualTreeItemProps.length; index++){
|
|
14
|
-
const { parentValue =virtualTreeRootId , ...treeItemProps } = virtualTreeItemProps[index];
|
|
15
|
-
const nextItemProps = virtualTreeItemProps[index + 1];
|
|
16
|
-
const currentParent = itemsPerValue.get(parentValue);
|
|
17
|
-
if (!currentParent) {
|
|
18
|
-
if (process.env.NODE_ENV === 'development') {
|
|
19
|
-
// eslint-disable-next-line no-console
|
|
20
|
-
console.error(`useHeadlessTree: item ${virtualTreeItemProps[index].value} is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized`);
|
|
21
|
-
}
|
|
22
|
-
break;
|
|
23
|
-
}
|
|
24
|
-
var _treeItemProps_itemType;
|
|
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
|
-
var _currentParent_level;
|
|
27
|
-
const currentLevel = ((_currentParent_level = currentParent.level) !== null && _currentParent_level !== void 0 ? _currentParent_level : 0) + 1;
|
|
28
|
-
const virtualTreeItem = {
|
|
29
|
-
value: treeItemProps.value,
|
|
30
|
-
getTreeItemProps: ()=>({
|
|
31
|
-
...treeItemProps,
|
|
32
|
-
'aria-level': currentLevel,
|
|
33
|
-
'aria-posinset': currentChildrenSize,
|
|
34
|
-
'aria-setsize': currentParent.childrenValues.length,
|
|
35
|
-
itemType
|
|
36
|
-
}),
|
|
37
|
-
level: currentLevel,
|
|
38
|
-
parentValue,
|
|
39
|
-
childrenValues: [],
|
|
40
|
-
index: -1
|
|
41
|
-
};
|
|
42
|
-
const currentChildrenSize = currentParent.childrenValues.push(virtualTreeItem.value);
|
|
43
|
-
itemsPerValue.set(virtualTreeItem.value, virtualTreeItem);
|
|
44
|
-
items.push(virtualTreeItem);
|
|
45
|
-
}
|
|
46
12
|
var _itemsPerValue_get_parentValue, _itemsPerValue_get;
|
|
47
|
-
const
|
|
13
|
+
const headlessTree = {
|
|
48
14
|
root,
|
|
49
|
-
size
|
|
50
|
-
|
|
15
|
+
get size () {
|
|
16
|
+
return itemsPerValue.size;
|
|
17
|
+
},
|
|
51
18
|
getParent: (key)=>{
|
|
52
19
|
var _itemsPerValue_get1;
|
|
53
20
|
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
21
|
},
|
|
55
22
|
get: (key)=>itemsPerValue.get(key),
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
23
|
+
has: (key)=>itemsPerValue.has(key),
|
|
24
|
+
add (props) {
|
|
25
|
+
const { parentValue =headlessTreeRootId , ...propsWithoutParentValue } = props;
|
|
26
|
+
const parentItem = itemsPerValue.get(parentValue);
|
|
27
|
+
if (!parentItem) {
|
|
28
|
+
if (process.env.NODE_ENV === 'development') {
|
|
29
|
+
// eslint-disable-next-line no-console
|
|
30
|
+
console.error(`HeadlessTree: item ${props.value} is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized, parents should come before children`);
|
|
31
|
+
}
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
parentItem.itemType = 'branch';
|
|
35
|
+
const item = {
|
|
36
|
+
value: props.value,
|
|
37
|
+
getTreeItemProps: ()=>({
|
|
38
|
+
...propsWithoutParentValue,
|
|
39
|
+
'aria-level': item.level,
|
|
40
|
+
'aria-posinset': item.position,
|
|
41
|
+
'aria-setsize': parentItem.childrenValues.length,
|
|
42
|
+
itemType: item.itemType
|
|
43
|
+
}),
|
|
44
|
+
itemType: 'leaf',
|
|
45
|
+
level: parentItem.level + 1,
|
|
46
|
+
parentValue,
|
|
47
|
+
childrenValues: [],
|
|
48
|
+
index: -1,
|
|
49
|
+
position: parentItem.childrenValues.push(props.value)
|
|
50
|
+
};
|
|
51
|
+
itemsPerValue.set(item.value, item);
|
|
52
|
+
},
|
|
53
|
+
// TODO: eventually it would be nice to have this method exported for the user to modify
|
|
54
|
+
// the internal state of the virtual tree
|
|
55
|
+
// remove(value) {
|
|
56
|
+
// const itemToBeRemoved = itemsPerValue.get(value);
|
|
57
|
+
// if (!itemToBeRemoved) {
|
|
58
|
+
// return;
|
|
59
|
+
// }
|
|
60
|
+
// const parentItem = headlessTree.getParent(value);
|
|
61
|
+
// parentItem.childrenValues.splice(itemToBeRemoved.position, 1);
|
|
62
|
+
// itemsPerValue.delete(value);
|
|
63
|
+
// if (parentItem.childrenValues.length === 0) {
|
|
64
|
+
// parentItem.itemType = 'leaf';
|
|
65
|
+
// }
|
|
66
|
+
// for (let index = itemToBeRemoved.position; index < parentItem.childrenValues.length; index++) {
|
|
67
|
+
// const child = itemsPerValue.get(parentItem.childrenValues[index]);
|
|
68
|
+
// if (child) {
|
|
69
|
+
// child.position = index + 1;
|
|
70
|
+
// }
|
|
71
|
+
// }
|
|
72
|
+
// for (const descendant of HeadlessTreeSubtreeGenerator(value, headlessTree)) {
|
|
73
|
+
// itemsPerValue.delete(descendant.value);
|
|
74
|
+
// }
|
|
75
|
+
// },
|
|
76
|
+
subtree: (key)=>HeadlessTreeSubtreeGenerator(key, headlessTree),
|
|
77
|
+
children: (key)=>HeadlessTreeChildrenGenerator(key, headlessTree),
|
|
78
|
+
ancestors: (key)=>HeadlessTreeAncestorsGenerator(key, headlessTree),
|
|
79
|
+
visibleItems: (openItems)=>HeadlessTreeVisibleItemsGenerator(openItems, headlessTree)
|
|
60
80
|
};
|
|
61
|
-
|
|
81
|
+
initialProps.forEach(headlessTree.add);
|
|
82
|
+
return headlessTree;
|
|
62
83
|
}
|
|
63
|
-
export const
|
|
84
|
+
export const headlessTreeRootId = '__fuiHeadlessTreeRoot';
|
|
64
85
|
function createHeadlessTreeRootItem() {
|
|
65
86
|
return {
|
|
66
87
|
parentValue: undefined,
|
|
67
|
-
value:
|
|
88
|
+
value: headlessTreeRootId,
|
|
89
|
+
itemType: 'branch',
|
|
68
90
|
getTreeItemProps: ()=>{
|
|
69
91
|
if (process.env.NODE_ENV !== 'production') {
|
|
70
92
|
// eslint-disable-next-line no-console
|
|
71
|
-
console.error('
|
|
93
|
+
console.error('HeadlessTree: internal error, trying to access treeitem props from invalid root element');
|
|
72
94
|
}
|
|
73
95
|
return {
|
|
74
|
-
id:
|
|
75
|
-
value:
|
|
96
|
+
id: headlessTreeRootId,
|
|
97
|
+
value: headlessTreeRootId,
|
|
76
98
|
'aria-setsize': -1,
|
|
77
99
|
'aria-level': -1,
|
|
78
100
|
'aria-posinset': -1,
|
|
@@ -83,7 +105,14 @@ function createHeadlessTreeRootItem() {
|
|
|
83
105
|
get index () {
|
|
84
106
|
if (process.env.NODE_ENV !== 'production') {
|
|
85
107
|
// eslint-disable-next-line no-console
|
|
86
|
-
console.error('
|
|
108
|
+
console.error('HeadlessTree: internal error, trying to access treeitem props from invalid root element');
|
|
109
|
+
}
|
|
110
|
+
return -1;
|
|
111
|
+
},
|
|
112
|
+
get position () {
|
|
113
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
114
|
+
// eslint-disable-next-line no-console
|
|
115
|
+
console.error('HeadlessTree: internal error, trying to access treeitem props from invalid root element');
|
|
87
116
|
}
|
|
88
117
|
return -1;
|
|
89
118
|
},
|
|
@@ -97,14 +126,11 @@ function createHeadlessTreeRootItem() {
|
|
|
97
126
|
function* HeadlessTreeSubtreeGenerator(key, virtualTreeItems) {
|
|
98
127
|
const item = virtualTreeItems.get(key);
|
|
99
128
|
if (!item || item.childrenValues.length === 0) {
|
|
100
|
-
return
|
|
129
|
+
return;
|
|
101
130
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
const children = virtualTreeItems.getByIndex(++index);
|
|
106
|
-
yield children;
|
|
107
|
-
counter += children.childrenValues.length - 1;
|
|
131
|
+
for (const childValue of item.childrenValues){
|
|
132
|
+
yield virtualTreeItems.get(childValue);
|
|
133
|
+
yield* HeadlessTreeSubtreeGenerator(childValue, virtualTreeItems);
|
|
108
134
|
}
|
|
109
135
|
}
|
|
110
136
|
/**
|
|
@@ -136,14 +162,11 @@ function* HeadlessTreeAncestorsGenerator(key, virtualTreeItems) {
|
|
|
136
162
|
* @param openItems the open items of the tree
|
|
137
163
|
*/ // eslint-disable-next-line @typescript-eslint/naming-convention
|
|
138
164
|
function* HeadlessTreeVisibleItemsGenerator(openItems, virtualTreeItems) {
|
|
139
|
-
|
|
140
|
-
|
|
165
|
+
let index = 0;
|
|
166
|
+
for (const item of HeadlessTreeSubtreeGenerator(virtualTreeItems.root.value, virtualTreeItems)){
|
|
141
167
|
if (isItemVisible(item, openItems, virtualTreeItems)) {
|
|
142
|
-
item.index =
|
|
168
|
+
item.index = index++;
|
|
143
169
|
yield item;
|
|
144
|
-
} else {
|
|
145
|
-
// Jump the amount of children the current item has, since those items will also be hidden
|
|
146
|
-
index += item.childrenValues.length;
|
|
147
170
|
}
|
|
148
171
|
}
|
|
149
172
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["createHeadlessTree.ts"],"sourcesContent":["import { TreeItemProps, TreeItemType, TreeItemValue } from '../TreeItem';\nimport { ImmutableSet } from './ImmutableSet';\n\nexport type HeadlessTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> & {\n value: TreeItemValue;\n itemType?: TreeItemType;\n parentValue?: TreeItemValue;\n};\n\n/**\n * The item that is returned by `createHeadlessTree`, it represents a wrapper around the properties provided to\n * `createHeadlessTree` but with extra information that might be useful on virtual tree scenarios\n */\nexport type HeadlessTreeItem<Props extends HeadlessTreeItemProps> = {\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, 'parentValue'>;\n};\n\n/**\n * @internal\n */\nexport type HeadlessTree<Props extends HeadlessTreeItemProps> = {\n size: number;\n root: HeadlessTreeItem<HeadlessTreeItemProps>;\n get(key: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n getParent(key: TreeItemValue): HeadlessTreeItem<Props>;\n getByIndex(index: number): HeadlessTreeItem<Props>;\n subtree(key: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n children(key: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n visibleItems(openItems: ImmutableSet<TreeItemValue>): IterableIterator<HeadlessTreeItem<Props>>;\n ancestors(key: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\n/**\n * creates a list of virtual tree items\n * and provides a map to access each item by id\n */\nexport function createHeadlessTree<Props extends HeadlessTreeItemProps>(\n virtualTreeItemProps: Props[],\n): HeadlessTree<Props> {\n const root = createHeadlessTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, HeadlessTreeItem<HeadlessTreeItemProps>>([[root.value, root]]);\n const items: HeadlessTreeItem<HeadlessTreeItemProps>[] = [];\n\n for (let index = 0; index < virtualTreeItemProps.length; index++) {\n const { parentValue = virtualTreeRootId, ...treeItemProps } = virtualTreeItemProps[index];\n\n const nextItemProps: Props | undefined = virtualTreeItemProps[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 `useHeadlessTree: item ${virtualTreeItemProps[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 virtualTreeItem: HeadlessTreeItem<HeadlessTreeItemProps> = {\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(virtualTreeItem.value);\n itemsPerValue.set(virtualTreeItem.value, virtualTreeItem);\n items.push(virtualTreeItem);\n }\n\n const virtualTreeItems: HeadlessTree<HeadlessTreeItemProps> = {\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 => HeadlessTreeSubtreeGenerator(key, virtualTreeItems),\n children: key => HeadlessTreeChildrenGenerator(key, virtualTreeItems),\n ancestors: key => HeadlessTreeAncestorsGenerator(key, virtualTreeItems),\n visibleItems: openItems => HeadlessTreeVisibleItemsGenerator(openItems, virtualTreeItems),\n };\n\n return virtualTreeItems as HeadlessTree<Props>;\n}\n\nexport const virtualTreeRootId = '__fuiHeadlessTreeRoot';\n\nfunction createHeadlessTreeRootItem(): HeadlessTreeItem<HeadlessTreeItemProps> {\n return {\n parentValue: undefined,\n value: virtualTreeRootId,\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('useHeadlessTree: internal error, trying to access treeitem props from invalid root element');\n }\n return {\n id: virtualTreeRootId,\n value: virtualTreeRootId,\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('useHeadlessTree: 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 virtual 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* HeadlessTreeSubtreeGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n) {\n const item = virtualTreeItems.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 = virtualTreeItems.getByIndex(++index);\n yield children;\n counter += children.childrenValues.length - 1;\n }\n}\n\n/**\n * Generator that returns all children of a given virtual 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* HeadlessTreeChildrenGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n) {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n }\n}\n\n/**\n * Generator that returns all ancestors of a given virtual 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* HeadlessTreeAncestorsGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n) {\n let parent = virtualTreeItems.getParent(key);\n while (parent !== virtualTreeItems.root) {\n yield parent;\n parent = virtualTreeItems.getParent(parent.value);\n }\n}\n\n/**\n * Generator that returns all visible items of a given virtual tree\n * @param openItems the open items of the tree\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeVisibleItemsGenerator<Props extends HeadlessTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n) {\n for (let index = 0, visibleIndex = 0; index < virtualTreeItems.size; index++) {\n const item = virtualTreeItems.getByIndex(index) as HeadlessTreeItem<Props>;\n if (isItemVisible(item, openItems, virtualTreeItems)) {\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: HeadlessTreeItem<HeadlessTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== virtualTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = virtualTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createHeadlessTree","virtualTreeItemProps","root","createHeadlessTreeRootItem","itemsPerValue","Map","value","items","index","length","parentValue","virtualTreeRootId","treeItemProps","nextItemProps","currentParent","get","process","env","NODE_ENV","console","error","itemType","undefined","currentLevel","level","virtualTreeItem","getTreeItemProps","currentChildrenSize","childrenValues","push","set","virtualTreeItems","size","getByIndex","getParent","key","subtree","HeadlessTreeSubtreeGenerator","children","HeadlessTreeChildrenGenerator","ancestors","HeadlessTreeAncestorsGenerator","visibleItems","openItems","HeadlessTreeVisibleItemsGenerator","id","item","counter","childValue","parent","visibleIndex","isItemVisible","has"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["createHeadlessTree.ts"],"sourcesContent":["import { TreeItemProps, TreeItemType, TreeItemValue } from '../TreeItem';\nimport { ImmutableSet } from './ImmutableSet';\n\nexport type HeadlessTreeItemProps = Omit<TreeItemProps, 'itemType' | 'value'> & {\n value: TreeItemValue;\n itemType?: TreeItemType;\n parentValue?: TreeItemValue;\n};\n\n/**\n * The item that is returned by `createHeadlessTree`, it represents a wrapper around the properties provided to\n * `createHeadlessTree` but with extra information that might be useful on virtual tree scenarios\n */\nexport type HeadlessTreeItem<Props extends HeadlessTreeItemProps> = {\n level: number;\n index: number;\n position: number;\n childrenValues: TreeItemValue[];\n value: TreeItemValue;\n parentValue: TreeItemValue | undefined;\n itemType: TreeItemType;\n getTreeItemProps(): Required<Pick<Props, 'value' | 'aria-setsize' | 'aria-level' | 'aria-posinset' | 'itemType'>> &\n Omit<Props, 'parentValue'>;\n};\n\n/**\n * @internal\n */\nexport type HeadlessTree<Props extends HeadlessTreeItemProps> = {\n /**\n * the number of items in the virtual tree\n */\n readonly size: number;\n /**\n * the root item of the virtual tree\n */\n root: HeadlessTreeItem<HeadlessTreeItemProps>;\n /**\n * method to get a virtual tree item by its value\n * @param key the key of the item to get\n */\n get(value: TreeItemValue): HeadlessTreeItem<Props> | undefined;\n /**\n * method to check if a virtual tree item exists by its value\n * @param value the value of the item to check if exists\n */\n has(value: TreeItemValue): boolean;\n /**\n * method to add a new virtual tree item to the virtual tree\n * @param props the props of the item to add\n */\n add(props: Props): void;\n /**\n * method to remove a virtual tree item from the virtual tree.\n * When an item is removed:\n * 1. all its children are also removed\n * 2. all its siblings are repositioned\n * @param value the value of the item to remove\n */\n // remove(value: TreeItemValue): void;\n /**\n * method to get the parent of a virtual tree item by its value\n * @param value the value of the item to get the parent from\n */\n getParent(value: TreeItemValue): HeadlessTreeItem<Props>;\n /**\n * method to get the subtree of a virtual tree item by its value\n * @param value the value of the item to get the subtree from\n */\n subtree(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the children of a virtual tree item by its value\n * @param value the value of the item to get the children from\n */\n children(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the visible items of a virtual tree\n * @param openItems the open items of the tree\n */\n visibleItems(openItems: ImmutableSet<TreeItemValue>): IterableIterator<HeadlessTreeItem<Props>>;\n /**\n * method to get the ancestors of a virtual tree item by its value\n * @param value the value of the item to get the ancestors from\n */\n ancestors(value: TreeItemValue): IterableIterator<HeadlessTreeItem<Props>>;\n};\n\n/**\n * creates a list of virtual tree items\n * and provides a map to access each item by id\n */\nexport function createHeadlessTree<Props extends HeadlessTreeItemProps>(\n initialProps: Props[] = [],\n): HeadlessTree<Props> {\n const root = createHeadlessTreeRootItem();\n const itemsPerValue = new Map<TreeItemValue, HeadlessTreeItem<HeadlessTreeItemProps>>([[root.value, root]]);\n\n const headlessTree: HeadlessTree<HeadlessTreeItemProps> = {\n root,\n get size() {\n return itemsPerValue.size;\n },\n getParent: key => itemsPerValue.get(itemsPerValue.get(key)?.parentValue ?? root.value) ?? root,\n get: key => itemsPerValue.get(key),\n has: key => itemsPerValue.has(key),\n add(props) {\n const { parentValue = headlessTreeRootId, ...propsWithoutParentValue } = props;\n const parentItem = itemsPerValue.get(parentValue);\n if (!parentItem) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(\n `HeadlessTree: item ${props.value} is wrongly positioned, did you properly ordered provided item props? make sure provided items are organized, parents should come before children`,\n );\n }\n return;\n }\n parentItem.itemType = 'branch';\n\n const item: HeadlessTreeItem<HeadlessTreeItemProps> = {\n value: props.value,\n getTreeItemProps: () => ({\n ...propsWithoutParentValue,\n 'aria-level': item.level,\n 'aria-posinset': item.position,\n 'aria-setsize': parentItem.childrenValues.length,\n itemType: item.itemType,\n }),\n itemType: 'leaf',\n level: parentItem.level + 1,\n parentValue,\n childrenValues: [],\n index: -1,\n position: parentItem.childrenValues.push(props.value),\n };\n itemsPerValue.set(item.value, item);\n },\n // TODO: eventually it would be nice to have this method exported for the user to modify\n // the internal state of the virtual tree\n // remove(value) {\n // const itemToBeRemoved = itemsPerValue.get(value);\n // if (!itemToBeRemoved) {\n // return;\n // }\n // const parentItem = headlessTree.getParent(value);\n // parentItem.childrenValues.splice(itemToBeRemoved.position, 1);\n // itemsPerValue.delete(value);\n // if (parentItem.childrenValues.length === 0) {\n // parentItem.itemType = 'leaf';\n // }\n // for (let index = itemToBeRemoved.position; index < parentItem.childrenValues.length; index++) {\n // const child = itemsPerValue.get(parentItem.childrenValues[index]);\n // if (child) {\n // child.position = index + 1;\n // }\n // }\n // for (const descendant of HeadlessTreeSubtreeGenerator(value, headlessTree)) {\n // itemsPerValue.delete(descendant.value);\n // }\n // },\n subtree: key => HeadlessTreeSubtreeGenerator(key, headlessTree),\n children: key => HeadlessTreeChildrenGenerator(key, headlessTree),\n ancestors: key => HeadlessTreeAncestorsGenerator(key, headlessTree),\n visibleItems: openItems => HeadlessTreeVisibleItemsGenerator(openItems, headlessTree),\n };\n\n initialProps.forEach(headlessTree.add);\n\n return headlessTree as HeadlessTree<Props>;\n}\n\nexport const headlessTreeRootId = '__fuiHeadlessTreeRoot';\n\nfunction createHeadlessTreeRootItem(): HeadlessTreeItem<HeadlessTreeItemProps> {\n return {\n parentValue: undefined,\n value: headlessTreeRootId,\n itemType: 'branch',\n getTreeItemProps: () => {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('HeadlessTree: internal error, trying to access treeitem props from invalid root element');\n }\n return {\n id: headlessTreeRootId,\n value: headlessTreeRootId,\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('HeadlessTree: internal error, trying to access treeitem props from invalid root element');\n }\n return -1;\n },\n get position() {\n if (process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.error('HeadlessTree: 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 virtual 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* HeadlessTreeSubtreeGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n yield* HeadlessTreeSubtreeGenerator(childValue, virtualTreeItems);\n }\n}\n\n/**\n * Generator that returns all children of a given virtual 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* HeadlessTreeChildrenGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n const item = virtualTreeItems.get(key);\n if (!item || item.childrenValues.length === 0) {\n return;\n }\n for (const childValue of item.childrenValues) {\n yield virtualTreeItems.get(childValue)!;\n }\n}\n\n/**\n * Generator that returns all ancestors of a given virtual 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* HeadlessTreeAncestorsGenerator<Props extends HeadlessTreeItemProps>(\n key: TreeItemValue,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let parent = virtualTreeItems.getParent(key);\n while (parent !== virtualTreeItems.root) {\n yield parent;\n parent = virtualTreeItems.getParent(parent.value);\n }\n}\n\n/**\n * Generator that returns all visible items of a given virtual tree\n * @param openItems the open items of the tree\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nfunction* HeadlessTreeVisibleItemsGenerator<Props extends HeadlessTreeItemProps>(\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<Props>,\n): Generator<HeadlessTreeItem<Props>, void, void> {\n let index = 0;\n for (const item of HeadlessTreeSubtreeGenerator(virtualTreeItems.root.value, virtualTreeItems)) {\n if (isItemVisible(item, openItems, virtualTreeItems)) {\n item.index = index++;\n yield item;\n }\n }\n}\n\nfunction isItemVisible(\n item: HeadlessTreeItem<HeadlessTreeItemProps>,\n openItems: ImmutableSet<TreeItemValue>,\n virtualTreeItems: HeadlessTree<HeadlessTreeItemProps>,\n) {\n if (item.level === 1) {\n return true;\n }\n while (item.parentValue && item.parentValue !== virtualTreeItems.root.value) {\n if (!openItems.has(item.parentValue)) {\n return false;\n }\n const parent = virtualTreeItems.get(item.parentValue);\n if (!parent) {\n return false;\n }\n item = parent;\n }\n return true;\n}\n"],"names":["createHeadlessTree","initialProps","root","createHeadlessTreeRootItem","itemsPerValue","Map","value","headlessTree","size","getParent","key","get","parentValue","has","add","props","headlessTreeRootId","propsWithoutParentValue","parentItem","process","env","NODE_ENV","console","error","itemType","item","getTreeItemProps","level","position","childrenValues","length","index","push","set","subtree","HeadlessTreeSubtreeGenerator","children","HeadlessTreeChildrenGenerator","ancestors","HeadlessTreeAncestorsGenerator","visibleItems","openItems","HeadlessTreeVisibleItemsGenerator","forEach","undefined","id","virtualTreeItems","childValue","parent","isItemVisible"],"mappings":"AAuFA;;;CAGC,GACD,OAAO,SAASA,mBACdC,eAAwB,EAAE,EACL;IACrB,MAAMC,OAAOC;IACb,MAAMC,gBAAgB,IAAIC,IAA4D;QAAC;YAACH,KAAKI,KAAK;YAAEJ;SAAK;KAAC;QAOpEE,gCAAlBA;IALpB,MAAMG,eAAoD;QACxDL;QACA,IAAIM,QAAO;YACT,OAAOJ,cAAcI,IAAI;QAC3B;QACAC,WAAWC,CAAAA;gBAAyBN;YAAlBA,OAAAA,CAAAA,qBAAAA,cAAcO,GAAG,CAACP,CAAAA,iCAAAA,CAAAA,sBAAAA,cAAcO,GAAG,CAACD,kBAAlBN,iCAAAA,KAAAA,IAAAA,oBAAwBQ,WAAW,cAAnCR,4CAAAA,iCAAuCF,KAAKI,KAAK,eAAnEF,gCAAAA,qBAAwEF,IAAI;;QAC9FS,KAAKD,CAAAA,MAAON,cAAcO,GAAG,CAACD;QAC9BG,KAAKH,CAAAA,MAAON,cAAcS,GAAG,CAACH;QAC9BI,KAAIC,KAAK,EAAE;YACT,MAAM,EAAEH,aAAcI,mBAAkB,EAAE,GAAGC,yBAAyB,GAAGF;YACzE,MAAMG,aAAad,cAAcO,GAAG,CAACC;YACrC,IAAI,CAACM,YAAY;gBACf,IAAIC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;oBAC1C,sCAAsC;oBACtCC,QAAQC,KAAK,CACX,CAAC,mBAAmB,EAAER,MAAMT,KAAK,CAAC,iJAAiJ,CAAC;gBAExL,CAAC;gBACD;YACF,CAAC;YACDY,WAAWM,QAAQ,GAAG;YAEtB,MAAMC,OAAgD;gBACpDnB,OAAOS,MAAMT,KAAK;gBAClBoB,kBAAkB,IAAO,CAAA;wBACvB,GAAGT,uBAAuB;wBAC1B,cAAcQ,KAAKE,KAAK;wBACxB,iBAAiBF,KAAKG,QAAQ;wBAC9B,gBAAgBV,WAAWW,cAAc,CAACC,MAAM;wBAChDN,UAAUC,KAAKD,QAAQ;oBACzB,CAAA;gBACAA,UAAU;gBACVG,OAAOT,WAAWS,KAAK,GAAG;gBAC1Bf;gBACAiB,gBAAgB,EAAE;gBAClBE,OAAO,CAAC;gBACRH,UAAUV,WAAWW,cAAc,CAACG,IAAI,CAACjB,MAAMT,KAAK;YACtD;YACAF,cAAc6B,GAAG,CAACR,KAAKnB,KAAK,EAAEmB;QAChC;QACA,wFAAwF;QACxF,yCAAyC;QACzC,kBAAkB;QAClB,sDAAsD;QACtD,4BAA4B;QAC5B,cAAc;QACd,MAAM;QACN,sDAAsD;QACtD,mEAAmE;QACnE,iCAAiC;QACjC,kDAAkD;QAClD,oCAAoC;QACpC,MAAM;QACN,oGAAoG;QACpG,yEAAyE;QACzE,mBAAmB;QACnB,oCAAoC;QACpC,QAAQ;QACR,MAAM;QACN,kFAAkF;QAClF,8CAA8C;QAC9C,MAAM;QACN,KAAK;QACLS,SAASxB,CAAAA,MAAOyB,6BAA6BzB,KAAKH;QAClD6B,UAAU1B,CAAAA,MAAO2B,8BAA8B3B,KAAKH;QACpD+B,WAAW5B,CAAAA,MAAO6B,+BAA+B7B,KAAKH;QACtDiC,cAAcC,CAAAA,YAAaC,kCAAkCD,WAAWlC;IAC1E;IAEAN,aAAa0C,OAAO,CAACpC,aAAaO,GAAG;IAErC,OAAOP;AACT,CAAC;AAED,OAAO,MAAMS,qBAAqB,wBAAwB;AAE1D,SAASb,6BAAsE;IAC7E,OAAO;QACLS,aAAagC;QACbtC,OAAOU;QACPQ,UAAU;QACVE,kBAAkB,IAAM;YACtB,IAAIP,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAC;YAChB,CAAC;YACD,OAAO;gBACLsB,IAAI7B;gBACJV,OAAOU;gBACP,gBAAgB,CAAC;gBACjB,cAAc,CAAC;gBACf,iBAAiB,CAAC;gBAClBQ,UAAU;YACZ;QACF;QACAK,gBAAgB,EAAE;QAClB,IAAIE,SAAQ;YACV,IAAIZ,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAC;YAChB,CAAC;YACD,OAAO,CAAC;QACV;QACA,IAAIK,YAAW;YACb,IAAIT,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAC;YAChB,CAAC;YACD,OAAO,CAAC;QACV;QACAI,OAAO;IACT;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUQ,6BACRzB,GAAkB,EAClBoC,gBAAqC,EACW;IAChD,MAAMrB,OAAOqB,iBAAiBnC,GAAG,CAACD;IAClC,IAAI,CAACe,QAAQA,KAAKI,cAAc,CAACC,MAAM,KAAK,GAAG;QAC7C;IACF,CAAC;IACD,KAAK,MAAMiB,cAActB,KAAKI,cAAc,CAAE;QAC5C,MAAMiB,iBAAiBnC,GAAG,CAACoC;QAC3B,OAAOZ,6BAA6BY,YAAYD;IAClD;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUT,8BACR3B,GAAkB,EAClBoC,gBAAqC,EACW;IAChD,MAAMrB,OAAOqB,iBAAiBnC,GAAG,CAACD;IAClC,IAAI,CAACe,QAAQA,KAAKI,cAAc,CAACC,MAAM,KAAK,GAAG;QAC7C;IACF,CAAC;IACD,KAAK,MAAMiB,cAActB,KAAKI,cAAc,CAAE;QAC5C,MAAMiB,iBAAiBnC,GAAG,CAACoC;IAC7B;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUR,+BACR7B,GAAkB,EAClBoC,gBAAqC,EACW;IAChD,IAAIE,SAASF,iBAAiBrC,SAAS,CAACC;IACxC,MAAOsC,WAAWF,iBAAiB5C,IAAI,CAAE;QACvC,MAAM8C;QACNA,SAASF,iBAAiBrC,SAAS,CAACuC,OAAO1C,KAAK;IAClD;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUoC,kCACRD,SAAsC,EACtCK,gBAAqC,EACW;IAChD,IAAIf,QAAQ;IACZ,KAAK,MAAMN,QAAQU,6BAA6BW,iBAAiB5C,IAAI,CAACI,KAAK,EAAEwC,kBAAmB;QAC9F,IAAIG,cAAcxB,MAAMgB,WAAWK,mBAAmB;YACpDrB,KAAKM,KAAK,GAAGA;YACb,MAAMN;QACR,CAAC;IACH;AACF;AAEA,SAASwB,cACPxB,IAA6C,EAC7CgB,SAAsC,EACtCK,gBAAqD,EACrD;IACA,IAAIrB,KAAKE,KAAK,KAAK,GAAG;QACpB,OAAO,IAAI;IACb,CAAC;IACD,MAAOF,KAAKb,WAAW,IAAIa,KAAKb,WAAW,KAAKkC,iBAAiB5C,IAAI,CAACI,KAAK,CAAE;QAC3E,IAAI,CAACmC,UAAU5B,GAAG,CAACY,KAAKb,WAAW,GAAG;YACpC,OAAO,KAAK;QACd,CAAC;QACD,MAAMoC,SAASF,iBAAiBnC,GAAG,CAACc,KAAKb,WAAW;QACpD,IAAI,CAACoC,QAAQ;YACX,OAAO,KAAK;QACd,CAAC;QACDvB,OAAOuB;IACT;IACA,OAAO,IAAI;AACb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["nextTypeAheadElement.ts"],"sourcesContent":["import { HTMLElementWalker } from '
|
|
1
|
+
{"version":3,"sources":["nextTypeAheadElement.ts"],"sourcesContent":["import { HTMLElementWalker } from './createHTMLElementWalker';\n\nexport function nextTypeAheadElement(treeWalker: HTMLElementWalker, key: string) {\n const keyToLowerCase = key.toLowerCase();\n const typeAheadFilter = (element: HTMLElement) => {\n return element.textContent?.trim().charAt(0).toLowerCase() === keyToLowerCase\n ? NodeFilter.FILTER_ACCEPT\n : NodeFilter.FILTER_SKIP;\n };\n let nextElement = treeWalker.nextElement(typeAheadFilter);\n if (!nextElement) {\n treeWalker.currentElement = treeWalker.root;\n nextElement = treeWalker.nextElement(typeAheadFilter);\n }\n return nextElement;\n}\n"],"names":["nextTypeAheadElement","treeWalker","key","keyToLowerCase","toLowerCase","typeAheadFilter","element","textContent","trim","charAt","NodeFilter","FILTER_ACCEPT","FILTER_SKIP","nextElement","currentElement","root"],"mappings":"AAEA,OAAO,SAASA,qBAAqBC,UAA6B,EAAEC,GAAW,EAAE;IAC/E,MAAMC,iBAAiBD,IAAIE,WAAW;IACtC,MAAMC,kBAAkB,CAACC,UAAyB;YACzCA;QAAP,OAAOA,CAAAA,CAAAA,uBAAAA,QAAQC,WAAW,cAAnBD,kCAAAA,KAAAA,IAAAA,qBAAqBE,OAAOC,MAAM,CAAC,GAAGL,WAAW,EAAE,AAAD,MAAMD,iBAC3DO,WAAWC,aAAa,GACxBD,WAAWE,WAAW;IAC5B;IACA,IAAIC,cAAcZ,WAAWY,WAAW,CAACR;IACzC,IAAI,CAACQ,aAAa;QAChBZ,WAAWa,cAAc,GAAGb,WAAWc,IAAI;QAC3CF,cAAcZ,WAAWY,WAAW,CAACR;IACvC,CAAC;IACD,OAAOQ;AACT,CAAC"}
|
|
@@ -11,53 +11,50 @@ const _reactUtilities = require("@fluentui/react-utilities");
|
|
|
11
11
|
const _nextTypeAheadElement = require("../../utils/nextTypeAheadElement");
|
|
12
12
|
const _tokens = require("../../utils/tokens");
|
|
13
13
|
const _treeItemFilter = require("../../utils/treeItemFilter");
|
|
14
|
-
const _useHTMLElementWalker = require("../../hooks/useHTMLElementWalker");
|
|
15
14
|
const _useRovingTabIndexes = require("../../hooks/useRovingTabIndexes");
|
|
16
15
|
const _getTreeItemValueFromElement = require("../../utils/getTreeItemValueFromElement");
|
|
17
16
|
function useFlatTreeNavigation(virtualTree) {
|
|
18
17
|
const { targetDocument } = (0, _reactSharedContexts.useFluent_unstable)();
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (!targetDocument || !treeItemWalkerRef.current) {
|
|
18
|
+
const { rove , initialize } = (0, _useRovingTabIndexes.useRovingTabIndex)(_treeItemFilter.treeItemFilter);
|
|
19
|
+
function getNextElement(data, walker) {
|
|
20
|
+
if (!targetDocument) {
|
|
23
21
|
return null;
|
|
24
22
|
}
|
|
25
|
-
const treeItemWalker = treeItemWalkerRef.current;
|
|
26
23
|
switch(data.type){
|
|
27
24
|
case _tokens.treeDataTypes.Click:
|
|
28
25
|
return data.target;
|
|
29
26
|
case _tokens.treeDataTypes.TypeAhead:
|
|
30
|
-
|
|
31
|
-
return (0, _nextTypeAheadElement.nextTypeAheadElement)(
|
|
27
|
+
walker.currentElement = data.target;
|
|
28
|
+
return (0, _nextTypeAheadElement.nextTypeAheadElement)(walker, data.event.key);
|
|
32
29
|
case _tokens.treeDataTypes.ArrowLeft:
|
|
33
|
-
return parentElement(virtualTree, data.target,
|
|
30
|
+
return parentElement(virtualTree, data.target, walker);
|
|
34
31
|
case _tokens.treeDataTypes.ArrowRight:
|
|
35
|
-
|
|
36
|
-
return firstChild(data.target,
|
|
32
|
+
walker.currentElement = data.target;
|
|
33
|
+
return firstChild(data.target, walker);
|
|
37
34
|
case _tokens.treeDataTypes.End:
|
|
38
|
-
|
|
39
|
-
return
|
|
35
|
+
walker.currentElement = walker.root;
|
|
36
|
+
return walker.lastChild();
|
|
40
37
|
case _tokens.treeDataTypes.Home:
|
|
41
|
-
|
|
42
|
-
return
|
|
38
|
+
walker.currentElement = walker.root;
|
|
39
|
+
return walker.firstChild();
|
|
43
40
|
case _tokens.treeDataTypes.ArrowDown:
|
|
44
|
-
|
|
45
|
-
return
|
|
41
|
+
walker.currentElement = data.target;
|
|
42
|
+
return walker.nextElement();
|
|
46
43
|
case _tokens.treeDataTypes.ArrowUp:
|
|
47
|
-
|
|
48
|
-
return
|
|
44
|
+
walker.currentElement = data.target;
|
|
45
|
+
return walker.previousElement();
|
|
49
46
|
}
|
|
50
47
|
}
|
|
51
|
-
const navigate = (0, _reactUtilities.useEventCallback)((data)=>{
|
|
52
|
-
const nextElement = getNextElement(data);
|
|
48
|
+
const navigate = (0, _reactUtilities.useEventCallback)((data, walker)=>{
|
|
49
|
+
const nextElement = getNextElement(data, walker);
|
|
53
50
|
if (nextElement) {
|
|
54
51
|
rove(nextElement);
|
|
55
52
|
}
|
|
56
53
|
});
|
|
57
|
-
return
|
|
54
|
+
return {
|
|
58
55
|
navigate,
|
|
59
|
-
|
|
60
|
-
|
|
56
|
+
initialize
|
|
57
|
+
};
|
|
61
58
|
}
|
|
62
59
|
function firstChild(target, treeWalker) {
|
|
63
60
|
const nextElement = treeWalker.nextElement();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useFlatTreeNavigation.js"],"sourcesContent":["import { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport { useEventCallback
|
|
1
|
+
{"version":3,"sources":["useFlatTreeNavigation.js"],"sourcesContent":["import { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport { useEventCallback } from '@fluentui/react-utilities';\nimport { nextTypeAheadElement } from '../../utils/nextTypeAheadElement';\nimport { treeDataTypes } from '../../utils/tokens';\nimport { treeItemFilter } from '../../utils/treeItemFilter';\nimport { useRovingTabIndex } from '../../hooks/useRovingTabIndexes';\nimport { dataTreeItemValueAttrName, getTreeItemValueFromElement } from '../../utils/getTreeItemValueFromElement';\nexport function useFlatTreeNavigation(virtualTree) {\n const { targetDocument } = useFluent_unstable();\n const { rove , initialize } = useRovingTabIndex(treeItemFilter);\n function getNextElement(data, walker) {\n if (!targetDocument) {\n return null;\n }\n switch(data.type){\n case treeDataTypes.Click:\n return data.target;\n case treeDataTypes.TypeAhead:\n walker.currentElement = data.target;\n return nextTypeAheadElement(walker, data.event.key);\n case treeDataTypes.ArrowLeft:\n return parentElement(virtualTree, data.target, walker);\n case treeDataTypes.ArrowRight:\n walker.currentElement = data.target;\n return firstChild(data.target, walker);\n case treeDataTypes.End:\n walker.currentElement = walker.root;\n return walker.lastChild();\n case treeDataTypes.Home:\n walker.currentElement = walker.root;\n return walker.firstChild();\n case treeDataTypes.ArrowDown:\n walker.currentElement = data.target;\n return walker.nextElement();\n case treeDataTypes.ArrowUp:\n walker.currentElement = data.target;\n return walker.previousElement();\n }\n }\n const navigate = useEventCallback((data, walker)=>{\n const nextElement = getNextElement(data, walker);\n if (nextElement) {\n rove(nextElement);\n }\n });\n return {\n navigate,\n initialize\n };\n}\nfunction firstChild(target, treeWalker) {\n const nextElement = treeWalker.nextElement();\n if (!nextElement) {\n return null;\n }\n const nextElementAriaPosInSet = nextElement.getAttribute('aria-posinset');\n const nextElementAriaLevel = nextElement.getAttribute('aria-level');\n const targetAriaLevel = target.getAttribute('aria-level');\n if (nextElementAriaPosInSet === '1' && Number(nextElementAriaLevel) === Number(targetAriaLevel) + 1) {\n return nextElement;\n }\n return null;\n}\nfunction parentElement(virtualTreeItems, target, treeWalker) {\n const value = getTreeItemValueFromElement(target);\n if (value === null) {\n return null;\n }\n const virtualTreeItem = virtualTreeItems.get(value);\n if (virtualTreeItem === null || virtualTreeItem === void 0 ? void 0 : virtualTreeItem.parentValue) {\n return treeWalker.root.querySelector(`[${dataTreeItemValueAttrName}=\"${virtualTreeItem.parentValue}\"]`);\n }\n return null;\n}\n"],"names":["useFlatTreeNavigation","virtualTree","targetDocument","useFluent_unstable","rove","initialize","useRovingTabIndex","treeItemFilter","getNextElement","data","walker","type","treeDataTypes","Click","target","TypeAhead","currentElement","nextTypeAheadElement","event","key","ArrowLeft","parentElement","ArrowRight","firstChild","End","root","lastChild","Home","ArrowDown","nextElement","ArrowUp","previousElement","navigate","useEventCallback","treeWalker","nextElementAriaPosInSet","getAttribute","nextElementAriaLevel","targetAriaLevel","Number","virtualTreeItems","value","getTreeItemValueFromElement","virtualTreeItem","get","parentValue","querySelector","dataTreeItemValueAttrName"],"mappings":";;;;+BAOgBA;;aAAAA;;qCAPmB;gCACF;sCACI;wBACP;gCACC;qCACG;6CACqC;AAChE,SAASA,sBAAsBC,WAAW,EAAE;IAC/C,MAAM,EAAEC,eAAc,EAAG,GAAGC,IAAAA,uCAAkB;IAC9C,MAAM,EAAEC,KAAI,EAAGC,WAAU,EAAG,GAAGC,IAAAA,sCAAiB,EAACC,8BAAc;IAC/D,SAASC,eAAeC,IAAI,EAAEC,MAAM,EAAE;QAClC,IAAI,CAACR,gBAAgB;YACjB,OAAO,IAAI;QACf,CAAC;QACD,OAAOO,KAAKE,IAAI;YACZ,KAAKC,qBAAa,CAACC,KAAK;gBACpB,OAAOJ,KAAKK,MAAM;YACtB,KAAKF,qBAAa,CAACG,SAAS;gBACxBL,OAAOM,cAAc,GAAGP,KAAKK,MAAM;gBACnC,OAAOG,IAAAA,0CAAoB,EAACP,QAAQD,KAAKS,KAAK,CAACC,GAAG;YACtD,KAAKP,qBAAa,CAACQ,SAAS;gBACxB,OAAOC,cAAcpB,aAAaQ,KAAKK,MAAM,EAAEJ;YACnD,KAAKE,qBAAa,CAACU,UAAU;gBACzBZ,OAAOM,cAAc,GAAGP,KAAKK,MAAM;gBACnC,OAAOS,WAAWd,KAAKK,MAAM,EAAEJ;YACnC,KAAKE,qBAAa,CAACY,GAAG;gBAClBd,OAAOM,cAAc,GAAGN,OAAOe,IAAI;gBACnC,OAAOf,OAAOgB,SAAS;YAC3B,KAAKd,qBAAa,CAACe,IAAI;gBACnBjB,OAAOM,cAAc,GAAGN,OAAOe,IAAI;gBACnC,OAAOf,OAAOa,UAAU;YAC5B,KAAKX,qBAAa,CAACgB,SAAS;gBACxBlB,OAAOM,cAAc,GAAGP,KAAKK,MAAM;gBACnC,OAAOJ,OAAOmB,WAAW;YAC7B,KAAKjB,qBAAa,CAACkB,OAAO;gBACtBpB,OAAOM,cAAc,GAAGP,KAAKK,MAAM;gBACnC,OAAOJ,OAAOqB,eAAe;QACrC;IACJ;IACA,MAAMC,WAAWC,IAAAA,gCAAgB,EAAC,CAACxB,MAAMC,SAAS;QAC9C,MAAMmB,cAAcrB,eAAeC,MAAMC;QACzC,IAAImB,aAAa;YACbzB,KAAKyB;QACT,CAAC;IACL;IACA,OAAO;QACHG;QACA3B;IACJ;AACJ;AACA,SAASkB,WAAWT,MAAM,EAAEoB,UAAU,EAAE;IACpC,MAAML,cAAcK,WAAWL,WAAW;IAC1C,IAAI,CAACA,aAAa;QACd,OAAO,IAAI;IACf,CAAC;IACD,MAAMM,0BAA0BN,YAAYO,YAAY,CAAC;IACzD,MAAMC,uBAAuBR,YAAYO,YAAY,CAAC;IACtD,MAAME,kBAAkBxB,OAAOsB,YAAY,CAAC;IAC5C,IAAID,4BAA4B,OAAOI,OAAOF,0BAA0BE,OAAOD,mBAAmB,GAAG;QACjG,OAAOT;IACX,CAAC;IACD,OAAO,IAAI;AACf;AACA,SAASR,cAAcmB,gBAAgB,EAAE1B,MAAM,EAAEoB,UAAU,EAAE;IACzD,MAAMO,QAAQC,IAAAA,wDAA2B,EAAC5B;IAC1C,IAAI2B,UAAU,IAAI,EAAE;QAChB,OAAO,IAAI;IACf,CAAC;IACD,MAAME,kBAAkBH,iBAAiBI,GAAG,CAACH;IAC7C,IAAIE,oBAAoB,IAAI,IAAIA,oBAAoB,KAAK,IAAI,KAAK,IAAIA,gBAAgBE,WAAW,EAAE;QAC/F,OAAOX,WAAWT,IAAI,CAACqB,aAAa,CAAC,CAAC,CAAC,EAAEC,sDAAyB,CAAC,EAAE,EAAEJ,gBAAgBE,WAAW,CAAC,EAAE,CAAC;IAC1G,CAAC;IACD,OAAO,IAAI;AACf"}
|
|
@@ -21,33 +21,16 @@ const useStyles = /*#__PURE__*/ (0, _react["__styles"])({
|
|
|
21
21
|
mc9l5x: "f22iagw",
|
|
22
22
|
Beiy3e4: "f1vx9l62",
|
|
23
23
|
Belr9w4: "f1j0q4x9"
|
|
24
|
-
},
|
|
25
|
-
subtree: {
|
|
26
|
-
Bh6795r: "fqerorx",
|
|
27
|
-
Bnnss6s: "f1neuvcm",
|
|
28
|
-
xawz: "f1s4axba",
|
|
29
|
-
Ijaq50: "f1na4k6z",
|
|
30
|
-
Br312pm: "fwt6ga",
|
|
31
|
-
nk6f5a: "fi45nfw",
|
|
32
|
-
Bw0ie65: "f10ort2y"
|
|
33
24
|
}
|
|
34
25
|
}, {
|
|
35
26
|
d: [
|
|
36
27
|
".f22iagw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}",
|
|
37
28
|
".f1vx9l62{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}",
|
|
38
|
-
".f1j0q4x9{row-gap:var(--spacingVerticalXXS);}"
|
|
39
|
-
".fqerorx{-webkit-box-flex:1;-webkit-flex-grow:1;-ms-flex-positive:1;flex-grow:1;}",
|
|
40
|
-
".f1neuvcm{-webkit-flex-shrink:1;-ms-flex-negative:1;flex-shrink:1;}",
|
|
41
|
-
".f1s4axba{-webkit-flex-basis:100%;-ms-flex-preferred-size:100%;flex-basis:100%;}",
|
|
42
|
-
".f1na4k6z{-ms-grid-row:subtree;grid-row-start:subtree;}",
|
|
43
|
-
".fwt6ga{-ms-grid-column:subtree;grid-column-start:subtree;}",
|
|
44
|
-
".fi45nfw{-ms-grid-row-span:subtree;grid-row-end:subtree;}",
|
|
45
|
-
".f10ort2y{-ms-grid-column-span:subtree;grid-column-end:subtree;}"
|
|
29
|
+
".f1j0q4x9{row-gap:var(--spacingVerticalXXS);}"
|
|
46
30
|
]
|
|
47
31
|
});
|
|
48
32
|
const useFlatTreeStyles_unstable = (state)=>{
|
|
49
33
|
const styles = useStyles();
|
|
50
|
-
|
|
51
|
-
state.root.className = (0, _react.mergeClasses)(flatTreeClassNames.root, styles.root, isSubTree && styles.subtree, state.root.className);
|
|
34
|
+
state.root.className = (0, _react.mergeClasses)(flatTreeClassNames.root, styles.root, state.root.className);
|
|
52
35
|
return state;
|
|
53
36
|
}; //# sourceMappingURL=useFlatTreeStyles.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useFlatTreeStyles.styles.js"],"sourcesContent":["import { __styles, mergeClasses
|
|
1
|
+
{"version":3,"sources":["useFlatTreeStyles.styles.js"],"sourcesContent":["import { __styles, mergeClasses } from '@griffel/react';\nimport { tokens } from '@fluentui/react-theme';\nexport const flatTreeClassNames = {\n root: 'fui-FlatTree'\n};\nconst useStyles = /*#__PURE__*/__styles({\n root: {\n mc9l5x: \"f22iagw\",\n Beiy3e4: \"f1vx9l62\",\n Belr9w4: \"f1j0q4x9\"\n }\n}, {\n d: [\".f22iagw{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;}\", \".f1vx9l62{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;}\", \".f1j0q4x9{row-gap:var(--spacingVerticalXXS);}\"]\n});\nexport const useFlatTreeStyles_unstable = state => {\n const styles = useStyles();\n state.root.className = mergeClasses(flatTreeClassNames.root, styles.root, state.root.className);\n return state;\n};\n//# sourceMappingURL=useFlatTreeStyles.styles.js.map"],"names":["flatTreeClassNames","useFlatTreeStyles_unstable","root","useStyles","__styles","mc9l5x","Beiy3e4","Belr9w4","d","state","styles","className","mergeClasses"],"mappings":";;;;;;;;;;;IAEaA,kBAAkB,MAAlBA;IAYAC,0BAA0B,MAA1BA;;uBAd0B;AAEhC,MAAMD,qBAAqB;IAChCE,MAAM;AACR;AACA,MAAMC,YAAY,WAAW,GAAEC,IAAAA,kBAAQ,EAAC;IACtCF,MAAM;QACJG,QAAQ;QACRC,SAAS;QACTC,SAAS;IACX;AACF,GAAG;IACDC,GAAG;QAAC;QAAwF;QAA6F;KAAgD;AAC3O;AACO,MAAMP,6BAA6BQ,CAAAA,QAAS;IACjD,MAAMC,SAASP;IACfM,MAAMP,IAAI,CAACS,SAAS,GAAGC,IAAAA,mBAAY,EAACZ,mBAAmBE,IAAI,EAAEQ,OAAOR,IAAI,EAAEO,MAAMP,IAAI,CAACS,SAAS;IAC9F,OAAOF;AACT,GACA,oDAAoD"}
|
|
@@ -15,13 +15,24 @@ const _useFlatTreeNavigation = require("./useFlatTreeNavigation");
|
|
|
15
15
|
const _useControllableOpenItems = require("../../hooks/useControllableOpenItems");
|
|
16
16
|
const _getTreeItemValueFromElement = require("../../utils/getTreeItemValueFromElement");
|
|
17
17
|
const _useFlatControllableCheckedItems = require("./useFlatControllableCheckedItems");
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const _createHTMLElementWalker = require("../../utils/createHTMLElementWalker");
|
|
19
|
+
const _treeItemFilter = require("../../utils/treeItemFilter");
|
|
20
|
+
function useHeadlessFlatTree_unstable(props, options = {}) {
|
|
21
|
+
const headlessTree = _react.useMemo(()=>(0, _createHeadlessTree.createHeadlessTree)(props), [
|
|
22
|
+
props
|
|
21
23
|
]);
|
|
22
24
|
const [openItems, setOpenItems] = (0, _useControllableOpenItems.useControllableOpenItems)(options);
|
|
23
25
|
const [checkedItems, setCheckedItems] = (0, _useFlatControllableCheckedItems.useFlatControllableCheckedItems)(options);
|
|
24
|
-
const
|
|
26
|
+
const { initialize , navigate } = (0, _useFlatTreeNavigation.useFlatTreeNavigation)(headlessTree);
|
|
27
|
+
const walkerRef = _react.useRef();
|
|
28
|
+
const initializeWalker = _react.useCallback((root)=>{
|
|
29
|
+
if (root) {
|
|
30
|
+
walkerRef.current = (0, _createHTMLElementWalker.createHTMLElementWalker)(root, _treeItemFilter.treeItemFilter);
|
|
31
|
+
initialize(walkerRef.current);
|
|
32
|
+
}
|
|
33
|
+
}, [
|
|
34
|
+
initialize
|
|
35
|
+
]);
|
|
25
36
|
const treeRef = _react.useRef(null);
|
|
26
37
|
const handleOpenChange = (0, _reactUtilities.useEventCallback)((event, data)=>{
|
|
27
38
|
var _options_onOpenChange;
|
|
@@ -31,21 +42,23 @@ function useHeadlessFlatTree_unstable(flatTreeItemProps, options = {}) {
|
|
|
31
42
|
const handleCheckedChange = (0, _reactUtilities.useEventCallback)((event, data)=>{
|
|
32
43
|
var _options_onCheckedChange;
|
|
33
44
|
(_options_onCheckedChange = options.onCheckedChange) === null || _options_onCheckedChange === void 0 ? void 0 : _options_onCheckedChange.call(options, event, data);
|
|
34
|
-
setCheckedItems((0, _useFlatControllableCheckedItems.createNextFlatCheckedItems)(data, checkedItems,
|
|
45
|
+
setCheckedItems((0, _useFlatControllableCheckedItems.createNextFlatCheckedItems)(data, checkedItems, headlessTree));
|
|
35
46
|
});
|
|
36
47
|
const handleNavigation = (0, _reactUtilities.useEventCallback)((event, data)=>{
|
|
37
48
|
var _options_onNavigation_unstable;
|
|
38
49
|
(_options_onNavigation_unstable = options.onNavigation_unstable) === null || _options_onNavigation_unstable === void 0 ? void 0 : _options_onNavigation_unstable.call(options, event, data);
|
|
39
|
-
|
|
50
|
+
if (walkerRef.current) {
|
|
51
|
+
navigate(data, walkerRef.current);
|
|
52
|
+
}
|
|
40
53
|
});
|
|
41
54
|
const getNextNavigableItem = (0, _reactUtilities.useEventCallback)((visibleItems, data)=>{
|
|
42
|
-
const item =
|
|
55
|
+
const item = headlessTree.get(data.value);
|
|
43
56
|
if (item) {
|
|
44
57
|
switch(data.type){
|
|
45
58
|
case _tokens.treeDataTypes.TypeAhead:
|
|
46
59
|
return item;
|
|
47
60
|
case _tokens.treeDataTypes.ArrowLeft:
|
|
48
|
-
return
|
|
61
|
+
return headlessTree.get(item.parentValue);
|
|
49
62
|
case _tokens.treeDataTypes.ArrowRight:
|
|
50
63
|
return visibleItems[item.index + 1];
|
|
51
64
|
case _tokens.treeDataTypes.End:
|
|
@@ -63,7 +76,7 @@ function useHeadlessFlatTree_unstable(flatTreeItemProps, options = {}) {
|
|
|
63
76
|
var _treeRef_current;
|
|
64
77
|
return (_treeRef_current = treeRef.current) === null || _treeRef_current === void 0 ? void 0 : _treeRef_current.querySelector(`[${_getTreeItemValueFromElement.dataTreeItemValueAttrName}="${item.value}"]`);
|
|
65
78
|
}, []);
|
|
66
|
-
const ref = (0, _reactUtilities.useMergedRefs)(treeRef,
|
|
79
|
+
const ref = (0, _reactUtilities.useMergedRefs)(treeRef, initializeWalker);
|
|
67
80
|
const getTreeProps = _react.useCallback(()=>({
|
|
68
81
|
ref,
|
|
69
82
|
openItems,
|
|
@@ -77,12 +90,16 @@ function useHeadlessFlatTree_unstable(flatTreeItemProps, options = {}) {
|
|
|
77
90
|
openItems,
|
|
78
91
|
checkedItems
|
|
79
92
|
]);
|
|
80
|
-
const items = _react.useCallback(()=>
|
|
93
|
+
const items = _react.useCallback(()=>headlessTree.visibleItems(openItems), [
|
|
81
94
|
openItems,
|
|
82
|
-
|
|
95
|
+
headlessTree
|
|
83
96
|
]);
|
|
84
97
|
return _react.useMemo(()=>({
|
|
85
|
-
navigate
|
|
98
|
+
navigate: (data)=>{
|
|
99
|
+
if (walkerRef.current) {
|
|
100
|
+
navigate(data, walkerRef.current);
|
|
101
|
+
}
|
|
102
|
+
},
|
|
86
103
|
getTreeProps,
|
|
87
104
|
getNextNavigableItem,
|
|
88
105
|
getElementFromItem,
|