@fluentui/react-tree 9.2.1 → 9.3.1
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 +201 -1
- package/CHANGELOG.md +51 -2
- package/dist/index.d.ts +13 -2
- package/lib/components/FlatTree/useFlatTree.js +57 -2
- package/lib/components/FlatTree/useFlatTree.js.map +1 -1
- package/lib/components/FlatTree/useFlatTreeNavigation.js +28 -14
- package/lib/components/FlatTree/useFlatTreeNavigation.js.map +1 -1
- package/lib/components/FlatTree/useHeadlessFlatTree.js +16 -16
- 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 +7 -7
- package/lib/components/Tree/useTree.js.map +1 -1
- package/lib/components/TreeItem/TreeItem.types.js.map +1 -1
- package/lib/components/TreeItem/useTreeItem.js +51 -25
- package/lib/components/TreeItem/useTreeItem.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/hooks/useRootTree.js +24 -78
- package/lib/hooks/useRootTree.js.map +1 -1
- package/lib/utils/createHTMLElementWalker.js +2 -3
- package/lib/utils/createHTMLElementWalker.js.map +1 -1
- package/lib/utils/createHeadlessTree.js +5 -3
- package/lib/utils/createHeadlessTree.js.map +1 -1
- package/lib/utils/flattenTree.js +1 -2
- package/lib/utils/flattenTree.js.map +1 -1
- package/lib/utils/normalizeOpenItems.js +1 -2
- package/lib/utils/normalizeOpenItems.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTree.js +57 -2
- package/lib-commonjs/components/FlatTree/useFlatTree.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useFlatTreeNavigation.js +27 -13
- package/lib-commonjs/components/FlatTree/useFlatTreeNavigation.js.map +1 -1
- package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js +16 -16
- package/lib-commonjs/components/FlatTree/useHeadlessFlatTree.js.map +1 -1
- package/lib-commonjs/components/Tree/useTree.js +7 -7
- package/lib-commonjs/components/Tree/useTree.js.map +1 -1
- package/lib-commonjs/components/TreeItem/useTreeItem.js +50 -24
- package/lib-commonjs/components/TreeItem/useTreeItem.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/hooks/useRootTree.js +24 -78
- package/lib-commonjs/hooks/useRootTree.js.map +1 -1
- package/lib-commonjs/utils/createHTMLElementWalker.js +2 -3
- package/lib-commonjs/utils/createHTMLElementWalker.js.map +1 -1
- package/lib-commonjs/utils/createHeadlessTree.js +5 -3
- package/lib-commonjs/utils/createHeadlessTree.js.map +1 -1
- package/lib-commonjs/utils/flattenTree.js +1 -2
- package/lib-commonjs/utils/flattenTree.js.map +1 -1
- package/lib-commonjs/utils/normalizeOpenItems.js +1 -2
- package/lib-commonjs/utils/normalizeOpenItems.js.map +1 -1
- package/package.json +15 -15
package/lib/hooks/useRootTree.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { getNativeElementProps, useEventCallback, slot } from '@fluentui/react-utilities';
|
|
2
2
|
import * as React from 'react';
|
|
3
|
-
import * as ReactDOM from 'react-dom';
|
|
4
3
|
import { createOpenItems } from '../utils/createOpenItems';
|
|
5
4
|
import { createCheckedItems } from '../utils/createCheckedItems';
|
|
6
5
|
import { treeDataTypes } from '../utils/tokens';
|
|
6
|
+
import { createNextOpenItems } from './useControllableOpenItems';
|
|
7
7
|
/**
|
|
8
8
|
* Create the state required to render the root level tree.
|
|
9
9
|
*
|
|
@@ -19,16 +19,20 @@ import { treeDataTypes } from '../utils/tokens';
|
|
|
19
19
|
props.checkedItems
|
|
20
20
|
]);
|
|
21
21
|
const requestOpenChange = (data)=>{
|
|
22
|
-
var _props_onOpenChange
|
|
23
|
-
|
|
22
|
+
var _props_onOpenChange;
|
|
23
|
+
const nextOpenItems = createNextOpenItems(data, openItems);
|
|
24
|
+
(_props_onOpenChange = props.onOpenChange) === null || _props_onOpenChange === void 0 ? void 0 : _props_onOpenChange.call(props, data.event, {
|
|
25
|
+
...data,
|
|
26
|
+
openItems: nextOpenItems.dangerouslyGetInternalSet_unstable()
|
|
27
|
+
});
|
|
24
28
|
};
|
|
25
29
|
const requestCheckedChange = (data)=>{
|
|
26
|
-
var _props_onCheckedChange
|
|
27
|
-
return (_props_onCheckedChange =
|
|
30
|
+
var _props_onCheckedChange;
|
|
31
|
+
return (_props_onCheckedChange = props.onCheckedChange) === null || _props_onCheckedChange === void 0 ? void 0 : _props_onCheckedChange.call(props, data.event, data);
|
|
28
32
|
};
|
|
29
33
|
const requestNavigation = (data)=>{
|
|
30
|
-
var _props_onNavigation
|
|
31
|
-
(_props_onNavigation =
|
|
34
|
+
var _props_onNavigation;
|
|
35
|
+
(_props_onNavigation = props.onNavigation) === null || _props_onNavigation === void 0 ? void 0 : _props_onNavigation.call(props, data.event, data);
|
|
32
36
|
switch(data.type){
|
|
33
37
|
case treeDataTypes.ArrowDown:
|
|
34
38
|
case treeDataTypes.ArrowUp:
|
|
@@ -40,79 +44,21 @@ import { treeDataTypes } from '../utils/tokens';
|
|
|
40
44
|
}
|
|
41
45
|
};
|
|
42
46
|
const requestTreeResponse = useEventCallback((request)=>{
|
|
43
|
-
switch(request.
|
|
44
|
-
case
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
...request,
|
|
55
|
-
type: treeDataTypes.Click
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
}
|
|
59
|
-
case treeDataTypes.ArrowRight:
|
|
60
|
-
{
|
|
61
|
-
if (request.itemType === 'leaf') {
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
const open = openItems.has(request.value);
|
|
65
|
-
if (!open) {
|
|
66
|
-
return requestOpenChange({
|
|
67
|
-
...request,
|
|
68
|
-
open: true,
|
|
69
|
-
openItems: openItems.dangerouslyGetInternalSet_unstable()
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
return requestNavigation(request);
|
|
73
|
-
}
|
|
74
|
-
case treeDataTypes.Enter:
|
|
75
|
-
{
|
|
76
|
-
const open = openItems.has(request.value);
|
|
77
|
-
return requestOpenChange({
|
|
78
|
-
...request,
|
|
79
|
-
open: request.itemType === 'branch' && !open,
|
|
80
|
-
openItems: openItems.dangerouslyGetInternalSet_unstable()
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
case treeDataTypes.ArrowLeft:
|
|
84
|
-
{
|
|
85
|
-
const open = openItems.has(request.value);
|
|
86
|
-
if (open && request.itemType === 'branch') {
|
|
87
|
-
return requestOpenChange({
|
|
88
|
-
...request,
|
|
89
|
-
open: false,
|
|
90
|
-
type: treeDataTypes.ArrowLeft,
|
|
91
|
-
openItems: openItems.dangerouslyGetInternalSet_unstable()
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
return requestNavigation({
|
|
95
|
-
...request,
|
|
96
|
-
type: treeDataTypes.ArrowLeft
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
case treeDataTypes.End:
|
|
100
|
-
case treeDataTypes.Home:
|
|
101
|
-
case treeDataTypes.ArrowUp:
|
|
102
|
-
case treeDataTypes.ArrowDown:
|
|
103
|
-
case treeDataTypes.TypeAhead:
|
|
104
|
-
return requestNavigation({
|
|
47
|
+
switch(request.requestType){
|
|
48
|
+
case 'navigate':
|
|
49
|
+
return requestNavigation(request);
|
|
50
|
+
case 'open':
|
|
51
|
+
return requestOpenChange({
|
|
52
|
+
...request,
|
|
53
|
+
open: request.itemType === 'branch' && !openItems.has(request.value),
|
|
54
|
+
openItems: openItems.dangerouslyGetInternalSet_unstable()
|
|
55
|
+
});
|
|
56
|
+
case 'selection':
|
|
57
|
+
return requestCheckedChange({
|
|
105
58
|
...request,
|
|
106
|
-
|
|
59
|
+
selectionMode: selectionMode,
|
|
60
|
+
checkedItems: checkedItems.dangerouslyGetInternalMap_unstable()
|
|
107
61
|
});
|
|
108
|
-
case treeDataTypes.Change:
|
|
109
|
-
{
|
|
110
|
-
return requestCheckedChange({
|
|
111
|
-
...request,
|
|
112
|
-
selectionMode: selectionMode,
|
|
113
|
-
checkedItems: checkedItems.dangerouslyGetInternalMap_unstable()
|
|
114
|
-
});
|
|
115
|
-
}
|
|
116
62
|
}
|
|
117
63
|
});
|
|
118
64
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useRootTree.ts"],"sourcesContent":["import { SelectionMode, getNativeElementProps, useEventCallback, slot } from '@fluentui/react-utilities';\nimport type {\n TreeCheckedChangeData,\n TreeNavigationData_unstable,\n TreeOpenChangeData,\n TreeProps,\n TreeState,\n} from '../Tree';\nimport * as React from 'react';\nimport
|
|
1
|
+
{"version":3,"sources":["useRootTree.ts"],"sourcesContent":["import { SelectionMode, getNativeElementProps, useEventCallback, slot } from '@fluentui/react-utilities';\nimport type {\n TreeCheckedChangeData,\n TreeNavigationData_unstable,\n TreeOpenChangeData,\n TreeProps,\n TreeState,\n} from '../Tree';\nimport * as React from 'react';\nimport { TreeItemRequest } from '../contexts/treeContext';\nimport { createOpenItems } from '../utils/createOpenItems';\nimport { createCheckedItems } from '../utils/createCheckedItems';\nimport { treeDataTypes } from '../utils/tokens';\nimport { createNextOpenItems } from './useControllableOpenItems';\n\n/**\n * Create the state required to render the root level tree.\n *\n * @param props - props from this instance of tree\n * @param ref - reference to root HTMLElement of tree\n */\nexport function useRootTree(\n props: Pick<\n TreeProps,\n | 'selectionMode'\n | 'appearance'\n | 'size'\n | 'openItems'\n | 'checkedItems'\n | 'onOpenChange'\n | 'onCheckedChange'\n | 'onNavigation'\n | 'aria-label'\n | 'aria-labelledby'\n >,\n\n ref: React.Ref<HTMLElement>,\n): Omit<TreeState, 'treeType'> {\n warnIfNoProperPropsRootTree(props);\n\n const { appearance = 'subtle', size = 'medium', selectionMode = 'none' } = props;\n\n const openItems = React.useMemo(() => createOpenItems(props.openItems), [props.openItems]);\n const checkedItems = React.useMemo(() => createCheckedItems(props.checkedItems), [props.checkedItems]);\n const requestOpenChange = (data: TreeOpenChangeData) => {\n const nextOpenItems = createNextOpenItems(data, openItems);\n props.onOpenChange?.(data.event, {\n ...data,\n openItems: nextOpenItems.dangerouslyGetInternalSet_unstable(),\n });\n };\n\n const requestCheckedChange = (data: TreeCheckedChangeData) => props.onCheckedChange?.(data.event, data);\n\n const requestNavigation = (data: TreeNavigationData_unstable) => {\n props.onNavigation?.(data.event, data);\n switch (data.type) {\n case treeDataTypes.ArrowDown:\n case treeDataTypes.ArrowUp:\n case treeDataTypes.Home:\n case treeDataTypes.End:\n // stop the default behavior of the event\n // which is to scroll the page\n data.event.preventDefault();\n }\n };\n\n const requestTreeResponse = useEventCallback((request: TreeItemRequest) => {\n switch (request.requestType) {\n case 'navigate':\n return requestNavigation(request);\n case 'open':\n return requestOpenChange({\n ...request,\n open: request.itemType === 'branch' && !openItems.has(request.value),\n openItems: openItems.dangerouslyGetInternalSet_unstable(),\n });\n case 'selection':\n return requestCheckedChange({\n ...request,\n selectionMode: selectionMode as SelectionMode,\n checkedItems: checkedItems.dangerouslyGetInternalMap_unstable(),\n } as TreeCheckedChangeData);\n }\n });\n\n return {\n components: {\n root: 'div',\n },\n selectionMode,\n open: true,\n appearance,\n size,\n level: 1,\n openItems,\n checkedItems,\n requestTreeResponse,\n root: slot.always(\n getNativeElementProps('div', {\n ref,\n role: 'tree',\n 'aria-multiselectable': selectionMode === 'multiselect' ? true : undefined,\n ...props,\n }),\n { elementType: 'div' },\n ),\n };\n}\n\nfunction warnIfNoProperPropsRootTree(props: Pick<TreeProps, 'aria-label' | 'aria-labelledby'>) {\n if (process.env.NODE_ENV === 'development') {\n if (!props['aria-label'] && !props['aria-labelledby']) {\n // eslint-disable-next-line no-console\n console.warn(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [useRootTree]:\n Tree must have either a \\`aria-label\\` or \\`aria-labelledby\\` property defined\n `);\n }\n }\n}\n"],"names":["getNativeElementProps","useEventCallback","slot","React","createOpenItems","createCheckedItems","treeDataTypes","createNextOpenItems","useRootTree","props","ref","warnIfNoProperPropsRootTree","appearance","size","selectionMode","openItems","useMemo","checkedItems","requestOpenChange","data","nextOpenItems","onOpenChange","event","dangerouslyGetInternalSet_unstable","requestCheckedChange","onCheckedChange","requestNavigation","onNavigation","type","ArrowDown","ArrowUp","Home","End","preventDefault","requestTreeResponse","request","requestType","open","itemType","has","value","dangerouslyGetInternalMap_unstable","components","root","level","always","role","undefined","elementType","process","env","NODE_ENV","console","warn"],"mappings":"AAAA,SAAwBA,qBAAqB,EAAEC,gBAAgB,EAAEC,IAAI,QAAQ,4BAA4B;AAQzG,YAAYC,WAAW,QAAQ;AAE/B,SAASC,eAAe,QAAQ,2BAA2B;AAC3D,SAASC,kBAAkB,QAAQ,8BAA8B;AACjE,SAASC,aAAa,QAAQ,kBAAkB;AAChD,SAASC,mBAAmB,QAAQ,6BAA6B;AAEjE;;;;;CAKC,GACD,OAAO,SAASC,YACdC,KAYC,EAEDC,GAA2B;IAE3BC,4BAA4BF;IAE5B,MAAM,EAAEG,aAAa,QAAQ,EAAEC,OAAO,QAAQ,EAAEC,gBAAgB,MAAM,EAAE,GAAGL;IAE3E,MAAMM,YAAYZ,MAAMa,OAAO,CAAC,IAAMZ,gBAAgBK,MAAMM,SAAS,GAAG;QAACN,MAAMM,SAAS;KAAC;IACzF,MAAME,eAAed,MAAMa,OAAO,CAAC,IAAMX,mBAAmBI,MAAMQ,YAAY,GAAG;QAACR,MAAMQ,YAAY;KAAC;IACrG,MAAMC,oBAAoB,CAACC;YAEzBV;QADA,MAAMW,gBAAgBb,oBAAoBY,MAAMJ;SAChDN,sBAAAA,MAAMY,YAAY,cAAlBZ,0CAAAA,yBAAAA,OAAqBU,KAAKG,KAAK,EAAE;YAC/B,GAAGH,IAAI;YACPJ,WAAWK,cAAcG,kCAAkC;QAC7D;IACF;IAEA,MAAMC,uBAAuB,CAACL;YAAgCV;gBAAAA,yBAAAA,MAAMgB,eAAe,cAArBhB,6CAAAA,4BAAAA,OAAwBU,KAAKG,KAAK,EAAEH;;IAElG,MAAMO,oBAAoB,CAACP;YACzBV;SAAAA,sBAAAA,MAAMkB,YAAY,cAAlBlB,0CAAAA,yBAAAA,OAAqBU,KAAKG,KAAK,EAAEH;QACjC,OAAQA,KAAKS,IAAI;YACf,KAAKtB,cAAcuB,SAAS;YAC5B,KAAKvB,cAAcwB,OAAO;YAC1B,KAAKxB,cAAcyB,IAAI;YACvB,KAAKzB,cAAc0B,GAAG;gBACpB,yCAAyC;gBACzC,8BAA8B;gBAC9Bb,KAAKG,KAAK,CAACW,cAAc;QAC7B;IACF;IAEA,MAAMC,sBAAsBjC,iBAAiB,CAACkC;QAC5C,OAAQA,QAAQC,WAAW;YACzB,KAAK;gBACH,OAAOV,kBAAkBS;YAC3B,KAAK;gBACH,OAAOjB,kBAAkB;oBACvB,GAAGiB,OAAO;oBACVE,MAAMF,QAAQG,QAAQ,KAAK,YAAY,CAACvB,UAAUwB,GAAG,CAACJ,QAAQK,KAAK;oBACnEzB,WAAWA,UAAUQ,kCAAkC;gBACzD;YACF,KAAK;gBACH,OAAOC,qBAAqB;oBAC1B,GAAGW,OAAO;oBACVrB,eAAeA;oBACfG,cAAcA,aAAawB,kCAAkC;gBAC/D;QACJ;IACF;IAEA,OAAO;QACLC,YAAY;YACVC,MAAM;QACR;QACA7B;QACAuB,MAAM;QACNzB;QACAC;QACA+B,OAAO;QACP7B;QACAE;QACAiB;QACAS,MAAMzC,KAAK2C,MAAM,CACf7C,sBAAsB,OAAO;YAC3BU;YACAoC,MAAM;YACN,wBAAwBhC,kBAAkB,gBAAgB,OAAOiC;YACjE,GAAGtC,KAAK;QACV,IACA;YAAEuC,aAAa;QAAM;IAEzB;AACF;AAEA,SAASrC,4BAA4BF,KAAwD;IAC3F,IAAIwC,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QAC1C,IAAI,CAAC1C,KAAK,CAAC,aAAa,IAAI,CAACA,KAAK,CAAC,kBAAkB,EAAE;YACrD,sCAAsC;YACtC2C,QAAQC,IAAI,CAAsB,CAAC;8EAGnC,CAAC;QACH;IACF;AACF"}
|
|
@@ -3,13 +3,12 @@ export function createHTMLElementWalker(root, targetDocument, filter = ()=>NodeF
|
|
|
3
3
|
let temporaryFilter;
|
|
4
4
|
const treeWalker = targetDocument.createTreeWalker(root, NodeFilter.SHOW_ELEMENT, {
|
|
5
5
|
acceptNode (node) {
|
|
6
|
-
var _temporaryFilter;
|
|
7
6
|
if (!isHTMLElement(node)) {
|
|
8
7
|
return NodeFilter.FILTER_REJECT;
|
|
9
8
|
}
|
|
10
9
|
const filterResult = filter(node);
|
|
11
|
-
var
|
|
12
|
-
return filterResult === NodeFilter.FILTER_ACCEPT ? (
|
|
10
|
+
var _temporaryFilter;
|
|
11
|
+
return filterResult === NodeFilter.FILTER_ACCEPT ? (_temporaryFilter = temporaryFilter === null || temporaryFilter === void 0 ? void 0 : temporaryFilter(node)) !== null && _temporaryFilter !== void 0 ? _temporaryFilter : filterResult : filterResult;
|
|
13
12
|
}
|
|
14
13
|
});
|
|
15
14
|
return {
|
|
@@ -1 +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 targetDocument: Document,\n filter: HTMLElementFilter = () => NodeFilter.FILTER_ACCEPT,\n): HTMLElementWalker {\n let temporaryFilter: HTMLElementFilter | undefined;\n const treeWalker = targetDocument.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","targetDocument","filter","NodeFilter","FILTER_ACCEPT","temporaryFilter","treeWalker","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,cAAwB,EACxBC,SAA4B,IAAMC,WAAWC,aAAa;IAE1D,IAAIC;IACJ,MAAMC,aAAaL,eAAeM,gBAAgB,CAACP,MAAMG,WAAWK,YAAY,EAAE;QAChFC,YAAWC,IAAU;
|
|
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 targetDocument: Document,\n filter: HTMLElementFilter = () => NodeFilter.FILTER_ACCEPT,\n): HTMLElementWalker {\n let temporaryFilter: HTMLElementFilter | undefined;\n const treeWalker = targetDocument.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","targetDocument","filter","NodeFilter","FILTER_ACCEPT","temporaryFilter","treeWalker","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,cAAwB,EACxBC,SAA4B,IAAMC,WAAWC,aAAa;IAE1D,IAAIC;IACJ,MAAMC,aAAaL,eAAeM,gBAAgB,CAACP,MAAMG,WAAWK,YAAY,EAAE;QAChFC,YAAWC,IAAU;YACnB,IAAI,CAACZ,cAAcY,OAAO;gBACxB,OAAOP,WAAWQ,aAAa;YACjC;YACA,MAAMC,eAAeV,OAAOQ;gBACuBL;YAAnD,OAAOO,iBAAiBT,WAAWC,aAAa,GAAGC,CAAAA,mBAAAA,4BAAAA,sCAAAA,gBAAkBK,mBAAlBL,8BAAAA,mBAA2BO,eAAeA;QAC/F;IACF;IACA,OAAO;QACL,IAAIZ,QAAO;YACT,OAAOM,WAAWN,IAAI;QACxB;QACA,IAAIa,kBAAiB;YACnB,OAAOP,WAAWQ,WAAW;QAC/B;QACA,IAAID,gBAAeE,QAAS;YAC1BT,WAAWQ,WAAW,GAAGC;QAC3B;QACAC,YAAYC,CAAAA;YACVZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWU,UAAU;YACpCX,kBAAkBc;YAClB,OAAOD;QACT;QACAE,WAAWH,CAAAA;YACTZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWc,SAAS;YACnCf,kBAAkBc;YAClB,OAAOD;QACT;QACAG,aAAaJ,CAAAA;YACXZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWgB,QAAQ;YAClCjB,kBAAkBc;YAClB,OAAOD;QACT;QACAK,aAAaN,CAAAA;YACXZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWiB,WAAW;YACrClB,kBAAkBc;YAClB,OAAOD;QACT;QACAM,eAAeP,CAAAA;YACbZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWmB,UAAU;YACpCpB,kBAAkBc;YAClB,OAAOD;QACT;QACAQ,iBAAiBT,CAAAA;YACfZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWqB,YAAY;YACtCtB,kBAAkBc;YAClB,OAAOD;QACT;QACAU,iBAAiBX,CAAAA;YACfZ,kBAAkBY;YAClB,MAAMC,SAASZ,WAAWsB,eAAe;YACzCvB,kBAAkBc;YAClB,OAAOD;QACT;IACF;AACF"}
|
|
@@ -9,15 +9,15 @@
|
|
|
9
9
|
root
|
|
10
10
|
]
|
|
11
11
|
]);
|
|
12
|
-
var _itemsPerValue_get_parentValue, _itemsPerValue_get;
|
|
13
12
|
const headlessTree = {
|
|
14
13
|
root,
|
|
15
14
|
get size () {
|
|
16
15
|
return itemsPerValue.size;
|
|
17
16
|
},
|
|
18
17
|
getParent: (key)=>{
|
|
19
|
-
var
|
|
20
|
-
|
|
18
|
+
var _itemsPerValue_get;
|
|
19
|
+
var _itemsPerValue_get_parentValue, _itemsPerValue_get1;
|
|
20
|
+
return (_itemsPerValue_get1 = itemsPerValue.get((_itemsPerValue_get_parentValue = (_itemsPerValue_get = itemsPerValue.get(key)) === null || _itemsPerValue_get === void 0 ? void 0 : _itemsPerValue_get.parentValue) !== null && _itemsPerValue_get_parentValue !== void 0 ? _itemsPerValue_get_parentValue : root.value)) !== null && _itemsPerValue_get1 !== void 0 ? _itemsPerValue_get1 : root;
|
|
21
21
|
},
|
|
22
22
|
get: (key)=>itemsPerValue.get(key),
|
|
23
23
|
has: (key)=>itemsPerValue.has(key),
|
|
@@ -38,6 +38,7 @@ TreeItem "${props.value}" is wrongly positioned, did you properly ordered provid
|
|
|
38
38
|
value: props.value,
|
|
39
39
|
getTreeItemProps: ()=>({
|
|
40
40
|
...propsWithoutParentValue,
|
|
41
|
+
parentValue,
|
|
41
42
|
'aria-level': item.level,
|
|
42
43
|
'aria-posinset': item.position,
|
|
43
44
|
'aria-setsize': parentItem.childrenValues.length,
|
|
@@ -97,6 +98,7 @@ Internal error, trying to access treeitem props from invalid root element`);
|
|
|
97
98
|
}
|
|
98
99
|
return {
|
|
99
100
|
id: headlessTreeRootId,
|
|
101
|
+
parentValue: undefined,
|
|
100
102
|
value: headlessTreeRootId,
|
|
101
103
|
'aria-setsize': -1,
|
|
102
104
|
'aria-level': -1,
|
|
@@ -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 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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n TreeItem \"${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: propsWithoutParentValue.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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\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;IAE1B,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;mBAAlBA,CAAAA,qBAAAA,cAAcO,GAAG,CAACP,CAAAA,kCAAAA,sBAAAA,cAAcO,GAAG,CAACD,kBAAlBN,0CAAAA,oBAAwBQ,WAAW,cAAnCR,4CAAAA,iCAAuCF,KAAKI,KAAK,eAAnEF,gCAAAA,qBAAwEF;;QAC1FS,KAAKD,CAAAA,MAAON,cAAcO,GAAG,CAACD;QAC9BG,KAAKH,CAAAA,MAAON,cAAcS,GAAG,CAACH;QAC9BI,KAAIC,KAAK;YACP,MAAM,EAAEH,cAAcI,kBAAkB,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,CAAsB,CAAC;UAExB,EAAER,MAAMT,KAAK,CAAC,kJAC1B,CAAC;gBACH;gBACA;YACF;YACAY,WAAWM,QAAQ,GAAG;gBAWVP;YATZ,MAAMQ,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,UAAUP,CAAAA,oCAAAA,wBAAwBO,QAAQ,cAAhCP,+CAAAA,oCAAoC;gBAC9CU,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;AAEA,OAAO,MAAMS,qBAAqB,wBAAwB;AAE1D,SAASb;IACP,OAAO;QACLS,aAAagC;QACbtC,OAAOU;QACPQ,UAAU;QACVE,kBAAkB;YAChB,IAAIP,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAsB,CAAC;yEAGpC,CAAC;YACH;YACA,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,CAAsB,CAAC;yEAGpC,CAAC;YACH;YACA,OAAO,CAAC;QACV;QACA,IAAIK,YAAW;YACb,IAAIT,QAAQC,GAAG,CAACC,QAAQ,KAAK,cAAc;gBACzC,sCAAsC;gBACtCC,QAAQC,KAAK,CAAsB,CAAC;yEAGpC,CAAC;YACH;YACA,OAAO,CAAC;QACV;QACAI,OAAO;IACT;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUQ,6BACRzB,GAAkB,EAClBoC,gBAAqC;IAErC,MAAMrB,OAAOqB,iBAAiBnC,GAAG,CAACD;IAClC,IAAI,CAACe,QAAQA,KAAKI,cAAc,CAACC,MAAM,KAAK,GAAG;QAC7C;IACF;IACA,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;IAErC,MAAMrB,OAAOqB,iBAAiBnC,GAAG,CAACD;IAClC,IAAI,CAACe,QAAQA,KAAKI,cAAc,CAACC,MAAM,KAAK,GAAG;QAC7C;IACF;IACA,KAAK,MAAMiB,cAActB,KAAKI,cAAc,CAAE;QAC5C,MAAMiB,iBAAiBnC,GAAG,CAACoC;IAC7B;AACF;AAEA;;;CAGC,GACD,gEAAgE;AAChE,UAAUR,+BACR7B,GAAkB,EAClBoC,gBAAqC;IAErC,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;IAErC,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;IACF;AACF;AAEA,SAASwB,cACPxB,IAA6C,EAC7CgB,SAAsC,EACtCK,gBAAqD;IAErD,IAAIrB,KAAKE,KAAK,KAAK,GAAG;QACpB,OAAO;IACT;IACA,MAAOF,KAAKb,WAAW,IAAIa,KAAKb,WAAW,KAAKkC,iBAAiB5C,IAAI,CAACI,KAAK,CAAE;QAC3E,IAAI,CAACmC,UAAU5B,GAAG,CAACY,KAAKb,WAAW,GAAG;YACpC,OAAO;QACT;QACA,MAAMoC,SAASF,iBAAiBnC,GAAG,CAACc,KAAKb,WAAW;QACpD,IAAI,CAACoC,QAAQ;YACX,OAAO;QACT;QACAvB,OAAOuB;IACT;IACA,OAAO;AACT"}
|
|
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 Props;\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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n TreeItem \"${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 parentValue,\n 'aria-level': item.level,\n 'aria-posinset': item.position,\n 'aria-setsize': parentItem.childrenValues.length,\n itemType: item.itemType,\n }),\n itemType: propsWithoutParentValue.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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\n }\n return {\n id: headlessTreeRootId,\n parentValue: undefined,\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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\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(/* #__DE-INDENT__ */ `\n @fluentui/react-tree [createHeadlessTree]:\n Internal error, trying to access treeitem props from invalid root element\n `);\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":"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"}
|
package/lib/utils/flattenTree.js
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
function flattenTreeRecursive(items, parent, level = 1) {
|
|
2
2
|
return items.reduce((acc, { subtree, ...item }, index)=>{
|
|
3
|
-
var _parent;
|
|
4
3
|
const flatTreeItem = {
|
|
5
4
|
'aria-level': level,
|
|
6
5
|
'aria-posinset': index + 1,
|
|
7
6
|
'aria-setsize': items.length,
|
|
8
|
-
parentValue:
|
|
7
|
+
parentValue: parent === null || parent === void 0 ? void 0 : parent.value,
|
|
9
8
|
...item
|
|
10
9
|
};
|
|
11
10
|
acc.push(flatTreeItem);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["flattenTree.ts"],"sourcesContent":["import { HeadlessFlatTreeItemProps } from '../FlatTree';\nimport { TreeItemProps, TreeItemValue } from '../TreeItem';\n\nexport type FlattenTreeItem<Props extends TreeItemProps> = Omit<Props, 'subtree' | 'itemType'> & {\n value: TreeItemValue;\n subtree?: FlattenTreeItem<Props>[];\n};\n\nexport type FlattenedTreeItem<Props extends TreeItemProps> = HeadlessFlatTreeItemProps & Props;\n\nfunction flattenTreeRecursive<Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n parent?: HeadlessFlatTreeItemProps & Props,\n level = 1,\n): FlattenedTreeItem<Props>[] {\n return items.reduce<FlattenedTreeItem<Props>[]>((acc, { subtree, ...item }, index) => {\n const flatTreeItem = {\n 'aria-level': level,\n 'aria-posinset': index + 1,\n 'aria-setsize': items.length,\n parentValue: parent?.value,\n ...item,\n } as FlattenedTreeItem<Props>;\n acc.push(flatTreeItem);\n if (subtree !== undefined) {\n acc.push(...flattenTreeRecursive<Props>(subtree, flatTreeItem, level + 1));\n }\n return acc;\n }, []);\n}\n\n/**\n * Converts a nested structure to a flat one which can be consumed by `useFlatTreeItems`\n * @example\n * ```tsx\n * const defaultItems = flattenTree_unstable([\n * {\n * children: <TreeItemLayout>level 1, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 2</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 3</TreeItemLayout>,\n * },\n * ],\n * },\n * {\n * children: <TreeItemLayout>level 1, item 2</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 3, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 4, item 1</TreeItemLayout>,\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * },\n * ]);\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const flattenTree_unstable = <Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n): FlattenedTreeItem<Props>[] => flattenTreeRecursive(items);\n"],"names":["flattenTreeRecursive","items","parent","level","reduce","acc","subtree","item","index","flatTreeItem","length","parentValue","value","push","undefined","flattenTree_unstable"],"mappings":"AAUA,SAASA,qBACPC,KAA+B,EAC/BC,MAA0C,EAC1CC,QAAQ,CAAC;IAET,OAAOF,MAAMG,MAAM,CAA6B,CAACC,KAAK,EAAEC,OAAO,EAAE,GAAGC,MAAM,EAAEC;
|
|
1
|
+
{"version":3,"sources":["flattenTree.ts"],"sourcesContent":["import { HeadlessFlatTreeItemProps } from '../FlatTree';\nimport { TreeItemProps, TreeItemValue } from '../TreeItem';\n\nexport type FlattenTreeItem<Props extends TreeItemProps> = Omit<Props, 'subtree' | 'itemType'> & {\n value: TreeItemValue;\n subtree?: FlattenTreeItem<Props>[];\n};\n\nexport type FlattenedTreeItem<Props extends TreeItemProps> = HeadlessFlatTreeItemProps & Props;\n\nfunction flattenTreeRecursive<Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n parent?: HeadlessFlatTreeItemProps & Props,\n level = 1,\n): FlattenedTreeItem<Props>[] {\n return items.reduce<FlattenedTreeItem<Props>[]>((acc, { subtree, ...item }, index) => {\n const flatTreeItem = {\n 'aria-level': level,\n 'aria-posinset': index + 1,\n 'aria-setsize': items.length,\n parentValue: parent?.value,\n ...item,\n } as FlattenedTreeItem<Props>;\n acc.push(flatTreeItem);\n if (subtree !== undefined) {\n acc.push(...flattenTreeRecursive<Props>(subtree, flatTreeItem, level + 1));\n }\n return acc;\n }, []);\n}\n\n/**\n * Converts a nested structure to a flat one which can be consumed by `useFlatTreeItems`\n * @example\n * ```tsx\n * const defaultItems = flattenTree_unstable([\n * {\n * children: <TreeItemLayout>level 1, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 2</TreeItemLayout>,\n * },\n * {\n * children: <TreeItemLayout>level 2, item 3</TreeItemLayout>,\n * },\n * ],\n * },\n * {\n * children: <TreeItemLayout>level 1, item 2</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 2, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 3, item 1</TreeItemLayout>,\n * subtree: [\n * {\n * children: <TreeItemLayout>level 4, item 1</TreeItemLayout>,\n * },\n * ],\n * },\n * ],\n * },\n * ],\n * },\n * ]);\n * ```\n */\n// eslint-disable-next-line @typescript-eslint/naming-convention\nexport const flattenTree_unstable = <Props extends TreeItemProps>(\n items: FlattenTreeItem<Props>[],\n): FlattenedTreeItem<Props>[] => flattenTreeRecursive(items);\n"],"names":["flattenTreeRecursive","items","parent","level","reduce","acc","subtree","item","index","flatTreeItem","length","parentValue","value","push","undefined","flattenTree_unstable"],"mappings":"AAUA,SAASA,qBACPC,KAA+B,EAC/BC,MAA0C,EAC1CC,QAAQ,CAAC;IAET,OAAOF,MAAMG,MAAM,CAA6B,CAACC,KAAK,EAAEC,OAAO,EAAE,GAAGC,MAAM,EAAEC;QAC1E,MAAMC,eAAe;YACnB,cAAcN;YACd,iBAAiBK,QAAQ;YACzB,gBAAgBP,MAAMS,MAAM;YAC5BC,WAAW,EAAET,mBAAAA,6BAAAA,OAAQU,KAAK;YAC1B,GAAGL,IAAI;QACT;QACAF,IAAIQ,IAAI,CAACJ;QACT,IAAIH,YAAYQ,WAAW;YACzBT,IAAIQ,IAAI,IAAIb,qBAA4BM,SAASG,cAAcN,QAAQ;QACzE;QACA,OAAOE;IACT,GAAG,EAAE;AACP;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuCC,GACD,gEAAgE;AAChE,OAAO,MAAMU,uBAAuB,CAClCd,QAC+BD,qBAAqBC,OAAO"}
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
export function normalizeOpenItems(openSubtrees, options) {
|
|
2
2
|
if (!openSubtrees) {
|
|
3
|
-
|
|
4
|
-
return ((_options = options) === null || _options === void 0 ? void 0 : _options.keepUndefined) ? undefined : [];
|
|
3
|
+
return (options === null || options === void 0 ? void 0 : options.keepUndefined) ? undefined : [];
|
|
5
4
|
}
|
|
6
5
|
return Array.isArray(openSubtrees) ? openSubtrees : [
|
|
7
6
|
openSubtrees
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["normalizeOpenItems.ts"],"sourcesContent":["export function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined?: false;\n },\n): string[];\n\nexport function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined: true;\n },\n): string[] | undefined;\n\nexport function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined?: boolean;\n },\n): string[] | undefined {\n if (!openSubtrees) {\n return options?.keepUndefined ? undefined : [];\n }\n return Array.isArray(openSubtrees) ? openSubtrees : [openSubtrees];\n}\n"],"names":["normalizeOpenItems","openSubtrees","options","keepUndefined","undefined","Array","isArray"],"mappings":"AAcA,OAAO,SAASA,mBACdC,YAAgC,EAChCC,OAEC;IAED,IAAI,CAACD,cAAc;
|
|
1
|
+
{"version":3,"sources":["normalizeOpenItems.ts"],"sourcesContent":["export function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined?: false;\n },\n): string[];\n\nexport function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined: true;\n },\n): string[] | undefined;\n\nexport function normalizeOpenItems(\n openSubtrees?: string | string[],\n options?: {\n keepUndefined?: boolean;\n },\n): string[] | undefined {\n if (!openSubtrees) {\n return options?.keepUndefined ? undefined : [];\n }\n return Array.isArray(openSubtrees) ? openSubtrees : [openSubtrees];\n}\n"],"names":["normalizeOpenItems","openSubtrees","options","keepUndefined","undefined","Array","isArray"],"mappings":"AAcA,OAAO,SAASA,mBACdC,YAAgC,EAChCC,OAEC;IAED,IAAI,CAACD,cAAc;QACjB,OAAOC,CAAAA,oBAAAA,8BAAAA,QAASC,aAAa,IAAGC,YAAY,EAAE;IAChD;IACA,OAAOC,MAAMC,OAAO,CAACL,gBAAgBA,eAAe;QAACA;KAAa;AACpE"}
|
|
@@ -11,9 +11,64 @@ Object.defineProperty(exports, "useFlatTree_unstable", {
|
|
|
11
11
|
const _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard");
|
|
12
12
|
const _react = /*#__PURE__*/ _interop_require_wildcard._(require("react"));
|
|
13
13
|
const _useRootTree = require("../../hooks/useRootTree");
|
|
14
|
+
const _useFlatTreeNavigation = require("./useFlatTreeNavigation");
|
|
15
|
+
const _createHTMLElementWalker = require("../../utils/createHTMLElementWalker");
|
|
16
|
+
const _reactsharedcontexts = require("@fluentui/react-shared-contexts");
|
|
17
|
+
const _treeItemFilter = require("../../utils/treeItemFilter");
|
|
18
|
+
const _reactutilities = require("@fluentui/react-utilities");
|
|
19
|
+
const _treeContext = require("../../contexts/treeContext");
|
|
20
|
+
const _useSubtree = require("../../hooks/useSubtree");
|
|
14
21
|
const useFlatTree_unstable = (props, ref)=>{
|
|
22
|
+
const level = (0, _treeContext.useTreeContext_unstable)((ctx)=>ctx.level);
|
|
23
|
+
// as level is static, this doesn't break rule of hooks
|
|
24
|
+
// and if this becomes an issue later on, this can be easily converted
|
|
25
|
+
// eslint-disable-next-line react-hooks/rules-of-hooks
|
|
26
|
+
return level > 1 ? useSubFlatTree(props, ref) : useRootFlatTree(props, ref);
|
|
27
|
+
};
|
|
28
|
+
function useRootFlatTree(props, ref) {
|
|
29
|
+
const { navigate, initialize } = (0, _useFlatTreeNavigation.useFlatTreeNavigation)();
|
|
30
|
+
const walkerRef = _react.useRef();
|
|
31
|
+
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
|
|
32
|
+
const initializeWalker = _react.useCallback((root)=>{
|
|
33
|
+
if (root && targetDocument) {
|
|
34
|
+
walkerRef.current = (0, _createHTMLElementWalker.createHTMLElementWalker)(root, targetDocument, _treeItemFilter.treeItemFilter);
|
|
35
|
+
initialize(walkerRef.current);
|
|
36
|
+
}
|
|
37
|
+
}, [
|
|
38
|
+
initialize,
|
|
39
|
+
targetDocument
|
|
40
|
+
]);
|
|
41
|
+
const handleNavigation = (0, _reactutilities.useEventCallback)((event, data)=>{
|
|
42
|
+
var _props_onNavigation;
|
|
43
|
+
(_props_onNavigation = props.onNavigation) === null || _props_onNavigation === void 0 ? void 0 : _props_onNavigation.call(props, event, data);
|
|
44
|
+
if (walkerRef.current && !event.isDefaultPrevented()) {
|
|
45
|
+
navigate(data, walkerRef.current);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
15
48
|
return {
|
|
16
49
|
treeType: 'flat',
|
|
17
|
-
...(0, _useRootTree.useRootTree)(
|
|
50
|
+
...(0, _useRootTree.useRootTree)({
|
|
51
|
+
...props,
|
|
52
|
+
onNavigation: handleNavigation
|
|
53
|
+
}, (0, _reactutilities.useMergedRefs)(ref, initializeWalker))
|
|
18
54
|
};
|
|
19
|
-
}
|
|
55
|
+
}
|
|
56
|
+
function useSubFlatTree(props, ref) {
|
|
57
|
+
if (process.env.NODE_ENV === 'development') {
|
|
58
|
+
// eslint-disable-next-line no-console
|
|
59
|
+
console.error(`@fluentui/react-tree [useFlatTree]:
|
|
60
|
+
Subtrees are not allowed in a FlatTree!
|
|
61
|
+
You cannot use a <FlatTree> component inside of another <FlatTree> component.`);
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
...(0, _useSubtree.useSubtree)(props, ref),
|
|
65
|
+
open: false,
|
|
66
|
+
treeType: 'flat',
|
|
67
|
+
components: {
|
|
68
|
+
root: _react.Fragment
|
|
69
|
+
},
|
|
70
|
+
root: _reactutilities.slot.always(undefined, {
|
|
71
|
+
elementType: _react.Fragment
|
|
72
|
+
})
|
|
73
|
+
};
|
|
74
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["useFlatTree.js"],"sourcesContent":["import * as React from 'react';\nimport { useRootTree } from '../../hooks/useRootTree';\nexport const useFlatTree_unstable = (props, ref)=>{\n return {\n treeType: 'flat',\n ...useRootTree(props, ref)\n };\n};\n"],"names":["useFlatTree_unstable","props","ref","treeType","useRootTree"],"mappings":";;;;+
|
|
1
|
+
{"version":3,"sources":["useFlatTree.js"],"sourcesContent":["import * as React from 'react';\nimport { useRootTree } from '../../hooks/useRootTree';\nimport { useFlatTreeNavigation } from './useFlatTreeNavigation';\nimport { createHTMLElementWalker } from '../../utils/createHTMLElementWalker';\nimport { useFluent_unstable } from '@fluentui/react-shared-contexts';\nimport { treeItemFilter } from '../../utils/treeItemFilter';\nimport { slot, useEventCallback, useMergedRefs } from '@fluentui/react-utilities';\nimport { useTreeContext_unstable } from '../../contexts/treeContext';\nimport { useSubtree } from '../../hooks/useSubtree';\nexport const useFlatTree_unstable = (props, ref)=>{\n const level = useTreeContext_unstable((ctx)=>ctx.level);\n // as level is static, this doesn't break rule of hooks\n // and if this becomes an issue later on, this can be easily converted\n // eslint-disable-next-line react-hooks/rules-of-hooks\n return level > 1 ? useSubFlatTree(props, ref) : useRootFlatTree(props, ref);\n};\nfunction useRootFlatTree(props, ref) {\n const { navigate, initialize } = useFlatTreeNavigation();\n const walkerRef = React.useRef();\n const { targetDocument } = useFluent_unstable();\n const initializeWalker = React.useCallback((root)=>{\n if (root && targetDocument) {\n walkerRef.current = createHTMLElementWalker(root, targetDocument, treeItemFilter);\n initialize(walkerRef.current);\n }\n }, [\n initialize,\n targetDocument\n ]);\n const handleNavigation = useEventCallback((event, data)=>{\n var _props_onNavigation;\n (_props_onNavigation = props.onNavigation) === null || _props_onNavigation === void 0 ? void 0 : _props_onNavigation.call(props, event, data);\n if (walkerRef.current && !event.isDefaultPrevented()) {\n navigate(data, walkerRef.current);\n }\n });\n return {\n treeType: 'flat',\n ...useRootTree({\n ...props,\n onNavigation: handleNavigation\n }, useMergedRefs(ref, initializeWalker))\n };\n}\nfunction useSubFlatTree(props, ref) {\n if (process.env.NODE_ENV === 'development') {\n // eslint-disable-next-line no-console\n console.error(`@fluentui/react-tree [useFlatTree]:\nSubtrees are not allowed in a FlatTree!\nYou cannot use a <FlatTree> component inside of another <FlatTree> component.`);\n }\n return {\n ...useSubtree(props, ref),\n open: false,\n treeType: 'flat',\n components: {\n root: React.Fragment\n },\n root: slot.always(undefined, {\n elementType: React.Fragment\n })\n };\n}\n"],"names":["useFlatTree_unstable","props","ref","level","useTreeContext_unstable","ctx","useSubFlatTree","useRootFlatTree","navigate","initialize","useFlatTreeNavigation","walkerRef","React","useRef","targetDocument","useFluent_unstable","initializeWalker","useCallback","root","current","createHTMLElementWalker","treeItemFilter","handleNavigation","useEventCallback","event","data","_props_onNavigation","onNavigation","call","isDefaultPrevented","treeType","useRootTree","useMergedRefs","process","env","NODE_ENV","console","error","useSubtree","open","components","Fragment","slot","always","undefined","elementType"],"mappings":";;;;+BASaA;;;eAAAA;;;;iEATU;6BACK;uCACU;yCACE;qCACL;gCACJ;gCACuB;6BACd;4BACb;AACpB,MAAMA,uBAAuB,CAACC,OAAOC;IACxC,MAAMC,QAAQC,IAAAA,oCAAuB,EAAC,CAACC,MAAMA,IAAIF,KAAK;IACtD,uDAAuD;IACvD,sEAAsE;IACtE,sDAAsD;IACtD,OAAOA,QAAQ,IAAIG,eAAeL,OAAOC,OAAOK,gBAAgBN,OAAOC;AAC3E;AACA,SAASK,gBAAgBN,KAAK,EAAEC,GAAG;IAC/B,MAAM,EAAEM,QAAQ,EAAEC,UAAU,EAAE,GAAGC,IAAAA,4CAAqB;IACtD,MAAMC,YAAYC,OAAMC,MAAM;IAC9B,MAAM,EAAEC,cAAc,EAAE,GAAGC,IAAAA,uCAAkB;IAC7C,MAAMC,mBAAmBJ,OAAMK,WAAW,CAAC,CAACC;QACxC,IAAIA,QAAQJ,gBAAgB;YACxBH,UAAUQ,OAAO,GAAGC,IAAAA,gDAAuB,EAACF,MAAMJ,gBAAgBO,8BAAc;YAChFZ,WAAWE,UAAUQ,OAAO;QAChC;IACJ,GAAG;QACCV;QACAK;KACH;IACD,MAAMQ,mBAAmBC,IAAAA,gCAAgB,EAAC,CAACC,OAAOC;QAC9C,IAAIC;QACHA,CAAAA,sBAAsBzB,MAAM0B,YAAY,AAAD,MAAO,QAAQD,wBAAwB,KAAK,IAAI,KAAK,IAAIA,oBAAoBE,IAAI,CAAC3B,OAAOuB,OAAOC;QACxI,IAAId,UAAUQ,OAAO,IAAI,CAACK,MAAMK,kBAAkB,IAAI;YAClDrB,SAASiB,MAAMd,UAAUQ,OAAO;QACpC;IACJ;IACA,OAAO;QACHW,UAAU;QACV,GAAGC,IAAAA,wBAAW,EAAC;YACX,GAAG9B,KAAK;YACR0B,cAAcL;QAClB,GAAGU,IAAAA,6BAAa,EAAC9B,KAAKc,kBAAkB;IAC5C;AACJ;AACA,SAASV,eAAeL,KAAK,EAAEC,GAAG;IAC9B,IAAI+B,QAAQC,GAAG,CAACC,QAAQ,KAAK,eAAe;QACxC,sCAAsC;QACtCC,QAAQC,KAAK,CAAC,CAAC;;6EAEsD,CAAC;IAC1E;IACA,OAAO;QACH,GAAGC,IAAAA,sBAAU,EAACrC,OAAOC,IAAI;QACzBqC,MAAM;QACNT,UAAU;QACVU,YAAY;YACRtB,MAAMN,OAAM6B,QAAQ;QACxB;QACAvB,MAAMwB,oBAAI,CAACC,MAAM,CAACC,WAAW;YACzBC,aAAajC,OAAM6B,QAAQ;QAC/B;IACJ;AACJ"}
|
|
@@ -15,7 +15,7 @@ const _tokens = require("../../utils/tokens");
|
|
|
15
15
|
const _treeItemFilter = require("../../utils/treeItemFilter");
|
|
16
16
|
const _useRovingTabIndexes = require("../../hooks/useRovingTabIndexes");
|
|
17
17
|
const _getTreeItemValueFromElement = require("../../utils/getTreeItemValueFromElement");
|
|
18
|
-
function useFlatTreeNavigation(
|
|
18
|
+
function useFlatTreeNavigation() {
|
|
19
19
|
const { targetDocument } = (0, _reactsharedcontexts.useFluent_unstable)();
|
|
20
20
|
const { rove, initialize } = (0, _useRovingTabIndexes.useRovingTabIndex)(_treeItemFilter.treeItemFilter);
|
|
21
21
|
function getNextElement(data, walker) {
|
|
@@ -29,10 +29,30 @@ function useFlatTreeNavigation(virtualTree) {
|
|
|
29
29
|
walker.currentElement = data.target;
|
|
30
30
|
return (0, _nextTypeAheadElement.nextTypeAheadElement)(walker, data.event.key);
|
|
31
31
|
case _tokens.treeDataTypes.ArrowLeft:
|
|
32
|
-
|
|
32
|
+
{
|
|
33
|
+
const nextElement = parentElement(data.parentValue, walker);
|
|
34
|
+
if (!nextElement && process.env.NODE_ENV !== 'production') {
|
|
35
|
+
// eslint-disable-next-line no-console
|
|
36
|
+
console.warn(`@fluentui/react-tree [useFlatTreeNavigation]:
|
|
37
|
+
\'ArrowLeft\' navigation was not possible.
|
|
38
|
+
No parent element found for the current element:`, data.target);
|
|
39
|
+
}
|
|
40
|
+
return nextElement;
|
|
41
|
+
}
|
|
33
42
|
case _tokens.treeDataTypes.ArrowRight:
|
|
34
|
-
|
|
35
|
-
|
|
43
|
+
{
|
|
44
|
+
walker.currentElement = data.target;
|
|
45
|
+
const nextElement = firstChild(data.target, walker);
|
|
46
|
+
if (!nextElement && process.env.NODE_ENV !== 'production') {
|
|
47
|
+
const ariaLevel = Number(data.target.getAttribute('aria-level'));
|
|
48
|
+
// eslint-disable-next-line no-console
|
|
49
|
+
console.warn(`@fluentui/react-tree [useFlatTreeNavigation]:
|
|
50
|
+
\'ArrowRight\' navigation was not possible.
|
|
51
|
+
No element with "aria-posinset=1" and "aria-level=${ariaLevel + 1}"
|
|
52
|
+
was found after the current element!`, data.target);
|
|
53
|
+
}
|
|
54
|
+
return nextElement;
|
|
55
|
+
}
|
|
36
56
|
case _tokens.treeDataTypes.End:
|
|
37
57
|
walker.currentElement = walker.root;
|
|
38
58
|
return walker.lastChild();
|
|
@@ -71,15 +91,9 @@ function firstChild(target, treeWalker) {
|
|
|
71
91
|
}
|
|
72
92
|
return null;
|
|
73
93
|
}
|
|
74
|
-
function parentElement(
|
|
75
|
-
|
|
76
|
-
const value = (0, _getTreeItemValueFromElement.getTreeItemValueFromElement)(target);
|
|
77
|
-
if (value === null) {
|
|
94
|
+
function parentElement(parentValue, treeWalker) {
|
|
95
|
+
if (parentValue === undefined) {
|
|
78
96
|
return null;
|
|
79
97
|
}
|
|
80
|
-
|
|
81
|
-
if ((_virtualTreeItem = virtualTreeItem) === null || _virtualTreeItem === void 0 ? void 0 : _virtualTreeItem.parentValue) {
|
|
82
|
-
return treeWalker.root.querySelector(`[${_getTreeItemValueFromElement.dataTreeItemValueAttrName}="${virtualTreeItem.parentValue}"]`);
|
|
83
|
-
}
|
|
84
|
-
return null;
|
|
98
|
+
return treeWalker.root.querySelector(`[${_getTreeItemValueFromElement.dataTreeItemValueAttrName}="${parentValue}"]`);
|
|
85
99
|
}
|
|
@@ -1 +1 @@
|
|
|
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
|
|
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 } from '../../utils/getTreeItemValueFromElement';\nexport function useFlatTreeNavigation() {\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 {\n const nextElement = parentElement(data.parentValue, walker);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n // eslint-disable-next-line no-console\n console.warn(`@fluentui/react-tree [useFlatTreeNavigation]:\n\\'ArrowLeft\\' navigation was not possible.\nNo parent element found for the current element:`, data.target);\n }\n return nextElement;\n }\n case treeDataTypes.ArrowRight:\n {\n walker.currentElement = data.target;\n const nextElement = firstChild(data.target, walker);\n if (!nextElement && process.env.NODE_ENV !== 'production') {\n const ariaLevel = Number(data.target.getAttribute('aria-level'));\n // eslint-disable-next-line no-console\n console.warn(`@fluentui/react-tree [useFlatTreeNavigation]:\n\\'ArrowRight\\' navigation was not possible.\nNo element with \"aria-posinset=1\" and \"aria-level=${ariaLevel + 1}\"\nwas found after the current element!`, data.target);\n }\n return nextElement;\n }\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(parentValue, treeWalker) {\n if (parentValue === undefined) {\n return null;\n }\n return treeWalker.root.querySelector(`[${dataTreeItemValueAttrName}=\"${parentValue}\"]`);\n}\n"],"names":["useFlatTreeNavigation","targetDocument","useFluent_unstable","rove","initialize","useRovingTabIndex","treeItemFilter","getNextElement","data","walker","type","treeDataTypes","Click","target","TypeAhead","currentElement","nextTypeAheadElement","event","key","ArrowLeft","nextElement","parentElement","parentValue","process","env","NODE_ENV","console","warn","ArrowRight","firstChild","ariaLevel","Number","getAttribute","End","root","lastChild","Home","ArrowDown","ArrowUp","previousElement","navigate","useEventCallback","treeWalker","nextElementAriaPosInSet","nextElementAriaLevel","targetAriaLevel","undefined","querySelector","dataTreeItemValueAttrName"],"mappings":"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"}
|