@itwin/presentation-hierarchies-react 2.0.0-alpha.60 → 2.0.0-alpha.62

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.
Files changed (31) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/README.md +7 -23
  3. package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts +1 -1
  4. package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts.map +1 -1
  5. package/lib/presentation-hierarchies-react/FlatTreeNode.js +11 -8
  6. package/lib/presentation-hierarchies-react/FlatTreeNode.js.map +1 -1
  7. package/lib/presentation-hierarchies-react/TreeNode.d.ts +2 -2
  8. package/lib/presentation-hierarchies-react/TreeNode.d.ts.map +1 -1
  9. package/lib/presentation-hierarchies-react/UseTree.d.ts +4 -4
  10. package/lib/presentation-hierarchies-react/UseTree.d.ts.map +1 -1
  11. package/lib/presentation-hierarchies-react/UseTree.js +11 -11
  12. package/lib/presentation-hierarchies-react/UseTree.js.map +1 -1
  13. package/lib/presentation-hierarchies-react/internal/TreeActions.js +2 -7
  14. package/lib/presentation-hierarchies-react/internal/TreeActions.js.map +1 -1
  15. package/lib/presentation-hierarchies-react/internal/TreeLoader.js.map +1 -1
  16. package/lib/presentation-hierarchies-react/internal/TreeModel.js +2 -9
  17. package/lib/presentation-hierarchies-react/internal/TreeModel.js.map +1 -1
  18. package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +1 -1
  19. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts +8 -6
  20. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts.map +1 -1
  21. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js +80 -79
  22. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js.map +1 -1
  23. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts +1 -7
  24. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts.map +1 -1
  25. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js.map +1 -1
  26. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts +1 -1
  27. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js +49 -35
  28. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js.map +1 -1
  29. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +14 -8
  30. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -1
  31. package/package.json +16 -39
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @itwin/presentation-hierarchies-react
2
2
 
3
+ ## 2.0.0-alpha.62
4
+
5
+ ### Patch Changes
6
+
7
+ - [#1304](https://github.com/iTwin/presentation/pull/1304): Remove `@stratakit/bricks` and `@stratakit/structures` from peer dependencies list.
8
+
9
+ Only `@stratakit/foundations` and `@stratakit/icons` are required as peer dependencies when using StrataKit components, the rest of `@stratakit` packages can be used as direct dependencies.
10
+
11
+ - Updated dependencies:
12
+ - @itwin/presentation-hierarchies@2.0.0-alpha.15
13
+ - @itwin/presentation-shared@2.0.0-alpha.10
14
+ - @itwin/unified-selection@1.7.1-alpha.0
15
+
16
+ ## 2.0.0-alpha.61
17
+
18
+ ### Minor Changes
19
+
20
+ - [#1267](https://github.com/iTwin/presentation/pull/1267): `TreeNode` now supports multiple errors via `errors: ErrorInfo[]`, allowing both internal errors and custom errors provided through `getTreeNodeErrors` to be combined and displayed.
21
+
22
+ **Breaking changes:**
23
+
24
+ - `TreeNode.error?: ErrorInfo` replaced by `TreeNode.errors: ErrorInfo[]`.
25
+ - `UseTreeProps.getTreeNodeError` renamed to `getTreeNodeErrors` and now returns `ErrorInfo[]` instead of `ErrorInfo | undefined`.
26
+ - `ErrorItemRendererProps` now provides `treeNode` without `errors` and `error` instead of `errorNode`.
27
+ - `TreeErrorRenderer`'s `renderError` callback is now called once per error (instead of once per node), receiving the updated `ErrorItemRendererProps`.
28
+ - `scrollToNode` callback in `ErrorItemRendererProps` now receives `Omit<TreeNode, "errors">` instead of `TreeNode`.
29
+
3
30
  ## 2.0.0-alpha.60
4
31
 
5
32
  ### Minor Changes
@@ -944,6 +971,22 @@
944
971
 
945
972
  - [#847](https://github.com/iTwin/presentation/pull/847): Moving tree rendering components to a new design systems.
946
973
 
974
+ ## 1.10.1
975
+
976
+ ### Patch Changes
977
+
978
+ - [#1286](https://github.com/iTwin/presentation/pull/1286): Bump dependencies.
979
+ - Updated dependencies:
980
+ - @itwin/presentation-hierarchies@1.7.12
981
+ - @itwin/presentation-shared@1.2.11
982
+ - @itwin/unified-selection@1.7.0
983
+
984
+ ## 1.10.0
985
+
986
+ ### Minor Changes
987
+
988
+ - [#1258](https://github.com/iTwin/presentation/pull/1258): Introduced new import paths: `@itwin/presentation-hierarchies-react/core` and `@itwin/presentation-hierarchies-react/itwinui`. They should allow to use this package without `@itwin/itwinui-react` dependency.
989
+
947
990
  ## 1.9.13
948
991
 
949
992
  ### Patch Changes
package/README.md CHANGED
@@ -64,11 +64,7 @@ The hook takes 2 required properties:
64
64
  import { IModelConnection } from "@itwin/core-frontend";
65
65
  import { createCachingECClassHierarchyInspector } from "@itwin/presentation-shared";
66
66
  import { createECSchemaProvider, createECSqlQueryExecutor, createIModelKey } from "@itwin/presentation-core-interop";
67
- import {
68
- createLimitingECSqlQueryExecutor,
69
- createNodesQueryClauseFactory,
70
- HierarchyDefinition,
71
- } from "@itwin/presentation-hierarchies";
67
+ import { createLimitingECSqlQueryExecutor } from "@itwin/presentation-hierarchies";
72
68
 
73
69
  function createIModelAccess(imodel: IModelConnection) {
74
70
  const schemaProvider = createECSchemaProvider(imodel.schemaContext);
@@ -105,15 +101,9 @@ The component renders a virtualized tree using the `Tree` component from `@strat
105
101
 
106
102
  ```tsx
107
103
  import { IModelConnection } from "@itwin/core-frontend";
108
- import { createCachingECClassHierarchyInspector } from "@itwin/presentation-shared";
104
+ import { createCachingECClassHierarchyInspector, Props } from "@itwin/presentation-shared";
109
105
  import { createECSchemaProvider, createECSqlQueryExecutor, createIModelKey } from "@itwin/presentation-core-interop";
110
- import {
111
- createLimitingECSqlQueryExecutor,
112
- createNodesQueryClauseFactory,
113
- HierarchyDefinition,
114
- } from "@itwin/presentation-hierarchies";
115
-
116
- import { createBisInstanceLabelSelectClauseFactory, Props } from "@itwin/presentation-shared";
106
+ import { createLimitingECSqlQueryExecutor, HierarchyDefinition } from "@itwin/presentation-hierarchies";
117
107
 
118
108
  import { useIModelUnifiedSelectionTree } from "@itwin/presentation-hierarchies-react";
119
109
  import { StrataKitTreeRenderer, StrataKitRootErrorRenderer } from "@itwin/presentation-hierarchies-react/stratakit";
@@ -154,25 +144,19 @@ type IModelAccess = Props<typeof useIModelUnifiedSelectionTree>["imodelAccess"];
154
144
 
155
145
  // The hierarchy definition describes the hierarchy using ECSQL queries; here it just returns all `BisCore.PhysicalModel` instances
156
146
  function getHierarchyDefinition({ imodelAccess }: { imodelAccess: IModelAccess }): HierarchyDefinition {
157
- // Create a factory for building labels SELECT query clauses according to BIS conventions
158
- const labelsQueryFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: imodelAccess });
159
- // Create a factory for building nodes SELECT query clauses in a format understood by the provider
160
- const nodesQueryFactory = createNodesQueryClauseFactory({
161
- imodelAccess,
162
- instanceLabelSelectClauseFactory: labelsQueryFactory,
163
- });
164
147
  return {
165
- defineHierarchyLevel: async () => [
148
+ // The `instanceLabelSelectClauseFactory` and `nodeSelectClauseFactory` are provided automatically by the hierarchy provider
149
+ defineHierarchyLevel: async ({ instanceLabelSelectClauseFactory, nodeSelectClauseFactory }) => [
166
150
  {
167
151
  fullClassName: "BisCore.PhysicalModel",
168
152
  query: {
169
153
  ecsql: `
170
154
  SELECT
171
- ${await nodesQueryFactory.createSelectClause({
155
+ ${await nodeSelectClauseFactory.createSelectClause({
172
156
  ecClassId: { selector: "this.ECClassId" },
173
157
  ecInstanceId: { selector: "this.ECInstanceId" },
174
158
  nodeLabel: {
175
- selector: await labelsQueryFactory.createSelectClause({
159
+ selector: await instanceLabelSelectClauseFactory.createSelectClause({
176
160
  classAlias: "this",
177
161
  className: "BisCore.PhysicalModel",
178
162
  }),
@@ -43,7 +43,7 @@ declare function useFlatTreeItems(rootNodes: TreeNode[]): FlatTreeItem[];
43
43
  *
44
44
  * @alpha
45
45
  */
46
- declare function useErrorNodes(rootNodes: TreeNode[]): Array<TreeNode & Pick<Required<TreeNode>, "error">>;
46
+ declare function useErrorNodes(rootNodes: TreeNode[]): TreeNode[];
47
47
  //#endregion
48
48
  export { FlatTreeItem, useErrorNodes, useFlatTreeItems };
49
49
  //# sourceMappingURL=FlatTreeNode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"FlatTreeNode.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/FlatTreeNode.ts"],"mappings":";;;;;AAO8C;;;UAOpC,mBAAA;EACR,EAAA;EACA,KAAA;EACA,WAAA;AAAA;;AAQF;;;;UAAiB,gBAAA;EACf,EAAA;EACA,KAAA;EACA,SAAA;EACA,UAAA;EACA,IAAA,EAAM,QAAA;AAAA;;AASR;;;;;KAAY,YAAA,GAAe,gBAAA,GAAmB,mBAAA;;;;;;;AAkD9C;iBApCgB,gBAAA,CAAiB,SAAA,EAAW,QAAA,KAAU,YAAA;;;;;;iBAoCtC,aAAA,CAAc,SAAA,EAAW,QAAA,KAAa,KAAA,CAAM,QAAA,GAAW,IAAA,CAAK,QAAA,CAAS,QAAA"}
1
+ {"version":3,"file":"FlatTreeNode.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/FlatTreeNode.ts"],"mappings":";;;;;AAOyD;;;UAO/C,mBAAA;EACR,EAAA;EACA,KAAA;EACA,WAAA;AAAA;;AAQF;;;;UAAiB,gBAAA;EACf,EAAA;EACA,KAAA;EACA,SAAA;EACA,UAAA;EACA,IAAA,EAAM,QAAA;AAAA;;AASR;;;;;KAAY,YAAA,GAAe,gBAAA,GAAmB,mBAAA;;;;;;;AAkD9C;iBApCgB,gBAAA,CAAiB,SAAA,EAAW,QAAA,KAAU,YAAA;;;;;;iBAoCtC,aAAA,CAAc,SAAA,EAAW,QAAA,KAAa,QAAA"}
@@ -32,7 +32,7 @@ function getFlatItems(nodes, level) {
32
32
  posInLevel: index + 1
33
33
  });
34
34
  if (!node.isExpanded) return;
35
- if (node.error && (node.error.type !== "Unknown" || !node.error.isNodeExpandable)) return;
35
+ if (node.errors.some(isErrorBlockingExpansion)) return;
36
36
  if (node.children !== true) {
37
37
  const childNodes = getFlatItems(node.children, level + 1);
38
38
  flatItems.push(...childNodes);
@@ -62,11 +62,11 @@ function useErrorNodes(rootNodes) {
62
62
  return t0;
63
63
  }
64
64
  function _temp(rootNode) {
65
- const errors = isErrorNode(rootNode) ? [rootNode] : [];
66
- if (rootNode.children === true) return errors;
67
- if (errors.length === 1 && (rootNode.error?.type !== "Unknown" || !rootNode.error.isNodeExpandable)) return errors;
68
- errors.push(...getErrorNodes(rootNode));
69
- return errors;
65
+ const errorNodes = isErrorNode(rootNode) ? [rootNode] : [];
66
+ if (rootNode.children === true) return errorNodes;
67
+ if (errorNodes.length === 1 && errorNodes[0].errors.some(isErrorBlockingExpansion)) return errorNodes;
68
+ errorNodes.push(...getErrorNodes(rootNode));
69
+ return errorNodes;
70
70
  }
71
71
  function getErrorNodes(parent) {
72
72
  const errorList = [];
@@ -74,7 +74,7 @@ function getErrorNodes(parent) {
74
74
  parent.children.forEach((node) => {
75
75
  if (isErrorNode(node)) {
76
76
  errorList.push(node);
77
- if (node.error.type !== "Unknown" || !node.error.isNodeExpandable) return;
77
+ if (node.errors.some(isErrorBlockingExpansion)) return;
78
78
  }
79
79
  if (node.children !== true) {
80
80
  const childErrorList = getErrorNodes(node);
@@ -85,7 +85,10 @@ function getErrorNodes(parent) {
85
85
  return errorList;
86
86
  }
87
87
  function isErrorNode(node) {
88
- return node.error !== void 0;
88
+ return node.errors.length > 0;
89
+ }
90
+ function isErrorBlockingExpansion(error) {
91
+ return error.type !== "Unknown" || !error.isNodeExpandable;
89
92
  }
90
93
  //#endregion
91
94
  export { isPlaceholderItem, useErrorNodes, useFlatTreeItems };
@@ -1 +1 @@
1
- {"version":3,"file":"FlatTreeNode.js","names":["useMemo","TreeNode","FlatPlaceholderItem","id","level","placeholder","FlatTreeNodeItem","levelSize","posInLevel","node","FlatTreeItem","isPlaceholderItem","item","useFlatTreeItems","rootNodes","$","_c","t0","getFlatItems","nodes","flatItems","forEach","index","push","length","isExpanded","error","type","isNodeExpandable","children","childNodes","useErrorNodes","flatMap","_temp","rootNode","errors","isErrorNode","getErrorNodes","parent","errorList","ReturnType","childErrorList","Pick","Required","undefined"],"sources":["../../src/presentation-hierarchies-react/FlatTreeNode.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useMemo } from \"react\";\n\nimport type { TreeNode } from \"./TreeNode.js\";\n\n/**\n * Placeholder item that is added to hierarchy as a child for a parent item while its child items are loading.\n *\n * @alpha\n */\ninterface FlatPlaceholderItem {\n id: string;\n level: number;\n placeholder: true;\n}\n\n/**\n * An item containing `TreeNode` node with properties needed for a flat tree structure.\n *\n * @alpha\n */\nexport interface FlatTreeNodeItem {\n id: string;\n level: number;\n levelSize: number;\n posInLevel: number;\n node: TreeNode;\n}\n\n/**\n * An Item describing single tree item position and its content inside tree.\n * Returned by `useFlatTreeNodeList` hook.\n *\n * @alpha\n */\nexport type FlatTreeItem = FlatTreeNodeItem | FlatPlaceholderItem;\n\n/** @alpha */\nexport function isPlaceholderItem(item: FlatTreeItem): item is FlatPlaceholderItem {\n return \"placeholder\" in item;\n}\n\n/**\n * Used to get a list of `FlatTreeItem` objects for the given list of `TreeNode` objects that represent\n * a hierarchical structure. The resulting items can be used to render the hierarchy in a flat manner, e.g. using a\n * virtualized list.\n *\n * @alpha\n */\nexport function useFlatTreeItems(rootNodes: TreeNode[]) {\n return useMemo(() => getFlatItems(rootNodes, 1), [rootNodes]);\n}\n\nfunction getFlatItems(nodes: TreeNode[], level: number) {\n const flatItems: FlatTreeItem[] = [];\n nodes.forEach((node, index) => {\n flatItems.push({ node, id: node.id, level, levelSize: nodes.length, posInLevel: index + 1 });\n if (!node.isExpanded) {\n return;\n }\n\n if (node.error && (node.error.type !== \"Unknown\" || !node.error.isNodeExpandable)) {\n return;\n }\n\n if (node.children !== true) {\n const childNodes = getFlatItems(node.children, level + 1);\n flatItems.push(...childNodes);\n return;\n }\n\n flatItems.push({\n id: `${node.id}-children-placeholder`,\n level: level + 1,\n placeholder: true,\n } satisfies FlatPlaceholderItem);\n });\n return flatItems;\n}\n\n/**\n * Finds and returns all nodes containing errors in a given hierarchy.\n *\n * @alpha\n */\nexport function useErrorNodes(rootNodes: TreeNode[]): Array<TreeNode & Pick<Required<TreeNode>, \"error\">> {\n return useMemo(\n () =>\n rootNodes.flatMap((rootNode) => {\n const errors = isErrorNode(rootNode) ? [rootNode] : [];\n if (rootNode.children === true) {\n return errors;\n }\n\n if (errors.length === 1 && (rootNode.error?.type !== \"Unknown\" || !rootNode.error.isNodeExpandable)) {\n return errors;\n }\n errors.push(...getErrorNodes(rootNode));\n return errors;\n }),\n [rootNodes],\n );\n}\n\nfunction getErrorNodes(parent: TreeNode) {\n const errorList: ReturnType<typeof useErrorNodes> = [];\n\n if (parent.children === true) {\n return [];\n }\n\n parent.children.forEach((node) => {\n if (isErrorNode(node)) {\n errorList.push(node);\n if (node.error.type !== \"Unknown\" || !node.error.isNodeExpandable) {\n return;\n }\n }\n\n if (node.children !== true) {\n const childErrorList = getErrorNodes(node);\n errorList.push(...childErrorList);\n return;\n }\n });\n return errorList;\n}\n\nfunction isErrorNode(node: TreeNode): node is TreeNode & Pick<Required<TreeNode>, \"error\"> {\n return node.error !== undefined;\n}\n"],"mappings":";;;AA0CA,SAAgBW,kBAAkBC,MAAiD;AACjF,QAAO,iBAAiBA;;;;;;;;;AAU1B,SAAOC,iBAAAC,WAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,WAAA;AACgBG,OAAAC,aAAaJ,WAAW,EAAE;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAA1BE;;AAGvB,SAASC,aAAaC,OAAmBf,OAAe;CACtD,MAAMgB,YAA4B,EAAE;AACpCD,OAAME,SAASZ,MAAMa,UAAU;AAC7BF,YAAUG,KAAK;GAAEd;GAAMN,IAAIM,KAAKN;GAAIC;GAAOG,WAAWY,MAAMK;GAAQhB,YAAYc,QAAQ;GAAG,CAAC;AAC5F,MAAI,CAACb,KAAKgB,WACR;AAGF,MAAIhB,KAAKiB,UAAUjB,KAAKiB,MAAMC,SAAS,aAAa,CAAClB,KAAKiB,MAAME,kBAC9D;AAGF,MAAInB,KAAKoB,aAAa,MAAM;GAC1B,MAAMC,aAAaZ,aAAaT,KAAKoB,UAAUzB,QAAQ,EAAE;AACzDgB,aAAUG,KAAK,GAAGO,WAAW;AAC7B;;AAGFV,YAAUG,KAAK;GACbpB,IAAI,GAAGM,KAAKN,GAAE;GACdC,OAAOA,QAAQ;GACfC,aAAa;GACd,CAA+B;GAChC;AACF,QAAOe;;;;;;;AAQT,SAAOW,cAAAjB,WAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,WAAA;AAGDG,OAAAH,UAASkB,QAASC,MAWhB;AAAAlB,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAXFE;;AAHC,SAAAgB,MAAAC,UAAA;CAIC,MAAAC,SAAeC,YAAYF,SAA2B,GAAvC,CAAyBA,SAAc,GAAvC,EAAuC;AACtD,KAAIA,SAAQL,aAAc,KAAI,QACrBM;AAGT,KAAIA,OAAMX,WAAY,MAAMU,SAAQR,OAAYC,SAAK,aAAzB,CAAuCO,SAAQR,MAAME,kBAAkB,QAC1FO;AAETA,QAAMZ,KAAK,GAAIc,cAAcH,SAAS,CAAC;AAAA,QAChCC;;AAMf,SAASE,cAAcC,QAAkB;CACvC,MAAMC,YAA8C,EAAE;AAEtD,KAAID,OAAOT,aAAa,KACtB,QAAO,EAAE;AAGXS,QAAOT,SAASR,SAASZ,SAAS;AAChC,MAAI2B,YAAY3B,KAAK,EAAE;AACrB8B,aAAUhB,KAAKd,KAAK;AACpB,OAAIA,KAAKiB,MAAMC,SAAS,aAAa,CAAClB,KAAKiB,MAAME,iBAC/C;;AAIJ,MAAInB,KAAKoB,aAAa,MAAM;GAC1B,MAAMY,iBAAiBJ,cAAc5B,KAAK;AAC1C8B,aAAUhB,KAAK,GAAGkB,eAAe;AACjC;;GAEF;AACF,QAAOF;;AAGT,SAASH,YAAY3B,MAAsE;AACzF,QAAOA,KAAKiB,UAAUkB,KAAAA"}
1
+ {"version":3,"file":"FlatTreeNode.js","names":["useMemo","ErrorInfo","TreeNode","FlatPlaceholderItem","id","level","placeholder","FlatTreeNodeItem","levelSize","posInLevel","node","FlatTreeItem","isPlaceholderItem","item","useFlatTreeItems","rootNodes","$","_c","t0","getFlatItems","nodes","flatItems","forEach","index","push","length","isExpanded","errors","some","isErrorBlockingExpansion","children","childNodes","useErrorNodes","flatMap","_temp","rootNode","errorNodes","isErrorNode","getErrorNodes","parent","errorList","childErrorList","error","type","isNodeExpandable"],"sources":["../../src/presentation-hierarchies-react/FlatTreeNode.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useMemo } from \"react\";\n\nimport type { ErrorInfo, TreeNode } from \"./TreeNode.js\";\n\n/**\n * Placeholder item that is added to hierarchy as a child for a parent item while its child items are loading.\n *\n * @alpha\n */\ninterface FlatPlaceholderItem {\n id: string;\n level: number;\n placeholder: true;\n}\n\n/**\n * An item containing `TreeNode` node with properties needed for a flat tree structure.\n *\n * @alpha\n */\nexport interface FlatTreeNodeItem {\n id: string;\n level: number;\n levelSize: number;\n posInLevel: number;\n node: TreeNode;\n}\n\n/**\n * An Item describing single tree item position and its content inside tree.\n * Returned by `useFlatTreeNodeList` hook.\n *\n * @alpha\n */\nexport type FlatTreeItem = FlatTreeNodeItem | FlatPlaceholderItem;\n\n/** @alpha */\nexport function isPlaceholderItem(item: FlatTreeItem): item is FlatPlaceholderItem {\n return \"placeholder\" in item;\n}\n\n/**\n * Used to get a list of `FlatTreeItem` objects for the given list of `TreeNode` objects that represent\n * a hierarchical structure. The resulting items can be used to render the hierarchy in a flat manner, e.g. using a\n * virtualized list.\n *\n * @alpha\n */\nexport function useFlatTreeItems(rootNodes: TreeNode[]) {\n return useMemo(() => getFlatItems(rootNodes, 1), [rootNodes]);\n}\n\nfunction getFlatItems(nodes: TreeNode[], level: number) {\n const flatItems: FlatTreeItem[] = [];\n nodes.forEach((node, index) => {\n flatItems.push({ node, id: node.id, level, levelSize: nodes.length, posInLevel: index + 1 });\n if (!node.isExpanded) {\n return;\n }\n\n if (node.errors.some(isErrorBlockingExpansion)) {\n return;\n }\n\n if (node.children !== true) {\n const childNodes = getFlatItems(node.children, level + 1);\n flatItems.push(...childNodes);\n return;\n }\n\n flatItems.push({\n id: `${node.id}-children-placeholder`,\n level: level + 1,\n placeholder: true,\n } satisfies FlatPlaceholderItem);\n });\n return flatItems;\n}\n\n/**\n * Finds and returns all nodes containing errors in a given hierarchy.\n *\n * @alpha\n */\nexport function useErrorNodes(rootNodes: TreeNode[]): TreeNode[] {\n return useMemo(\n () =>\n rootNodes.flatMap((rootNode) => {\n const errorNodes = isErrorNode(rootNode) ? [rootNode] : [];\n if (rootNode.children === true) {\n return errorNodes;\n }\n\n if (errorNodes.length === 1 && errorNodes[0].errors.some(isErrorBlockingExpansion)) {\n return errorNodes;\n }\n errorNodes.push(...getErrorNodes(rootNode));\n return errorNodes;\n }),\n [rootNodes],\n );\n}\n\nfunction getErrorNodes(parent: TreeNode) {\n const errorList: TreeNode[] = [];\n\n if (parent.children === true) {\n return [];\n }\n\n parent.children.forEach((node) => {\n if (isErrorNode(node)) {\n errorList.push(node);\n if (node.errors.some(isErrorBlockingExpansion)) {\n return;\n }\n }\n\n if (node.children !== true) {\n const childErrorList = getErrorNodes(node);\n errorList.push(...childErrorList);\n return;\n }\n });\n return errorList;\n}\n\nfunction isErrorNode(node: TreeNode): boolean {\n return node.errors.length > 0;\n}\n\nfunction isErrorBlockingExpansion(error: ErrorInfo): boolean {\n return error.type !== \"Unknown\" || !error.isNodeExpandable;\n}\n"],"mappings":";;;AA0CA,SAAgBY,kBAAkBC,MAAiD;AACjF,QAAO,iBAAiBA;;;;;;;;;AAU1B,SAAOC,iBAAAC,WAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,WAAA;AACgBG,OAAAC,aAAaJ,WAAW,EAAE;AAAAC,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAA1BE;;AAGvB,SAASC,aAAaC,OAAmBf,OAAe;CACtD,MAAMgB,YAA4B,EAAE;AACpCD,OAAME,SAASZ,MAAMa,UAAU;AAC7BF,YAAUG,KAAK;GAAEd;GAAMN,IAAIM,KAAKN;GAAIC;GAAOG,WAAWY,MAAMK;GAAQhB,YAAYc,QAAQ;GAAG,CAAC;AAC5F,MAAI,CAACb,KAAKgB,WACR;AAGF,MAAIhB,KAAKiB,OAAOC,KAAKC,yBAAyB,CAC5C;AAGF,MAAInB,KAAKoB,aAAa,MAAM;GAC1B,MAAMC,aAAaZ,aAAaT,KAAKoB,UAAUzB,QAAQ,EAAE;AACzDgB,aAAUG,KAAK,GAAGO,WAAW;AAC7B;;AAGFV,YAAUG,KAAK;GACbpB,IAAI,GAAGM,KAAKN,GAAE;GACdC,OAAOA,QAAQ;GACfC,aAAa;GACd,CAA+B;GAChC;AACF,QAAOe;;;;;;;AAQT,SAAOW,cAAAjB,WAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAA,IAAAC;AAAA,KAAAF,EAAA,OAAAD,WAAA;AAGDG,OAAAH,UAASkB,QAASC,MAWhB;AAAAlB,IAAA,KAAAD;AAAAC,IAAA,KAAAE;OAAAA,MAAAF,EAAA;AAAA,QAXFE;;AAHC,SAAAgB,MAAAC,UAAA;CAIC,MAAAC,aAAmBC,YAAYF,SAA2B,GAAvC,CAAyBA,SAAc,GAAvC,EAAuC;AAC1D,KAAIA,SAAQL,aAAc,KAAI,QACrBM;AAGT,KAAIA,WAAUX,WAAY,KAAKW,WAAU,GAAGT,OAAOC,KAAMC,yBAAyB,CAAA,QACzEO;AAETA,YAAUZ,KAAK,GAAIc,cAAcH,SAAS,CAAC;AAAA,QACpCC;;AAMf,SAASE,cAAcC,QAAkB;CACvC,MAAMC,YAAwB,EAAE;AAEhC,KAAID,OAAOT,aAAa,KACtB,QAAO,EAAE;AAGXS,QAAOT,SAASR,SAASZ,SAAS;AAChC,MAAI2B,YAAY3B,KAAK,EAAE;AACrB8B,aAAUhB,KAAKd,KAAK;AACpB,OAAIA,KAAKiB,OAAOC,KAAKC,yBAAyB,CAC5C;;AAIJ,MAAInB,KAAKoB,aAAa,MAAM;GAC1B,MAAMW,iBAAiBH,cAAc5B,KAAK;AAC1C8B,aAAUhB,KAAK,GAAGiB,eAAe;AACjC;;GAEF;AACF,QAAOD;;AAGT,SAASH,YAAY3B,MAAyB;AAC5C,QAAOA,KAAKiB,OAAOF,SAAS;;AAG9B,SAASI,yBAAyBa,OAA2B;AAC3D,QAAOA,MAAMC,SAAS,aAAa,CAACD,MAAME"}
@@ -15,8 +15,8 @@ interface TreeNode {
15
15
  isFiltered: boolean;
16
16
  /** UI-agnostic source of this node object. */
17
17
  nodeData: HierarchyNode;
18
- /** Contains error encountered from expanding the node */
19
- error?: ErrorInfo;
18
+ /** Errors associated with this tree node. */
19
+ errors: ErrorInfo[];
20
20
  }
21
21
  /**
22
22
  * A type of `ErrorInfo` that is returned,
@@ -1 +1 @@
1
- {"version":3,"file":"TreeNode.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/TreeNode.ts"],"mappings":";;;;;AAWA;;UAAiB,QAAA;EACf,EAAA;EACA,KAAA;EACA,QAAA,SAAiB,KAAA,CAAM,QAAA;EACvB,UAAA;EACA,SAAA;EACA,YAAA;EACA,UAAA;EALA;EAOA,QAAA,EAAU,aAAA;EANO;EAQjB,KAAA,GAAQ,SAAA;AAAA;;;;;;;UASO,wBAAA;EACf,EAAA;EACA,IAAA;AAAA;;;;;AAUF;;;UAAiB,0BAAA;EACf,EAAA;EACA,IAAA;EACA,kBAAA;AAAA;;AAUF;;;;;;UAAiB,qBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;AAAA;;;;;;;;;UAWe,gBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;EAaE;EAXF,gBAAA;EACA,cAAA;AAAA;;;;;;;KASU,SAAA,GACR,gBAAA,GACA,0BAAA,GACA,wBAAA,GACA,qBAAA"}
1
+ {"version":3,"file":"TreeNode.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/TreeNode.ts"],"mappings":";;;;;AAWA;;UAAiB,QAAA;EACf,EAAA;EACA,KAAA;EACA,QAAA,SAAiB,KAAA,CAAM,QAAA;EACvB,UAAA;EACA,SAAA;EACA,YAAA;EACA,UAAA;EALA;EAOA,QAAA,EAAU,aAAA;EANO;EAQjB,MAAA,EAAQ,SAAA;AAAA;;;;;;;UASO,wBAAA;EACf,EAAA;EACA,IAAA;AAAA;;;;;AAUF;;;UAAiB,0BAAA;EACf,EAAA;EACA,IAAA;EACA,kBAAA;AAAA;;AAUF;;;;;;UAAiB,qBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;AAAA;;;;;;;;;UAWe,gBAAA;EACf,EAAA;EACA,IAAA;EACA,OAAA;EAaE;EAXF,gBAAA;EACA,cAAA;AAAA;;;;;;;KASU,SAAA,GACR,gBAAA,GACA,0BAAA,GACA,wBAAA,GACA,qBAAA"}
@@ -66,11 +66,11 @@ interface UseTreeProps {
66
66
  type: "timeout" | "unknown";
67
67
  error: unknown;
68
68
  }) => void;
69
- /** Callback to set custom TreeNode errors.
70
- *
71
- * **Note:** Internal errors take precedence over custom ones.
69
+ /**
70
+ * Callback to set custom TreeNode errors.
71
+ * Errors returned from this callback are combined with internal errors when populating `TreeNode.errors`.
72
72
  */
73
- getTreeNodeError?: (node: HierarchyNode) => ErrorInfo | undefined;
73
+ getTreeNodeErrors?: (node: HierarchyNode) => ErrorInfo[];
74
74
  }
75
75
  /** @public */
76
76
  type UseTreeResult = {
@@ -1 +1 @@
1
- {"version":3,"file":"UseTree.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/UseTree.ts"],"mappings":";;;;;;;;AAiCA;;;;;;;;;AAoBA;;iBApBgB,OAAA,CAAQ,KAAA,EAAO,YAAA,GAAe,aAAA;;;;;;;;;;;;;;;;iBAoB9B,uBAAA,CAAA;EACd,UAAA;EACA,gBAAA;EACA,8BAAA;EAAA,GACG;AAAA,GACF,YAAA,GAAe,4BAAA,GAA+B,aAAA;;UAehC,YAAA;EAf6C;EAiB5D,oBAAA,QAA4B,iBAAA;EAFb;EAIf,cAAA;IAAoB;EAAA;IAAiB,WAAA,EAAa,WAAA;EAAA,MAAkB,OAAA,CAAQ,mBAAA;EAAxD;;;;EAKpB,qBAAA,IAAyB,MAAA,sDAA4D,QAAA;EAa3D;EAX1B,wBAAA,IAA4B,KAAA;IAC1B,QAAA;IACA,MAAA,GAAS,qBAAA;IACT,KAAA;EAAA;EAVF;EAaA,oBAAA,IAAwB,KAAA;IAAS,QAAA;IAAmB,IAAA;IAA6B,KAAA;EAAA;EAbL;;;;EAkB5E,gBAAA,IAAoB,IAAA,EAAM,aAAA,KAAkB,SAAA;AAAA;;KAIlC,aAAA;EAZR;;;;EAiBF,WAAA;EAdiF;;;EAkBjF,OAAA,GAAU,MAAA,aAAmB,QAAA;EAbT;;;EAiBpB,YAAA,GAAe,SAAA,EAAW,wBAAA;AAAA,IACxB,aAAA;;;;KAKC,aAAA;EALD;;;;;EAYE,sBAAA,EAAwB,sBAAA;AAAA;EAb5B,8FAiBI,sBAAA;EAjBW;;;;AACC;EAsBZ,iBAAA,GAAoB,iBAAA;AAAA"}
1
+ {"version":3,"file":"UseTree.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/UseTree.ts"],"mappings":";;;;;;;;AAiCA;;;;;;;;;AAoBA;;iBApBgB,OAAA,CAAQ,KAAA,EAAO,YAAA,GAAe,aAAA;;;;;;;;;;;;;;;;iBAoB9B,uBAAA,CAAA;EACd,UAAA;EACA,gBAAA;EACA,8BAAA;EAAA,GACG;AAAA,GACF,YAAA,GAAe,4BAAA,GAA+B,aAAA;;UAehC,YAAA;EAf6C;EAiB5D,oBAAA,QAA4B,iBAAA;EAFb;EAIf,cAAA;IAAoB;EAAA;IAAiB,WAAA,EAAa,WAAA;EAAA,MAAkB,OAAA,CAAQ,mBAAA;EAAxD;;;;EAKpB,qBAAA,IAAyB,MAAA,sDAA4D,QAAA;EAa1D;EAX3B,wBAAA,IAA4B,KAAA;IAC1B,QAAA;IACA,MAAA,GAAS,qBAAA;IACT,KAAA;EAAA;EAVF;EAaA,oBAAA,IAAwB,KAAA;IAAS,QAAA;IAAmB,IAAA;IAA6B,KAAA;EAAA;EAbL;;;;EAkB5E,iBAAA,IAAqB,IAAA,EAAM,aAAA,KAAkB,SAAA;AAAA;;KAInC,aAAA;EAZR;;;;EAiBF,WAAA;EAdiF;;;EAkBjF,OAAA,GAAU,MAAA,aAAmB,QAAA;EAbR;;;EAiBrB,YAAA,GAAe,SAAA,EAAW,wBAAA;AAAA,IACxB,aAAA;;;;KAKC,aAAA;EALD;;;;;EAYE,sBAAA,EAAwB,sBAAA;AAAA;EAb5B,8FAiBI,sBAAA;EAjBW;;;;AACC;EAsBZ,iBAAA,GAAoB,iBAAA;AAAA"}
@@ -117,7 +117,7 @@ function useUnifiedSelectionTree(t0) {
117
117
  }
118
118
  return rest;
119
119
  }
120
- function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMeasured, onHierarchyLimitExceeded, onHierarchyLoadError, getTreeNodeError }) {
120
+ function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMeasured, onHierarchyLimitExceeded, onHierarchyLoadError, getTreeNodeErrors }) {
121
121
  const [state, setState] = useState({
122
122
  model: {
123
123
  idToNode: /* @__PURE__ */ new Map(),
@@ -132,11 +132,11 @@ function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMe
132
132
  const onPerformanceMeasuredRef = useLatest(onPerformanceMeasured);
133
133
  const onHierarchyLimitExceededRef = useLatest(onHierarchyLimitExceeded);
134
134
  const onHierarchyLoadErrorRef = useLatest(onHierarchyLoadError);
135
- const getTreeNodeErrorRef = useLatest(getTreeNodeError);
135
+ const getTreeNodeErrorsRef = useLatest(getTreeNodeErrors);
136
136
  const [actions] = useState(() => new TreeActions((model) => {
137
137
  setState({
138
138
  model,
139
- rootNodes: model.parentChildMap.get(void 0) !== void 0 ? generateTreeStructure(void 0, model, getTreeNodeErrorRef.current) : void 0
139
+ rootNodes: model.parentChildMap.get(void 0) !== void 0 ? generateTreeStructure(void 0, model, getTreeNodeErrorsRef.current) : void 0
140
140
  });
141
141
  }, (actionType, duration) => onPerformanceMeasuredRef.current?.(actionType, duration), (props) => onHierarchyLimitExceededRef.current?.(props), (props_0) => onHierarchyLoadErrorRef.current?.(props_0)));
142
142
  const currentFormatter = useRef();
@@ -194,10 +194,10 @@ function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMe
194
194
  const getNode = useCallback((nodeId_0) => {
195
195
  const node = actions.getNode(nodeId_0);
196
196
  if (!node || node.id === void 0) return;
197
- return createTreeNode(node, state.model, getTreeNodeErrorRef.current);
197
+ return createTreeNode(node, state.model, getTreeNodeErrorsRef.current);
198
198
  }, [
199
199
  actions,
200
- getTreeNodeErrorRef,
200
+ getTreeNodeErrorsRef,
201
201
  state.model
202
202
  ]);
203
203
  const expandNode = useCallback((nodeId_1, isExpanded) => {
@@ -212,7 +212,6 @@ function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMe
212
212
  const isNodeSelected = useCallback((nodeId_2) => TreeModel.isNodeSelected(state.model, nodeId_2), [state]);
213
213
  const setFormatter = useCallback((formatter) => {
214
214
  currentFormatter.current = formatter;
215
- /* c8 ignore next 3 */
216
215
  if (!hierarchyProvider) return;
217
216
  hierarchyProvider.setFormatter(formatter);
218
217
  }, [hierarchyProvider]);
@@ -267,14 +266,15 @@ function useTreeInternal({ getHierarchyProvider, getSearchPaths, onPerformanceMe
267
266
  setFormatter
268
267
  };
269
268
  }
270
- function generateTreeStructure(parentNodeId, model, getTreeNodeError) {
269
+ function generateTreeStructure(parentNodeId, model, getTreeNodeErrors) {
271
270
  const currentChildren = model.parentChildMap.get(parentNodeId);
272
271
  if (!currentChildren) return;
273
272
  return currentChildren.map((childId) => model.idToNode.get(childId)).filter((node) => !!node).map((node) => {
274
- return createTreeNode(node, model, getTreeNodeError);
273
+ return createTreeNode(node, model, getTreeNodeErrors);
275
274
  });
276
275
  }
277
- function createTreeNode(modelNode, model, getTreeNodeError) {
276
+ function createTreeNode(modelNode, model, getTreeNodeErrors) {
277
+ const allErrors = [...modelNode.error ? [modelNode.error] : [], ...getTreeNodeErrors?.(modelNode.nodeData) ?? []];
278
278
  let children;
279
279
  return {
280
280
  id: modelNode.id,
@@ -284,9 +284,9 @@ function createTreeNode(modelNode, model, getTreeNodeError) {
284
284
  isExpanded: !!modelNode.isExpanded,
285
285
  isFilterable: !HierarchyNode.isGroupingNode(modelNode.nodeData) && !!modelNode.nodeData.supportsFiltering && modelNode.children,
286
286
  isFiltered: !!modelNode.instanceFilter,
287
- error: modelNode.error ?? getTreeNodeError?.(modelNode.nodeData),
287
+ errors: allErrors,
288
288
  get children() {
289
- if (!children) children = generateTreeStructure(modelNode.id, model, getTreeNodeError);
289
+ if (!children) children = generateTreeStructure(modelNode.id, model, getTreeNodeErrors);
290
290
  return children ? children : modelNode.children === true ? true : [];
291
291
  }
292
292
  };
@@ -1 +1 @@
1
- {"version":3,"file":"UseTree.js","names":["useCallback","useEffect","useMemo","useRef","useState","HierarchyNode","TreeActions","TreeModel","useUnifiedTreeSelection","safeDispose","useLatest","GenericInstanceFilter","HierarchyProvider","HierarchySearchTree","IPrimitiveValueFormatter","TreeModelHierarchyNode","TreeModelRootNode","UseUnifiedTreeSelectionProps","RootErrorRendererProps","TreeRendererProps","ErrorInfo","TreeNode","SelectionChangeType","useTree","props","$","_c","t0","useTreeInternal","rest","getTreeModelNode","_","t1","useUnifiedSelectionTree","createSelectableForGenericNode","selectionStorage","sourceName","t2","selectionProps","rootErrorRendererProps","undefined","treeRendererProps","rootNodes","t3","t4","UseTreeProps","getHierarchyProvider","getSearchPaths","abortSignal","AbortSignal","Promise","onPerformanceMeasured","action","duration","onHierarchyLimitExceeded","parentId","filter","limit","onHierarchyLoadError","type","error","getTreeNodeError","node","UseTreeResult","isReloading","getNode","nodeId","setFormatter","formatter","RendererProps","TreeState","model","Array","state","setState","idToNode","Map","parentChildMap","rootNode","id","nodeData","onPerformanceMeasuredRef","onHierarchyLimitExceededRef","onHierarchyLoadErrorRef","getTreeNodeErrorRef","actions","get","generateTreeStructure","current","actionType","currentFormatter","hierarchyProvider","setHierarchyProvider","provider","removeHierarchyChangedListener","hierarchyChanged","addListener","hierarchyChangeArgs","shouldDiscardState","searchChange","newSearch","reloadTree","reset","isSearching","setIsSearching","disposed","controller","AbortController","setHierarchySearch","paths","signal","abort","createTreeNode","expandNode","isExpanded","options","selectNodes","nodeIds","changeType","isNodeSelected","getHierarchyLevelDetails","hierarchyNode","isGroupingNode","getInstanceKeysIterator","getNodeInstanceKeys","parentNode","instanceFilter","hierarchyLevelSizeLimit","setInstanceFilter","sizeLimit","hierarchyLimit","setSizeLimit","value","setHierarchyLimit","renderProps","isLoading","parentNodeId","currentChildren","map","childId","modelNode","children","label","isFilterable","supportsFiltering","isFiltered"],"sources":["../../src/presentation-hierarchies-react/UseTree.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport { TreeActions } from \"./internal/TreeActions.js\";\nimport { TreeModel } from \"./internal/TreeModel.js\";\nimport { useUnifiedTreeSelection } from \"./internal/UseUnifiedSelection.js\";\nimport { safeDispose } from \"./internal/Utils.js\";\nimport { useLatest } from \"./Utils.js\";\n\nimport type { GenericInstanceFilter, HierarchyProvider, HierarchySearchTree } from \"@itwin/presentation-hierarchies\";\nimport type { IPrimitiveValueFormatter } from \"@itwin/presentation-shared\";\nimport type { TreeModelHierarchyNode, TreeModelRootNode } from \"./internal/TreeModel.js\";\nimport type { UseUnifiedTreeSelectionProps } from \"./internal/UseUnifiedSelection.js\";\nimport type { RootErrorRendererProps, TreeRendererProps } from \"./Renderers.js\";\nimport type { ErrorInfo, TreeNode } from \"./TreeNode.js\";\nimport type { SelectionChangeType } from \"./UseSelectionHandler.js\";\n\n/**\n * A React hook that creates state for a tree component.\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useUnifiedSelectionTree`\n * @see `useIModelTree`\n * @public\n */\nexport function useTree(props: UseTreeProps): UseTreeResult {\n const { getTreeModelNode: _, ...rest } = useTreeInternal(props);\n return rest;\n}\n\n/**\n * A React hook that creates state for a tree component, that is integrated with unified selection\n * through the given selection storage (previously the storage was provided through the, now\n * deprecated, `UnifiedSelectionProvider`).\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useTree`\n * @see `useIModelUnifiedSelectionTree`\n * @see `UnifiedSelectionProvider`\n * @public\n */\nexport function useUnifiedSelectionTree({\n sourceName,\n selectionStorage,\n createSelectableForGenericNode,\n ...props\n}: UseTreeProps & UseUnifiedTreeSelectionProps): UseTreeResult {\n const { getTreeModelNode, ...rest } = useTreeInternal(props);\n const selectionProps = useUnifiedTreeSelection({\n sourceName,\n selectionStorage,\n getTreeModelNode,\n createSelectableForGenericNode,\n });\n if (rest.rootErrorRendererProps === undefined && rest.treeRendererProps?.rootNodes) {\n return { ...rest, treeRendererProps: { ...rest.treeRendererProps, ...selectionProps } };\n }\n return rest;\n}\n\n/** @public */\nexport interface UseTreeProps {\n /** Provides the hierarchy provider for the tree. */\n getHierarchyProvider: () => HierarchyProvider;\n /** Provides paths to search nodes. */\n getSearchPaths?: ({ abortSignal }: { abortSignal: AbortSignal }) => Promise<HierarchySearchTree[] | undefined>;\n /**\n * Callback that is called just after a certain action is finished.\n * Can be used for performance tracking.\n */\n onPerformanceMeasured?: (action: \"initial-load\" | \"hierarchy-level-load\" | \"reload\", duration: number) => void;\n /** Action to perform when hierarchy level contains more items that the specified limit. */\n onHierarchyLimitExceeded?: (props: {\n parentId?: string;\n filter?: GenericInstanceFilter;\n limit?: number | \"unbounded\";\n }) => void;\n /** Action to perform when an error occurs while loading hierarchy. */\n onHierarchyLoadError?: (props: { parentId?: string; type: \"timeout\" | \"unknown\"; error: unknown }) => void;\n /** Callback to set custom TreeNode errors.\n *\n * **Note:** Internal errors take precedence over custom ones.\n */\n getTreeNodeError?: (node: HierarchyNode) => ErrorInfo | undefined;\n}\n\n/** @public */\nexport type UseTreeResult = {\n /**\n * Specifies whether tree is reloading or not. It is set to `false` when initial tree load is in progress to check if\n * or tree is reloading.\n */\n isReloading: boolean;\n /**\n * Get a tree node by id\n */\n getNode: (nodeId: string) => TreeNode | undefined;\n /**\n * Sets a formatter for the primitive values that are displayed in the hierarchy.\n */\n setFormatter: (formatter: IPrimitiveValueFormatter | undefined) => void;\n} & RendererProps;\n\n/**.\n * @alpha\n */\ntype RendererProps =\n | {\n /**\n * An object containing information used to render root error handling UI.\n * Use in combination with `RootErrorRenderer` or your custom implementation.\n * Defined when root nodes fail to load.\n */\n rootErrorRendererProps: RootErrorRendererProps;\n }\n | {\n /** Is undefined when rootNodes were successfully loaded or are in initial loading process. */\n rootErrorRendererProps: undefined;\n /**\n * An object containing information used to render tree.\n * Use with `TreeRenderer` or your custom implementation.\n * Is undefined on initial loading process.\n */\n treeRendererProps?: TreeRendererProps;\n };\n\ninterface TreeState {\n model: TreeModel;\n rootNodes: Array<TreeNode> | undefined;\n}\n\nfunction useTreeInternal({\n getHierarchyProvider,\n getSearchPaths,\n onPerformanceMeasured,\n onHierarchyLimitExceeded,\n onHierarchyLoadError,\n getTreeNodeError,\n}: UseTreeProps): UseTreeResult & {\n getTreeModelNode: (nodeId: string) => TreeModelRootNode | TreeModelHierarchyNode | undefined;\n} {\n const [state, setState] = useState<TreeState>({\n model: { idToNode: new Map(), parentChildMap: new Map(), rootNode: { id: undefined, nodeData: undefined } },\n rootNodes: undefined,\n });\n const onPerformanceMeasuredRef = useLatest(onPerformanceMeasured);\n const onHierarchyLimitExceededRef = useLatest(onHierarchyLimitExceeded);\n const onHierarchyLoadErrorRef = useLatest(onHierarchyLoadError);\n const getTreeNodeErrorRef = useLatest(getTreeNodeError);\n\n const [actions] = useState<TreeActions>(\n () =>\n new TreeActions(\n (model) => {\n const rootNodes =\n model.parentChildMap.get(undefined) !== undefined\n ? generateTreeStructure(undefined, model, getTreeNodeErrorRef.current)\n : undefined;\n setState({ model, rootNodes });\n },\n (actionType, duration) => onPerformanceMeasuredRef.current?.(actionType, duration),\n (props) => onHierarchyLimitExceededRef.current?.(props),\n (props) => onHierarchyLoadErrorRef.current?.(props),\n ),\n );\n const currentFormatter = useRef<IPrimitiveValueFormatter>();\n\n const [hierarchyProvider, setHierarchyProvider] = useState<HierarchyProvider | undefined>();\n useEffect(() => {\n const provider = getHierarchyProvider();\n provider.setFormatter(currentFormatter.current);\n const removeHierarchyChangedListener = provider.hierarchyChanged.addListener((hierarchyChangeArgs) => {\n const shouldDiscardState = hierarchyChangeArgs.searchChange?.newSearch !== undefined;\n actions.reloadTree({ state: shouldDiscardState ? \"discard\" : \"keep\" });\n });\n actions.setHierarchyProvider(provider);\n setHierarchyProvider(provider);\n return () => {\n removeHierarchyChangedListener();\n actions.reset();\n safeDispose(provider);\n };\n }, [actions, getHierarchyProvider]);\n\n const [isSearching, setIsSearching] = useState(false);\n useEffect(() => {\n let disposed = false as boolean;\n const controller = new AbortController();\n void (async () => {\n if (!hierarchyProvider) {\n return;\n }\n\n if (!getSearchPaths) {\n hierarchyProvider.setHierarchySearch(undefined);\n // reload tree in case hierarchy provider does not use hierarchy search to load initial nodes\n actions.reloadTree({ state: \"keep\" });\n setIsSearching(false);\n return;\n }\n\n setIsSearching(true);\n let paths: HierarchySearchTree[] | undefined;\n try {\n paths = await getSearchPaths({ abortSignal: controller.signal });\n } catch {\n } finally {\n if (!disposed) {\n hierarchyProvider.setHierarchySearch(paths ? { paths } : undefined);\n setIsSearching(false);\n }\n }\n })();\n return () => {\n controller.abort();\n disposed = true;\n };\n }, [hierarchyProvider, getSearchPaths, actions]);\n\n const getTreeModelNode = useCallback<(nodeId: string) => TreeModelRootNode | TreeModelHierarchyNode | undefined>(\n (nodeId: string) => {\n return actions.getNode(nodeId);\n },\n [actions],\n );\n\n const getNode = useCallback(\n (nodeId: string): TreeNode | undefined => {\n const node = actions.getNode(nodeId);\n if (!node || node.id === undefined) {\n return undefined;\n }\n return createTreeNode(node, state.model, getTreeNodeErrorRef.current);\n },\n [actions, getTreeNodeErrorRef, state.model],\n );\n\n const expandNode = useCallback<TreeRendererProps[\"expandNode\"]>(\n (nodeId: string, isExpanded: boolean) => {\n actions.expandNode(nodeId, isExpanded);\n },\n [actions],\n );\n\n const reloadTree = useCallback<TreeRendererProps[\"reloadTree\"]>(\n (options) => {\n actions.reloadTree(options);\n },\n [actions],\n );\n\n const selectNodes = useCallback<TreeRendererProps[\"selectNodes\"]>(\n (nodeIds: Array<string>, changeType: SelectionChangeType) => {\n actions.selectNodes(nodeIds, changeType);\n },\n [actions],\n );\n\n const isNodeSelected = useCallback<TreeRendererProps[\"isNodeSelected\"]>(\n (nodeId: string) => TreeModel.isNodeSelected(state.model, nodeId),\n [state],\n );\n\n const setFormatter = useCallback<UseTreeResult[\"setFormatter\"]>(\n (formatter: IPrimitiveValueFormatter | undefined) => {\n currentFormatter.current = formatter;\n /* c8 ignore next 3 */\n if (!hierarchyProvider) {\n return;\n }\n\n hierarchyProvider.setFormatter(formatter);\n },\n [hierarchyProvider],\n );\n\n const getHierarchyLevelDetails = useCallback<TreeRendererProps[\"getHierarchyLevelDetails\"]>(\n (nodeId) => {\n const node = actions.getNode(nodeId);\n if (!hierarchyProvider || !node) {\n return undefined;\n }\n const hierarchyNode = node.nodeData;\n if (hierarchyNode && HierarchyNode.isGroupingNode(hierarchyNode)) {\n return undefined;\n }\n\n return {\n hierarchyNode,\n getInstanceKeysIterator: (props) =>\n hierarchyProvider.getNodeInstanceKeys({\n parentNode: hierarchyNode,\n instanceFilter: props?.instanceFilter,\n hierarchyLevelSizeLimit: props?.hierarchyLevelSizeLimit,\n }),\n instanceFilter: node.instanceFilter,\n setInstanceFilter: (filter) => actions.setInstanceFilter(nodeId, filter),\n sizeLimit: node.hierarchyLimit,\n setSizeLimit: (value) => actions.setHierarchyLimit(nodeId, value),\n };\n },\n [actions, hierarchyProvider],\n );\n\n const renderProps: RendererProps = useMemo(() => {\n if (state.model.rootNode.error) {\n return { rootErrorRendererProps: { error: state.model.rootNode.error, reloadTree, getHierarchyLevelDetails } };\n }\n return {\n rootErrorRendererProps: undefined,\n treeRendererProps: state.rootNodes\n ? { rootNodes: state.rootNodes, expandNode, selectNodes, isNodeSelected, reloadTree, getHierarchyLevelDetails }\n : undefined,\n };\n }, [\n expandNode,\n getHierarchyLevelDetails,\n isNodeSelected,\n reloadTree,\n selectNodes,\n state.model.rootNode.error,\n state.rootNodes,\n ]);\n\n return {\n ...renderProps,\n isReloading: !!state.model.rootNode.isLoading || isSearching,\n getTreeModelNode,\n getNode,\n setFormatter,\n };\n}\n\nfunction generateTreeStructure(\n parentNodeId: string | undefined,\n model: TreeModel,\n getTreeNodeError?: (node: HierarchyNode) => ErrorInfo | undefined,\n): Array<TreeNode> | undefined {\n const currentChildren = model.parentChildMap.get(parentNodeId);\n if (!currentChildren) {\n return undefined;\n }\n\n return currentChildren\n .map((childId) => model.idToNode.get(childId))\n .filter((node): node is TreeModelHierarchyNode => !!node)\n .map<TreeNode>((node) => {\n return createTreeNode(node, model, getTreeNodeError);\n });\n}\n\nfunction createTreeNode(\n modelNode: TreeModelHierarchyNode,\n model: TreeModel,\n getTreeNodeError?: (node: HierarchyNode) => ErrorInfo | undefined,\n): TreeNode {\n let children: Array<TreeNode> | undefined;\n return {\n id: modelNode.id,\n label: modelNode.label,\n nodeData: modelNode.nodeData,\n isLoading: !!modelNode.isLoading,\n isExpanded: !!modelNode.isExpanded,\n isFilterable:\n !HierarchyNode.isGroupingNode(modelNode.nodeData) && !!modelNode.nodeData.supportsFiltering && modelNode.children,\n isFiltered: !!modelNode.instanceFilter,\n error: modelNode.error ?? getTreeNodeError?.(modelNode.nodeData),\n get children() {\n if (!children) {\n children = generateTreeStructure(modelNode.id, model, getTreeNodeError);\n }\n return children ? children : modelNode.children === true ? true : [];\n },\n };\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"UseTree.js","names":["useCallback","useEffect","useMemo","useRef","useState","HierarchyNode","TreeActions","TreeModel","useUnifiedTreeSelection","safeDispose","useLatest","GenericInstanceFilter","HierarchyProvider","HierarchySearchTree","IPrimitiveValueFormatter","TreeModelHierarchyNode","TreeModelRootNode","UseUnifiedTreeSelectionProps","RootErrorRendererProps","TreeRendererProps","ErrorInfo","TreeNode","SelectionChangeType","useTree","props","$","_c","t0","useTreeInternal","rest","getTreeModelNode","_","t1","useUnifiedSelectionTree","createSelectableForGenericNode","selectionStorage","sourceName","t2","selectionProps","rootErrorRendererProps","undefined","treeRendererProps","rootNodes","t3","t4","UseTreeProps","getHierarchyProvider","getSearchPaths","abortSignal","AbortSignal","Promise","onPerformanceMeasured","action","duration","onHierarchyLimitExceeded","parentId","filter","limit","onHierarchyLoadError","type","error","getTreeNodeErrors","node","UseTreeResult","isReloading","getNode","nodeId","setFormatter","formatter","RendererProps","TreeState","model","Array","state","setState","idToNode","Map","parentChildMap","rootNode","id","nodeData","onPerformanceMeasuredRef","onHierarchyLimitExceededRef","onHierarchyLoadErrorRef","getTreeNodeErrorsRef","actions","get","generateTreeStructure","current","actionType","currentFormatter","hierarchyProvider","setHierarchyProvider","provider","removeHierarchyChangedListener","hierarchyChanged","addListener","hierarchyChangeArgs","shouldDiscardState","searchChange","newSearch","reloadTree","reset","isSearching","setIsSearching","disposed","controller","AbortController","setHierarchySearch","paths","signal","abort","createTreeNode","expandNode","isExpanded","options","selectNodes","nodeIds","changeType","isNodeSelected","getHierarchyLevelDetails","hierarchyNode","isGroupingNode","getInstanceKeysIterator","getNodeInstanceKeys","parentNode","instanceFilter","hierarchyLevelSizeLimit","setInstanceFilter","sizeLimit","hierarchyLimit","setSizeLimit","value","setHierarchyLimit","renderProps","isLoading","parentNodeId","currentChildren","map","childId","modelNode","allErrors","children","label","isFilterable","supportsFiltering","isFiltered","errors"],"sources":["../../src/presentation-hierarchies-react/UseTree.ts"],"sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport { HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport { TreeActions } from \"./internal/TreeActions.js\";\nimport { TreeModel } from \"./internal/TreeModel.js\";\nimport { useUnifiedTreeSelection } from \"./internal/UseUnifiedSelection.js\";\nimport { safeDispose } from \"./internal/Utils.js\";\nimport { useLatest } from \"./Utils.js\";\n\nimport type { GenericInstanceFilter, HierarchyProvider, HierarchySearchTree } from \"@itwin/presentation-hierarchies\";\nimport type { IPrimitiveValueFormatter } from \"@itwin/presentation-shared\";\nimport type { TreeModelHierarchyNode, TreeModelRootNode } from \"./internal/TreeModel.js\";\nimport type { UseUnifiedTreeSelectionProps } from \"./internal/UseUnifiedSelection.js\";\nimport type { RootErrorRendererProps, TreeRendererProps } from \"./Renderers.js\";\nimport type { ErrorInfo, TreeNode } from \"./TreeNode.js\";\nimport type { SelectionChangeType } from \"./UseSelectionHandler.js\";\n\n/**\n * A React hook that creates state for a tree component.\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useUnifiedSelectionTree`\n * @see `useIModelTree`\n * @public\n */\nexport function useTree(props: UseTreeProps): UseTreeResult {\n const { getTreeModelNode: _, ...rest } = useTreeInternal(props);\n return rest;\n}\n\n/**\n * A React hook that creates state for a tree component, that is integrated with unified selection\n * through the given selection storage (previously the storage was provided through the, now\n * deprecated, `UnifiedSelectionProvider`).\n *\n * The hook uses `@itwin/presentation-hierarchies` package to load the hierarchy data and returns a\n * component-agnostic result which may be used to render the hierarchy using any UI framework.\n *\n * See `README.md` for an example\n *\n * @see `useTree`\n * @see `useIModelUnifiedSelectionTree`\n * @see `UnifiedSelectionProvider`\n * @public\n */\nexport function useUnifiedSelectionTree({\n sourceName,\n selectionStorage,\n createSelectableForGenericNode,\n ...props\n}: UseTreeProps & UseUnifiedTreeSelectionProps): UseTreeResult {\n const { getTreeModelNode, ...rest } = useTreeInternal(props);\n const selectionProps = useUnifiedTreeSelection({\n sourceName,\n selectionStorage,\n getTreeModelNode,\n createSelectableForGenericNode,\n });\n if (rest.rootErrorRendererProps === undefined && rest.treeRendererProps?.rootNodes) {\n return { ...rest, treeRendererProps: { ...rest.treeRendererProps, ...selectionProps } };\n }\n return rest;\n}\n\n/** @public */\nexport interface UseTreeProps {\n /** Provides the hierarchy provider for the tree. */\n getHierarchyProvider: () => HierarchyProvider;\n /** Provides paths to search nodes. */\n getSearchPaths?: ({ abortSignal }: { abortSignal: AbortSignal }) => Promise<HierarchySearchTree[] | undefined>;\n /**\n * Callback that is called just after a certain action is finished.\n * Can be used for performance tracking.\n */\n onPerformanceMeasured?: (action: \"initial-load\" | \"hierarchy-level-load\" | \"reload\", duration: number) => void;\n /** Action to perform when hierarchy level contains more items that the specified limit. */\n onHierarchyLimitExceeded?: (props: {\n parentId?: string;\n filter?: GenericInstanceFilter;\n limit?: number | \"unbounded\";\n }) => void;\n /** Action to perform when an error occurs while loading hierarchy. */\n onHierarchyLoadError?: (props: { parentId?: string; type: \"timeout\" | \"unknown\"; error: unknown }) => void;\n /**\n * Callback to set custom TreeNode errors.\n * Errors returned from this callback are combined with internal errors when populating `TreeNode.errors`.\n */\n getTreeNodeErrors?: (node: HierarchyNode) => ErrorInfo[];\n}\n\n/** @public */\nexport type UseTreeResult = {\n /**\n * Specifies whether tree is reloading or not. It is set to `false` when initial tree load is in progress to check if\n * or tree is reloading.\n */\n isReloading: boolean;\n /**\n * Get a tree node by id\n */\n getNode: (nodeId: string) => TreeNode | undefined;\n /**\n * Sets a formatter for the primitive values that are displayed in the hierarchy.\n */\n setFormatter: (formatter: IPrimitiveValueFormatter | undefined) => void;\n} & RendererProps;\n\n/**.\n * @alpha\n */\ntype RendererProps =\n | {\n /**\n * An object containing information used to render root error handling UI.\n * Use in combination with `RootErrorRenderer` or your custom implementation.\n * Defined when root nodes fail to load.\n */\n rootErrorRendererProps: RootErrorRendererProps;\n }\n | {\n /** Is undefined when rootNodes were successfully loaded or are in initial loading process. */\n rootErrorRendererProps: undefined;\n /**\n * An object containing information used to render tree.\n * Use with `TreeRenderer` or your custom implementation.\n * Is undefined on initial loading process.\n */\n treeRendererProps?: TreeRendererProps;\n };\n\ninterface TreeState {\n model: TreeModel;\n rootNodes: Array<TreeNode> | undefined;\n}\n\nfunction useTreeInternal({\n getHierarchyProvider,\n getSearchPaths,\n onPerformanceMeasured,\n onHierarchyLimitExceeded,\n onHierarchyLoadError,\n getTreeNodeErrors,\n}: UseTreeProps): UseTreeResult & {\n getTreeModelNode: (nodeId: string) => TreeModelRootNode | TreeModelHierarchyNode | undefined;\n} {\n const [state, setState] = useState<TreeState>({\n model: { idToNode: new Map(), parentChildMap: new Map(), rootNode: { id: undefined, nodeData: undefined } },\n rootNodes: undefined,\n });\n const onPerformanceMeasuredRef = useLatest(onPerformanceMeasured);\n const onHierarchyLimitExceededRef = useLatest(onHierarchyLimitExceeded);\n const onHierarchyLoadErrorRef = useLatest(onHierarchyLoadError);\n const getTreeNodeErrorsRef = useLatest(getTreeNodeErrors);\n\n const [actions] = useState<TreeActions>(\n () =>\n new TreeActions(\n (model) => {\n const rootNodes =\n model.parentChildMap.get(undefined) !== undefined\n ? generateTreeStructure(undefined, model, getTreeNodeErrorsRef.current)\n : undefined;\n setState({ model, rootNodes });\n },\n (actionType, duration) => onPerformanceMeasuredRef.current?.(actionType, duration),\n (props) => onHierarchyLimitExceededRef.current?.(props),\n (props) => onHierarchyLoadErrorRef.current?.(props),\n ),\n );\n const currentFormatter = useRef<IPrimitiveValueFormatter>();\n\n const [hierarchyProvider, setHierarchyProvider] = useState<HierarchyProvider | undefined>();\n useEffect(() => {\n const provider = getHierarchyProvider();\n provider.setFormatter(currentFormatter.current);\n const removeHierarchyChangedListener = provider.hierarchyChanged.addListener((hierarchyChangeArgs) => {\n const shouldDiscardState = hierarchyChangeArgs.searchChange?.newSearch !== undefined;\n actions.reloadTree({ state: shouldDiscardState ? \"discard\" : \"keep\" });\n });\n actions.setHierarchyProvider(provider);\n setHierarchyProvider(provider);\n return () => {\n removeHierarchyChangedListener();\n actions.reset();\n safeDispose(provider);\n };\n }, [actions, getHierarchyProvider]);\n\n const [isSearching, setIsSearching] = useState(false);\n useEffect(() => {\n let disposed = false as boolean;\n const controller = new AbortController();\n void (async () => {\n if (!hierarchyProvider) {\n return;\n }\n\n if (!getSearchPaths) {\n hierarchyProvider.setHierarchySearch(undefined);\n // reload tree in case hierarchy provider does not use hierarchy search to load initial nodes\n actions.reloadTree({ state: \"keep\" });\n setIsSearching(false);\n return;\n }\n\n setIsSearching(true);\n let paths: HierarchySearchTree[] | undefined;\n try {\n paths = await getSearchPaths({ abortSignal: controller.signal });\n } catch {\n } finally {\n if (!disposed) {\n hierarchyProvider.setHierarchySearch(paths ? { paths } : undefined);\n setIsSearching(false);\n }\n }\n })();\n return () => {\n controller.abort();\n disposed = true;\n };\n }, [hierarchyProvider, getSearchPaths, actions]);\n\n const getTreeModelNode = useCallback<(nodeId: string) => TreeModelRootNode | TreeModelHierarchyNode | undefined>(\n (nodeId: string) => {\n return actions.getNode(nodeId);\n },\n [actions],\n );\n\n const getNode = useCallback(\n (nodeId: string): TreeNode | undefined => {\n const node = actions.getNode(nodeId);\n if (!node || node.id === undefined) {\n return undefined;\n }\n return createTreeNode(node, state.model, getTreeNodeErrorsRef.current);\n },\n [actions, getTreeNodeErrorsRef, state.model],\n );\n\n const expandNode = useCallback<TreeRendererProps[\"expandNode\"]>(\n (nodeId: string, isExpanded: boolean) => {\n actions.expandNode(nodeId, isExpanded);\n },\n [actions],\n );\n\n const reloadTree = useCallback<TreeRendererProps[\"reloadTree\"]>(\n (options) => {\n actions.reloadTree(options);\n },\n [actions],\n );\n\n const selectNodes = useCallback<TreeRendererProps[\"selectNodes\"]>(\n (nodeIds: Array<string>, changeType: SelectionChangeType) => {\n actions.selectNodes(nodeIds, changeType);\n },\n [actions],\n );\n\n const isNodeSelected = useCallback<TreeRendererProps[\"isNodeSelected\"]>(\n (nodeId: string) => TreeModel.isNodeSelected(state.model, nodeId),\n [state],\n );\n\n const setFormatter = useCallback<UseTreeResult[\"setFormatter\"]>(\n (formatter: IPrimitiveValueFormatter | undefined) => {\n currentFormatter.current = formatter;\n if (!hierarchyProvider) {\n return;\n }\n\n hierarchyProvider.setFormatter(formatter);\n },\n [hierarchyProvider],\n );\n\n const getHierarchyLevelDetails = useCallback<TreeRendererProps[\"getHierarchyLevelDetails\"]>(\n (nodeId) => {\n const node = actions.getNode(nodeId);\n if (!hierarchyProvider || !node) {\n return undefined;\n }\n const hierarchyNode = node.nodeData;\n if (hierarchyNode && HierarchyNode.isGroupingNode(hierarchyNode)) {\n return undefined;\n }\n\n return {\n hierarchyNode,\n getInstanceKeysIterator: (props) =>\n hierarchyProvider.getNodeInstanceKeys({\n parentNode: hierarchyNode,\n instanceFilter: props?.instanceFilter,\n hierarchyLevelSizeLimit: props?.hierarchyLevelSizeLimit,\n }),\n instanceFilter: node.instanceFilter,\n setInstanceFilter: (filter) => actions.setInstanceFilter(nodeId, filter),\n sizeLimit: node.hierarchyLimit,\n setSizeLimit: (value) => actions.setHierarchyLimit(nodeId, value),\n };\n },\n [actions, hierarchyProvider],\n );\n\n const renderProps: RendererProps = useMemo(() => {\n if (state.model.rootNode.error) {\n return { rootErrorRendererProps: { error: state.model.rootNode.error, reloadTree, getHierarchyLevelDetails } };\n }\n return {\n rootErrorRendererProps: undefined,\n treeRendererProps: state.rootNodes\n ? { rootNodes: state.rootNodes, expandNode, selectNodes, isNodeSelected, reloadTree, getHierarchyLevelDetails }\n : undefined,\n };\n }, [\n expandNode,\n getHierarchyLevelDetails,\n isNodeSelected,\n reloadTree,\n selectNodes,\n state.model.rootNode.error,\n state.rootNodes,\n ]);\n\n return {\n ...renderProps,\n isReloading: !!state.model.rootNode.isLoading || isSearching,\n getTreeModelNode,\n getNode,\n setFormatter,\n };\n}\n\nfunction generateTreeStructure(\n parentNodeId: string | undefined,\n model: TreeModel,\n getTreeNodeErrors?: (node: HierarchyNode) => ErrorInfo[],\n): Array<TreeNode> | undefined {\n const currentChildren = model.parentChildMap.get(parentNodeId);\n if (!currentChildren) {\n return undefined;\n }\n\n return currentChildren\n .map((childId) => model.idToNode.get(childId))\n .filter((node): node is TreeModelHierarchyNode => !!node)\n .map<TreeNode>((node) => {\n return createTreeNode(node, model, getTreeNodeErrors);\n });\n}\n\nfunction createTreeNode(\n modelNode: TreeModelHierarchyNode,\n model: TreeModel,\n getTreeNodeErrors?: (node: HierarchyNode) => ErrorInfo[],\n): TreeNode {\n const allErrors = [\n // internal errors\n ...(modelNode.error ? [modelNode.error] : []),\n // external errors\n ...(getTreeNodeErrors?.(modelNode.nodeData) ?? []),\n ];\n\n let children: Array<TreeNode> | undefined;\n return {\n id: modelNode.id,\n label: modelNode.label,\n nodeData: modelNode.nodeData,\n isLoading: !!modelNode.isLoading,\n isExpanded: !!modelNode.isExpanded,\n isFilterable:\n !HierarchyNode.isGroupingNode(modelNode.nodeData) && !!modelNode.nodeData.supportsFiltering && modelNode.children,\n isFiltered: !!modelNode.instanceFilter,\n errors: allErrors,\n get children() {\n if (!children) {\n children = generateTreeStructure(modelNode.id, model, getTreeNodeErrors);\n }\n return children ? children : modelNode.children === true ? true : [];\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAiCA,SAAOuB,QAAAC,OAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CACoC,MAAAC,KAAAC,gBAAgBJ,MAAM;CAAA,IAAAK;AAAA,KAAAJ,EAAA,OAAAE,IAAA;EAA/D,MAAA,EAAAG,kBAAAC,GAAA,GAAAC,OAAyCL;AAAzCE,SAAAG;AAAgEP,IAAA,KAAAE;AAAAF,IAAA,KAAAI;OAAAA,QAAAJ,EAAA;AAAA,QACzDI;;;;;;;;;;;;;;;;;AAkBT,SAAOI,wBAAAN,IAAA;CAAA,MAAAF,IAAAC,EAAA,GAAA;CAAA,IAAAQ;CAAA,IAAAV;CAAA,IAAAW;CAAA,IAAAC;AAAA,KAAAX,EAAA,OAAAE,IAAA;AAAiC,GAAA,CAAAS,YAAAD,kBAAAD,mCAAAV,SAAAG;AAKMF,IAAA,KAAAE;AAAAF,IAAA,KAAAS;AAAAT,IAAA,KAAAD;AAAAC,IAAA,KAAAU;AAAAV,IAAA,KAAAW;QAAA;AAAAF,mCAAAT,EAAA;AAAAD,UAAAC,EAAA;AAAAU,qBAAAV,EAAA;AAAAW,eAAAX,EAAA;;CACN,MAAAO,KAAAJ,gBAAgBJ,MAAM;CAAA,IAAAM;CAAA,IAAAD;AAAA,KAAAJ,EAAA,OAAAO,IAAA;AAA5D,GAAA,CAAAF,qBAAAD,QAAsCG;AAAuBP,IAAA,KAAAO;AAAAP,IAAA,KAAAK;AAAAL,IAAA,KAAAI;QAAA;AAAAC,qBAAAL,EAAA;AAAAI,SAAAJ,EAAA;;CAAA,IAAAY;AAAA,KAAAZ,EAAA,OAAAS,kCAAAT,EAAA,OAAAK,oBAAAL,EAAA,QAAAU,oBAAAV,EAAA,QAAAW,YAAA;AACdC,OAAA;GAAAD;GAAAD;GAAAL;GAAAI;GAK9C;AAAAT,IAAA,KAAAS;AAAAT,IAAA,KAAAK;AAAAL,IAAA,MAAAU;AAAAV,IAAA,MAAAW;AAAAX,IAAA,MAAAY;OAAAA,MAAAZ,EAAA;CALD,MAAAa,iBAAuB9B,wBAAwB6B,GAK7C;AACF,KAAIR,KAAIU,2BAA4BC,KAAAA,KAAaX,KAAIY,mBAA6BC,WAAA;EAAA,IAAAC;AAAA,MAAAlB,EAAA,QAAAI,KAAAY,qBAAAhB,EAAA,QAAAa,gBAAA;AAC3CK,QAAA;IAAA,GAAKd,KAAIY;IAAkB,GAAKH;IAAgB;AAAAb,KAAA,MAAAI,KAAAY;AAAAhB,KAAA,MAAAa;AAAAb,KAAA,MAAAkB;QAAAA,MAAAlB,EAAA;EAAA,IAAAmB;AAAA,MAAAnB,EAAA,QAAAI,QAAAJ,EAAA,QAAAkB,IAAA;AAA9EC,QAAA;IAAA,GAAKf;IAAIY,mBAAqBE;IAAkD;AAAAlB,KAAA,MAAAI;AAAAJ,KAAA,MAAAkB;AAAAlB,KAAA,MAAAmB;QAAAA,MAAAnB,EAAA;AAAA,SAAhFmB;;AACR,QACMf;;AA0ET,SAASD,gBAAgB,EACvBkB,sBACAC,gBACAI,uBACAG,0BACAI,sBACAG,qBAGA;CACA,MAAM,CAACY,OAAOC,YAAYtE,SAAoB;EAC5CmE,OAAO;GAAEI,0BAAU,IAAIC,KAAK;GAAEC,gCAAgB,IAAID,KAAK;GAAEE,UAAU;IAAEC,IAAIvC,KAAAA;IAAWwC,UAAUxC,KAAAA;IAAU;GAAG;EAC3GE,WAAWF,KAAAA;EACZ,CAAC;CACF,MAAMyC,2BAA2BvE,UAAUyC,sBAAsB;CACjE,MAAM+B,8BAA8BxE,UAAU4C,yBAAyB;CACvE,MAAM6B,0BAA0BzE,UAAUgD,qBAAqB;CAC/D,MAAM0B,uBAAuB1E,UAAUmD,kBAAkB;CAEzD,MAAM,CAACwB,WAAWjF,eAEd,IAAIE,aACDiE,UAAU;AAKTG,WAAS;GAAEH;GAAO7B,WAHhB6B,MAAMM,eAAeS,IAAI9C,KAAAA,EAAU,KAAKA,KAAAA,IACpC+C,sBAAsB/C,KAAAA,GAAW+B,OAAOa,qBAAqBI,QAAQ,GACrEhD,KAAAA;GACuB,CAAC;KAE/BiD,YAAYpC,aAAa4B,yBAAyBO,UAAUC,YAAYpC,SAAS,GACjF7B,UAAU0D,4BAA4BM,UAAUhE,MAAM,GACtDA,YAAU2D,wBAAwBK,UAAUhE,QAC/C,CACJ,CAAC;CACD,MAAMkE,mBAAmBvF,QAAkC;CAE3D,MAAM,CAACwF,mBAAmBC,wBAAwBxF,UAAyC;AAC3FH,iBAAgB;EACd,MAAM4F,WAAW/C,sBAAsB;AACvC+C,WAAS1B,aAAauB,iBAAiBF,QAAQ;EAC/C,MAAMM,iCAAiCD,SAASE,iBAAiBC,aAAaC,wBAAwB;GACpG,MAAMC,qBAAqBD,oBAAoBE,cAAcC,cAAc5D,KAAAA;AAC3E6C,WAAQgB,WAAW,EAAE5B,OAAOyB,qBAAqB,YAAY,QAAQ,CAAC;IACtE;AACFb,UAAQO,qBAAqBC,SAAS;AACtCD,uBAAqBC,SAAS;AAC9B,eAAa;AACXC,mCAAgC;AAChCT,WAAQiB,OAAO;AACf7F,eAAYoF,SAAS;;IAEtB,CAACR,SAASvC,qBAAqB,CAAC;CAEnC,MAAM,CAACyD,aAAaC,kBAAkBpG,SAAS,MAAM;AACrDH,iBAAgB;EACd,IAAIwG,WAAW;EACf,MAAMC,aAAa,IAAIC,iBAAiB;AACxC,GAAM,YAAY;AAChB,OAAI,CAAChB,kBACH;AAGF,OAAI,CAAC5C,gBAAgB;AACnB4C,sBAAkBiB,mBAAmBpE,KAAAA,EAAU;AAE/C6C,YAAQgB,WAAW,EAAE5B,OAAO,QAAQ,CAAC;AACrC+B,mBAAe,MAAM;AACrB;;AAGFA,kBAAe,KAAK;GACpB,IAAIK;AACJ,OAAI;AACFA,YAAQ,MAAM9D,eAAe,EAAEC,aAAa0D,WAAWI,QAAQ,CAAC;WAC1D,WACE;AACR,QAAI,CAACL,UAAU;AACbd,uBAAkBiB,mBAAmBC,QAAQ,EAAEA,OAAO,GAAGrE,KAAAA,EAAU;AACnEgE,oBAAe,MAAM;;;MAGvB;AACJ,eAAa;AACXE,cAAWK,OAAO;AAClBN,cAAW;;IAEZ;EAACd;EAAmB5C;EAAgBsC;EAAQ,CAAC;CAEhD,MAAMvD,mBAAmB9B,aACtBkE,WAAmB;AAClB,SAAOmB,QAAQpB,QAAQC,OAAO;IAEhC,CAACmB,QACH,CAAC;CAED,MAAMpB,UAAUjE,aACbkE,aAAyC;EACxC,MAAMJ,OAAOuB,QAAQpB,QAAQC,SAAO;AACpC,MAAI,CAACJ,QAAQA,KAAKiB,OAAOvC,KAAAA,EACvB;AAEF,SAAOwE,eAAelD,MAAMW,MAAMF,OAAOa,qBAAqBI,QAAQ;IAExE;EAACH;EAASD;EAAsBX,MAAMF;EACxC,CAAC;CAED,MAAM0C,aAAajH,aAChBkE,UAAgBgD,eAAwB;AACvC7B,UAAQ4B,WAAW/C,UAAQgD,WAAW;IAExC,CAAC7B,QACH,CAAC;CAED,MAAMgB,aAAarG,aAChBmH,YAAY;AACX9B,UAAQgB,WAAWc,QAAQ;IAE7B,CAAC9B,QACH,CAAC;CAED,MAAM+B,cAAcpH,aACjBqH,SAAwBC,eAAoC;AAC3DjC,UAAQ+B,YAAYC,SAASC,WAAW;IAE1C,CAACjC,QACH,CAAC;CAED,MAAMkC,iBAAiBvH,aACpBkE,aAAmB3D,UAAUgH,eAAe9C,MAAMF,OAAOL,SAAO,EACjE,CAACO,MACH,CAAC;CAED,MAAMN,eAAenE,aAClBoE,cAAoD;AACnDsB,mBAAiBF,UAAUpB;AAC3B,MAAI,CAACuB,kBACH;AAGFA,oBAAkBxB,aAAaC,UAAU;IAE3C,CAACuB,kBACH,CAAC;CAED,MAAM6B,2BAA2BxH,aAC9BkE,aAAW;EACV,MAAMJ,SAAOuB,QAAQpB,QAAQC,SAAO;AACpC,MAAI,CAACyB,qBAAqB,CAAC7B,OACzB;EAEF,MAAM2D,gBAAgB3D,OAAKkB;AAC3B,MAAIyC,iBAAiBpH,cAAcqH,eAAeD,cAAc,CAC9D;AAGF,SAAO;GACLA;GACAE,0BAA0BnG,YACxBmE,kBAAkBiC,oBAAoB;IACpCC,YAAYJ;IACZK,gBAAgBtG,SAAOsG;IACvBC,yBAAyBvG,SAAOuG;IACjC,CAAC;GACJD,gBAAgBhE,OAAKgE;GACrBE,oBAAoBxE,WAAW6B,QAAQ2C,kBAAkB9D,UAAQV,OAAO;GACxEyE,WAAWnE,OAAKoE;GAChBC,eAAeC,UAAU/C,QAAQgD,kBAAkBnE,UAAQkE,MAAK;GACjE;IAEH,CAAC/C,SAASM,kBACZ,CAAC;AAsBD,QAAO;EACL,GArBiCzF,cAAc;AAC/C,OAAIuE,MAAMF,MAAMO,SAASlB,MACvB,QAAO,EAAErB,wBAAwB;IAAEqB,OAAOa,MAAMF,MAAMO,SAASlB;IAAOyC;IAAYmB;IAAyB,EAAG;AAEhH,UAAO;IACLjF,wBAAwBC,KAAAA;IACxBC,mBAAmBgC,MAAM/B,YACrB;KAAEA,WAAW+B,MAAM/B;KAAWuE;KAAYG;KAAaG;KAAgBlB;KAAYmB;KAA0B,GAC7GhF,KAAAA;IACL;KACA;GACDyE;GACAO;GACAD;GACAlB;GACAe;GACA3C,MAAMF,MAAMO,SAASlB;GACrBa,MAAM/B;GACP,CAAC;EAIAsB,aAAa,CAAC,CAACS,MAAMF,MAAMO,SAASyD,aAAahC;EACjDzE;EACAmC;EACAE;EACD;;AAGH,SAASoB,sBACPiD,cACAjE,OACAV,mBAC6B;CAC7B,MAAM4E,kBAAkBlE,MAAMM,eAAeS,IAAIkD,aAAa;AAC9D,KAAI,CAACC,gBACH;AAGF,QAAOA,gBACJC,KAAKC,YAAYpE,MAAMI,SAASW,IAAIqD,QAAQ,CAAC,CAC7CnF,QAAQM,SAAyC,CAAC,CAACA,KAAK,CACxD4E,KAAe5E,SAAS;AACvB,SAAOkD,eAAelD,MAAMS,OAAOV,kBAAkB;GACrD;;AAGN,SAASmD,eACP4B,WACArE,OACAV,mBACU;CACV,MAAMgF,YAAY,CAEhB,GAAID,UAAUhF,QAAQ,CAACgF,UAAUhF,MAAM,GAAG,EAAE,EAE5C,GAAIC,oBAAoB+E,UAAU5D,SAAS,IAAI,EAAE,CAClD;CAED,IAAI8D;AACJ,QAAO;EACL/D,IAAI6D,UAAU7D;EACdgE,OAAOH,UAAUG;EACjB/D,UAAU4D,UAAU5D;EACpBuD,WAAW,CAAC,CAACK,UAAUL;EACvBrB,YAAY,CAAC,CAAC0B,UAAU1B;EACxB8B,cACE,CAAC3I,cAAcqH,eAAekB,UAAU5D,SAAS,IAAI,CAAC,CAAC4D,UAAU5D,SAASiE,qBAAqBL,UAAUE;EAC3GI,YAAY,CAAC,CAACN,UAAUd;EACxBqB,QAAQN;EACR,IAAIC,WAAW;AACb,OAAI,CAACA,SACHA,YAAWvD,sBAAsBqD,UAAU7D,IAAIR,OAAOV,kBAAkB;AAE1E,UAAOiF,WAAWA,WAAWF,UAAUE,aAAa,OAAO,OAAO,EAAE;;EAEvE"}
@@ -21,14 +21,14 @@ var TreeActions = class {
21
21
  this._onHierarchyLoadError = _onHierarchyLoadError;
22
22
  this._loader = new NoopTreeLoader();
23
23
  this._nodeIdFactory = nodeIdFactory ?? createNodeId;
24
- this._currentModel = seed ?? ( /* c8 ignore next */ {
24
+ this._currentModel = seed ?? {
25
25
  idToNode: /* @__PURE__ */ new Map(),
26
26
  parentChildMap: /* @__PURE__ */ new Map(),
27
27
  rootNode: {
28
28
  id: void 0,
29
29
  nodeData: void 0
30
30
  }
31
- });
31
+ };
32
32
  this._nodeLoader = this.createNodeLoader();
33
33
  }
34
34
  createNodeLoader() {
@@ -93,7 +93,6 @@ var TreeActions = class {
93
93
  }
94
94
  loadNodes(parentId, ignoreCache) {
95
95
  const parentNode = this._currentModel.idToNode.get(parentId);
96
- /* c8 ignore next 3 */
97
96
  if (!parentNode) return { complete: Promise.resolve() };
98
97
  return this.loadSubTree({
99
98
  parent: parentNode,
@@ -121,7 +120,6 @@ var TreeActions = class {
121
120
  };
122
121
  const buildNode = (node) => !!options?.discardState || node.id === parentId ? node : addAttributes(node, oldModel);
123
122
  const rootNode = parentId !== void 0 ? this.getNode(parentId) : currModel.rootNode;
124
- /* c8 ignore next 3 */
125
123
  if (!rootNode) return { complete: Promise.resolve() };
126
124
  if (parentId === void 0) this._reset.next();
127
125
  return this.loadSubTree({
@@ -263,13 +261,11 @@ function createHierarchyLevelOptions(model, nodeId) {
263
261
  hierarchyLevelSizeLimit: modelNode.hierarchyLimit
264
262
  };
265
263
  }
266
- /* c8 ignore start */
267
264
  var NoopTreeLoader = class {
268
265
  loadNodes() {
269
266
  return EMPTY;
270
267
  }
271
268
  };
272
- /* c8 ignore end */
273
269
  var TimeTracker = class {
274
270
  _start;
275
271
  _stopped = false;
@@ -281,7 +277,6 @@ var TimeTracker = class {
281
277
  this._stopped = true;
282
278
  }
283
279
  finish() {
284
- /* c8 ignore next 3 */
285
280
  if (this._stopped) return;
286
281
  this._stopped = true;
287
282
  const elapsedTime = Date.now() - this._start;