@itwin/presentation-hierarchies-react 2.0.0-alpha.6 → 2.0.0-alpha.60
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.md +1137 -11
- package/README.md +93 -160
- package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts +49 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.js +93 -0
- package/lib/presentation-hierarchies-react/FlatTreeNode.js.map +1 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.d.ts +24 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.js +40 -0
- package/lib/presentation-hierarchies-react/LocalizationContext.js.map +1 -0
- package/lib/presentation-hierarchies-react/Renderers.d.ts +92 -0
- package/lib/presentation-hierarchies-react/Renderers.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/TreeNode.d.ts +80 -0
- package/lib/presentation-hierarchies-react/TreeNode.d.ts.map +1 -0
- package/lib/{esm/presentation-hierarchies-react → presentation-hierarchies-react}/UseIModelTree.d.ts +28 -15
- package/lib/presentation-hierarchies-react/UseIModelTree.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseIModelTree.js +183 -0
- package/lib/presentation-hierarchies-react/UseIModelTree.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts +30 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.js +57 -0
- package/lib/presentation-hierarchies-react/UseNodeHighlighting.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts +23 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.js +124 -0
- package/lib/presentation-hierarchies-react/UseSelectionHandler.js.map +1 -0
- package/lib/presentation-hierarchies-react/UseTree.d.ts +112 -0
- package/lib/presentation-hierarchies-react/UseTree.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/UseTree.js +297 -0
- package/lib/presentation-hierarchies-react/UseTree.js.map +1 -0
- package/lib/presentation-hierarchies-react/Utils.js +56 -0
- package/lib/presentation-hierarchies-react/Utils.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js +10 -0
- package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts +9 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js +12 -0
- package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeActions.js +294 -0
- package/lib/presentation-hierarchies-react/internal/TreeActions.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeLoader.js +98 -0
- package/lib/presentation-hierarchies-react/internal/TreeLoader.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.d.ts +1 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.js +120 -0
- package/lib/presentation-hierarchies-react/internal/TreeModel.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +35 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js +141 -0
- package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +1 -0
- package/lib/presentation-hierarchies-react/internal/Utils.js +42 -0
- package/lib/presentation-hierarchies-react/internal/Utils.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts +38 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js +380 -0
- package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts +27 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js +185 -0
- package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts +49 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.js +88 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts +38 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js +63 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts +29 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js +91 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts +31 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js +155 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.css +25 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts +14 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +534 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts +75 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts.map +1 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js +417 -0
- package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js.map +1 -0
- package/lib/presentation-hierarchies-react-extract.d.ts +17 -0
- package/lib/presentation-hierarchies-react-extract.js +16 -0
- package/lib/presentation-hierarchies-react-stratakit.d.ts +8 -0
- package/lib/presentation-hierarchies-react-stratakit.js +8 -0
- package/lib/presentation-hierarchies-react.d.ts +11 -0
- package/lib/presentation-hierarchies-react.js +8 -0
- package/lib/public/locales/en/PresentationHierarchies_1.0.json +26 -0
- package/package.json +78 -56
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts +0 -75
- package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/TreeNode.js +0 -12
- package/lib/esm/presentation-hierarchies-react/TreeNode.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts +0 -15
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js +0 -22
- package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js +0 -62
- package/lib/esm/presentation-hierarchies-react/UseIModelTree.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts +0 -46
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js +0 -98
- package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts +0 -132
- package/lib/esm/presentation-hierarchies-react/UseTree.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/UseTree.js +0 -242
- package/lib/esm/presentation-hierarchies-react/UseTree.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts +0 -2
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js +0 -11
- package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts +0 -53
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js +0 -307
- package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts +0 -44
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js +0 -94
- package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts +0 -70
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js +0 -153
- package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +0 -28
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js +0 -128
- package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts +0 -23
- package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/internal/Utils.js +0 -58
- package/lib/esm/presentation-hierarchies-react/internal/Utils.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts +0 -21
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js +0 -30
- package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts +0 -73
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js +0 -34
- package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts +0 -25
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js +0 -40
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts +0 -23
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js +0 -72
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts +0 -40
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js +0 -80
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts +0 -30
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js +0 -48
- package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js.map +0 -1
- package/lib/esm/presentation-hierarchies-react.d.ts +0 -13
- package/lib/esm/presentation-hierarchies-react.d.ts.map +0 -1
- package/lib/esm/presentation-hierarchies-react.js +0 -16
- package/lib/esm/presentation-hierarchies-react.js.map +0 -1
package/README.md
CHANGED
|
@@ -2,7 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
Copyright © Bentley Systems, Incorporated. All rights reserved. See LICENSE.md for license terms and full copyright notice.
|
|
4
4
|
|
|
5
|
-
The `@itwin/presentation-hierarchies-react` package provides APIs for building a headless UI for rendering tree components based on data in an [iTwin.js iModel](https://www.itwinjs.org/learning/imodels/#imodel-overview). In addition, it delivers a set of [
|
|
5
|
+
The `@itwin/presentation-hierarchies-react` package provides APIs for building a headless UI for rendering tree components based on data in an [iTwin.js iModel](https://www.itwinjs.org/learning/imodels/#imodel-overview). In addition, it delivers a set of [StrataKit](https://www.npmjs.com/package/@stratakit/bricks)-based components for rendering the tree.
|
|
6
|
+
|
|
7
|
+
## Entry points
|
|
8
|
+
|
|
9
|
+
Because StrataKit packages are optional peer dependencies, the package exposes two entry points:
|
|
10
|
+
|
|
11
|
+
| Entry point | Requires StrataKit peer dependencies | Description |
|
|
12
|
+
| ------------------------------------------------- | ------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
|
|
13
|
+
| `@itwin/presentation-hierarchies-react` | ❌ | Core API - headless hooks and utilities, including localization helpers. |
|
|
14
|
+
| `@itwin/presentation-hierarchies-react/stratakit` | ✔️ | StrataKit-based components and actions (`StrataKitTreeRenderer`, `TreeNodeFilterAction`, `TreeNodeRenameAction`). |
|
|
6
15
|
|
|
7
16
|
## Headless UI
|
|
8
17
|
|
|
@@ -15,30 +24,22 @@ The package provides different flavors of the same hook for creating and managin
|
|
|
15
24
|
| Supported data source | any | iModel | any | iModel |
|
|
16
25
|
| Integration with [Unified Selection](https://www.itwinjs.org/presentation/unified-selection/) system | ❌ | ❌ | ✔️ | ✔️ |
|
|
17
26
|
|
|
18
|
-
All these hooks return
|
|
19
|
-
|
|
20
|
-
- `isLoading` is a boolean indicating whether the root tree nodes are being loaded. Set to `true` on initial load and on reload (e.g. when iModel data changes).
|
|
21
|
-
|
|
22
|
-
- `rootNodes` is an array of root tree nodes and is what the component should render. There are several types of nodes:
|
|
23
|
-
|
|
24
|
-
- A `PresentationHierarchyNode` is the primary type of node, created based on the hierarchy definition. The `isPresentationHierarchyNode` type guard utility may be used to check if a node is of this type.
|
|
25
|
-
- A `PresentationInfoNode` is a non-expandable, non-selectable informational type of node, generally created when for some reason we don't have any real nodes to show. There may be different reasons like filtered-out nodes, too large result set, a network error, etc. The `type` attribute of the node indicates that.
|
|
26
|
-
|
|
27
|
-
- `expandNode` function to expand or collapse a node.
|
|
28
|
-
|
|
29
|
-
- `isNodeSelected` and `selectNodes` function to inspect and change tree selection.
|
|
27
|
+
All these hooks return a `UseTreeResult` object with top-level properties and two optional renderer prop bags:
|
|
30
28
|
|
|
31
|
-
- `
|
|
29
|
+
- `isReloading` is a boolean that is `true` while the tree is being reloaded (does not apply to the initial load).
|
|
32
30
|
|
|
33
|
-
- `
|
|
31
|
+
- `getNode` function to get a tree node by its id.
|
|
34
32
|
|
|
35
|
-
|
|
36
|
-
- hierarchy level instance filter,
|
|
37
|
-
- instance keys of the nodes in the hierarchy level.
|
|
33
|
+
- `setFormatter` function to set the active node label formatter.
|
|
38
34
|
|
|
39
|
-
- `
|
|
35
|
+
- `rootErrorRendererProps` is defined (and `treeRendererProps` is `undefined`) when root nodes fail to load. Pass it directly to `StrataKitRootErrorRenderer` or use it to build a custom error UI.
|
|
40
36
|
|
|
41
|
-
- `
|
|
37
|
+
- `treeRendererProps` is defined once root nodes have loaded successfully. It is `undefined` during the initial load. Pass it directly to `StrataKitTreeRenderer` or use it to build a custom tree renderer. It contains:
|
|
38
|
+
- `rootNodes` — array of `TreeNode` items to render.
|
|
39
|
+
- `expandNode` — function to expand or collapse a node.
|
|
40
|
+
- `isNodeSelected` and `selectNodes` — functions to inspect and change tree selection.
|
|
41
|
+
- `getHierarchyLevelDetails` — function to get details of a specific hierarchy level (size limit, instance filter, instance key iterator).
|
|
42
|
+
- `reloadTree` — function to reload part of the tree, optionally keeping its state.
|
|
42
43
|
|
|
43
44
|
#### `useTree` props
|
|
44
45
|
|
|
@@ -61,31 +62,16 @@ The hook takes 2 required properties:
|
|
|
61
62
|
|
|
62
63
|
```tsx
|
|
63
64
|
import { IModelConnection } from "@itwin/core-frontend";
|
|
64
|
-
import { SchemaContext } from "@itwin/ecschema-metadata";
|
|
65
|
-
import { ECSchemaRpcLocater } from "@itwin/ecschema-rpcinterface-common";
|
|
66
65
|
import { createCachingECClassHierarchyInspector } from "@itwin/presentation-shared";
|
|
67
66
|
import { createECSchemaProvider, createECSqlQueryExecutor, createIModelKey } from "@itwin/presentation-core-interop";
|
|
68
|
-
import {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const imodelSchemaContextsCache = new Map<string, SchemaContext>();
|
|
74
|
-
|
|
75
|
-
function getIModelSchemaContext(imodel: IModelConnection) {
|
|
76
|
-
const imodelKey = createIModelKey(imodel);
|
|
77
|
-
let context = imodelSchemaContextsCache.get(imodelKey);
|
|
78
|
-
if (!context) {
|
|
79
|
-
context = new SchemaContext();
|
|
80
|
-
context.addLocater(new ECSchemaRpcLocater(imodel.getRpcProps()));
|
|
81
|
-
imodelSchemaContextsCache.set(imodelKey, context);
|
|
82
|
-
imodel.onClose.addListener(() => imodelSchemaContextsCache.delete(imodelKey));
|
|
83
|
-
}
|
|
84
|
-
return context;
|
|
85
|
-
}
|
|
67
|
+
import {
|
|
68
|
+
createLimitingECSqlQueryExecutor,
|
|
69
|
+
createNodesQueryClauseFactory,
|
|
70
|
+
HierarchyDefinition,
|
|
71
|
+
} from "@itwin/presentation-hierarchies";
|
|
86
72
|
|
|
87
73
|
function createIModelAccess(imodel: IModelConnection) {
|
|
88
|
-
const schemaProvider = createECSchemaProvider(
|
|
74
|
+
const schemaProvider = createECSchemaProvider(imodel.schemaContext);
|
|
89
75
|
return {
|
|
90
76
|
imodelKey: createIModelKey(imodel),
|
|
91
77
|
...schemaProvider,
|
|
@@ -107,78 +93,35 @@ In addition to [props required by `useIModelTree`](#useimodeltree-props), the ho
|
|
|
107
93
|
- `selectionStorage` - unified selection storage used across different app's components, allowing them all to share selection state.
|
|
108
94
|
- `sourceName` - a string that distinguishes selection changes being made by different components. The value should be unique for each component.
|
|
109
95
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
This is a React hook that helps implement different selection modes in a tree, whose state is managed through one of the [tree state hooks](#tree-state-hooks).
|
|
113
|
-
|
|
114
|
-
It takes 3 required properties:
|
|
115
|
-
|
|
116
|
-
- `rootNodes` and `selectNodes` are the corresponding properties from the tree state object, created using one of the [tree state hooks](#tree-state-hooks).
|
|
117
|
-
|
|
118
|
-
- `selectionMode` is a string that defines the selection mode. It can be one of the following values:
|
|
119
|
-
- `none` - no selection is allowed,
|
|
120
|
-
- `single` - only one node can be selected at a time,
|
|
121
|
-
- `extended` - multiple nodes can be selected using shift and ctrl keys,
|
|
122
|
-
- `multiple` - multiple nodes can be selected without using shift or ctrl keys.
|
|
123
|
-
|
|
124
|
-
The returned object contains 2 functions, that should be called by the node renderer: `onNodeClick` and `onNodeKeyDown`.
|
|
125
|
-
|
|
126
|
-
Our [tree renderer implementation](#treerenderer) calls this hook and passes the callbacks to the [node renderer](#treenoderenderer), so there's no need to use it unless implementing a custom tree renderer.
|
|
96
|
+
## StrataKit components
|
|
127
97
|
|
|
128
|
-
|
|
98
|
+
While the package provides a headless UI, it also delivers a set of [StrataKit](https://www.npmjs.com/package/@stratakit/bricks)-based components for rendering the tree, which should cover majority of use cases. Consumers using the below components are required to provide compatible `@stratakit/bricks`/`@stratakit/icons`/`@stratakit/foundations` packages, which are optional peer dependencies to this package.
|
|
129
99
|
|
|
130
|
-
|
|
100
|
+
### `StrataKitTreeRenderer`
|
|
131
101
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
The component is based on [iTwinUI Tree component](https://itwinui.bentley.com/docs/tree) and uses our [`TreeNodeRenderer`](#treenoderenderer) to render the nodes. In addition, it makes use of the [`useSelectionHandler` hook](#useselectionhandler-hook) to add selection modes' support.
|
|
135
|
-
|
|
136
|
-
The iTwinUI Tree component requires a `getNode` function that maps nodes to `NodeData<TNode>` objects. Our `TreeRenderer` uses `createRenderedTreeNodeData` function for this purpose, and it's available for consumers as well, in case a custom iTwinUI Tree component implementation is being written.
|
|
137
|
-
|
|
138
|
-
### `TreeNodeRenderer`
|
|
139
|
-
|
|
140
|
-
The component is based on `TreeNode` component from iTwinUI library and supports the following features:
|
|
141
|
-
|
|
142
|
-
- Rendering informational type of nodes (e.g. "No filter matches", "Too many nodes in a hierarchy level", etc.).
|
|
143
|
-
- Reporting click and key down events for use with [`useSelectionHandler` hook](#useselectionhandler-hook).
|
|
144
|
-
- Icons, selection, expand / collapse.
|
|
145
|
-
- Action buttons to clear / set hierarchy level instance filter.
|
|
102
|
+
The component renders a virtualized tree using the `Tree` component from `@stratakit/structures`. It handles node selection modes, error display, and virtualized scrolling. It accepts a required `treeLabel` prop (used for accessibility) and spreads `treeRendererProps` returned by the tree state hooks.
|
|
146
103
|
|
|
147
104
|
## Full example
|
|
148
105
|
|
|
149
106
|
```tsx
|
|
150
107
|
import { IModelConnection } from "@itwin/core-frontend";
|
|
151
|
-
import { SchemaContext } from "@itwin/ecschema-metadata";
|
|
152
|
-
import { ECSchemaRpcLocater } from "@itwin/ecschema-rpcinterface-common";
|
|
153
108
|
import { createCachingECClassHierarchyInspector } from "@itwin/presentation-shared";
|
|
154
109
|
import { createECSchemaProvider, createECSqlQueryExecutor, createIModelKey } from "@itwin/presentation-core-interop";
|
|
155
|
-
import {
|
|
110
|
+
import {
|
|
111
|
+
createLimitingECSqlQueryExecutor,
|
|
112
|
+
createNodesQueryClauseFactory,
|
|
113
|
+
HierarchyDefinition,
|
|
114
|
+
} from "@itwin/presentation-hierarchies";
|
|
156
115
|
|
|
157
116
|
import { createBisInstanceLabelSelectClauseFactory, Props } from "@itwin/presentation-shared";
|
|
158
117
|
|
|
159
|
-
import {
|
|
118
|
+
import { useIModelUnifiedSelectionTree } from "@itwin/presentation-hierarchies-react";
|
|
119
|
+
import { StrataKitTreeRenderer, StrataKitRootErrorRenderer } from "@itwin/presentation-hierarchies-react/stratakit";
|
|
160
120
|
import { createStorage, SelectionStorage } from "@itwin/unified-selection";
|
|
161
121
|
import { useEffect, useState } from "react";
|
|
162
122
|
|
|
163
|
-
// Not really part of the package, but we need SchemaContext to create the tree state. It's
|
|
164
|
-
// recommended to cache the schema context and reuse it across different application's components to
|
|
165
|
-
// avoid loading and storing same schemas multiple times.
|
|
166
|
-
const imodelSchemaContextsCache = new Map<string, SchemaContext>();
|
|
167
|
-
|
|
168
|
-
function getIModelSchemaContext(imodel: IModelConnection) {
|
|
169
|
-
const imodelKey = createIModelKey(imodel);
|
|
170
|
-
let context = imodelSchemaContextsCache.get(imodelKey);
|
|
171
|
-
if (!context) {
|
|
172
|
-
context = new SchemaContext();
|
|
173
|
-
context.addLocater(new ECSchemaRpcLocater(imodel.getRpcProps()));
|
|
174
|
-
imodelSchemaContextsCache.set(imodelKey, context);
|
|
175
|
-
imodel.onClose.addListener(() => imodelSchemaContextsCache.delete(imodelKey));
|
|
176
|
-
}
|
|
177
|
-
return context;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
123
|
function createIModelAccess(imodel: IModelConnection) {
|
|
181
|
-
const schemaProvider = createECSchemaProvider(
|
|
124
|
+
const schemaProvider = createECSchemaProvider(imodel.schemaContext);
|
|
182
125
|
return {
|
|
183
126
|
imodelKey: createIModelKey(imodel),
|
|
184
127
|
...schemaProvider,
|
|
@@ -214,7 +157,10 @@ function getHierarchyDefinition({ imodelAccess }: { imodelAccess: IModelAccess }
|
|
|
214
157
|
// Create a factory for building labels SELECT query clauses according to BIS conventions
|
|
215
158
|
const labelsQueryFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: imodelAccess });
|
|
216
159
|
// Create a factory for building nodes SELECT query clauses in a format understood by the provider
|
|
217
|
-
const nodesQueryFactory = createNodesQueryClauseFactory({
|
|
160
|
+
const nodesQueryFactory = createNodesQueryClauseFactory({
|
|
161
|
+
imodelAccess,
|
|
162
|
+
instanceLabelSelectClauseFactory: labelsQueryFactory,
|
|
163
|
+
});
|
|
218
164
|
return {
|
|
219
165
|
defineHierarchyLevel: async () => [
|
|
220
166
|
{
|
|
@@ -226,7 +172,10 @@ function getHierarchyDefinition({ imodelAccess }: { imodelAccess: IModelAccess }
|
|
|
226
172
|
ecClassId: { selector: "this.ECClassId" },
|
|
227
173
|
ecInstanceId: { selector: "this.ECInstanceId" },
|
|
228
174
|
nodeLabel: {
|
|
229
|
-
selector: await labelsQueryFactory.createSelectClause({
|
|
175
|
+
selector: await labelsQueryFactory.createSelectClause({
|
|
176
|
+
classAlias: "this",
|
|
177
|
+
className: "BisCore.PhysicalModel",
|
|
178
|
+
}),
|
|
230
179
|
},
|
|
231
180
|
hasChildren: false,
|
|
232
181
|
})}
|
|
@@ -239,8 +188,14 @@ function getHierarchyDefinition({ imodelAccess }: { imodelAccess: IModelAccess }
|
|
|
239
188
|
}
|
|
240
189
|
|
|
241
190
|
/** Internal component that creates and renders tree state. */
|
|
242
|
-
function MyTreeComponentInternal({
|
|
243
|
-
|
|
191
|
+
function MyTreeComponentInternal({
|
|
192
|
+
imodelAccess,
|
|
193
|
+
selectionStorage,
|
|
194
|
+
}: {
|
|
195
|
+
imodelAccess: IModelAccess;
|
|
196
|
+
selectionStorage: SelectionStorage;
|
|
197
|
+
}) {
|
|
198
|
+
const treeProps = useIModelUnifiedSelectionTree({
|
|
244
199
|
// the unified selection storage used by all app components let them share selection state
|
|
245
200
|
selectionStorage,
|
|
246
201
|
// the source name is used to distinguish selection changes being made by different components
|
|
@@ -250,85 +205,63 @@ function MyTreeComponentInternal({ imodelAccess, selectionStorage }: { imodelAcc
|
|
|
250
205
|
// supply the hierarchy definition
|
|
251
206
|
getHierarchyDefinition,
|
|
252
207
|
});
|
|
253
|
-
|
|
208
|
+
|
|
209
|
+
if (treeProps.rootErrorRendererProps) {
|
|
210
|
+
// render error component if tree fails to load
|
|
211
|
+
return <StrataKitRootErrorRenderer {...treeProps.rootErrorRendererProps} />;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (treeProps.isReloading || treeProps.treeRendererProps === undefined) {
|
|
254
215
|
return "Loading...";
|
|
255
216
|
}
|
|
256
|
-
|
|
217
|
+
|
|
218
|
+
return <StrataKitTreeRenderer {...treeProps.treeRendererProps} treeLabel="My Tree" />;
|
|
257
219
|
}
|
|
258
220
|
```
|
|
259
221
|
|
|
260
222
|
## Localization
|
|
261
223
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
Example:
|
|
224
|
+
This package delivers a locale JSON file with English strings that follows the [`i18next JSON format`](https://www.i18next.com/misc/json-format). To enable localization, register `LOCALIZATION_NAMESPACES` during initialization and wrap components in `LocalizationContextProvider`:
|
|
265
225
|
|
|
266
226
|
```tsx
|
|
267
|
-
import {
|
|
268
|
-
|
|
269
|
-
|
|
227
|
+
import {
|
|
228
|
+
LocalizationContextProvider,
|
|
229
|
+
LOCALIZATION_NAMESPACES,
|
|
230
|
+
useIModelUnifiedSelectionTree,
|
|
231
|
+
} from "@itwin/presentation-hierarchies-react";
|
|
232
|
+
import { StrataKitTreeRenderer } from "@itwin/presentation-hierarchies-react/stratakit";
|
|
270
233
|
|
|
271
|
-
|
|
234
|
+
// Register localization namespaces with `i18next` based localization provider.
|
|
235
|
+
for (const namespace of LOCALIZATION_NAMESPACES) {
|
|
236
|
+
await localization.registerNamespace(namespace);
|
|
237
|
+
}
|
|
272
238
|
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
clearHierarchyLevelFilter: "Clear active filter",
|
|
282
|
-
noFilteredChildren: "No child nodes match current filter",
|
|
283
|
-
resultLimitExceeded: "There are more items than allowed limit of {{limit}}.",
|
|
284
|
-
resultLimitExceededWithFiltering: "Please provide <link>additional filtering</link> - there are more items than allowed limit of {{limit}}.",
|
|
285
|
-
increaseHierarchyLimit: "<link>Increase the hierarchy level size limit to {{limit}}.</link>",
|
|
286
|
-
increaseHierarchyLimitWithFiltering: "Or, <link>increase the hierarchy level size limit to {{limit}}.</link>",
|
|
287
|
-
};
|
|
239
|
+
// Wrap components with LocalizationContextProvider
|
|
240
|
+
function Tree() {
|
|
241
|
+
return (
|
|
242
|
+
<LocalizationContextProvider localization={localization}>
|
|
243
|
+
<MyTreeComponent imodelAccess={imodelAccess} />
|
|
244
|
+
</LocalizationContextProvider>
|
|
245
|
+
);
|
|
246
|
+
}
|
|
288
247
|
|
|
289
248
|
function MyTreeComponent({ imodelAccess }: { imodelAccess: IModelAccess }) {
|
|
290
|
-
const
|
|
249
|
+
const treeProps = useIModelUnifiedSelectionTree({
|
|
291
250
|
sourceName: "MyTreeComponent",
|
|
292
251
|
imodelAccess,
|
|
293
|
-
localizedStrings,
|
|
294
252
|
getHierarchyDefinition,
|
|
295
253
|
});
|
|
296
|
-
if (!rootNodes) {
|
|
297
|
-
return localizedStrings.loading;
|
|
298
|
-
}
|
|
299
|
-
return <TreeRenderer rootNodes={rootNodes} expandNode={expandNode} localizedStrings={localizedStrings} onFilterClick={() => {}} />;
|
|
300
|
-
}
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
In case the `TreeNodeRenderer` component is used within a custom tree renderer, the tree component should supply localized strings through `LocalizationContextProvider`:
|
|
304
|
-
|
|
305
|
-
```tsx
|
|
306
|
-
import { Props } from "@itwin/presentation-shared";
|
|
307
|
-
|
|
308
|
-
import { ComponentPropsWithoutRef, useCallback } from "react";
|
|
309
|
-
import { Tree } from "@itwin/itwinui-react";
|
|
310
|
-
import {
|
|
311
|
-
createRenderedTreeNodeData,
|
|
312
|
-
LocalizationContextProvider,
|
|
313
|
-
RenderedTreeNode,
|
|
314
|
-
TreeNodeRenderer,
|
|
315
|
-
TreeRenderer,
|
|
316
|
-
} from "@itwin/presentation-hierarchies-react";
|
|
317
254
|
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
function MyTreeRenderer({ rootNodes }: TreeRendererProps) {
|
|
322
|
-
const nodeRenderer = useCallback<TreeProps["nodeRenderer"]>((nodeProps) => {
|
|
323
|
-
return <TreeNodeRenderer {...nodeProps} onFilterClick={() => {}} expandNode={() => {}} />;
|
|
324
|
-
}, []);
|
|
255
|
+
if (treeProps.rootErrorRendererProps) {
|
|
256
|
+
return <div>Error</div>;
|
|
257
|
+
}
|
|
325
258
|
|
|
326
|
-
|
|
259
|
+
if (treeProps.isReloading || treeProps.treeRendererProps === undefined) {
|
|
260
|
+
return <div>Loading...</div>;
|
|
261
|
+
}
|
|
327
262
|
|
|
328
|
-
return
|
|
329
|
-
<LocalizationContextProvider localizedStrings={localizedStrings}>
|
|
330
|
-
<Tree<RenderedTreeNode> data={rootNodes} nodeRenderer={nodeRenderer} getNode={getNode} enableVirtualization={true} />
|
|
331
|
-
</LocalizationContextProvider>
|
|
332
|
-
);
|
|
263
|
+
return <StrataKitTreeRenderer {...treeProps.treeRendererProps} treeLabel="My Tree" />;
|
|
333
264
|
}
|
|
334
265
|
```
|
|
266
|
+
|
|
267
|
+
`LocalizationContextProvider` accepts a `localization` prop — an object with a `getLocalizedString(key: string): string` method. It is designed to work with the `Localization` interface from `@itwin/core-common`, but a custom implementation can be used as well by providing an object with a custom `getLocalizedString` function. The provider uses it internally to resolve translation keys prefixed with localization namespace.
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { TreeNode } from "./TreeNode.js";
|
|
2
|
+
|
|
3
|
+
//#region src/presentation-hierarchies-react/FlatTreeNode.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Placeholder item that is added to hierarchy as a child for a parent item while its child items are loading.
|
|
6
|
+
*
|
|
7
|
+
* @alpha
|
|
8
|
+
*/
|
|
9
|
+
interface FlatPlaceholderItem {
|
|
10
|
+
id: string;
|
|
11
|
+
level: number;
|
|
12
|
+
placeholder: true;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* An item containing `TreeNode` node with properties needed for a flat tree structure.
|
|
16
|
+
*
|
|
17
|
+
* @alpha
|
|
18
|
+
*/
|
|
19
|
+
interface FlatTreeNodeItem {
|
|
20
|
+
id: string;
|
|
21
|
+
level: number;
|
|
22
|
+
levelSize: number;
|
|
23
|
+
posInLevel: number;
|
|
24
|
+
node: TreeNode;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* An Item describing single tree item position and its content inside tree.
|
|
28
|
+
* Returned by `useFlatTreeNodeList` hook.
|
|
29
|
+
*
|
|
30
|
+
* @alpha
|
|
31
|
+
*/
|
|
32
|
+
type FlatTreeItem = FlatTreeNodeItem | FlatPlaceholderItem;
|
|
33
|
+
/**
|
|
34
|
+
* Used to get a list of `FlatTreeItem` objects for the given list of `TreeNode` objects that represent
|
|
35
|
+
* a hierarchical structure. The resulting items can be used to render the hierarchy in a flat manner, e.g. using a
|
|
36
|
+
* virtualized list.
|
|
37
|
+
*
|
|
38
|
+
* @alpha
|
|
39
|
+
*/
|
|
40
|
+
declare function useFlatTreeItems(rootNodes: TreeNode[]): FlatTreeItem[];
|
|
41
|
+
/**
|
|
42
|
+
* Finds and returns all nodes containing errors in a given hierarchy.
|
|
43
|
+
*
|
|
44
|
+
* @alpha
|
|
45
|
+
*/
|
|
46
|
+
declare function useErrorNodes(rootNodes: TreeNode[]): Array<TreeNode & Pick<Required<TreeNode>, "error">>;
|
|
47
|
+
//#endregion
|
|
48
|
+
export { FlatTreeItem, useErrorNodes, useFlatTreeItems };
|
|
49
|
+
//# sourceMappingURL=FlatTreeNode.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { c } from "react-compiler-runtime";
|
|
2
|
+
//#region src/presentation-hierarchies-react/FlatTreeNode.ts
|
|
3
|
+
/** @alpha */
|
|
4
|
+
function isPlaceholderItem(item) {
|
|
5
|
+
return "placeholder" in item;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Used to get a list of `FlatTreeItem` objects for the given list of `TreeNode` objects that represent
|
|
9
|
+
* a hierarchical structure. The resulting items can be used to render the hierarchy in a flat manner, e.g. using a
|
|
10
|
+
* virtualized list.
|
|
11
|
+
*
|
|
12
|
+
* @alpha
|
|
13
|
+
*/
|
|
14
|
+
function useFlatTreeItems(rootNodes) {
|
|
15
|
+
const $ = c(2);
|
|
16
|
+
let t0;
|
|
17
|
+
if ($[0] !== rootNodes) {
|
|
18
|
+
t0 = getFlatItems(rootNodes, 1);
|
|
19
|
+
$[0] = rootNodes;
|
|
20
|
+
$[1] = t0;
|
|
21
|
+
} else t0 = $[1];
|
|
22
|
+
return t0;
|
|
23
|
+
}
|
|
24
|
+
function getFlatItems(nodes, level) {
|
|
25
|
+
const flatItems = [];
|
|
26
|
+
nodes.forEach((node, index) => {
|
|
27
|
+
flatItems.push({
|
|
28
|
+
node,
|
|
29
|
+
id: node.id,
|
|
30
|
+
level,
|
|
31
|
+
levelSize: nodes.length,
|
|
32
|
+
posInLevel: index + 1
|
|
33
|
+
});
|
|
34
|
+
if (!node.isExpanded) return;
|
|
35
|
+
if (node.error && (node.error.type !== "Unknown" || !node.error.isNodeExpandable)) return;
|
|
36
|
+
if (node.children !== true) {
|
|
37
|
+
const childNodes = getFlatItems(node.children, level + 1);
|
|
38
|
+
flatItems.push(...childNodes);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
flatItems.push({
|
|
42
|
+
id: `${node.id}-children-placeholder`,
|
|
43
|
+
level: level + 1,
|
|
44
|
+
placeholder: true
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
return flatItems;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Finds and returns all nodes containing errors in a given hierarchy.
|
|
51
|
+
*
|
|
52
|
+
* @alpha
|
|
53
|
+
*/
|
|
54
|
+
function useErrorNodes(rootNodes) {
|
|
55
|
+
const $ = c(2);
|
|
56
|
+
let t0;
|
|
57
|
+
if ($[0] !== rootNodes) {
|
|
58
|
+
t0 = rootNodes.flatMap(_temp);
|
|
59
|
+
$[0] = rootNodes;
|
|
60
|
+
$[1] = t0;
|
|
61
|
+
} else t0 = $[1];
|
|
62
|
+
return t0;
|
|
63
|
+
}
|
|
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;
|
|
70
|
+
}
|
|
71
|
+
function getErrorNodes(parent) {
|
|
72
|
+
const errorList = [];
|
|
73
|
+
if (parent.children === true) return [];
|
|
74
|
+
parent.children.forEach((node) => {
|
|
75
|
+
if (isErrorNode(node)) {
|
|
76
|
+
errorList.push(node);
|
|
77
|
+
if (node.error.type !== "Unknown" || !node.error.isNodeExpandable) return;
|
|
78
|
+
}
|
|
79
|
+
if (node.children !== true) {
|
|
80
|
+
const childErrorList = getErrorNodes(node);
|
|
81
|
+
errorList.push(...childErrorList);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
return errorList;
|
|
86
|
+
}
|
|
87
|
+
function isErrorNode(node) {
|
|
88
|
+
return node.error !== void 0;
|
|
89
|
+
}
|
|
90
|
+
//#endregion
|
|
91
|
+
export { isPlaceholderItem, useErrorNodes, useFlatTreeItems };
|
|
92
|
+
|
|
93
|
+
//# sourceMappingURL=FlatTreeNode.js.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { JSX, PropsWithChildren } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/presentation-hierarchies-react/LocalizationContext.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Properties for `LocalizationContextProvider`.
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
interface LocalizationContextProviderProps {
|
|
9
|
+
/** Localization object compatible with `@itwin/core-common` */
|
|
10
|
+
localization: {
|
|
11
|
+
getLocalizedString: (key: string) => string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Context provider for localizing components.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
declare function LocalizationContextProvider({
|
|
19
|
+
localization,
|
|
20
|
+
children
|
|
21
|
+
}: PropsWithChildren<LocalizationContextProviderProps>): JSX.Element;
|
|
22
|
+
//#endregion
|
|
23
|
+
export { LocalizationContextProvider };
|
|
24
|
+
//# sourceMappingURL=LocalizationContext.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalizationContext.d.ts","names":[],"sources":["../../src/presentation-hierarchies-react/LocalizationContext.tsx"],"mappings":";;;AAW0C;;;;AAAA,UAQhC,gCAAA;EAEQ;EAAhB,YAAA;IAAgB,kBAAA,GAAqB,GAAA;EAAA;AAAA;;;;;iBAOvB,2BAAA,CAAA;EACd,YAAA;EACA;AAAA,GACC,iBAAA,CAAkB,gCAAA,IAAoC,GAAA,CAAI,OAAA"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { LOCALIZATION_NAMESPACE } from "./internal/LocalizedStrings.js";
|
|
2
|
+
import { c } from "react-compiler-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
//#region src/presentation-hierarchies-react/LocalizationContext.tsx
|
|
6
|
+
const localizationContext = createContext((key) => key);
|
|
7
|
+
/**
|
|
8
|
+
* Context provider for localizing components.
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
function LocalizationContextProvider(t0) {
|
|
12
|
+
const $ = c(5);
|
|
13
|
+
const { localization, children } = t0;
|
|
14
|
+
let t1;
|
|
15
|
+
if ($[0] !== localization) {
|
|
16
|
+
t1 = (key) => localization.getLocalizedString(`${LOCALIZATION_NAMESPACE}:${key}`);
|
|
17
|
+
$[0] = localization;
|
|
18
|
+
$[1] = t1;
|
|
19
|
+
} else t1 = $[1];
|
|
20
|
+
const translate = t1;
|
|
21
|
+
let t2;
|
|
22
|
+
if ($[2] !== children || $[3] !== translate) {
|
|
23
|
+
t2 = /* @__PURE__ */ jsx(localizationContext.Provider, {
|
|
24
|
+
value: translate,
|
|
25
|
+
children
|
|
26
|
+
});
|
|
27
|
+
$[2] = children;
|
|
28
|
+
$[3] = translate;
|
|
29
|
+
$[4] = t2;
|
|
30
|
+
} else t2 = $[4];
|
|
31
|
+
return t2;
|
|
32
|
+
}
|
|
33
|
+
/** @internal */
|
|
34
|
+
function useTranslation() {
|
|
35
|
+
return useContext(localizationContext);
|
|
36
|
+
}
|
|
37
|
+
//#endregion
|
|
38
|
+
export { LocalizationContextProvider, useTranslation };
|
|
39
|
+
|
|
40
|
+
//# sourceMappingURL=LocalizationContext.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LocalizationContext.js","names":["createContext","useContext","useMemo","LOCALIZATION_NAMESPACE","JSX","PropsWithChildren","LocalizationKey","TranslateFunc","key","localizationContext","LocalizationContextProviderProps","localization","getLocalizedString","LocalizationContextProvider","t0","$","_c","children","t1","translate","t2","useTranslation"],"sources":["../../src/presentation-hierarchies-react/LocalizationContext.tsx"],"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 { createContext, useContext, useMemo } from \"react\";\nimport { LOCALIZATION_NAMESPACE } from \"./internal/LocalizedStrings.js\";\n\nimport type { JSX, PropsWithChildren } from \"react\";\nimport type { LocalizationKey } from \"./internal/LocalizedStrings.js\";\n\ntype TranslateFunc = (key: LocalizationKey) => string;\n\nconst localizationContext = createContext<TranslateFunc>((key) => key);\n\n/**\n * Properties for `LocalizationContextProvider`.\n * @public\n */\ninterface LocalizationContextProviderProps {\n /** Localization object compatible with `@itwin/core-common` */\n localization: { getLocalizedString: (key: string) => string };\n}\n\n/**\n * Context provider for localizing components.\n * @public\n */\nexport function LocalizationContextProvider({\n localization,\n children,\n}: PropsWithChildren<LocalizationContextProviderProps>): JSX.Element {\n const translate = useMemo<TranslateFunc>(() => {\n return (key: LocalizationKey) => localization.getLocalizedString(`${LOCALIZATION_NAMESPACE}:${key}`);\n }, [localization]);\n return <localizationContext.Provider value={translate}>{children}</localizationContext.Provider>;\n}\n\n/** @internal */\nexport function useTranslation() {\n return useContext(localizationContext);\n}\n"],"mappings":";;;;;AAaA,MAAMS,sBAAsBT,eAA8BQ,QAAQA,IAAI;;;;;AAetE,SAAOK,4BAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAqC,MAAA,EAAAL,cAAAM,aAAAH;CAGU,IAAAI;AAAA,KAAAH,EAAA,OAAAJ,cAAA;AAE3CO,QAAAV,QAA0BG,aAAYC,mBAAoB,GAAGT,uBAAsB,GAAIK,MAAM;AAAAO,IAAA,KAAAJ;AAAAI,IAAA,KAAAG;OAAAA,MAAAH,EAAA;CADtG,MAAAI,YACED;CACiB,IAAAE;AAAA,KAAAL,EAAA,OAAAE,YAAAF,EAAA,OAAAI,WAAA;AACZC,OAAA,oBAAA,oBAAA,UAAA;GAAqCD,OAAAA;GAAYF;GAAwC,CAAA;AAAAF,IAAA,KAAAE;AAAAF,IAAA,KAAAI;AAAAJ,IAAA,KAAAK;OAAAA,MAAAL,EAAA;AAAA,QAAzFK;;;AAIT,SAAOC,iBAAA;AAAA,QACEpB,WAAWQ,oBAAoB"}
|