@itwin/tree-widget-react 4.0.0-alpha.6 → 4.0.0-alpha.8

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 (206) hide show
  1. package/CHANGELOG.md +22 -1
  2. package/README.md +2 -1
  3. package/lib/esm/tree-widget-react/TreeWidget.d.ts +6 -1
  4. package/lib/esm/tree-widget-react/TreeWidget.js +19 -2
  5. package/lib/esm/tree-widget-react/TreeWidget.js.map +1 -1
  6. package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.d.ts +6 -0
  7. package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.js +22 -23
  8. package/lib/esm/tree-widget-react/components/TreeWidgetComponentImpl.js.map +1 -1
  9. package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js +1 -1
  10. package/lib/esm/tree-widget-react/components/TreeWidgetUiItemsProvider.js.map +1 -1
  11. package/lib/esm/tree-widget-react/components/tree-header/ErrorState.js +1 -1
  12. package/lib/esm/tree-widget-react/components/tree-header/ErrorState.js.map +1 -1
  13. package/lib/esm/tree-widget-react/components/tree-header/SearchBox.d.ts +1 -1
  14. package/lib/esm/tree-widget-react/components/tree-header/SearchBox.js +4 -4
  15. package/lib/esm/tree-widget-react/components/tree-header/SearchBox.js.map +1 -1
  16. package/lib/esm/tree-widget-react/components/tree-header/SelectableTree.css +2 -0
  17. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.css +1 -0
  18. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.d.ts +12 -4
  19. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.js +13 -9
  20. package/lib/esm/tree-widget-react/components/tree-header/WidgetHeader.js.map +1 -1
  21. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.d.ts +2 -2
  22. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js +2 -2
  23. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTree.js.map +1 -1
  24. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.d.ts +9 -2
  25. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js +53 -7
  26. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
  27. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.d.ts +1 -1
  28. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js +1 -1
  29. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
  30. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.d.ts +17 -3
  31. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js +561 -161
  32. package/lib/esm/tree-widget-react/components/trees/categories-tree/CategoriesTreeDefinition.js.map +1 -1
  33. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.d.ts +6 -2
  34. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js +46 -117
  35. package/lib/esm/tree-widget-react/components/trees/categories-tree/UseCategoriesTree.js.map +1 -1
  36. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.d.ts +30 -15
  37. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js +188 -38
  38. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeIdsCache.js.map +1 -1
  39. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.d.ts +18 -3
  40. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js +30 -3
  41. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeNode.js.map +1 -1
  42. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.d.ts +24 -0
  43. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.js +701 -0
  44. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesTreeVisibilityHandler.js.map +1 -0
  45. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.d.ts +39 -0
  46. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js +221 -0
  47. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/FilteredTree.js.map +1 -0
  48. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.d.ts +25 -0
  49. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js +133 -0
  50. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.js.map +1 -0
  51. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.d.ts +8 -0
  52. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.js +48 -0
  53. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.js.map +1 -0
  54. package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.d.ts +5 -17
  55. package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js +5 -62
  56. package/lib/esm/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
  57. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.d.ts +2 -2
  58. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js +11 -5
  59. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyVisibility.js.map +1 -1
  60. package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.d.ts +1 -0
  61. package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js +13 -11
  62. package/lib/esm/tree-widget-react/components/trees/common/UseNodeHighlighting.js.map +1 -1
  63. package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.d.ts +1 -0
  64. package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.js +2 -1
  65. package/lib/esm/tree-widget-react/components/trees/common/UseTelemetryContext.js.map +1 -1
  66. package/lib/esm/tree-widget-react/components/trees/common/Utils.d.ts +38 -23
  67. package/lib/esm/tree-widget-react/components/trees/common/Utils.js +65 -47
  68. package/lib/esm/tree-widget-react/components/trees/common/Utils.js.map +1 -1
  69. package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.d.ts +1 -1
  70. package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js +4 -4
  71. package/lib/esm/tree-widget-react/components/trees/common/components/BaseTreeRenderer.js.map +1 -1
  72. package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.d.ts +1 -0
  73. package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.js +1 -0
  74. package/lib/esm/tree-widget-react/components/trees/common/components/Delayed.js.map +1 -1
  75. package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.d.ts +1 -0
  76. package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.js +1 -0
  77. package/lib/esm/tree-widget-react/components/trees/common/components/ProgressOverlay.js.map +1 -1
  78. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.css +2 -1
  79. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.d.ts +3 -3
  80. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js +15 -6
  81. package/lib/esm/tree-widget-react/components/trees/common/components/Tree.js.map +1 -1
  82. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.d.ts +6 -4
  83. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js +20 -25
  84. package/lib/esm/tree-widget-react/components/trees/common/components/TreeNodeVisibilityButton.js.map +1 -1
  85. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.d.ts +1 -1
  86. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js +10 -4
  87. package/lib/esm/tree-widget-react/components/trees/common/components/TreeRenderer.js.map +1 -1
  88. package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.d.ts +1 -0
  89. package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js +7 -3
  90. package/lib/esm/tree-widget-react/components/trees/common/components/UseVisibilityButtonHandler.js.map +1 -1
  91. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js +1 -1
  92. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTree.js.map +1 -1
  93. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.d.ts +1 -1
  94. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js +12 -11
  95. package/lib/esm/tree-widget-react/components/trees/common/components/VisibilityTreeRenderer.js.map +1 -1
  96. package/lib/esm/tree-widget-react/components/trees/common/internal/AlwaysAndNeverDrawnElementInfo.d.ts +44 -0
  97. package/lib/esm/tree-widget-react/components/trees/{models-tree → common}/internal/AlwaysAndNeverDrawnElementInfo.js +81 -31
  98. package/lib/esm/tree-widget-react/components/trees/common/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -0
  99. package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.d.ts +33 -0
  100. package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js +37 -0
  101. package/lib/esm/tree-widget-react/components/trees/common/internal/ClassNameDefinitions.js.map +1 -0
  102. package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.d.ts +16 -0
  103. package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js +72 -0
  104. package/lib/esm/tree-widget-react/components/trees/common/internal/ModelCategoryElementsCountCache.js.map +1 -0
  105. package/lib/esm/tree-widget-react/components/trees/common/{Rxjs.d.ts → internal/Rxjs.d.ts} +9 -2
  106. package/lib/esm/tree-widget-react/components/trees/common/{Rxjs.js → internal/Rxjs.js} +9 -2
  107. package/lib/esm/tree-widget-react/components/trees/common/internal/Rxjs.js.map +1 -0
  108. package/lib/esm/tree-widget-react/components/trees/common/{Tooltip.d.ts → internal/Tooltip.d.ts} +4 -8
  109. package/lib/esm/tree-widget-react/components/trees/common/{Tooltip.js → internal/Tooltip.js} +4 -10
  110. package/lib/esm/tree-widget-react/components/trees/common/internal/Tooltip.js.map +1 -0
  111. package/lib/esm/tree-widget-react/components/trees/common/internal/Types.d.ts +14 -0
  112. package/lib/esm/tree-widget-react/components/{tree-header/SearchBox.css → trees/common/internal/Types.js} +2 -4
  113. package/lib/esm/tree-widget-react/components/trees/common/internal/Types.js.map +1 -0
  114. package/lib/esm/tree-widget-react/components/trees/common/internal/UseActiveViewport.js.map +1 -0
  115. package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchiesLocalization.d.ts → internal/UseHierarchiesLocalization.d.ts} +1 -0
  116. package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchiesLocalization.js → internal/UseHierarchiesLocalization.js} +6 -2
  117. package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchiesLocalization.js.map +1 -0
  118. package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchyFiltering.d.ts → internal/UseHierarchyFiltering.d.ts} +1 -0
  119. package/lib/esm/tree-widget-react/components/trees/common/{UseHierarchyFiltering.js → internal/UseHierarchyFiltering.js} +4 -3
  120. package/lib/esm/tree-widget-react/components/trees/common/internal/UseHierarchyFiltering.js.map +1 -0
  121. package/lib/esm/tree-widget-react/components/trees/common/{UseIModelChangeListener.d.ts → internal/UseIModelChangeListener.d.ts} +1 -0
  122. package/lib/esm/tree-widget-react/components/trees/common/{UseIModelChangeListener.js → internal/UseIModelChangeListener.js} +1 -0
  123. package/lib/esm/tree-widget-react/components/trees/common/internal/UseIModelChangeListener.js.map +1 -0
  124. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.d.ts +47 -0
  125. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js +101 -0
  126. package/lib/esm/tree-widget-react/components/trees/common/internal/Utils.js.map +1 -0
  127. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityChangeEventListener.d.ts +20 -0
  128. package/lib/esm/tree-widget-react/components/trees/{models-tree → common}/internal/VisibilityChangeEventListener.js +17 -9
  129. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityChangeEventListener.js.map +1 -0
  130. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.d.ts +63 -0
  131. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js +210 -0
  132. package/lib/esm/tree-widget-react/components/trees/common/internal/VisibilityUtils.js.map +1 -0
  133. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +2 -2
  134. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js +8 -8
  135. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
  136. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.d.ts +1 -1
  137. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
  138. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.d.ts +1 -0
  139. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js +1 -0
  140. package/lib/esm/tree-widget-react/components/trees/external-sources-tree/ExternalSourcesTreeDefinition.js.map +1 -1
  141. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.d.ts +4 -2
  142. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js +22 -18
  143. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
  144. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.d.ts +1 -1
  145. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js +1 -1
  146. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
  147. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.d.ts +13 -0
  148. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js +39 -38
  149. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/IModelContentTreeDefinition.js.map +1 -1
  150. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.d.ts +5 -5
  151. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js +25 -24
  152. package/lib/esm/tree-widget-react/components/trees/imodel-content-tree/internal/IModelContentTreeIdsCache.js.map +1 -1
  153. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.d.ts +2 -2
  154. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js +2 -2
  155. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTree.js.map +1 -1
  156. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js +15 -11
  157. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
  158. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.d.ts +1 -1
  159. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js +1 -1
  160. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  161. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.d.ts +7 -2
  162. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js +73 -70
  163. package/lib/esm/tree-widget-react/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
  164. package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js +36 -202
  165. package/lib/esm/tree-widget-react/components/trees/models-tree/UseModelsTree.js.map +1 -1
  166. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.d.ts +7 -9
  167. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js +4 -6
  168. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/FilteredTree.js.map +1 -1
  169. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +4 -5
  170. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js +54 -104
  171. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  172. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.d.ts +0 -26
  173. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +80 -359
  174. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
  175. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.d.ts +27 -0
  176. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js +170 -0
  177. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseFilteredPaths.js.map +1 -0
  178. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.d.ts +8 -0
  179. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.js +47 -0
  180. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/UseIdsCache.js.map +1 -0
  181. package/lib/public/locales/en/TreeWidget.json +13 -59
  182. package/package.json +19 -20
  183. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.d.ts +0 -37
  184. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js +0 -214
  185. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/CategoriesVisibilityHandler.js.map +0 -1
  186. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.d.ts +0 -7
  187. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.js +0 -11
  188. package/lib/esm/tree-widget-react/components/trees/categories-tree/internal/ClassNameDefinitions.js.map +0 -1
  189. package/lib/esm/tree-widget-react/components/trees/common/Rxjs.js.map +0 -1
  190. package/lib/esm/tree-widget-react/components/trees/common/Tooltip.js.map +0 -1
  191. package/lib/esm/tree-widget-react/components/trees/common/UseActiveViewport.js.map +0 -1
  192. package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.d.ts +0 -11
  193. package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.js +0 -24
  194. package/lib/esm/tree-widget-react/components/trees/common/UseFiltering.js.map +0 -1
  195. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchiesLocalization.js.map +0 -1
  196. package/lib/esm/tree-widget-react/components/trees/common/UseHierarchyFiltering.js.map +0 -1
  197. package/lib/esm/tree-widget-react/components/trees/common/UseIModelChangeListener.js.map +0 -1
  198. package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.d.ts +0 -7
  199. package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js +0 -21
  200. package/lib/esm/tree-widget-react/components/trees/models-tree/Utils.js.map +0 -1
  201. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +0 -29
  202. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +0 -1
  203. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/VisibilityChangeEventListener.d.ts +0 -12
  204. package/lib/esm/tree-widget-react/components/trees/models-tree/internal/VisibilityChangeEventListener.js.map +0 -1
  205. /package/lib/esm/tree-widget-react/components/trees/common/{UseActiveViewport.d.ts → internal/UseActiveViewport.d.ts} +0 -0
  206. /package/lib/esm/tree-widget-react/components/trees/common/{UseActiveViewport.js → internal/UseActiveViewport.js} +0 -0
@@ -0,0 +1,133 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { useEffect, useMemo, useState } from "react";
6
+ import { assert } from "@itwin/core-bentley";
7
+ import { HierarchyFilteringPath, HierarchyNodeIdentifier } from "@itwin/presentation-hierarchies";
8
+ import { DEFINITION_CONTAINER_CLASS_NAME, SUB_CATEGORY_CLASS_NAME } from "../../common/internal/ClassNameDefinitions.js";
9
+ import { getClassesByView } from "../../common/internal/Utils.js";
10
+ import { FilterLimitExceededError } from "../../common/TreeErrors.js";
11
+ import { useTelemetryContext } from "../../common/UseTelemetryContext.js";
12
+ import { CategoriesTreeDefinition } from "../CategoriesTreeDefinition.js";
13
+ /** @internal */
14
+ export function useFilteredPaths({ filter, viewType, hierarchyConfiguration, getCategoriesTreeIdsCache, onCategoriesFiltered, onFilteredPathsChanged, }) {
15
+ const [filteringError, setFilteringError] = useState();
16
+ const { onFeatureUsed } = useTelemetryContext();
17
+ useEffect(() => {
18
+ setFilteringError(undefined);
19
+ onCategoriesFiltered?.({ categories: undefined, models: undefined });
20
+ if (!filter) {
21
+ onFilteredPathsChanged(undefined);
22
+ }
23
+ }, [filter, onCategoriesFiltered, onFilteredPathsChanged]);
24
+ const getFilteredPaths = useMemo(() => {
25
+ if (!filter) {
26
+ return undefined;
27
+ }
28
+ return async ({ imodelAccess }) => {
29
+ onFeatureUsed({ featureId: "filtering", reportInteraction: true });
30
+ try {
31
+ const paths = await CategoriesTreeDefinition.createInstanceKeyPaths({
32
+ imodelAccess,
33
+ label: filter,
34
+ viewType,
35
+ idsCache: getCategoriesTreeIdsCache(),
36
+ hierarchyConfig: hierarchyConfiguration,
37
+ });
38
+ onFilteredPathsChanged(paths);
39
+ const { elementClass, modelClass } = getClassesByView(viewType);
40
+ onCategoriesFiltered?.(await getCategoriesFromPaths(paths, getCategoriesTreeIdsCache(), elementClass, modelClass));
41
+ return paths;
42
+ }
43
+ catch (e) {
44
+ const newError = e instanceof FilterLimitExceededError ? "tooManyFilterMatches" : "unknownFilterError";
45
+ if (newError !== "tooManyFilterMatches") {
46
+ const feature = e instanceof Error && e.message.includes("query too long to execute or server is too busy") ? "error-timeout" : "error-unknown";
47
+ onFeatureUsed({ featureId: feature, reportInteraction: false });
48
+ }
49
+ setFilteringError(newError);
50
+ return [];
51
+ }
52
+ };
53
+ }, [onCategoriesFiltered, filter, onFilteredPathsChanged, onFeatureUsed, viewType, getCategoriesTreeIdsCache, hierarchyConfiguration]);
54
+ return {
55
+ getPaths: getFilteredPaths,
56
+ filteringError,
57
+ };
58
+ }
59
+ async function getCategoriesFromPaths(paths, idsCache, elementClassName, modelsClassName) {
60
+ if (!paths) {
61
+ return { categories: undefined };
62
+ }
63
+ const rootFilteredElementIds = new Set();
64
+ const subModelIds = new Set();
65
+ const categories = new Map();
66
+ for (const path of paths) {
67
+ const currPath = HierarchyFilteringPath.normalize(path).path;
68
+ if (currPath.length === 0) {
69
+ continue;
70
+ }
71
+ let category;
72
+ let subCategory;
73
+ let lastNodeInfo;
74
+ for (let i = 0; i < currPath.length; ++i) {
75
+ const currentNode = currPath[i];
76
+ if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(currentNode)) {
77
+ continue;
78
+ }
79
+ if (currentNode.className === elementClassName) {
80
+ rootFilteredElementIds.add(currentNode.id);
81
+ for (let j = i + 1; j < currPath.length; ++j) {
82
+ const childNode = currPath[j];
83
+ if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(childNode)) {
84
+ continue;
85
+ }
86
+ if (childNode.className === modelsClassName) {
87
+ subModelIds.add(childNode.id);
88
+ }
89
+ }
90
+ break;
91
+ }
92
+ lastNodeInfo = { lastNode: currentNode, nodeIndex: i };
93
+ }
94
+ assert(lastNodeInfo !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(lastNodeInfo.lastNode));
95
+ if (lastNodeInfo.lastNode.className === DEFINITION_CONTAINER_CLASS_NAME) {
96
+ const definitionContainerCategories = await idsCache.getAllContainedCategories([lastNodeInfo.lastNode.id]);
97
+ for (const categoryId of definitionContainerCategories) {
98
+ const value = categories.get(categoryId);
99
+ if (value === undefined) {
100
+ categories.set(categoryId, []);
101
+ }
102
+ }
103
+ continue;
104
+ }
105
+ if (lastNodeInfo.lastNode.className === SUB_CATEGORY_CLASS_NAME) {
106
+ const secondToLastNode = lastNodeInfo.nodeIndex > 0 ? currPath[lastNodeInfo.nodeIndex - 1] : undefined;
107
+ assert(secondToLastNode !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(secondToLastNode));
108
+ subCategory = lastNodeInfo.lastNode;
109
+ category = secondToLastNode;
110
+ }
111
+ else {
112
+ category = lastNodeInfo.lastNode;
113
+ }
114
+ let entry = categories.get(category.id);
115
+ if (entry === undefined) {
116
+ entry = [];
117
+ categories.set(category.id, entry);
118
+ }
119
+ if (subCategory) {
120
+ entry.push(subCategory.id);
121
+ }
122
+ }
123
+ const rootElementModelMap = await idsCache.getFilteredElementsModels([...rootFilteredElementIds]);
124
+ const models = [...subModelIds, ...new Set(rootElementModelMap.values())];
125
+ return {
126
+ categories: [...categories.entries()].map(([categoryId, subCategoryIds]) => ({
127
+ categoryId,
128
+ subCategoryIds: subCategoryIds.length === 0 ? undefined : subCategoryIds,
129
+ })),
130
+ models,
131
+ };
132
+ }
133
+ //# sourceMappingURL=UseFilteredPaths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UseFilteredPaths.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/categories-tree/internal/UseFilteredPaths.ts"],"names":[],"mappings":"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","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 { useEffect, useMemo, useState } from \"react\";\nimport { assert } from \"@itwin/core-bentley\";\nimport { HierarchyFilteringPath, HierarchyNodeIdentifier } from \"@itwin/presentation-hierarchies\";\nimport { DEFINITION_CONTAINER_CLASS_NAME, SUB_CATEGORY_CLASS_NAME } from \"../../common/internal/ClassNameDefinitions.js\";\nimport { getClassesByView } from \"../../common/internal/Utils.js\";\nimport { FilterLimitExceededError } from \"../../common/TreeErrors.js\";\nimport { useTelemetryContext } from \"../../common/UseTelemetryContext.js\";\nimport { CategoriesTreeDefinition } from \"../CategoriesTreeDefinition.js\";\n\nimport type { VisibilityTreeProps } from \"../../common/components/VisibilityTree.js\";\nimport type { CategoriesTreeHierarchyConfiguration } from \"../CategoriesTreeDefinition.js\";\nimport type { CategoriesTreeIdsCache } from \"./CategoriesTreeIdsCache.js\";\nimport type { CategoryId, ElementId, ModelId, SubCategoryId } from \"../../common/internal/Types.js\";\nimport type { CategoryInfo } from \"../../common/CategoriesVisibilityUtils.js\";\n\n/** @internal */\nexport type CategoriesTreeFilteringError = \"tooManyFilterMatches\" | \"unknownFilterError\";\n\ntype HierarchyFilteringPaths = Awaited<ReturnType<Required<VisibilityTreeProps>[\"getFilteredPaths\"]>>;\n\n/** @internal */\nexport function useFilteredPaths({\n filter,\n viewType,\n hierarchyConfiguration,\n getCategoriesTreeIdsCache,\n onCategoriesFiltered,\n onFilteredPathsChanged,\n}: {\n viewType: \"2d\" | \"3d\";\n filter?: string;\n hierarchyConfiguration: CategoriesTreeHierarchyConfiguration;\n getCategoriesTreeIdsCache: () => CategoriesTreeIdsCache;\n onCategoriesFiltered?: (categories: { categories: CategoryInfo[] | undefined; models?: Array<ModelId> }) => void;\n onFilteredPathsChanged: (paths: HierarchyFilteringPaths | undefined) => void;\n}): {\n getPaths: VisibilityTreeProps[\"getFilteredPaths\"] | undefined;\n filteringError: CategoriesTreeFilteringError | undefined;\n} {\n const [filteringError, setFilteringError] = useState<CategoriesTreeFilteringError | undefined>();\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n setFilteringError(undefined);\n onCategoriesFiltered?.({ categories: undefined, models: undefined });\n if (!filter) {\n onFilteredPathsChanged(undefined);\n }\n }, [filter, onCategoriesFiltered, onFilteredPathsChanged]);\n\n const getFilteredPaths = useMemo<VisibilityTreeProps[\"getFilteredPaths\"] | undefined>(() => {\n if (!filter) {\n return undefined;\n }\n\n return async ({ imodelAccess }) => {\n onFeatureUsed({ featureId: \"filtering\", reportInteraction: true });\n try {\n const paths = await CategoriesTreeDefinition.createInstanceKeyPaths({\n imodelAccess,\n label: filter,\n viewType,\n idsCache: getCategoriesTreeIdsCache(),\n hierarchyConfig: hierarchyConfiguration,\n });\n onFilteredPathsChanged(paths);\n const { elementClass, modelClass } = getClassesByView(viewType);\n onCategoriesFiltered?.(await getCategoriesFromPaths(paths, getCategoriesTreeIdsCache(), elementClass, modelClass));\n return paths;\n } catch (e) {\n const newError = e instanceof FilterLimitExceededError ? \"tooManyFilterMatches\" : \"unknownFilterError\";\n if (newError !== \"tooManyFilterMatches\") {\n const feature = e instanceof Error && e.message.includes(\"query too long to execute or server is too busy\") ? \"error-timeout\" : \"error-unknown\";\n onFeatureUsed({ featureId: feature, reportInteraction: false });\n }\n setFilteringError(newError);\n return [];\n }\n };\n }, [onCategoriesFiltered, filter, onFilteredPathsChanged, onFeatureUsed, viewType, getCategoriesTreeIdsCache, hierarchyConfiguration]);\n\n return {\n getPaths: getFilteredPaths,\n filteringError,\n };\n}\n\nasync function getCategoriesFromPaths(\n paths: HierarchyFilteringPaths,\n idsCache: CategoriesTreeIdsCache,\n elementClassName: string,\n modelsClassName: string,\n): Promise<{ categories: CategoryInfo[] | undefined; models?: Array<ModelId> }> {\n if (!paths) {\n return { categories: undefined };\n }\n\n const rootFilteredElementIds = new Set<ElementId>();\n const subModelIds = new Set<ModelId>();\n\n const categories = new Map<CategoryId, Array<SubCategoryId>>();\n for (const path of paths) {\n const currPath = HierarchyFilteringPath.normalize(path).path;\n if (currPath.length === 0) {\n continue;\n }\n\n let category: HierarchyNodeIdentifier;\n let subCategory: HierarchyNodeIdentifier | undefined;\n\n let lastNodeInfo: { lastNode: HierarchyNodeIdentifier; nodeIndex: number } | undefined;\n\n for (let i = 0; i < currPath.length; ++i) {\n const currentNode = currPath[i];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(currentNode)) {\n continue;\n }\n if (currentNode.className === elementClassName) {\n rootFilteredElementIds.add(currentNode.id);\n for (let j = i + 1; j < currPath.length; ++j) {\n const childNode = currPath[j];\n if (!HierarchyNodeIdentifier.isInstanceNodeIdentifier(childNode)) {\n continue;\n }\n if (childNode.className === modelsClassName) {\n subModelIds.add(childNode.id);\n }\n }\n break;\n }\n lastNodeInfo = { lastNode: currentNode, nodeIndex: i };\n }\n\n assert(lastNodeInfo !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(lastNodeInfo.lastNode));\n\n if (lastNodeInfo.lastNode.className === DEFINITION_CONTAINER_CLASS_NAME) {\n const definitionContainerCategories = await idsCache.getAllContainedCategories([lastNodeInfo.lastNode.id]);\n for (const categoryId of definitionContainerCategories) {\n const value = categories.get(categoryId);\n if (value === undefined) {\n categories.set(categoryId, []);\n }\n }\n continue;\n }\n\n if (lastNodeInfo.lastNode.className === SUB_CATEGORY_CLASS_NAME) {\n const secondToLastNode = lastNodeInfo.nodeIndex > 0 ? currPath[lastNodeInfo.nodeIndex - 1] : undefined;\n assert(secondToLastNode !== undefined && HierarchyNodeIdentifier.isInstanceNodeIdentifier(secondToLastNode));\n\n subCategory = lastNodeInfo.lastNode;\n category = secondToLastNode;\n } else {\n category = lastNodeInfo.lastNode;\n }\n\n let entry = categories.get(category.id);\n if (entry === undefined) {\n entry = [];\n categories.set(category.id, entry);\n }\n\n if (subCategory) {\n entry.push(subCategory.id);\n }\n }\n const rootElementModelMap = await idsCache.getFilteredElementsModels([...rootFilteredElementIds]);\n const models = [...subModelIds, ...new Set(rootElementModelMap.values())];\n return {\n categories: [...categories.entries()].map(([categoryId, subCategoryIds]) => ({\n categoryId,\n subCategoryIds: subCategoryIds.length === 0 ? undefined : subCategoryIds,\n })),\n models,\n };\n}\n"]}
@@ -0,0 +1,8 @@
1
+ import { CategoriesTreeIdsCache } from "./CategoriesTreeIdsCache.js";
2
+ import type { IModelConnection } from "@itwin/core-frontend";
3
+ import type { HierarchyFilteringPath } from "@itwin/presentation-hierarchies";
4
+ /** @internal */
5
+ export declare function useIdsCache(imodel: IModelConnection, viewType: "2d" | "3d", filteredPaths?: HierarchyFilteringPath[]): {
6
+ getCache: () => CategoriesTreeIdsCache;
7
+ };
8
+ //# sourceMappingURL=UseIdsCache.d.ts.map
@@ -0,0 +1,48 @@
1
+ /*---------------------------------------------------------------------------------------------
2
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
+ * See LICENSE.md in the project root for license terms and full copyright notice.
4
+ *--------------------------------------------------------------------------------------------*/
5
+ import { useCallback, useEffect, useRef, useState } from "react";
6
+ import { createECSqlQueryExecutor } from "@itwin/presentation-core-interop";
7
+ import { useIModelChangeListener } from "../../common/internal/UseIModelChangeListener.js";
8
+ import { CategoriesTreeIdsCache } from "./CategoriesTreeIdsCache.js";
9
+ /** @internal */
10
+ export function useIdsCache(imodel, viewType, filteredPaths) {
11
+ const cacheRef = useRef(undefined);
12
+ const clearCacheRef = useRef(() => () => {
13
+ cacheRef.current?.[Symbol.dispose]?.();
14
+ cacheRef.current = undefined;
15
+ });
16
+ const createCacheGetterRef = useRef((currImodel, currViewType) => () => {
17
+ if (cacheRef.current === undefined) {
18
+ cacheRef.current = new CategoriesTreeIdsCache(createECSqlQueryExecutor(currImodel), currViewType);
19
+ }
20
+ return cacheRef.current;
21
+ });
22
+ const [getCache, setCacheGetter] = useState(() => createCacheGetterRef.current(imodel, viewType));
23
+ useEffect(() => {
24
+ // clear cache in case it was created before `useEffect` was run first time
25
+ clearCacheRef.current();
26
+ // make sure all cache users rerender
27
+ setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));
28
+ return () => {
29
+ // eslint-disable-next-line react-hooks/exhaustive-deps
30
+ clearCacheRef.current();
31
+ };
32
+ }, [imodel, viewType]);
33
+ useEffect(() => {
34
+ cacheRef.current?.clearFilteredElementsModels();
35
+ }, [filteredPaths]);
36
+ useIModelChangeListener({
37
+ imodel,
38
+ action: useCallback(() => {
39
+ clearCacheRef.current();
40
+ // make sure all cache users rerender
41
+ setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));
42
+ }, [imodel, viewType]),
43
+ });
44
+ return {
45
+ getCache,
46
+ };
47
+ }
48
+ //# sourceMappingURL=UseIdsCache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"UseIdsCache.js","sourceRoot":"","sources":["../../../../../../../src/tree-widget-react/components/trees/categories-tree/internal/UseIdsCache.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,uBAAuB,EAAE,MAAM,kDAAkD,CAAC;AAC3F,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AAKrE,gBAAgB;AAChB,MAAM,UAAU,WAAW,CAAC,MAAwB,EAAE,QAAqB,EAAE,aAAwC;IACnH,MAAM,QAAQ,GAAG,MAAM,CAAqC,SAAS,CAAC,CAAC;IACvE,MAAM,aAAa,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE;QACtC,QAAQ,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QACvC,QAAQ,CAAC,OAAO,GAAG,SAAS,CAAC;IAC/B,CAAC,CAAC,CAAC;IACH,MAAM,oBAAoB,GAAG,MAAM,CAAC,CAAC,UAA4B,EAAE,YAAyB,EAAE,EAAE,CAAC,GAAG,EAAE;QACpG,IAAI,QAAQ,CAAC,OAAO,KAAK,SAAS,EAAE;YAClC,QAAQ,CAAC,OAAO,GAAG,IAAI,sBAAsB,CAAC,wBAAwB,CAAC,UAAU,CAAC,EAAE,YAAY,CAAC,CAAC;SACnG;QACD,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC,CAAC,CAAC;IACH,MAAM,CAAC,QAAQ,EAAE,cAAc,CAAC,GAAG,QAAQ,CAA+B,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEhI,SAAS,CAAC,GAAG,EAAE;QACb,2EAA2E;QAC3E,aAAa,CAAC,OAAO,EAAE,CAAC;QAExB,qCAAqC;QACrC,cAAc,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACrE,OAAO,GAAG,EAAE;YACV,uDAAuD;YACvD,aAAa,CAAC,OAAO,EAAE,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;IAEvB,SAAS,CAAC,GAAG,EAAE;QACb,QAAQ,CAAC,OAAO,EAAE,2BAA2B,EAAE,CAAC;IAClD,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC;IAEpB,uBAAuB,CAAC;QACtB,MAAM;QACN,MAAM,EAAE,WAAW,CAAC,GAAG,EAAE;YACvB,aAAa,CAAC,OAAO,EAAE,CAAC;YACxB,qCAAqC;YACrC,cAAc,CAAC,GAAG,EAAE,CAAC,oBAAoB,CAAC,OAAO,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;QACvE,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;KACvB,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;KACT,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useCallback, useEffect, useRef, useState } from \"react\";\nimport { createECSqlQueryExecutor } from \"@itwin/presentation-core-interop\";\nimport { useIModelChangeListener } from \"../../common/internal/UseIModelChangeListener.js\";\nimport { CategoriesTreeIdsCache } from \"./CategoriesTreeIdsCache.js\";\n\nimport type { IModelConnection } from \"@itwin/core-frontend\";\nimport type { HierarchyFilteringPath } from \"@itwin/presentation-hierarchies\";\n\n/** @internal */\nexport function useIdsCache(imodel: IModelConnection, viewType: \"2d\" | \"3d\", filteredPaths?: HierarchyFilteringPath[]) {\n const cacheRef = useRef<CategoriesTreeIdsCache | undefined>(undefined);\n const clearCacheRef = useRef(() => () => {\n cacheRef.current?.[Symbol.dispose]?.();\n cacheRef.current = undefined;\n });\n const createCacheGetterRef = useRef((currImodel: IModelConnection, currViewType: \"2d\" | \"3d\") => () => {\n if (cacheRef.current === undefined) {\n cacheRef.current = new CategoriesTreeIdsCache(createECSqlQueryExecutor(currImodel), currViewType);\n }\n return cacheRef.current;\n });\n const [getCache, setCacheGetter] = useState<() => CategoriesTreeIdsCache>(() => createCacheGetterRef.current(imodel, viewType));\n\n useEffect(() => {\n // clear cache in case it was created before `useEffect` was run first time\n clearCacheRef.current();\n\n // make sure all cache users rerender\n setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));\n return () => {\n // eslint-disable-next-line react-hooks/exhaustive-deps\n clearCacheRef.current();\n };\n }, [imodel, viewType]);\n\n useEffect(() => {\n cacheRef.current?.clearFilteredElementsModels();\n }, [filteredPaths]);\n\n useIModelChangeListener({\n imodel,\n action: useCallback(() => {\n clearCacheRef.current();\n // make sure all cache users rerender\n setCacheGetter(() => createCacheGetterRef.current(imodel, viewType));\n }, [imodel, viewType]),\n });\n\n return {\n getCache,\n };\n}\n"]}
@@ -1,35 +1,23 @@
1
+ import type { Id64Array, Id64String } from "@itwin/core-bentley";
1
2
  import type { Viewport } from "@itwin/core-frontend";
2
3
  /**
3
4
  * Data structure that describes category.
4
5
  * @beta
5
6
  */
6
7
  export interface CategoryInfo {
7
- categoryId: string;
8
- subCategoryIds?: string[];
8
+ categoryId: Id64String;
9
+ subCategoryIds?: Id64Array;
9
10
  }
10
- /**
11
- * Toggles visibility of categories to show or hide.
12
- */
13
- export declare function toggleAllCategories(viewport: Viewport, display: boolean): Promise<void>;
14
- /**
15
- * Changes category display in the viewport.
16
- */
17
- export declare function enableCategoryDisplay(viewport: Viewport, ids: string[], enabled: boolean, enableAllSubCategories?: boolean): Promise<void>;
18
- /**
19
- * Changes subcategory display in the viewport
20
- */
21
- export declare function enableSubCategoryDisplay(viewport: Viewport, key: string, enabled: boolean): void;
22
- export declare function loadCategoriesFromViewport(vp: Viewport): Promise<CategoryInfo[]>;
23
11
  /**
24
12
  * Enable display of all given categories.
25
13
  * @public
26
14
  */
27
- export declare function showAllCategories(categories: string[], viewport: Viewport): Promise<void>;
15
+ export declare function showAllCategories(categories: Id64Array, viewport: Viewport): Promise<void>;
28
16
  /**
29
17
  * Disable display of all given categories.
30
18
  * @public
31
19
  */
32
- export declare function hideAllCategories(categories: string[], viewport: Viewport): Promise<void>;
20
+ export declare function hideAllCategories(categories: Id64Array, viewport: Viewport): Promise<void>;
33
21
  /**
34
22
  * Invert display of all given categories.
35
23
  * @public
@@ -2,64 +2,7 @@
2
2
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
3
3
  * See LICENSE.md in the project root for license terms and full copyright notice.
4
4
  *--------------------------------------------------------------------------------------------*/
5
- import { QueryRowFormat } from "@itwin/core-common";
6
- import { PerModelCategoryVisibility } from "@itwin/core-frontend";
7
- /**
8
- * Toggles visibility of categories to show or hide.
9
- */
10
- export async function toggleAllCategories(viewport, display) {
11
- const ids = await getCategories(viewport);
12
- if (ids.length === 0) {
13
- return;
14
- }
15
- await enableCategoryDisplay(viewport, ids, display);
16
- }
17
- /**
18
- * Gets ids of all categories from specified imodel and viewport.
19
- */
20
- async function getCategories(viewport) {
21
- const categories = await loadCategoriesFromViewport(viewport);
22
- return categories.map((category) => category.categoryId);
23
- }
24
- /**
25
- * Changes category display in the viewport.
26
- */
27
- export async function enableCategoryDisplay(viewport, ids, enabled, enableAllSubCategories = true) {
28
- viewport.changeCategoryDisplay(ids, enabled, enableAllSubCategories);
29
- // remove category overrides per model
30
- const modelsContainingOverrides = [];
31
- for (const ovr of viewport.perModelCategoryVisibility) {
32
- if (ids.findIndex((id) => id === ovr.categoryId) !== -1) {
33
- modelsContainingOverrides.push(ovr.modelId);
34
- }
35
- }
36
- viewport.perModelCategoryVisibility.setOverride(modelsContainingOverrides, ids, PerModelCategoryVisibility.Override.None);
37
- // changeCategoryDisplay only enables subcategories, it does not disabled them. So we must do that ourselves.
38
- if (false === enabled) {
39
- (await viewport.iModel.categories.getCategoryInfo(ids)).forEach((categoryInfo) => {
40
- categoryInfo.subCategories.forEach((value) => enableSubCategoryDisplay(viewport, value.id, false));
41
- });
42
- }
43
- }
44
- /**
45
- * Changes subcategory display in the viewport
46
- */
47
- export function enableSubCategoryDisplay(viewport, key, enabled) {
48
- viewport.changeSubCategoryDisplay(key, enabled);
49
- }
50
- export async function loadCategoriesFromViewport(vp) {
51
- // Query categories and add them to state
52
- const selectUsedSpatialCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId from BisCore.SpatialCategory)";
53
- const selectUsedDrawingCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement2d WHERE Model.Id=? AND Category.Id IN (SELECT ECInstanceId from BisCore.DrawingCategory)";
54
- const ecsql = vp.view.is3d() ? selectUsedSpatialCategoryIds : selectUsedDrawingCategoryIds;
55
- const ecsql2 = `SELECT ECInstanceId as id FROM ${vp.view.is3d() ? "BisCore.SpatialCategory" : "BisCore.DrawingCategory"} WHERE ECInstanceId IN (${ecsql})`;
56
- const categories = [];
57
- const rows = await vp.iModel.createQueryReader(ecsql2, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames }).toArray();
58
- (await vp.iModel.categories.getCategoryInfo(rows.map((row) => row.id))).forEach((val) => {
59
- categories.push({ categoryId: val.id, subCategoryIds: val.subCategories.size ? [...val.subCategories.keys()] : undefined });
60
- });
61
- return categories;
62
- }
5
+ import { enableCategoryDisplay, enableSubCategoryDisplay } from "./internal/VisibilityUtils.js";
63
6
  /**
64
7
  * Enable display of all given categories.
65
8
  * @public
@@ -79,10 +22,10 @@ export async function hideAllCategories(categories, viewport) {
79
22
  * @public
80
23
  */
81
24
  export async function invertAllCategories(categories, viewport) {
82
- const enabled = [];
83
- const disabled = [];
84
- const enabledSubCategories = [];
85
- const disabledSubCategories = [];
25
+ const enabled = new Array();
26
+ const disabled = new Array();
27
+ const enabledSubCategories = new Array();
28
+ const disabledSubCategories = new Array();
86
29
  for (const category of categories) {
87
30
  if (!viewport.view.viewsCategory(category.categoryId)) {
88
31
  disabled.push(category.categoryId);
@@ -1 +1 @@
1
- {"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAalE;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,QAAkB,EAAE,OAAgB;IAC5E,MAAM,GAAG,GAAG,MAAM,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC1C,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC,EAAE;QACpB,OAAO;KACR;IAED,MAAM,qBAAqB,CAAC,QAAQ,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;AACtD,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,aAAa,CAAC,QAAkB;IAC7C,MAAM,UAAU,GAAG,MAAM,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9D,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,QAAkB,EAAE,GAAa,EAAE,OAAgB,EAAE,sBAAsB,GAAG,IAAI;IAC5H,QAAQ,CAAC,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC;IAErE,sCAAsC;IACtC,MAAM,yBAAyB,GAAa,EAAE,CAAC;IAC/C,KAAK,MAAM,GAAG,IAAI,QAAQ,CAAC,0BAA0B,EAAE;QACrD,IAAI,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,KAAK,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE;YACvD,yBAAyB,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SAC7C;KACF;IACD,QAAQ,CAAC,0BAA0B,CAAC,WAAW,CAAC,yBAAyB,EAAE,GAAG,EAAE,0BAA0B,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAE1H,6GAA6G;IAC7G,IAAI,KAAK,KAAK,OAAO,EAAE;QACrB,CAAC,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,EAAE;YAC/E,YAAY,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;QACrG,CAAC,CAAC,CAAC;KACJ;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,QAAkB,EAAE,GAAW,EAAE,OAAgB;IACxF,QAAQ,CAAC,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;AAClD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,EAAY;IAC3D,yCAAyC;IACzC,MAAM,4BAA4B,GAChC,2IAA2I,CAAC;IAC9I,MAAM,4BAA4B,GAChC,0JAA0J,CAAC;IAC7J,MAAM,KAAK,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,4BAA4B,CAAC,CAAC,CAAC,4BAA4B,CAAC;IAC3F,MAAM,MAAM,GAAG,kCAAkC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,yBAAyB,CAAC,CAAC,CAAC,yBAAyB,2BAA2B,KAAK,GAAG,CAAC;IAE3J,MAAM,UAAU,GAAmB,EAAE,CAAC;IAEtC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,MAAM,CAAC,iBAAiB,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,EAAE,cAAc,CAAC,kBAAkB,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IAC9H,CAAC,MAAM,EAAE,CAAC,MAAM,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE;QACtF,UAAU,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,GAAG,CAAC,EAAE,EAAE,cAAc,EAAE,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9H,CAAC,CAAC,CAAC;IACH,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAoB,EAAE,QAAkB;IAC9E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAoB,EAAE,QAAkB;IAC9E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAA0B,EAAE,QAAkB;IACtF,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,MAAM,oBAAoB,GAAa,EAAE,CAAC;IAC1C,MAAM,qBAAqB,GAAa,EAAE,CAAC;IAE3C,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;YACrD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACnC,SAAS;SACV;QACD,iJAAiJ;QACjJ,IAAI,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,EAAE;YAC/F,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,cAAc,EAAE;gBACjD,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/H;SACF;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;SACnC;KACF;IAED,kBAAkB;IAClB,oBAAoB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE5D,kBAAkB;IAClB,qBAAqB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC","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 { QueryRowFormat } from \"@itwin/core-common\";\nimport { PerModelCategoryVisibility } from \"@itwin/core-frontend\";\n\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/**\n * Data structure that describes category.\n * @beta\n */\nexport interface CategoryInfo {\n categoryId: string;\n subCategoryIds?: string[];\n}\n\n/**\n * Toggles visibility of categories to show or hide.\n */\nexport async function toggleAllCategories(viewport: Viewport, display: boolean) {\n const ids = await getCategories(viewport);\n if (ids.length === 0) {\n return;\n }\n\n await enableCategoryDisplay(viewport, ids, display);\n}\n\n/**\n * Gets ids of all categories from specified imodel and viewport.\n */\nasync function getCategories(viewport: Viewport) {\n const categories = await loadCategoriesFromViewport(viewport);\n return categories.map((category) => category.categoryId);\n}\n\n/**\n * Changes category display in the viewport.\n */\nexport async function enableCategoryDisplay(viewport: Viewport, ids: string[], enabled: boolean, enableAllSubCategories = true) {\n viewport.changeCategoryDisplay(ids, enabled, enableAllSubCategories);\n\n // remove category overrides per model\n const modelsContainingOverrides: string[] = [];\n for (const ovr of viewport.perModelCategoryVisibility) {\n if (ids.findIndex((id) => id === ovr.categoryId) !== -1) {\n modelsContainingOverrides.push(ovr.modelId);\n }\n }\n viewport.perModelCategoryVisibility.setOverride(modelsContainingOverrides, ids, PerModelCategoryVisibility.Override.None);\n\n // changeCategoryDisplay only enables subcategories, it does not disabled them. So we must do that ourselves.\n if (false === enabled) {\n (await viewport.iModel.categories.getCategoryInfo(ids)).forEach((categoryInfo) => {\n categoryInfo.subCategories.forEach((value) => enableSubCategoryDisplay(viewport, value.id, false));\n });\n }\n}\n\n/**\n * Changes subcategory display in the viewport\n */\nexport function enableSubCategoryDisplay(viewport: Viewport, key: string, enabled: boolean) {\n viewport.changeSubCategoryDisplay(key, enabled);\n}\n\nexport async function loadCategoriesFromViewport(vp: Viewport) {\n // Query categories and add them to state\n const selectUsedSpatialCategoryIds =\n \"SELECT DISTINCT Category.Id as id from BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId from BisCore.SpatialCategory)\";\n const selectUsedDrawingCategoryIds =\n \"SELECT DISTINCT Category.Id as id from BisCore.GeometricElement2d WHERE Model.Id=? AND Category.Id IN (SELECT ECInstanceId from BisCore.DrawingCategory)\";\n const ecsql = vp.view.is3d() ? selectUsedSpatialCategoryIds : selectUsedDrawingCategoryIds;\n const ecsql2 = `SELECT ECInstanceId as id FROM ${vp.view.is3d() ? \"BisCore.SpatialCategory\" : \"BisCore.DrawingCategory\"} WHERE ECInstanceId IN (${ecsql})`;\n\n const categories: CategoryInfo[] = [];\n\n const rows = await vp.iModel.createQueryReader(ecsql2, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames }).toArray();\n (await vp.iModel.categories.getCategoryInfo(rows.map((row) => row.id))).forEach((val) => {\n categories.push({ categoryId: val.id, subCategoryIds: val.subCategories.size ? [...val.subCategories.keys()] : undefined });\n });\n return categories;\n}\n\n/**\n * Enable display of all given categories.\n * @public\n */\nexport async function showAllCategories(categories: string[], viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, true, true);\n}\n\n/**\n * Disable display of all given categories.\n * @public\n */\nexport async function hideAllCategories(categories: string[], viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, false, true);\n}\n\n/**\n * Invert display of all given categories.\n * @public\n */\nexport async function invertAllCategories(categories: CategoryInfo[], viewport: Viewport) {\n const enabled: string[] = [];\n const disabled: string[] = [];\n const enabledSubCategories: string[] = [];\n const disabledSubCategories: string[] = [];\n\n for (const category of categories) {\n if (!viewport.view.viewsCategory(category.categoryId)) {\n disabled.push(category.categoryId);\n continue;\n }\n // First, we need to check if at least one subcategory is disabled. If it is true, then only subcategories should change display, not categories.\n if (category.subCategoryIds?.some((subCategory) => !viewport.isSubCategoryVisible(subCategory))) {\n for (const subCategory of category.subCategoryIds) {\n viewport.isSubCategoryVisible(subCategory) ? enabledSubCategories.push(subCategory) : disabledSubCategories.push(subCategory);\n }\n } else {\n enabled.push(category.categoryId);\n }\n }\n\n // Disable enabled\n enabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, false));\n\n await enableCategoryDisplay(viewport, enabled, false, true);\n\n // Enable disabled\n disabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, true));\n\n await enableCategoryDisplay(viewport, disabled, true, true);\n}\n"]}
1
+ {"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,EAAE,qBAAqB,EAAE,wBAAwB,EAAE,MAAM,+BAA+B,CAAC;AAchG;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAqB,EAAE,QAAkB;IAC/E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAChE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAqB,EAAE,QAAkB;IAC/E,MAAM,qBAAqB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;AACjE,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,UAA0B,EAAE,QAAkB;IACtF,MAAM,OAAO,GAAG,IAAI,KAAK,EAAc,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAc,CAAC;IACzC,MAAM,oBAAoB,GAAG,IAAI,KAAK,EAAc,CAAC;IACrD,MAAM,qBAAqB,GAAG,IAAI,KAAK,EAAc,CAAC;IAEtD,KAAK,MAAM,QAAQ,IAAI,UAAU,EAAE;QACjC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE;YACrD,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;YACnC,SAAS;SACV;QACD,iJAAiJ;QACjJ,IAAI,QAAQ,CAAC,cAAc,EAAE,IAAI,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,EAAE;YAC/F,KAAK,MAAM,WAAW,IAAI,QAAQ,CAAC,cAAc,EAAE;gBACjD,QAAQ,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;aAC/H;SACF;aAAM;YACL,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;SACnC;KACF;IAED,kBAAkB;IAClB,oBAAoB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;IAE5D,kBAAkB;IAClB,qBAAqB,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,wBAAwB,CAAC,QAAQ,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;IAEtG,MAAM,qBAAqB,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;AAC9D,CAAC","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 { enableCategoryDisplay, enableSubCategoryDisplay } from \"./internal/VisibilityUtils.js\";\n\nimport type { Id64Array, Id64String } from \"@itwin/core-bentley\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/**\n * Data structure that describes category.\n * @beta\n */\nexport interface CategoryInfo {\n categoryId: Id64String;\n subCategoryIds?: Id64Array;\n}\n\n/**\n * Enable display of all given categories.\n * @public\n */\nexport async function showAllCategories(categories: Id64Array, viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, true, true);\n}\n\n/**\n * Disable display of all given categories.\n * @public\n */\nexport async function hideAllCategories(categories: Id64Array, viewport: Viewport) {\n await enableCategoryDisplay(viewport, categories, false, true);\n}\n\n/**\n * Invert display of all given categories.\n * @public\n */\nexport async function invertAllCategories(categories: CategoryInfo[], viewport: Viewport) {\n const enabled = new Array<Id64String>();\n const disabled = new Array<Id64String>();\n const enabledSubCategories = new Array<Id64String>();\n const disabledSubCategories = new Array<Id64String>();\n\n for (const category of categories) {\n if (!viewport.view.viewsCategory(category.categoryId)) {\n disabled.push(category.categoryId);\n continue;\n }\n // First, we need to check if at least one subcategory is disabled. If it is true, then only subcategories should change display, not categories.\n if (category.subCategoryIds?.some((subCategory) => !viewport.isSubCategoryVisible(subCategory))) {\n for (const subCategory of category.subCategoryIds) {\n viewport.isSubCategoryVisible(subCategory) ? enabledSubCategories.push(subCategory) : disabledSubCategories.push(subCategory);\n }\n } else {\n enabled.push(category.categoryId);\n }\n }\n\n // Disable enabled\n enabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, false));\n\n await enableCategoryDisplay(viewport, enabled, false, true);\n\n // Enable disabled\n disabledSubCategories.forEach((subCategory) => enableSubCategoryDisplay(viewport, subCategory, true));\n\n await enableCategoryDisplay(viewport, disabled, true, true);\n}\n"]}
@@ -11,8 +11,6 @@ export interface VisibilityStatus {
11
11
  state: "visible" | "partial" | "hidden";
12
12
  /** Specifies whether visibility changing is disabled or not. */
13
13
  isDisabled?: boolean;
14
- /** Tooltip that should be displayed when hovering over the visibility checkbox. */
15
- tooltip?: string;
16
14
  }
17
15
  /**
18
16
  * Handler that can be used to determine and change visibility of instances represented by tree nodes.
@@ -29,6 +27,7 @@ export interface HierarchyVisibilityHandler extends IDisposable {
29
27
  interface UseHierarchyVisibilityProps {
30
28
  visibilityHandlerFactory: () => HierarchyVisibilityHandler;
31
29
  }
30
+ /** @internal */
32
31
  export declare function useHierarchyVisibility({ visibilityHandlerFactory, }: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & {
33
32
  triggerRefresh: () => void;
34
33
  };
@@ -50,6 +49,7 @@ export type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc exte
50
49
  * @beta
51
50
  */
52
51
  export type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult : never;
52
+ /** @internal */
53
53
  export declare function createVisibilityHandlerResult<TResult, TOverrideProps>(handler: HierarchyVisibilityHandler, props: TOverrideProps, obs: Observable<TResult>, override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined): Observable<TResult>;
54
54
  export {};
55
55
  //# sourceMappingURL=UseHierarchyVisibility.d.ts.map
@@ -4,11 +4,13 @@
4
4
  *--------------------------------------------------------------------------------------------*/
5
5
  import { useEffect, useRef, useState } from "react";
6
6
  import { asyncScheduler, defer, distinct, EMPTY, from, lastValueFrom, mergeMap, observeOn, onErrorResumeNextWith, Subject, takeUntil, tap, throttleTime, } from "rxjs";
7
+ import { createTooltip } from "./internal/Tooltip.js";
7
8
  import { useTelemetryContext } from "./UseTelemetryContext.js";
9
+ /** @internal */
8
10
  export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
9
11
  const visibilityStatusMap = useRef(new Map());
10
12
  const [state, setState] = useState({
11
- getVisibilityButtonState: () => ({ state: "hidden", isDisabled: true }),
13
+ getVisibilityButtonState: () => ({ state: "visible", isDisabled: true }),
12
14
  onVisibilityButtonClick: () => { },
13
15
  triggerRefresh: () => { },
14
16
  });
@@ -30,7 +32,7 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
30
32
  const triggerCheckboxUpdate = () => {
31
33
  setState((prev) => ({
32
34
  ...prev,
33
- getCheckboxState: createStateGetter(visibilityStatusMap, calculateNodeStatus),
35
+ getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),
34
36
  }));
35
37
  };
36
38
  const subscription = calculate
@@ -38,7 +40,10 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
38
40
  next: (status) => {
39
41
  visibilityStatusMap.current.set(node.id, {
40
42
  node,
41
- status,
43
+ status: {
44
+ ...status,
45
+ tooltip: createTooltip(status.state),
46
+ },
42
47
  needsRefresh: false,
43
48
  });
44
49
  },
@@ -58,7 +63,7 @@ export function useHierarchyVisibility({ visibilityHandlerFactory, }) {
58
63
  return;
59
64
  }
60
65
  entry.status.state = visibilityState;
61
- entry.status.tooltip = undefined;
66
+ entry.status.tooltip = createTooltip("determining");
62
67
  triggerCheckboxUpdate();
63
68
  };
64
69
  setState({
@@ -86,7 +91,7 @@ function createStateGetter(map, calculateVisibility) {
86
91
  const entry = map.current.get(node.id);
87
92
  if (entry === undefined) {
88
93
  calculateVisibility(node);
89
- return { state: "hidden", isDisabled: true };
94
+ return { state: "visible", isDisabled: true, tooltip: createTooltip("determining") };
90
95
  }
91
96
  if (entry.needsRefresh) {
92
97
  calculateVisibility(node);
@@ -99,6 +104,7 @@ function createStateGetter(map, calculateVisibility) {
99
104
  };
100
105
  };
101
106
  }
107
+ /** @internal */
102
108
  export function createVisibilityHandlerResult(handler, props, obs, override) {
103
109
  return override
104
110
  ? from(override({
@@ -1 +1 @@
1
- {"version":3,"file":"UseHierarchyVisibility.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/UseHierarchyVisibility.ts"],"names":[],"mappings":"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","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 { useEffect, useRef, useState } from \"react\";\nimport {\n asyncScheduler,\n defer,\n distinct,\n EMPTY,\n from,\n lastValueFrom,\n mergeMap,\n observeOn,\n onErrorResumeNextWith,\n Subject,\n takeUntil,\n tap,\n throttleTime,\n} from \"rxjs\";\nimport { useTelemetryContext } from \"./UseTelemetryContext.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { MutableRefObject } from \"react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { HierarchyNode, PresentationHierarchyNode } from \"@itwin/presentation-hierarchies-react\";\nimport type { TreeItemVisibilityButtonProps } from \"./components/TreeNodeVisibilityButton.js\";\n\n/**\n * Data structure that describes instance visibility status.\n * @beta\n */\nexport interface VisibilityStatus {\n /** Instance visibility state. */\n state: \"visible\" | \"partial\" | \"hidden\";\n /** Specifies whether visibility changing is disabled or not. */\n isDisabled?: boolean;\n /** Tooltip that should be displayed when hovering over the visibility checkbox. */\n tooltip?: string;\n}\n\n/**\n * Handler that can be used to determine and change visibility of instances represented by tree nodes.\n * @beta\n */\nexport interface HierarchyVisibilityHandler extends IDisposable {\n /** Event used to notify tree about visibility changes from outside. */\n readonly onVisibilityChange: BeEvent<() => void>;\n /** Returns current visibility status for tree node. */\n getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus;\n /** Changes visibility of the instance represented by tree node. */\n changeVisibility(node: HierarchyNode, on: boolean): Promise<void>;\n}\n\ninterface UseHierarchyVisibilityProps {\n visibilityHandlerFactory: () => HierarchyVisibilityHandler;\n}\n\nexport function useHierarchyVisibility({\n visibilityHandlerFactory,\n}: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeItemVisibilityButtonProps & { triggerRefresh: () => void }>({\n getVisibilityButtonState: () => ({ state: \"hidden\", isDisabled: true }),\n onVisibilityButtonClick: () => {},\n triggerRefresh: () => {},\n });\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n visibilityStatusMap.current.clear();\n const handler = visibilityHandlerFactory();\n\n const visibilityChanged = new Subject<void>();\n const calculate = new Subject<PresentationHierarchyNode>();\n const calculateNodeStatus = (node: PresentationHierarchyNode) => {\n calculate.next(node);\n };\n\n const resetCache = () => {\n visibilityStatusMap.current.forEach((value) => {\n value.needsRefresh = true;\n });\n visibilityChanged.next();\n };\n\n const triggerCheckboxUpdate = () => {\n setState((prev) => ({\n ...prev,\n getCheckboxState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n }));\n };\n\n const subscription = calculate\n .pipe(\n distinct(undefined, visibilityChanged),\n observeOn(asyncScheduler),\n mergeMap((node) =>\n defer(async () => handler.getVisibilityStatus(node.nodeData)).pipe(\n tap({\n next: (status) => {\n visibilityStatusMap.current.set(node.id, {\n node,\n status,\n needsRefresh: false,\n });\n },\n }),\n takeUntil(visibilityChanged),\n onErrorResumeNextWith(EMPTY),\n ),\n ),\n throttleTime(100, undefined, { leading: false, trailing: true }),\n )\n .subscribe({\n next: () => {\n triggerCheckboxUpdate();\n },\n });\n\n const changeVisibility: TreeItemVisibilityButtonProps[\"onVisibilityButtonClick\"] = (node, visibilityState) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n // visible should become hidden, partial and hidden should become visible TODO: redo for clarity\n const on = visibilityState === \"visible\" ? false : true;\n void handler.changeVisibility(node.nodeData, on);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = visibilityState;\n entry.status.tooltip = undefined;\n triggerCheckboxUpdate();\n };\n\n setState({\n onVisibilityButtonClick: changeVisibility,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n triggerRefresh: () => {\n resetCache();\n triggerCheckboxUpdate();\n },\n });\n\n const removeListener = handler.onVisibilityChange.addListener(() => {\n resetCache();\n triggerCheckboxUpdate();\n });\n\n return () => {\n subscription.unsubscribe();\n removeListener();\n handler.dispose();\n };\n }, [visibilityHandlerFactory, onFeatureUsed]);\n\n return state;\n}\n\nfunction createStateGetter(\n map: MutableRefObject<Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>>,\n calculateVisibility: (node: PresentationHierarchyNode) => void,\n): TreeItemVisibilityButtonProps[\"getVisibilityButtonState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"hidden\", isDisabled: true };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state,\n tooltip: status.tooltip,\n isDisabled: status.isDisabled,\n };\n };\n}\n\n/**\n * Properties for an overridden method of a `HierarchyVisibilityHandler` implementation.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc extends (props: infer TProps) => infer TResult\n ? TProps & {\n /** A callback that produces the value from the original implementation. */\n readonly originalImplementation: () => TResult;\n /**\n * Reference to the hierarchy based handler.\n * @note Calling `getVisibility` or `changeVisibility` of this object invokes the overridden implementation as well.\n */\n readonly handler: HierarchyVisibilityHandler;\n }\n : never;\n\n/**\n * Function type for an overridden method of `HierarchyVisibilityHandler`.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult\n ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult\n : never;\n\nexport function createVisibilityHandlerResult<TResult, TOverrideProps>(\n handler: HierarchyVisibilityHandler,\n props: TOverrideProps,\n obs: Observable<TResult>,\n override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined,\n): Observable<TResult> {\n return override\n ? from(\n override({\n ...props,\n originalImplementation: async () => lastValueFrom(obs, { defaultValue: undefined as TResult }),\n handler,\n }),\n )\n : obs;\n}\n"]}
1
+ {"version":3,"file":"UseHierarchyVisibility.js","sourceRoot":"","sources":["../../../../../../src/tree-widget-react/components/trees/common/UseHierarchyVisibility.ts"],"names":[],"mappings":"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","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 { useEffect, useRef, useState } from \"react\";\nimport {\n asyncScheduler,\n defer,\n distinct,\n EMPTY,\n from,\n lastValueFrom,\n mergeMap,\n observeOn,\n onErrorResumeNextWith,\n Subject,\n takeUntil,\n tap,\n throttleTime,\n} from \"rxjs\";\nimport { createTooltip } from \"./internal/Tooltip.js\";\nimport { useTelemetryContext } from \"./UseTelemetryContext.js\";\n\nimport type { Observable } from \"rxjs\";\nimport type { MutableRefObject } from \"react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { HierarchyNode, PresentationHierarchyNode } from \"@itwin/presentation-hierarchies-react\";\nimport type { TreeItemVisibilityButtonProps, TreeItemVisibilityButtonState } from \"./components/TreeNodeVisibilityButton.js\";\n\n/**\n * Data structure that describes instance visibility status.\n * @beta\n */\nexport interface VisibilityStatus {\n /** Instance visibility state. */\n state: \"visible\" | \"partial\" | \"hidden\";\n /** Specifies whether visibility changing is disabled or not. */\n isDisabled?: boolean;\n}\n\n/**\n * Handler that can be used to determine and change visibility of instances represented by tree nodes.\n * @beta\n */\nexport interface HierarchyVisibilityHandler extends IDisposable {\n /** Event used to notify tree about visibility changes from outside. */\n readonly onVisibilityChange: BeEvent<() => void>;\n /** Returns current visibility status for tree node. */\n getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus;\n /** Changes visibility of the instance represented by tree node. */\n changeVisibility(node: HierarchyNode, on: boolean): Promise<void>;\n}\n\ninterface UseHierarchyVisibilityProps {\n visibilityHandlerFactory: () => HierarchyVisibilityHandler;\n}\n\n/** @internal */\nexport function useHierarchyVisibility({\n visibilityHandlerFactory,\n}: UseHierarchyVisibilityProps): TreeItemVisibilityButtonProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: TreeItemVisibilityButtonState; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeItemVisibilityButtonProps & { triggerRefresh: () => void }>({\n getVisibilityButtonState: () => ({ state: \"visible\", isDisabled: true }),\n onVisibilityButtonClick: () => {},\n triggerRefresh: () => {},\n });\n const { onFeatureUsed } = useTelemetryContext();\n\n useEffect(() => {\n visibilityStatusMap.current.clear();\n const handler = visibilityHandlerFactory();\n\n const visibilityChanged = new Subject<void>();\n const calculate = new Subject<PresentationHierarchyNode>();\n const calculateNodeStatus = (node: PresentationHierarchyNode) => {\n calculate.next(node);\n };\n\n const resetCache = () => {\n visibilityStatusMap.current.forEach((value) => {\n value.needsRefresh = true;\n });\n visibilityChanged.next();\n };\n\n const triggerCheckboxUpdate = () => {\n setState((prev) => ({\n ...prev,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n }));\n };\n\n const subscription = calculate\n .pipe(\n distinct(undefined, visibilityChanged),\n observeOn(asyncScheduler),\n mergeMap((node) =>\n defer(async () => handler.getVisibilityStatus(node.nodeData)).pipe(\n tap({\n next: (status) => {\n visibilityStatusMap.current.set(node.id, {\n node,\n status: {\n ...status,\n tooltip: createTooltip(status.state),\n },\n needsRefresh: false,\n });\n },\n }),\n takeUntil(visibilityChanged),\n onErrorResumeNextWith(EMPTY),\n ),\n ),\n throttleTime(100, undefined, { leading: false, trailing: true }),\n )\n .subscribe({\n next: () => {\n triggerCheckboxUpdate();\n },\n });\n\n const changeVisibility: TreeItemVisibilityButtonProps[\"onVisibilityButtonClick\"] = (node, visibilityState) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n // visible should become hidden, partial and hidden should become visible TODO: redo for clarity\n const on = visibilityState === \"visible\" ? false : true;\n void handler.changeVisibility(node.nodeData, on);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = visibilityState;\n entry.status.tooltip = createTooltip(\"determining\");\n triggerCheckboxUpdate();\n };\n\n setState({\n onVisibilityButtonClick: changeVisibility,\n getVisibilityButtonState: createStateGetter(visibilityStatusMap, calculateNodeStatus),\n triggerRefresh: () => {\n resetCache();\n triggerCheckboxUpdate();\n },\n });\n\n const removeListener = handler.onVisibilityChange.addListener(() => {\n resetCache();\n triggerCheckboxUpdate();\n });\n\n return () => {\n subscription.unsubscribe();\n removeListener();\n handler.dispose();\n };\n }, [visibilityHandlerFactory, onFeatureUsed]);\n\n return state;\n}\n\nfunction createStateGetter(\n map: MutableRefObject<Map<string, { node: PresentationHierarchyNode; status: TreeItemVisibilityButtonState; needsRefresh: boolean }>>,\n calculateVisibility: (node: PresentationHierarchyNode) => void,\n): TreeItemVisibilityButtonProps[\"getVisibilityButtonState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"visible\", isDisabled: true, tooltip: createTooltip(\"determining\") };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state,\n tooltip: status.tooltip,\n isDisabled: status.isDisabled,\n };\n };\n}\n\n/**\n * Properties for an overridden method of a `HierarchyVisibilityHandler` implementation.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethodProps<TFunc> = TFunc extends (props: infer TProps) => infer TResult\n ? TProps & {\n /** A callback that produces the value from the original implementation. */\n readonly originalImplementation: () => TResult;\n /**\n * Reference to the hierarchy based handler.\n * @note Calling `getVisibility` or `changeVisibility` of this object invokes the overridden implementation as well.\n */\n readonly handler: HierarchyVisibilityHandler;\n }\n : never;\n\n/**\n * Function type for an overridden method of `HierarchyVisibilityHandler`.\n * @beta\n */\nexport type HierarchyVisibilityHandlerOverridableMethod<TFunc> = TFunc extends (...args: any[]) => infer TResult\n ? (props: HierarchyVisibilityHandlerOverridableMethodProps<TFunc>) => TResult\n : never;\n\n/** @internal */\nexport function createVisibilityHandlerResult<TResult, TOverrideProps>(\n handler: HierarchyVisibilityHandler,\n props: TOverrideProps,\n obs: Observable<TResult>,\n override: HierarchyVisibilityHandlerOverridableMethod<(props: TOverrideProps) => Promise<TResult>> | undefined,\n): Observable<TResult> {\n return override\n ? from(\n override({\n ...props,\n originalImplementation: async () => lastValueFrom(obs, { defaultValue: undefined as TResult }),\n handler,\n }),\n )\n : obs;\n}\n"]}
@@ -15,6 +15,7 @@ interface UseNodeHighlightingResult {
15
15
  activeNodeId?: string;
16
16
  getLabel: (node: PresentationHierarchyNode) => React.ReactElement;
17
17
  }
18
+ /** @internal */
18
19
  export declare function useNodeHighlighting({ rootNodes, highlight }: UseNodeHighlightingProps): UseNodeHighlightingResult;
19
20
  export {};
20
21
  //# sourceMappingURL=UseNodeHighlighting.d.ts.map
@@ -3,40 +3,42 @@ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
3
3
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
4
4
  * See LICENSE.md in the project root for license terms and full copyright notice.
5
5
  *--------------------------------------------------------------------------------------------*/
6
- import { useCallback, useEffect, useRef, useState } from "react";
6
+ import { useCallback, useEffect, useState } from "react";
7
7
  import { isPresentationHierarchyNode } from "@itwin/presentation-hierarchies-react";
8
- import { useLatest } from "./Utils.js";
8
+ import { useLatest } from "./internal/Utils.js";
9
+ /** @internal */
9
10
  export function useNodeHighlighting({ rootNodes, highlight }) {
10
- const state = useRef({ nodeInfoMap: new Map(), totalMatches: 0 });
11
+ const [state, setState] = useState({ nodeInfoMap: new Map(), totalMatches: 0 });
11
12
  const [activeNodeId, setActiveNodeId] = useState();
12
13
  const activeMatchIndexRef = useLatest(highlight?.activeMatchIndex);
13
14
  const activeNodeIdRef = useLatest(activeNodeId);
14
15
  const onHighlightChangedRef = useLatest(highlight?.onHighlightChanged);
16
+ const prevStateRef = useLatest(state);
15
17
  const searchText = highlight?.text;
16
18
  useEffect(() => {
17
19
  const { state: newState, activeIndex } = rootNodes && searchText
18
- ? computeHighlightState(rootNodes, searchText, state.current, activeNodeIdRef.current, activeMatchIndexRef.current)
20
+ ? computeHighlightState(rootNodes, searchText, prevStateRef.current, activeNodeIdRef.current, activeMatchIndexRef.current)
19
21
  : { state: { nodeInfoMap: new Map(), totalMatches: 0 }, activeIndex: 0 };
20
- state.current = newState;
22
+ setState(newState);
21
23
  if (newState.totalMatches === 0) {
22
24
  setActiveNodeId(undefined);
23
25
  }
24
26
  onHighlightChangedRef.current?.(newState.totalMatches === 0 ? 0 : activeIndex, newState.totalMatches);
25
- }, [rootNodes, searchText, activeNodeIdRef, activeMatchIndexRef, onHighlightChangedRef]);
27
+ }, [rootNodes, searchText, activeNodeIdRef, activeMatchIndexRef, onHighlightChangedRef, prevStateRef]);
26
28
  useEffect(() => {
27
- for (const nodeId of state.current.nodeInfoMap.keys()) {
28
- if (getNodeChunkInfo(state.current, nodeId, highlight?.activeMatchIndex)?.activeChunkIndex !== undefined) {
29
+ for (const nodeId of state.nodeInfoMap.keys()) {
30
+ if (getNodeChunkInfo(state, nodeId, highlight?.activeMatchIndex)?.activeChunkIndex !== undefined) {
29
31
  setActiveNodeId(nodeId);
30
32
  }
31
33
  }
32
- }, [highlight?.activeMatchIndex]);
34
+ }, [state, highlight?.activeMatchIndex]);
33
35
  const getLabel = useCallback((node) => {
34
- const chunkInfo = getNodeChunkInfo(state.current, node.id, highlight?.activeMatchIndex);
36
+ const chunkInfo = getNodeChunkInfo(state, node.id, highlight?.activeMatchIndex);
35
37
  if (searchText && chunkInfo) {
36
38
  return _jsx(_Fragment, { children: markChunks(node.label, chunkInfo.chunks, chunkInfo.activeChunkIndex) });
37
39
  }
38
40
  return _jsx("span", { children: node.label });
39
- }, [searchText, highlight?.activeMatchIndex]);
41
+ }, [state, searchText, highlight?.activeMatchIndex]);
40
42
  return { activeNodeId, getLabel };
41
43
  }
42
44
  function getNodeChunkInfo(state, nodeId, activeIndex) {