@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.
Files changed (163) hide show
  1. package/CHANGELOG.md +1137 -11
  2. package/README.md +93 -160
  3. package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts +49 -0
  4. package/lib/presentation-hierarchies-react/FlatTreeNode.d.ts.map +1 -0
  5. package/lib/presentation-hierarchies-react/FlatTreeNode.js +93 -0
  6. package/lib/presentation-hierarchies-react/FlatTreeNode.js.map +1 -0
  7. package/lib/presentation-hierarchies-react/LocalizationContext.d.ts +24 -0
  8. package/lib/presentation-hierarchies-react/LocalizationContext.d.ts.map +1 -0
  9. package/lib/presentation-hierarchies-react/LocalizationContext.js +40 -0
  10. package/lib/presentation-hierarchies-react/LocalizationContext.js.map +1 -0
  11. package/lib/presentation-hierarchies-react/Renderers.d.ts +92 -0
  12. package/lib/presentation-hierarchies-react/Renderers.d.ts.map +1 -0
  13. package/lib/presentation-hierarchies-react/TreeNode.d.ts +80 -0
  14. package/lib/presentation-hierarchies-react/TreeNode.d.ts.map +1 -0
  15. package/lib/{esm/presentation-hierarchies-react → presentation-hierarchies-react}/UseIModelTree.d.ts +28 -15
  16. package/lib/presentation-hierarchies-react/UseIModelTree.d.ts.map +1 -0
  17. package/lib/presentation-hierarchies-react/UseIModelTree.js +183 -0
  18. package/lib/presentation-hierarchies-react/UseIModelTree.js.map +1 -0
  19. package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts +30 -0
  20. package/lib/presentation-hierarchies-react/UseNodeHighlighting.d.ts.map +1 -0
  21. package/lib/presentation-hierarchies-react/UseNodeHighlighting.js +57 -0
  22. package/lib/presentation-hierarchies-react/UseNodeHighlighting.js.map +1 -0
  23. package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts +23 -0
  24. package/lib/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +1 -0
  25. package/lib/presentation-hierarchies-react/UseSelectionHandler.js +124 -0
  26. package/lib/presentation-hierarchies-react/UseSelectionHandler.js.map +1 -0
  27. package/lib/presentation-hierarchies-react/UseTree.d.ts +112 -0
  28. package/lib/presentation-hierarchies-react/UseTree.d.ts.map +1 -0
  29. package/lib/presentation-hierarchies-react/UseTree.js +297 -0
  30. package/lib/presentation-hierarchies-react/UseTree.js.map +1 -0
  31. package/lib/presentation-hierarchies-react/Utils.js +56 -0
  32. package/lib/presentation-hierarchies-react/Utils.js.map +1 -0
  33. package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js +10 -0
  34. package/lib/presentation-hierarchies-react/internal/DisposePolyfill.js.map +1 -0
  35. package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts +9 -0
  36. package/lib/presentation-hierarchies-react/internal/LocalizedStrings.d.ts.map +1 -0
  37. package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js +12 -0
  38. package/lib/presentation-hierarchies-react/internal/LocalizedStrings.js.map +1 -0
  39. package/lib/presentation-hierarchies-react/internal/TreeActions.js +294 -0
  40. package/lib/presentation-hierarchies-react/internal/TreeActions.js.map +1 -0
  41. package/lib/presentation-hierarchies-react/internal/TreeLoader.js +98 -0
  42. package/lib/presentation-hierarchies-react/internal/TreeLoader.js.map +1 -0
  43. package/lib/presentation-hierarchies-react/internal/TreeModel.d.ts +1 -0
  44. package/lib/presentation-hierarchies-react/internal/TreeModel.js +120 -0
  45. package/lib/presentation-hierarchies-react/internal/TreeModel.js.map +1 -0
  46. package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +35 -0
  47. package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +1 -0
  48. package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js +141 -0
  49. package/lib/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +1 -0
  50. package/lib/presentation-hierarchies-react/internal/Utils.js +42 -0
  51. package/lib/presentation-hierarchies-react/internal/Utils.js.map +1 -0
  52. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts +38 -0
  53. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.d.ts.map +1 -0
  54. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js +380 -0
  55. package/lib/presentation-hierarchies-react/stratakit/ErrorItemRenderer.js.map +1 -0
  56. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts +27 -0
  57. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.d.ts.map +1 -0
  58. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js +185 -0
  59. package/lib/presentation-hierarchies-react/stratakit/RootErrorRenderer.js.map +1 -0
  60. package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts +49 -0
  61. package/lib/presentation-hierarchies-react/stratakit/TreeAction.d.ts.map +1 -0
  62. package/lib/presentation-hierarchies-react/stratakit/TreeAction.js +88 -0
  63. package/lib/presentation-hierarchies-react/stratakit/TreeAction.js.map +1 -0
  64. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts +38 -0
  65. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.d.ts.map +1 -0
  66. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js +63 -0
  67. package/lib/presentation-hierarchies-react/stratakit/TreeErrorRenderer.js.map +1 -0
  68. package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts +29 -0
  69. package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.d.ts.map +1 -0
  70. package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js +91 -0
  71. package/lib/presentation-hierarchies-react/stratakit/TreeNodeFilterAction.js.map +1 -0
  72. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts +31 -0
  73. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.d.ts.map +1 -0
  74. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js +155 -0
  75. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenameAction.js.map +1 -0
  76. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.css +25 -0
  77. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts +14 -0
  78. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.d.ts.map +1 -0
  79. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js +534 -0
  80. package/lib/presentation-hierarchies-react/stratakit/TreeNodeRenderer.js.map +1 -0
  81. package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts +75 -0
  82. package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.d.ts.map +1 -0
  83. package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js +417 -0
  84. package/lib/presentation-hierarchies-react/stratakit/TreeRenderer.js.map +1 -0
  85. package/lib/presentation-hierarchies-react-extract.d.ts +17 -0
  86. package/lib/presentation-hierarchies-react-extract.js +16 -0
  87. package/lib/presentation-hierarchies-react-stratakit.d.ts +8 -0
  88. package/lib/presentation-hierarchies-react-stratakit.js +8 -0
  89. package/lib/presentation-hierarchies-react.d.ts +11 -0
  90. package/lib/presentation-hierarchies-react.js +8 -0
  91. package/lib/public/locales/en/PresentationHierarchies_1.0.json +26 -0
  92. package/package.json +78 -56
  93. package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts +0 -75
  94. package/lib/esm/presentation-hierarchies-react/TreeNode.d.ts.map +0 -1
  95. package/lib/esm/presentation-hierarchies-react/TreeNode.js +0 -12
  96. package/lib/esm/presentation-hierarchies-react/TreeNode.js.map +0 -1
  97. package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts +0 -15
  98. package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.d.ts.map +0 -1
  99. package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js +0 -22
  100. package/lib/esm/presentation-hierarchies-react/UnifiedSelectionContext.js.map +0 -1
  101. package/lib/esm/presentation-hierarchies-react/UseIModelTree.d.ts.map +0 -1
  102. package/lib/esm/presentation-hierarchies-react/UseIModelTree.js +0 -62
  103. package/lib/esm/presentation-hierarchies-react/UseIModelTree.js.map +0 -1
  104. package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts +0 -46
  105. package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.d.ts.map +0 -1
  106. package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js +0 -98
  107. package/lib/esm/presentation-hierarchies-react/UseSelectionHandler.js.map +0 -1
  108. package/lib/esm/presentation-hierarchies-react/UseTree.d.ts +0 -132
  109. package/lib/esm/presentation-hierarchies-react/UseTree.d.ts.map +0 -1
  110. package/lib/esm/presentation-hierarchies-react/UseTree.js +0 -242
  111. package/lib/esm/presentation-hierarchies-react/UseTree.js.map +0 -1
  112. package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts +0 -2
  113. package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.d.ts.map +0 -1
  114. package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js +0 -11
  115. package/lib/esm/presentation-hierarchies-react/internal/DisposePolyfill.js.map +0 -1
  116. package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts +0 -53
  117. package/lib/esm/presentation-hierarchies-react/internal/TreeActions.d.ts.map +0 -1
  118. package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js +0 -307
  119. package/lib/esm/presentation-hierarchies-react/internal/TreeActions.js.map +0 -1
  120. package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts +0 -44
  121. package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.d.ts.map +0 -1
  122. package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js +0 -94
  123. package/lib/esm/presentation-hierarchies-react/internal/TreeLoader.js.map +0 -1
  124. package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts +0 -70
  125. package/lib/esm/presentation-hierarchies-react/internal/TreeModel.d.ts.map +0 -1
  126. package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js +0 -153
  127. package/lib/esm/presentation-hierarchies-react/internal/TreeModel.js.map +0 -1
  128. package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts +0 -28
  129. package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.d.ts.map +0 -1
  130. package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js +0 -128
  131. package/lib/esm/presentation-hierarchies-react/internal/UseUnifiedSelection.js.map +0 -1
  132. package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts +0 -23
  133. package/lib/esm/presentation-hierarchies-react/internal/Utils.d.ts.map +0 -1
  134. package/lib/esm/presentation-hierarchies-react/internal/Utils.js +0 -58
  135. package/lib/esm/presentation-hierarchies-react/internal/Utils.js.map +0 -1
  136. package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts +0 -21
  137. package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.d.ts.map +0 -1
  138. package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js +0 -30
  139. package/lib/esm/presentation-hierarchies-react/itwinui/FlatTreeNode.js.map +0 -1
  140. package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts +0 -73
  141. package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.d.ts.map +0 -1
  142. package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js +0 -34
  143. package/lib/esm/presentation-hierarchies-react/itwinui/LocalizationContext.js.map +0 -1
  144. package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts +0 -25
  145. package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.d.ts.map +0 -1
  146. package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js +0 -40
  147. package/lib/esm/presentation-hierarchies-react/itwinui/TreeActionButton.js.map +0 -1
  148. package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts +0 -23
  149. package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.d.ts.map +0 -1
  150. package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js +0 -72
  151. package/lib/esm/presentation-hierarchies-react/itwinui/TreeErrorRenderer.js.map +0 -1
  152. package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts +0 -40
  153. package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.d.ts.map +0 -1
  154. package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js +0 -80
  155. package/lib/esm/presentation-hierarchies-react/itwinui/TreeNodeRenderer.js.map +0 -1
  156. package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts +0 -30
  157. package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.d.ts.map +0 -1
  158. package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js +0 -48
  159. package/lib/esm/presentation-hierarchies-react/itwinui/TreeRenderer.js.map +0 -1
  160. package/lib/esm/presentation-hierarchies-react.d.ts +0 -13
  161. package/lib/esm/presentation-hierarchies-react.d.ts.map +0 -1
  162. package/lib/esm/presentation-hierarchies-react.js +0 -16
  163. 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 [iTwinUI](https://itwinui.bentley.com/)-based components for rendering the tree.
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 the same state object, which contains properties and functions to manage the tree component:
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
- - `getNode` function to get node by its id.
29
+ - `isReloading` is a boolean that is `true` while the tree is being reloaded (does not apply to the initial load).
32
30
 
33
- - `getHierarchyLevelDetails` function to access details of a specific hierarchy level. The returned object provides access to:
31
+ - `getNode` function to get a tree node by its id.
34
32
 
35
- - hierarchy level size limit,
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
- - `reloadTree` function to reload part of the tree, optionally keeping its state.
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
- - `setFormatter` function to set active node label formatter.
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 { createLimitingECSqlQueryExecutor, createNodesQueryClauseFactory, HierarchyDefinition } from "@itwin/presentation-hierarchies";
69
-
70
- // Not really part of the package, but we need SchemaContext to create the tree state. It's
71
- // recommended to cache the schema context and reuse it across different application's components to
72
- // avoid loading and storing same schemas multiple times.
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(getIModelSchemaContext(imodel));
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
- ### `useSelectionHandler` hook
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
- ## iTwinUI components
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
- While the package provides a headless UI, it also delivers a set of [iTwinUI](https://itwinui.bentley.com/)-based components for rendering the tree, which should cover majority of use cases. Consumers using the below components are required to provide a compatible `@itwin/itwinui-react` package, which is an optional peer dependency to this package.
100
+ ### `StrataKitTreeRenderer`
131
101
 
132
- ### `TreeRenderer`
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 { createLimitingECSqlQueryExecutor, createNodesQueryClauseFactory, HierarchyDefinition } from "@itwin/presentation-hierarchies";
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 { TreeRenderer, useIModelUnifiedSelectionTree } from "@itwin/presentation-hierarchies-react";
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(getIModelSchemaContext(imodel));
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({ imodelAccess, instanceLabelSelectClauseFactory: labelsQueryFactory });
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({ classAlias: "this", className: "BisCore.PhysicalModel" }),
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({ imodelAccess, selectionStorage }: { imodelAccess: IModelAccess; selectionStorage: SelectionStorage }) {
243
- const { rootNodes, setFormatter, isLoading, ...state } = useIModelUnifiedSelectionTree({
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
- if (!rootNodes) {
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
- return <TreeRenderer {...state} rootNodes={rootNodes} />;
217
+
218
+ return <StrataKitTreeRenderer {...treeProps.treeRendererProps} treeLabel="My Tree" />;
257
219
  }
258
220
  ```
259
221
 
260
222
  ## Localization
261
223
 
262
- Localization can be enabled for `TreeRenderer` component and [tree state hooks](#tree-state-hooks) by providing an object with localized strings that will be used instead of the default English ones.
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 { Props } from "@itwin/presentation-shared";
268
-
269
- import { useIModelUnifiedSelectionTree } from "@itwin/presentation-hierarchies-react";
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
- type IModelAccess = Props<typeof useIModelUnifiedSelectionTree>["imodelAccess"];
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
- const localizedStrings = {
274
- // strings for the `useIModelUnifiedSelectionTree` hook
275
- unspecified: "Unspecified",
276
- other: "Other",
277
-
278
- // strings for `TreeRenderer` and `TreeNodeRenderPresentation.HierarchiesReact.iModelAccesser`
279
- loading: "Loading...",
280
- filterHierarchyLevel: "Apply hierarchy filter",
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 { rootNodes, expandNode } = useIModelUnifiedSelectionTree({
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
- type TreeProps = ComponentPropsWithoutRef<typeof Tree<RenderedTreeNode>>;
319
- type TreeRendererProps = Props<typeof TreeRenderer>;
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
- const getNode = useCallback<TreeProps["getNode"]>((node) => createRenderedTreeNodeData(node, () => false), []);
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"}