@itwin/tree-widget-react 3.0.3 → 3.2.0

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 (107) hide show
  1. package/CHANGELOG.md +31 -19
  2. package/README.md +8 -8
  3. package/lib/cjs/components/tree-header/TreeHeader.js +1 -1
  4. package/lib/cjs/components/tree-header/TreeHeader.js.map +1 -1
  5. package/lib/cjs/components/trees/categories-tree/CategoriesTreeButtons.js +3 -3
  6. package/lib/cjs/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
  7. package/lib/cjs/components/trees/categories-tree/CategoriesVisibilityHandler.js +2 -1
  8. package/lib/cjs/components/trees/categories-tree/CategoriesVisibilityHandler.js.map +1 -1
  9. package/lib/cjs/components/trees/{models-tree/internal → common}/Tooltip.d.ts +7 -3
  10. package/lib/cjs/components/trees/{models-tree/internal → common}/Tooltip.js +5 -5
  11. package/lib/cjs/components/trees/common/Tooltip.js.map +1 -0
  12. package/lib/cjs/components/trees/common/UseActiveViewport.js.map +1 -1
  13. package/lib/cjs/components/trees/common/UseHierarchyVisibility.js +3 -3
  14. package/lib/cjs/components/trees/common/UseHierarchyVisibility.js.map +1 -1
  15. package/lib/cjs/components/trees/common/components/Tree.d.ts +6 -1
  16. package/lib/cjs/components/trees/common/components/Tree.js +14 -4
  17. package/lib/cjs/components/trees/common/components/Tree.js.map +1 -1
  18. package/lib/cjs/components/trees/common/components/TreeNodeCheckbox.js +5 -5
  19. package/lib/cjs/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
  20. package/lib/cjs/components/trees/common/components/TreeRenderer.d.ts +1 -1
  21. package/lib/cjs/components/trees/common/components/TreeRenderer.js +4 -3
  22. package/lib/cjs/components/trees/common/components/TreeRenderer.js.map +1 -1
  23. package/lib/cjs/components/trees/common/components/TreeRenderer.scss +0 -6
  24. package/lib/cjs/components/trees/models-tree/ModelsTree.d.ts +1 -1
  25. package/lib/cjs/components/trees/models-tree/ModelsTree.js +2 -1
  26. package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
  27. package/lib/cjs/components/trees/models-tree/ModelsTreeButtons.js +13 -13
  28. package/lib/cjs/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
  29. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.d.ts +1 -1
  30. package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  31. package/lib/cjs/components/trees/models-tree/ModelsTreeDefinition.js +1 -1
  32. package/lib/cjs/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
  33. package/lib/cjs/components/trees/models-tree/UseModelsTree.d.ts +12 -3
  34. package/lib/cjs/components/trees/models-tree/UseModelsTree.js +32 -13
  35. package/lib/cjs/components/trees/models-tree/UseModelsTree.js.map +1 -1
  36. package/lib/cjs/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +5 -0
  37. package/lib/cjs/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js +28 -7
  38. package/lib/cjs/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -1
  39. package/lib/cjs/components/trees/models-tree/internal/FilteredTree.d.ts +25 -0
  40. package/lib/cjs/components/trees/models-tree/internal/FilteredTree.js +178 -0
  41. package/lib/cjs/components/trees/models-tree/internal/FilteredTree.js.map +1 -0
  42. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +2 -1
  43. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeIdsCache.js +55 -23
  44. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  45. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeNode.d.ts +12 -6
  46. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeNode.js +18 -1
  47. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeNode.js.map +1 -1
  48. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.d.ts +8 -8
  49. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +162 -207
  50. package/lib/cjs/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
  51. package/lib/cjs/components/trees/models-tree/internal/VisibilityChangeEventListener.d.ts +2 -0
  52. package/lib/cjs/components/trees/models-tree/internal/VisibilityChangeEventListener.js +11 -1
  53. package/lib/cjs/components/trees/models-tree/internal/VisibilityChangeEventListener.js.map +1 -1
  54. package/lib/esm/components/tree-header/TreeHeader.js +1 -1
  55. package/lib/esm/components/tree-header/TreeHeader.js.map +1 -1
  56. package/lib/esm/components/trees/categories-tree/CategoriesTreeButtons.js +3 -3
  57. package/lib/esm/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
  58. package/lib/esm/components/trees/categories-tree/CategoriesVisibilityHandler.js +2 -1
  59. package/lib/esm/components/trees/categories-tree/CategoriesVisibilityHandler.js.map +1 -1
  60. package/lib/esm/components/trees/{models-tree/internal → common}/Tooltip.d.ts +7 -3
  61. package/lib/esm/components/trees/{models-tree/internal → common}/Tooltip.js +5 -5
  62. package/lib/esm/components/trees/common/Tooltip.js.map +1 -0
  63. package/lib/esm/components/trees/common/UseActiveViewport.js.map +1 -1
  64. package/lib/esm/components/trees/common/UseHierarchyVisibility.js +4 -4
  65. package/lib/esm/components/trees/common/UseHierarchyVisibility.js.map +1 -1
  66. package/lib/esm/components/trees/common/components/Tree.d.ts +6 -1
  67. package/lib/esm/components/trees/common/components/Tree.js +14 -4
  68. package/lib/esm/components/trees/common/components/Tree.js.map +1 -1
  69. package/lib/esm/components/trees/common/components/TreeNodeCheckbox.js +6 -6
  70. package/lib/esm/components/trees/common/components/TreeNodeCheckbox.js.map +1 -1
  71. package/lib/esm/components/trees/common/components/TreeRenderer.d.ts +1 -1
  72. package/lib/esm/components/trees/common/components/TreeRenderer.js +4 -3
  73. package/lib/esm/components/trees/common/components/TreeRenderer.js.map +1 -1
  74. package/lib/esm/components/trees/common/components/TreeRenderer.scss +0 -6
  75. package/lib/esm/components/trees/models-tree/ModelsTree.d.ts +1 -1
  76. package/lib/esm/components/trees/models-tree/ModelsTree.js +2 -1
  77. package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
  78. package/lib/esm/components/trees/models-tree/ModelsTreeButtons.js +14 -14
  79. package/lib/esm/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
  80. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.d.ts +1 -1
  81. package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
  82. package/lib/esm/components/trees/models-tree/ModelsTreeDefinition.js.map +1 -1
  83. package/lib/esm/components/trees/models-tree/UseModelsTree.d.ts +12 -3
  84. package/lib/esm/components/trees/models-tree/UseModelsTree.js +33 -14
  85. package/lib/esm/components/trees/models-tree/UseModelsTree.js.map +1 -1
  86. package/lib/esm/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.d.ts +5 -0
  87. package/lib/esm/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js +29 -8
  88. package/lib/esm/components/trees/models-tree/internal/AlwaysAndNeverDrawnElementInfo.js.map +1 -1
  89. package/lib/esm/components/trees/models-tree/internal/FilteredTree.d.ts +25 -0
  90. package/lib/esm/components/trees/models-tree/internal/FilteredTree.js +173 -0
  91. package/lib/esm/components/trees/models-tree/internal/FilteredTree.js.map +1 -0
  92. package/lib/esm/components/trees/models-tree/internal/ModelsTreeIdsCache.d.ts +2 -1
  93. package/lib/esm/components/trees/models-tree/internal/ModelsTreeIdsCache.js +55 -23
  94. package/lib/esm/components/trees/models-tree/internal/ModelsTreeIdsCache.js.map +1 -1
  95. package/lib/esm/components/trees/models-tree/internal/ModelsTreeNode.d.ts +12 -6
  96. package/lib/esm/components/trees/models-tree/internal/ModelsTreeNode.js +17 -0
  97. package/lib/esm/components/trees/models-tree/internal/ModelsTreeNode.js.map +1 -1
  98. package/lib/esm/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.d.ts +8 -8
  99. package/lib/esm/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +161 -206
  100. package/lib/esm/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
  101. package/lib/esm/components/trees/models-tree/internal/VisibilityChangeEventListener.d.ts +2 -0
  102. package/lib/esm/components/trees/models-tree/internal/VisibilityChangeEventListener.js +11 -1
  103. package/lib/esm/components/trees/models-tree/internal/VisibilityChangeEventListener.js.map +1 -1
  104. package/lib/public/locales/en/TreeWidget.json +47 -43
  105. package/package.json +43 -37
  106. package/lib/cjs/components/trees/models-tree/internal/Tooltip.js.map +0 -1
  107. package/lib/esm/components/trees/models-tree/internal/Tooltip.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,12 +1,39 @@
1
1
  # Change Log - @itwin/tree-widget-react
2
2
 
3
- This log was last generated on Fri, 15 Nov 2024 15:02:53 GMT and should not be manually modified.
3
+ This log was last generated on Wed, 18 Dec 2024 12:42:07 GMT and should not be manually modified.
4
4
 
5
5
  <!-- Start content -->
6
6
 
7
+ ## 3.2.0
8
+
9
+ Wed, 18 Dec 2024 12:42:07 GMT
10
+
11
+ ### Minor changes
12
+
13
+ - Added an optional `selectionPredicate` function prop to `ModelsTreeComponent`, `ModelsTree`, `useModelsTree` and `Tree` components. When provided, it allows consumers to conditionally enable/disable selection of tree nodes. ([#1124](https://github.com/iTwin/viewer-components-react/pull/1124))
14
+
15
+ ### Patches
16
+
17
+ - Bump dependencies ([#1122](https://github.com/iTwin/viewer-components-react/pull/1122))
18
+
19
+ ## 3.1.0
20
+
21
+ Fri, 29 Nov 2024 10:43:06 GMT
22
+
23
+ ### Minor changes
24
+
25
+ - Replaced `ModelsTreeVisibilityHandlerOverrides.changeElementState` with `ModelsTreeVisibilityHandlerOverrides.changeElementsState`. The method is provided with a list of elements instead of single element to allow changing visibility of multiple elements in single batch istead of one by one. ([#1098](https://github.com/iTwin/viewer-components-react/pull/1098))
26
+
27
+ ### Patches
28
+
29
+ - Bump dependencies ([#1103](https://github.com/iTwin/viewer-components-react/pull/1103))
30
+ - Add missing tooltips ([#1092](https://github.com/iTwin/viewer-components-react/pull/1092))
31
+ - Reduce the number of queries being executed when always/never drawn sets change. ([#1102](https://github.com/iTwin/viewer-components-react/pull/1102))
32
+ - Improve performance of visibility status calculation and visibility changes. Also reduce main thread blocking to avoid UI freezing. ([#1098](https://github.com/iTwin/viewer-components-react/pull/1098))
33
+
7
34
  ## 3.0.3
8
35
 
9
- Fri, 15 Nov 2024 15:02:53 GMT
36
+ Fri, 15 Nov 2024 15:03:19 GMT
10
37
 
11
38
  ### Patches
12
39
 
@@ -36,22 +63,7 @@ Fri, 04 Oct 2024 15:06:44 GMT
36
63
 
37
64
  ### Major changes
38
65
 
39
- - Updated `ModelsTree` and `CategoriesTree` header buttons to apply action on filtered tree. ([#1034](https://github.com/iTwin/viewer-components-react/pull/1034))
40
- - Made `@itwin/itwinui-react` a peer dependency, bumped its version to `^3.11.0`. ([#1004](https://github.com/iTwin/viewer-components-react/pull/1004))
41
- - Models Tree: Changed the tree to determine status of node visibility using not just the element the node represents, but also its children. This also introduces partial visibility state for cases when visibility states of different elements are different. ([#829](https://github.com/iTwin/viewer-components-react/pull/829))
42
- - Refactor tree components to use `@itwin/presentation-hierarchies-react`. Add an `@itwin/ecschema-metadata@^4.0.0` peer dependency. ([#840](https://github.com/iTwin/viewer-components-react/pull/840))
43
-
44
- ### Minor changes
45
-
46
- - Add ability to focus nodes in `ModelsTree` ([#943](https://github.com/iTwin/viewer-components-react/pull/943))
47
- - Added ability to display a subset of `ModelsTree`. ([#994](https://github.com/iTwin/viewer-components-react/pull/994))
48
- - Added ability to retry loading failed hierarchy levels ([#976](https://github.com/iTwin/viewer-components-react/pull/976))
49
- - Added error reporting to feature telemetry in tree components. ([#988](https://github.com/iTwin/viewer-components-react/pull/988))
50
-
51
- ### Patches
52
-
53
- - Added a loading indicator when matching instances count is being calculated in hierarchy level filtering dialog. ([#962](https://github.com/iTwin/viewer-components-react/pull/962))
54
- - Add thousands separator to filter dialog result count ([#960](https://github.com/iTwin/viewer-components-react/pull/960))
66
+ - The `3.0` release affects nearly all components in this package, usually in a breaking way. As a result, we suggest treating this version as a completely new package rather than an incremental upgrade - please have a look at the [README](./README.md) for a list of new features and examples on how to consume the new version ([#966](https://github.com/iTwin/viewer-components-react/pull/966))
55
67
 
56
68
  ## 2.3.2
57
69
 
@@ -232,7 +244,7 @@ Mon, 31 Jul 2023 14:10:09 GMT
232
244
  - Handle errors thrown from tree components.
233
245
  - Persist tree scroll position when switching between widgets.
234
246
  - `Tree Header`: Fixed dropdown buttons menu not theming correctly.
235
- - `ModelsTree`: Refactor ruleset to not use deprecated `ImageIdOverride` rule.
247
+ - `ModelsTree`: Refactor ruleset to not use deprecated `ImageIdOverride` rule.
236
248
  - `ModelsTree`: Always render checkbox to avoid UI shifting when checkbox appear.
237
249
 
238
250
  ## 0.10.0
package/README.md CHANGED
@@ -419,16 +419,16 @@ Example:
419
419
  import type { ComponentPropsWithoutRef } from "react";
420
420
  import type { IModelConnection } from "@itwin/core-frontend";
421
421
  import { Tree, TreeRenderer } from "@itwin/tree-widget-react";
422
- import { createClassBasedHierarchyDefinition, createNodesQueryClauseFactory } from "@itwin/presentation-hierarchies";
422
+ import { createNodesQueryClauseFactory, createPredicateBasedHierarchyDefinition } from "@itwin/presentation-hierarchies";
423
423
  import { createBisInstanceLabelSelectClauseFactory } from "@itwin/presentation-shared";
424
424
 
425
425
  type TreeProps = ComponentPropsWithoutRef<typeof Tree>;
426
426
  const getHierarchyDefinition: TreeProps["getHierarchyDefinition"] = ({ imodelAccess }) => {
427
427
  // create a hierarchy definition that defines what should be shown in the tree
428
- // see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/README.md#hierarchy-definition
429
- const nodesQueryFactory = createNodesQueryClauseFactory({ imodelAccess });
428
+ // see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/learning/imodel/HierarchyDefinition.md
430
429
  const labelsQueryFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: imodelAccess });
431
- return createClassBasedHierarchyDefinition({
430
+ const nodesQueryFactory = createNodesQueryClauseFactory({ imodelAccess, instanceLabelSelectClauseFactory: labelsQueryFactory });
431
+ return createPredicateBasedHierarchyDefinition({
432
432
  classHierarchyInspector: imodelAccess,
433
433
  hierarchy: {
434
434
  // For root nodes, select all BisCore.GeometricModel3d instances
@@ -490,7 +490,7 @@ Example:
490
490
  ```tsx
491
491
  import { BeEvent } from "@itwin/core-bentley";
492
492
  import { VisibilityTree, VisibilityTreeRenderer } from "@itwin/tree-widget-react";
493
- import { createClassBasedHierarchyDefinition, createNodesQueryClauseFactory } from "@itwin/presentation-hierarchies";
493
+ import { createNodesQueryClauseFactory, createPredicateBasedHierarchyDefinition } from "@itwin/presentation-hierarchies";
494
494
  import { createBisInstanceLabelSelectClauseFactory } from "@itwin/presentation-shared";
495
495
  import type { ComponentPropsWithoutRef } from "react";
496
496
  import type { IModelConnection } from "@itwin/core-frontend";
@@ -498,10 +498,10 @@ import type { IModelConnection } from "@itwin/core-frontend";
498
498
  type VisibilityTreeProps = ComponentPropsWithoutRef<typeof VisibilityTree>;
499
499
  const getHierarchyDefinition: VisibilityTreeProps["getHierarchyDefinition"] = ({ imodelAccess }) => {
500
500
  // create a hierarchy definition that defines what should be shown in the tree
501
- // see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/README.md#hierarchy-definition
502
- const nodesQueryFactory = createNodesQueryClauseFactory({ imodelAccess });
501
+ // see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/learning/imodel/HierarchyDefinition.md
503
502
  const labelsQueryFactory = createBisInstanceLabelSelectClauseFactory({ classHierarchyInspector: imodelAccess });
504
- return createClassBasedHierarchyDefinition({
503
+ const nodesQueryFactory = createNodesQueryClauseFactory({ imodelAccess, instanceLabelSelectClauseFactory: labelsQueryFactory });
504
+ return createPredicateBasedHierarchyDefinition({
505
505
  classHierarchyInspector: imodelAccess,
506
506
  hierarchy: {
507
507
  // For root nodes, select all BisCore.GeometricModel3d instances
@@ -56,7 +56,7 @@ function HeaderButtons(props) {
56
56
  const className = (0, classnames_1.default)("button-container", props.contracted && "contracted");
57
57
  return ((0, jsx_runtime_1.jsx)(itwinui_react_1.ButtonGroup, { className: className, overflowButton: (overflowStart) => ((0, jsx_runtime_1.jsx)(itwinui_react_1.DropdownMenu, { menuItems: () => react_1.Children.toArray(props.children)
58
58
  .slice(overflowStart)
59
- .map((btn, index) => ((0, jsx_runtime_1.jsx)("li", { className: "dropdown-item", role: "menuitem", children: btn }, index))), className: "tree-header-button-dropdown-container", children: (0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { title: TreeWidget_1.TreeWidget.translate("header.dropdownMore"), styleType: "borderless", size: props.size, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgMore, {}) }) })), children: props.children }));
59
+ .map((btn, index) => ((0, jsx_runtime_1.jsx)("li", { className: "dropdown-item", role: "menuitem", children: btn }, index))), className: "tree-header-button-dropdown-container", children: (0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { label: TreeWidget_1.TreeWidget.translate("header.dropdownMore"), styleType: "borderless", size: props.size, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgMore, {}) }) })), children: props.children }));
60
60
  }
61
61
  function SearchResultStepper(props) {
62
62
  const { selectedIndex = 1, total, onStep } = props;
@@ -1 +1 @@
1
- {"version":3,"file":"TreeHeader.js","sourceRoot":"","sources":["../../../../src/components/tree-header/TreeHeader.tsx"],"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 \"./TreeHeader.scss\";\nimport classnames from \"classnames\";\nimport { Children, useEffect, useRef, useState } from \"react\";\nimport { SvgCaretDownSmall, SvgCaretUpSmall, SvgMore } from \"@itwin/itwinui-icons-react\";\nimport { ButtonGroup, Divider, DropdownMenu, IconButton, SearchBox } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../TreeWidget\";\nimport { useFocusedInstancesContext } from \"../trees/common/FocusedInstancesContext\";\n\nimport type { PropsWithChildren } from \"react\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/** @public */\nexport interface TreeHeaderButtonProps {\n viewport: Viewport;\n density?: \"default\" | \"enlarged\";\n onFeatureUsed?: (feature: string) => void;\n}\n\n/** @beta */\nexport interface TreeFilteringProps {\n /** Filtering is cleared after everything's loaded */\n onFilterStart: (newFilter: string) => void;\n /** listens for onClick event for Clear (x) icon */\n onFilterClear: () => void;\n /** Total number of results/entries */\n resultCount?: number;\n /** Current selected result index */\n selectedIndex?: number;\n /** Callback to currently selected result/entry change */\n onSelectedChanged?: (index: number) => void;\n /** Should the search box be disabled */\n isDisabled?: boolean;\n}\n\ninterface TreeHeaderProps {\n filteringProps?: TreeFilteringProps;\n /** Modifies the density of tree header. `enlarged` header contains larger content */\n density?: \"default\" | \"enlarged\";\n className?: string;\n}\n\nexport function TreeHeader(props: PropsWithChildren<TreeHeaderProps>) {\n const { filteringProps, density, className, children } = props;\n const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);\n const { enabled: instanceFocusEnabled } = useFocusedInstancesContext();\n const size = density === \"enlarged\" ? \"large\" : \"small\";\n\n useEffect(() => {\n // istanbul ignore if\n if (filteringProps?.isDisabled) {\n setIsSearchOpen(false);\n }\n }, [filteringProps?.isDisabled]);\n\n return (\n <div className={classnames(\"tree-widget-tree-header\", className)}>\n <HeaderButtons contracted={isSearchOpen} size={size}>\n {children}\n </HeaderButtons>\n {filteringProps ? (\n <DebouncedSearchBox\n isOpened={isSearchOpen}\n onOpen={() => setIsSearchOpen(true)}\n onClose={() => setIsSearchOpen(false)}\n onChange={(value) => (value ? filteringProps.onFilterStart(value) : filteringProps.onFilterClear())}\n delay={500}\n selectedResultIndex={filteringProps.selectedIndex}\n resultCount={filteringProps.resultCount}\n onSelectedResultChanged={(index) => filteringProps.onSelectedChanged?.(index)}\n size={size}\n isDisabled={instanceFocusEnabled || props.filteringProps?.isDisabled}\n />\n ) : null}\n </div>\n );\n}\n\ninterface DebouncedSearchBoxProps {\n isOpened: boolean;\n onOpen: () => void;\n onClose: () => void;\n onChange: (value: string) => void;\n delay: number;\n selectedResultIndex?: number;\n resultCount?: number;\n onSelectedResultChanged: (index: number) => void;\n size: \"large\" | \"small\";\n isDisabled?: boolean;\n}\n\nfunction DebouncedSearchBox({\n isOpened,\n selectedResultIndex,\n resultCount,\n onSelectedResultChanged,\n onChange,\n onOpen,\n onClose,\n delay,\n size,\n isDisabled,\n}: DebouncedSearchBoxProps) {\n const [inputValue, setInputValue] = useState<string>(\"\");\n const onChangeRef = useRef(onChange);\n // save latest `onChange` reference into `useRef` to avoid restarting timeout when `onChange` reference changes.\n onChangeRef.current = onChange;\n\n useEffect(() => {\n if (!inputValue) {\n onChangeRef.current(\"\");\n return;\n }\n\n const timeoutId = setTimeout(() => {\n onChangeRef.current(inputValue);\n }, delay);\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [inputValue, delay]);\n\n return (\n <SearchBox\n expandable\n isExpanded={isOpened}\n onExpand={onOpen}\n onCollapse={onClose}\n size={size}\n className={classnames(\"tree-widget-search-box\", !isOpened && \"contracted\")}\n isDisabled={isDisabled}\n >\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n title={TreeWidget.translate(\"header.searchBox.searchForSomething\")}\n aria-label={TreeWidget.translate(\"header.searchBox.open\")}\n size={size}\n styleType=\"borderless\"\n />\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState>\n <SearchBox.Input placeholder={TreeWidget.translate(\"header.searchBox.search\")} onChange={(e) => setInputValue(e.currentTarget.value)} />\n <SearchResultStepper selectedIndex={selectedResultIndex} total={resultCount} onStep={onSelectedResultChanged} size={size} />\n <SearchBox.CollapseButton\n onClick={() => {\n setInputValue(\"\");\n onClose();\n }}\n size={size}\n aria-label={TreeWidget.translate(\"header.searchBox.close\")}\n />\n </SearchBox.ExpandedState>\n </SearchBox>\n );\n}\n\ninterface HeaderButtonsProps {\n contracted: boolean;\n size: \"large\" | \"small\";\n}\n\nfunction HeaderButtons(props: PropsWithChildren<HeaderButtonsProps>) {\n const className = classnames(\"button-container\", props.contracted && \"contracted\");\n\n return (\n <ButtonGroup\n className={className}\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={() =>\n Children.toArray(props.children)\n .slice(overflowStart)\n .map((btn, index) => (\n <li key={index} className=\"dropdown-item\" role=\"menuitem\">\n {btn}\n </li>\n ))\n }\n className=\"tree-header-button-dropdown-container\"\n >\n <IconButton title={TreeWidget.translate(\"header.dropdownMore\")} styleType=\"borderless\" size={props.size}>\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.children}\n </ButtonGroup>\n );\n}\n\ninterface SearchResultStepperProps {\n total?: number;\n onStep: (newIndex: number) => void;\n selectedIndex?: number;\n size: \"large\" | \"small\";\n}\n\nfunction SearchResultStepper(props: SearchResultStepperProps) {\n const { selectedIndex = 1, total, onStep } = props;\n if (!total) {\n return null;\n }\n\n return (\n <>\n <span className=\"searchbox-stepping-count\">{`${selectedIndex}/${total}`}</span>\n <Divider orientation=\"vertical\" />\n <SearchBox.Button\n title={TreeWidget.translate(\"header.searchBox.previous\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex > 1) {\n onStep(selectedIndex - 1);\n }\n }}\n >\n <SvgCaretUpSmall />\n </SearchBox.Button>\n <SearchBox.Button\n title={TreeWidget.translate(\"header.searchBox.next\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex < total) {\n onStep(selectedIndex + 1);\n }\n }}\n >\n <SvgCaretDownSmall />\n </SearchBox.Button>\n </>\n );\n}\n"]}
1
+ {"version":3,"file":"TreeHeader.js","sourceRoot":"","sources":["../../../../src/components/tree-header/TreeHeader.tsx"],"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 \"./TreeHeader.scss\";\nimport classnames from \"classnames\";\nimport { Children, useEffect, useRef, useState } from \"react\";\nimport { SvgCaretDownSmall, SvgCaretUpSmall, SvgMore } from \"@itwin/itwinui-icons-react\";\nimport { ButtonGroup, Divider, DropdownMenu, IconButton, SearchBox } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../TreeWidget\";\nimport { useFocusedInstancesContext } from \"../trees/common/FocusedInstancesContext\";\n\nimport type { PropsWithChildren } from \"react\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/** @public */\nexport interface TreeHeaderButtonProps {\n viewport: Viewport;\n density?: \"default\" | \"enlarged\";\n onFeatureUsed?: (feature: string) => void;\n}\n\n/** @beta */\nexport interface TreeFilteringProps {\n /** Filtering is cleared after everything's loaded */\n onFilterStart: (newFilter: string) => void;\n /** listens for onClick event for Clear (x) icon */\n onFilterClear: () => void;\n /** Total number of results/entries */\n resultCount?: number;\n /** Current selected result index */\n selectedIndex?: number;\n /** Callback to currently selected result/entry change */\n onSelectedChanged?: (index: number) => void;\n /** Should the search box be disabled */\n isDisabled?: boolean;\n}\n\ninterface TreeHeaderProps {\n filteringProps?: TreeFilteringProps;\n /** Modifies the density of tree header. `enlarged` header contains larger content */\n density?: \"default\" | \"enlarged\";\n className?: string;\n}\n\nexport function TreeHeader(props: PropsWithChildren<TreeHeaderProps>) {\n const { filteringProps, density, className, children } = props;\n const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);\n const { enabled: instanceFocusEnabled } = useFocusedInstancesContext();\n const size = density === \"enlarged\" ? \"large\" : \"small\";\n\n useEffect(() => {\n // istanbul ignore if\n if (filteringProps?.isDisabled) {\n setIsSearchOpen(false);\n }\n }, [filteringProps?.isDisabled]);\n\n return (\n <div className={classnames(\"tree-widget-tree-header\", className)}>\n <HeaderButtons contracted={isSearchOpen} size={size}>\n {children}\n </HeaderButtons>\n {filteringProps ? (\n <DebouncedSearchBox\n isOpened={isSearchOpen}\n onOpen={() => setIsSearchOpen(true)}\n onClose={() => setIsSearchOpen(false)}\n onChange={(value) => (value ? filteringProps.onFilterStart(value) : filteringProps.onFilterClear())}\n delay={500}\n selectedResultIndex={filteringProps.selectedIndex}\n resultCount={filteringProps.resultCount}\n onSelectedResultChanged={(index) => filteringProps.onSelectedChanged?.(index)}\n size={size}\n isDisabled={instanceFocusEnabled || props.filteringProps?.isDisabled}\n />\n ) : null}\n </div>\n );\n}\n\ninterface DebouncedSearchBoxProps {\n isOpened: boolean;\n onOpen: () => void;\n onClose: () => void;\n onChange: (value: string) => void;\n delay: number;\n selectedResultIndex?: number;\n resultCount?: number;\n onSelectedResultChanged: (index: number) => void;\n size: \"large\" | \"small\";\n isDisabled?: boolean;\n}\n\nfunction DebouncedSearchBox({\n isOpened,\n selectedResultIndex,\n resultCount,\n onSelectedResultChanged,\n onChange,\n onOpen,\n onClose,\n delay,\n size,\n isDisabled,\n}: DebouncedSearchBoxProps) {\n const [inputValue, setInputValue] = useState<string>(\"\");\n const onChangeRef = useRef(onChange);\n // save latest `onChange` reference into `useRef` to avoid restarting timeout when `onChange` reference changes.\n onChangeRef.current = onChange;\n\n useEffect(() => {\n if (!inputValue) {\n onChangeRef.current(\"\");\n return;\n }\n\n const timeoutId = setTimeout(() => {\n onChangeRef.current(inputValue);\n }, delay);\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [inputValue, delay]);\n\n return (\n <SearchBox\n expandable\n isExpanded={isOpened}\n onExpand={onOpen}\n onCollapse={onClose}\n size={size}\n className={classnames(\"tree-widget-search-box\", !isOpened && \"contracted\")}\n isDisabled={isDisabled}\n >\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n title={TreeWidget.translate(\"header.searchBox.searchForSomething\")}\n aria-label={TreeWidget.translate(\"header.searchBox.open\")}\n size={size}\n styleType=\"borderless\"\n />\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState>\n <SearchBox.Input placeholder={TreeWidget.translate(\"header.searchBox.search\")} onChange={(e) => setInputValue(e.currentTarget.value)} />\n <SearchResultStepper selectedIndex={selectedResultIndex} total={resultCount} onStep={onSelectedResultChanged} size={size} />\n <SearchBox.CollapseButton\n onClick={() => {\n setInputValue(\"\");\n onClose();\n }}\n size={size}\n aria-label={TreeWidget.translate(\"header.searchBox.close\")}\n />\n </SearchBox.ExpandedState>\n </SearchBox>\n );\n}\n\ninterface HeaderButtonsProps {\n contracted: boolean;\n size: \"large\" | \"small\";\n}\n\nfunction HeaderButtons(props: PropsWithChildren<HeaderButtonsProps>) {\n const className = classnames(\"button-container\", props.contracted && \"contracted\");\n\n return (\n <ButtonGroup\n className={className}\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={() =>\n Children.toArray(props.children)\n .slice(overflowStart)\n .map((btn, index) => (\n <li key={index} className=\"dropdown-item\" role=\"menuitem\">\n {btn}\n </li>\n ))\n }\n className=\"tree-header-button-dropdown-container\"\n >\n <IconButton label={TreeWidget.translate(\"header.dropdownMore\")} styleType=\"borderless\" size={props.size}>\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.children}\n </ButtonGroup>\n );\n}\n\ninterface SearchResultStepperProps {\n total?: number;\n onStep: (newIndex: number) => void;\n selectedIndex?: number;\n size: \"large\" | \"small\";\n}\n\nfunction SearchResultStepper(props: SearchResultStepperProps) {\n const { selectedIndex = 1, total, onStep } = props;\n if (!total) {\n return null;\n }\n\n return (\n <>\n <span className=\"searchbox-stepping-count\">{`${selectedIndex}/${total}`}</span>\n <Divider orientation=\"vertical\" />\n <SearchBox.Button\n title={TreeWidget.translate(\"header.searchBox.previous\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex > 1) {\n onStep(selectedIndex - 1);\n }\n }}\n >\n <SvgCaretUpSmall />\n </SearchBox.Button>\n <SearchBox.Button\n title={TreeWidget.translate(\"header.searchBox.next\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex < total) {\n onStep(selectedIndex + 1);\n }\n }}\n >\n <SvgCaretDownSmall />\n </SearchBox.Button>\n </>\n );\n}\n"]}
@@ -44,7 +44,7 @@ function useCategoriesTreeButtonProps({ viewport }) {
44
44
  exports.useCategoriesTreeButtonProps = useCategoriesTreeButtonProps;
45
45
  /** @public */
46
46
  function ShowAllButton(props) {
47
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.showAll.tooltip"), onClick: () => {
47
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", label: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.showAll.tooltip"), onClick: () => {
48
48
  props.onFeatureUsed?.(`categories-tree-showall`);
49
49
  void (0, CategoriesVisibilityUtils_1.showAllCategories)(props.categories.map((category) => category.categoryId), props.viewport);
50
50
  }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityShow, {}) }));
@@ -52,7 +52,7 @@ function ShowAllButton(props) {
52
52
  exports.ShowAllButton = ShowAllButton;
53
53
  /** @public */
54
54
  function HideAllButton(props) {
55
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", title: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.hideAll.tooltip"), onClick: () => {
55
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", label: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.hideAll.tooltip"), onClick: () => {
56
56
  props.onFeatureUsed?.(`categories-tree-hideall`);
57
57
  void (0, CategoriesVisibilityUtils_1.hideAllCategories)(props.categories.map((category) => category.categoryId), props.viewport);
58
58
  }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHide, {}) }));
@@ -60,7 +60,7 @@ function HideAllButton(props) {
60
60
  exports.HideAllButton = HideAllButton;
61
61
  /** @public */
62
62
  function InvertAllButton(props) {
63
- return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { title: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.invert.tooltip"), size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", onClick: () => {
63
+ return ((0, jsx_runtime_1.jsx)(itwinui_react_1.IconButton, { label: TreeWidget_1.TreeWidget.translate("categoriesTree.buttons.invert.tooltip"), size: props.density === "enlarged" ? "large" : "small", styleType: "borderless", onClick: () => {
64
64
  props.onFeatureUsed?.(`categories-tree-invert`);
65
65
  void (0, CategoriesVisibilityUtils_1.invertAllCategories)(props.categories, props.viewport);
66
66
  }, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHalf, {}) }));
@@ -1 +1 @@
1
- {"version":3,"file":"CategoriesTreeButtons.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTreeButtons.tsx"],"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 { useMemo, useState } from \"react\";\nimport { useAsyncValue } from \"@itwin/components-react\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { IconButton } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { hideAllCategories, invertAllCategories, loadCategoriesFromViewport, showAllCategories } from \"../common/CategoriesVisibilityUtils\";\n\nimport type { CategoryInfo } from \"../common/CategoriesVisibilityUtils\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/**\n * Props that get passed to `CategoriesTreeComponent` header button renderer.\n * @see CategoriesTreeComponentProps.headerButtons\n * @public\n */\nexport interface CategoriesTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of categories available in the iModel */\n categories: CategoryInfo[];\n}\n\n/**\n * Custom hook that creates props required to render `CategoriesTreeComponent` header button.\n *\n * Example:\n * ```tsx\n * const { buttonProps, onCategoriesFiltered } = useCategoriesTreeButtonProps({ viewport });\n * <TreeWithHeader\n * buttons={[\n * <CategoriesTreeComponent.ShowAllButton {...buttonProps} />,\n * <CategoriesTreeComponent.HideAllButton {...buttonProps} />,\n * ]}\n * >\n * <CategoriesTree {...treeProps} onCategoriesFiltered={onCategoriesFiltered} />\n * </TreeWithHeader>\n * ```\n *\n * @public\n */\nexport function useCategoriesTreeButtonProps({ viewport }: { viewport: Viewport }): {\n buttonProps: Pick<CategoriesTreeHeaderButtonProps, \"categories\" | \"viewport\">;\n onCategoriesFiltered: (categories: CategoryInfo[] | undefined) => void;\n} {\n const [filteredCategories, setFilteredCategories] = useState<CategoryInfo[] | undefined>();\n const categories = useCategories(viewport);\n return {\n buttonProps: {\n viewport,\n categories: filteredCategories ?? categories,\n },\n onCategoriesFiltered: setFilteredCategories,\n };\n}\n\n/** @public */\nexport type CategoriesTreeHeaderButtonType = (props: CategoriesTreeHeaderButtonProps) => JSX.Element | null;\n\n/** @public */\nexport function ShowAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"categoriesTree.buttons.showAll.tooltip\")}\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-showall`);\n void showAllCategories(\n props.categories.map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\n/** @public */\nexport function HideAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n title={TreeWidget.translate(\"categoriesTree.buttons.hideAll.tooltip\")}\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-hideall`);\n void hideAllCategories(\n props.categories.map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\n/** @public */\nexport function InvertAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n title={TreeWidget.translate(\"categoriesTree.buttons.invert.tooltip\")}\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-invert`);\n void invertAllCategories(props.categories, props.viewport);\n }}\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n\nconst EMPTY_CATEGORIES_ARRAY: CategoryInfo[] = [];\n\nexport function useCategories(viewport: Viewport) {\n const categoriesPromise = useMemo(async () => loadCategoriesFromViewport(viewport), [viewport]);\n return useAsyncValue(categoriesPromise) ?? EMPTY_CATEGORIES_ARRAY;\n}\n"]}
1
+ {"version":3,"file":"CategoriesTreeButtons.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTreeButtons.tsx"],"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 { useMemo, useState } from \"react\";\nimport { useAsyncValue } from \"@itwin/components-react\";\nimport { SvgVisibilityHalf, SvgVisibilityHide, SvgVisibilityShow } from \"@itwin/itwinui-icons-react\";\nimport { IconButton } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../../TreeWidget\";\nimport { hideAllCategories, invertAllCategories, loadCategoriesFromViewport, showAllCategories } from \"../common/CategoriesVisibilityUtils\";\n\nimport type { CategoryInfo } from \"../common/CategoriesVisibilityUtils\";\nimport type { TreeHeaderButtonProps } from \"../../tree-header/TreeHeader\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/**\n * Props that get passed to `CategoriesTreeComponent` header button renderer.\n * @see CategoriesTreeComponentProps.headerButtons\n * @public\n */\nexport interface CategoriesTreeHeaderButtonProps extends TreeHeaderButtonProps {\n /** A list of categories available in the iModel */\n categories: CategoryInfo[];\n}\n\n/**\n * Custom hook that creates props required to render `CategoriesTreeComponent` header button.\n *\n * Example:\n * ```tsx\n * const { buttonProps, onCategoriesFiltered } = useCategoriesTreeButtonProps({ viewport });\n * <TreeWithHeader\n * buttons={[\n * <CategoriesTreeComponent.ShowAllButton {...buttonProps} />,\n * <CategoriesTreeComponent.HideAllButton {...buttonProps} />,\n * ]}\n * >\n * <CategoriesTree {...treeProps} onCategoriesFiltered={onCategoriesFiltered} />\n * </TreeWithHeader>\n * ```\n *\n * @public\n */\nexport function useCategoriesTreeButtonProps({ viewport }: { viewport: Viewport }): {\n buttonProps: Pick<CategoriesTreeHeaderButtonProps, \"categories\" | \"viewport\">;\n onCategoriesFiltered: (categories: CategoryInfo[] | undefined) => void;\n} {\n const [filteredCategories, setFilteredCategories] = useState<CategoryInfo[] | undefined>();\n const categories = useCategories(viewport);\n return {\n buttonProps: {\n viewport,\n categories: filteredCategories ?? categories,\n },\n onCategoriesFiltered: setFilteredCategories,\n };\n}\n\n/** @public */\nexport type CategoriesTreeHeaderButtonType = (props: CategoriesTreeHeaderButtonProps) => JSX.Element | null;\n\n/** @public */\nexport function ShowAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n label={TreeWidget.translate(\"categoriesTree.buttons.showAll.tooltip\")}\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-showall`);\n void showAllCategories(\n props.categories.map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityShow />\n </IconButton>\n );\n}\n\n/** @public */\nexport function HideAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n label={TreeWidget.translate(\"categoriesTree.buttons.hideAll.tooltip\")}\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-hideall`);\n void hideAllCategories(\n props.categories.map((category) => category.categoryId),\n props.viewport,\n );\n }}\n >\n <SvgVisibilityHide />\n </IconButton>\n );\n}\n\n/** @public */\nexport function InvertAllButton(props: CategoriesTreeHeaderButtonProps) {\n return (\n <IconButton\n label={TreeWidget.translate(\"categoriesTree.buttons.invert.tooltip\")}\n size={props.density === \"enlarged\" ? \"large\" : \"small\"}\n styleType=\"borderless\"\n onClick={() => {\n props.onFeatureUsed?.(`categories-tree-invert`);\n void invertAllCategories(props.categories, props.viewport);\n }}\n >\n <SvgVisibilityHalf />\n </IconButton>\n );\n}\n\nconst EMPTY_CATEGORIES_ARRAY: CategoryInfo[] = [];\n\nexport function useCategories(viewport: Viewport) {\n const categoriesPromise = useMemo(async () => loadCategoriesFromViewport(viewport), [viewport]);\n return useAsyncValue(categoriesPromise) ?? EMPTY_CATEGORIES_ARRAY;\n}\n"]}
@@ -8,6 +8,7 @@ exports.CategoriesVisibilityHandler = void 0;
8
8
  const core_bentley_1 = require("@itwin/core-bentley");
9
9
  const presentation_hierarchies_1 = require("@itwin/presentation-hierarchies");
10
10
  const CategoriesVisibilityUtils_1 = require("../common/CategoriesVisibilityUtils");
11
+ const Tooltip_1 = require("../common/Tooltip");
11
12
  /** @internal */
12
13
  class CategoriesVisibilityHandler {
13
14
  constructor(props) {
@@ -34,7 +35,7 @@ class CategoriesVisibilityHandler {
34
35
  if (!presentation_hierarchies_1.HierarchyNode.isInstancesNode(node)) {
35
36
  return { state: "hidden", isDisabled: true };
36
37
  }
37
- return { state: node.parentKeys.length ? this.getSubCategoryVisibility(node) : this.getCategoryVisibility(node) };
38
+ return (0, Tooltip_1.createVisibilityStatus)(node.parentKeys.length ? this.getSubCategoryVisibility(node) : this.getCategoryVisibility(node));
38
39
  }
39
40
  async changeVisibility(node, on) {
40
41
  if (!presentation_hierarchies_1.HierarchyNode.isInstancesNode(node)) {
@@ -1 +1 @@
1
- {"version":3,"file":"CategoriesVisibilityHandler.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesVisibilityHandler.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,sDAA8C;AAC9C,8EAAgE;AAChE,mFAAsG;AAStG,gBAAgB;AAChB,MAAa,2BAA2B;IAItC,YAAY,KAAuC;QAY5C,uBAAkB,GAAG,IAAI,sBAAO,EAAE,CAAC;QAiD1C,gEAAgE;QACxD,0BAAqB,GAAG,GAAG,EAAE;YACnC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC,CAAC;QAEF,gEAAgE;QACxD,8BAAyB,GAAG,GAAG,EAAE;YACvC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC,CAAC;QApEA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC7E,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACvF,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAChF,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxF,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC;IAID,kDAAkD;IAC3C,mBAAmB,CAAC,IAAmB;QAC5C,IAAI,CAAC,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC9C;QACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,EAAE,CAAC;IACpH,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,IAAmB,EAAE,EAAW;QAC5D,IAAI,CAAC,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO;SACR;QAED,uCAAuC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAC1B,MAAM,OAAO,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;YACjF,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;YAEvD,uCAAuC;YACvC,IAAI,EAAE,IAAI,gBAAgB,EAAE;gBAC1B,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;aAC5D;YAED,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO;SACR;QAED,MAAM,UAAU,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAEM,wBAAwB,CAAC,IAAmB;QACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;QACvD,IAAI,CAAC,gBAAgB,EAAE;YACrB,OAAO,QAAQ,CAAC;SACjB;QAED,MAAM,aAAa,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACvF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC5H,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAEM,qBAAqB,CAAC,IAAmB;QAC9C,MAAM,UAAU,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9E,CAAC;IAYO,0BAA0B;QAChC,IAAI,IAAI,CAAC,wBAAwB,EAAE;YACjC,OAAO;SACR;QAED,IAAI,CAAC,wBAAwB,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9C,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC;QAC5C,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAEM,MAAM,CAAC,8BAA8B,CAAC,IAAmB;QAC9D,OAAO,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,0BAA0B,CAAC,EAAE,CAAC;IAC/I,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,GAAa,EAAE,OAAgB,EAAE,sBAAsB,GAAG,IAAI;QACxF,MAAM,IAAA,iDAAqB,EAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACpF,CAAC;IAEM,iBAAiB,CAAC,GAAW,EAAE,OAAgB;QACpD,IAAA,oDAAwB,EAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;CACF;AAjGD,kEAiGC","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 { BeEvent } from \"@itwin/core-bentley\";\nimport { HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport { enableCategoryDisplay, enableSubCategoryDisplay } from \"../common/CategoriesVisibilityUtils\";\n\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { HierarchyVisibilityHandler, VisibilityStatus } from \"../common/UseHierarchyVisibility\";\n\ninterface CategoriesVisibilityHandlerProps {\n viewport: Viewport;\n}\n\n/** @internal */\nexport class CategoriesVisibilityHandler implements HierarchyVisibilityHandler {\n private _pendingVisibilityChange: any;\n private _viewport: Viewport;\n\n constructor(props: CategoriesVisibilityHandlerProps) {\n this._viewport = props.viewport;\n this._viewport.onDisplayStyleChanged.addListener(this.onDisplayStyleChanged);\n this._viewport.onViewedCategoriesChanged.addListener(this.onViewedCategoriesChanged);\n }\n\n public dispose() {\n this._viewport.onDisplayStyleChanged.removeListener(this.onDisplayStyleChanged);\n this._viewport.onViewedCategoriesChanged.removeListener(this.onViewedCategoriesChanged);\n clearTimeout(this._pendingVisibilityChange);\n }\n\n public onVisibilityChange = new BeEvent();\n\n /** Returns visibility status of the tree node. */\n public getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus {\n if (!HierarchyNode.isInstancesNode(node)) {\n return { state: \"hidden\", isDisabled: true };\n }\n return { state: node.parentKeys.length ? this.getSubCategoryVisibility(node) : this.getCategoryVisibility(node) };\n }\n\n public async changeVisibility(node: HierarchyNode, on: boolean) {\n if (!HierarchyNode.isInstancesNode(node)) {\n return;\n }\n\n // handle subcategory visibility change\n if (node.parentKeys.length) {\n const childId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n const parentCategoryId = node.extendedData?.categoryId;\n\n // make sure parent category is enabled\n if (on && parentCategoryId) {\n await this.enableCategory([parentCategoryId], true, false);\n }\n\n this.enableSubCategory(childId, on);\n return;\n }\n\n const instanceId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n await this.enableCategory([instanceId], on, true);\n }\n\n public getSubCategoryVisibility(node: HierarchyNode) {\n const parentCategoryId = node.extendedData?.categoryId;\n if (!parentCategoryId) {\n return \"hidden\";\n }\n\n const subcategoryId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n const isVisible = this._viewport.view.viewsCategory(parentCategoryId) && this._viewport.isSubCategoryVisible(subcategoryId);\n return isVisible ? \"visible\" : \"hidden\";\n }\n\n public getCategoryVisibility(node: HierarchyNode) {\n const instanceId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n return this._viewport.view.viewsCategory(instanceId) ? \"visible\" : \"hidden\";\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private onDisplayStyleChanged = () => {\n this.onVisibilityChangeInternal();\n };\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private onViewedCategoriesChanged = () => {\n this.onVisibilityChangeInternal();\n };\n\n private onVisibilityChangeInternal() {\n if (this._pendingVisibilityChange) {\n return;\n }\n\n this._pendingVisibilityChange = setTimeout(() => {\n this.onVisibilityChange.raiseEvent();\n this._pendingVisibilityChange = undefined;\n }, 0);\n }\n\n public static getInstanceIdFromHierarchyNode(node: HierarchyNode) {\n return HierarchyNode.isInstancesNode(node) && node.key.instanceKeys.length > 0 ? node.key.instanceKeys[0].id : /* istanbul ignore next */ \"\";\n }\n\n public async enableCategory(ids: string[], enabled: boolean, enableAllSubCategories = true) {\n await enableCategoryDisplay(this._viewport, ids, enabled, enableAllSubCategories);\n }\n\n public enableSubCategory(key: string, enabled: boolean) {\n enableSubCategoryDisplay(this._viewport, key, enabled);\n }\n}\n"]}
1
+ {"version":3,"file":"CategoriesVisibilityHandler.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesVisibilityHandler.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,sDAA8C;AAC9C,8EAAgE;AAChE,mFAAsG;AACtG,+CAA2D;AAS3D,gBAAgB;AAChB,MAAa,2BAA2B;IAItC,YAAY,KAAuC;QAY5C,uBAAkB,GAAG,IAAI,sBAAO,EAAE,CAAC;QAiD1C,gEAAgE;QACxD,0BAAqB,GAAG,GAAG,EAAE;YACnC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC,CAAC;QAEF,gEAAgE;QACxD,8BAAyB,GAAG,GAAG,EAAE;YACvC,IAAI,CAAC,0BAA0B,EAAE,CAAC;QACpC,CAAC,CAAC;QApEA,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC,QAAQ,CAAC;QAChC,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,WAAW,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAC7E,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,WAAW,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;IACvF,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,SAAS,CAAC,qBAAqB,CAAC,cAAc,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QAChF,IAAI,CAAC,SAAS,CAAC,yBAAyB,CAAC,cAAc,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;QACxF,YAAY,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IAC9C,CAAC;IAID,kDAAkD;IAC3C,mBAAmB,CAAC,IAAmB;QAC5C,IAAI,CAAC,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;SAC9C;QACD,OAAO,IAAA,gCAAsB,EAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,wBAAwB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC,CAAC;IACjI,CAAC;IAEM,KAAK,CAAC,gBAAgB,CAAC,IAAmB,EAAE,EAAW;QAC5D,IAAI,CAAC,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE;YACxC,OAAO;SACR;QAED,uCAAuC;QACvC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE;YAC1B,MAAM,OAAO,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;YACjF,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;YAEvD,uCAAuC;YACvC,IAAI,EAAE,IAAI,gBAAgB,EAAE;gBAC1B,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;aAC5D;YAED,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpC,OAAO;SACR;QAED,MAAM,UAAU,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACpF,MAAM,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,CAAC;IACpD,CAAC;IAEM,wBAAwB,CAAC,IAAmB;QACjD,MAAM,gBAAgB,GAAG,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC;QACvD,IAAI,CAAC,gBAAgB,EAAE;YACrB,OAAO,QAAQ,CAAC;SACjB;QAED,MAAM,aAAa,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACvF,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,aAAa,CAAC,CAAC;QAC5H,OAAO,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC1C,CAAC;IAEM,qBAAqB,CAAC,IAAmB;QAC9C,MAAM,UAAU,GAAG,2BAA2B,CAAC,8BAA8B,CAAC,IAAI,CAAC,CAAC;QACpF,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC9E,CAAC;IAYO,0BAA0B;QAChC,IAAI,IAAI,CAAC,wBAAwB,EAAE;YACjC,OAAO;SACR;QAED,IAAI,CAAC,wBAAwB,GAAG,UAAU,CAAC,GAAG,EAAE;YAC9C,IAAI,CAAC,kBAAkB,CAAC,UAAU,EAAE,CAAC;YACrC,IAAI,CAAC,wBAAwB,GAAG,SAAS,CAAC;QAC5C,CAAC,EAAE,CAAC,CAAC,CAAC;IACR,CAAC;IAEM,MAAM,CAAC,8BAA8B,CAAC,IAAmB;QAC9D,OAAO,wCAAa,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,0BAA0B,CAAC,EAAE,CAAC;IAC/I,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,GAAa,EAAE,OAAgB,EAAE,sBAAsB,GAAG,IAAI;QACxF,MAAM,IAAA,iDAAqB,EAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,EAAE,sBAAsB,CAAC,CAAC;IACpF,CAAC;IAEM,iBAAiB,CAAC,GAAW,EAAE,OAAgB;QACpD,IAAA,oDAAwB,EAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;IACzD,CAAC;CACF;AAjGD,kEAiGC","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 { BeEvent } from \"@itwin/core-bentley\";\nimport { HierarchyNode } from \"@itwin/presentation-hierarchies\";\nimport { enableCategoryDisplay, enableSubCategoryDisplay } from \"../common/CategoriesVisibilityUtils\";\nimport { createVisibilityStatus } from \"../common/Tooltip\";\n\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { HierarchyVisibilityHandler, VisibilityStatus } from \"../common/UseHierarchyVisibility\";\n\ninterface CategoriesVisibilityHandlerProps {\n viewport: Viewport;\n}\n\n/** @internal */\nexport class CategoriesVisibilityHandler implements HierarchyVisibilityHandler {\n private _pendingVisibilityChange: any;\n private _viewport: Viewport;\n\n constructor(props: CategoriesVisibilityHandlerProps) {\n this._viewport = props.viewport;\n this._viewport.onDisplayStyleChanged.addListener(this.onDisplayStyleChanged);\n this._viewport.onViewedCategoriesChanged.addListener(this.onViewedCategoriesChanged);\n }\n\n public dispose() {\n this._viewport.onDisplayStyleChanged.removeListener(this.onDisplayStyleChanged);\n this._viewport.onViewedCategoriesChanged.removeListener(this.onViewedCategoriesChanged);\n clearTimeout(this._pendingVisibilityChange);\n }\n\n public onVisibilityChange = new BeEvent();\n\n /** Returns visibility status of the tree node. */\n public getVisibilityStatus(node: HierarchyNode): Promise<VisibilityStatus> | VisibilityStatus {\n if (!HierarchyNode.isInstancesNode(node)) {\n return { state: \"hidden\", isDisabled: true };\n }\n return createVisibilityStatus(node.parentKeys.length ? this.getSubCategoryVisibility(node) : this.getCategoryVisibility(node));\n }\n\n public async changeVisibility(node: HierarchyNode, on: boolean) {\n if (!HierarchyNode.isInstancesNode(node)) {\n return;\n }\n\n // handle subcategory visibility change\n if (node.parentKeys.length) {\n const childId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n const parentCategoryId = node.extendedData?.categoryId;\n\n // make sure parent category is enabled\n if (on && parentCategoryId) {\n await this.enableCategory([parentCategoryId], true, false);\n }\n\n this.enableSubCategory(childId, on);\n return;\n }\n\n const instanceId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n await this.enableCategory([instanceId], on, true);\n }\n\n public getSubCategoryVisibility(node: HierarchyNode) {\n const parentCategoryId = node.extendedData?.categoryId;\n if (!parentCategoryId) {\n return \"hidden\";\n }\n\n const subcategoryId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n const isVisible = this._viewport.view.viewsCategory(parentCategoryId) && this._viewport.isSubCategoryVisible(subcategoryId);\n return isVisible ? \"visible\" : \"hidden\";\n }\n\n public getCategoryVisibility(node: HierarchyNode) {\n const instanceId = CategoriesVisibilityHandler.getInstanceIdFromHierarchyNode(node);\n return this._viewport.view.viewsCategory(instanceId) ? \"visible\" : \"hidden\";\n }\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private onDisplayStyleChanged = () => {\n this.onVisibilityChangeInternal();\n };\n\n // eslint-disable-next-line @typescript-eslint/naming-convention\n private onViewedCategoriesChanged = () => {\n this.onVisibilityChangeInternal();\n };\n\n private onVisibilityChangeInternal() {\n if (this._pendingVisibilityChange) {\n return;\n }\n\n this._pendingVisibilityChange = setTimeout(() => {\n this.onVisibilityChange.raiseEvent();\n this._pendingVisibilityChange = undefined;\n }, 0);\n }\n\n public static getInstanceIdFromHierarchyNode(node: HierarchyNode) {\n return HierarchyNode.isInstancesNode(node) && node.key.instanceKeys.length > 0 ? node.key.instanceKeys[0].id : /* istanbul ignore next */ \"\";\n }\n\n public async enableCategory(ids: string[], enabled: boolean, enableAllSubCategories = true) {\n await enableCategoryDisplay(this._viewport, ids, enabled, enableAllSubCategories);\n }\n\n public enableSubCategory(key: string, enabled: boolean) {\n enableSubCategoryDisplay(this._viewport, key, enabled);\n }\n}\n"]}
@@ -1,13 +1,17 @@
1
- import type { VisibilityStatus } from "../../common/UseHierarchyVisibility";
1
+ import type { VisibilityStatus } from "./UseHierarchyVisibility";
2
2
  /** @internal */
3
3
  export type Visibility = "visible" | "hidden" | "partial";
4
4
  /** @internal */
5
5
  export type NonPartialVisibilityStatus = Omit<VisibilityStatus, "state"> & {
6
6
  state: "visible" | "hidden";
7
7
  };
8
+ interface VisibilityStatusOptions {
9
+ useTooltip?: string | false;
10
+ }
8
11
  /** @internal */
9
- export declare function createVisibilityStatus(status: "visible" | "hidden", tooltipStringId?: string): NonPartialVisibilityStatus;
10
- export declare function createVisibilityStatus(status: "visible" | "hidden" | "partial" | "disabled", tooltipStringId?: string): VisibilityStatus;
12
+ export declare function createVisibilityStatus(status: "visible" | "hidden", options?: VisibilityStatusOptions): NonPartialVisibilityStatus;
13
+ export declare function createVisibilityStatus(status: "visible" | "hidden" | "partial" | "disabled", options?: VisibilityStatusOptions): VisibilityStatus;
11
14
  /** @internal */
12
15
  export declare function createTooltip(status: Visibility | "disabled", tooltipStringId: string | undefined): string;
16
+ export {};
13
17
  //# sourceMappingURL=Tooltip.d.ts.map
@@ -5,23 +5,23 @@
5
5
  *--------------------------------------------------------------------------------------------*/
6
6
  Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.createTooltip = exports.createVisibilityStatus = void 0;
8
- const TreeWidget_1 = require("../../../../TreeWidget");
9
- function createVisibilityStatus(status, tooltipStringId) {
8
+ const TreeWidget_1 = require("../../../TreeWidget");
9
+ function createVisibilityStatus(status, { useTooltip } = {}) {
10
10
  return {
11
11
  state: status === "disabled" ? "hidden" : status,
12
12
  isDisabled: status === "disabled",
13
- tooltip: createTooltip(status, tooltipStringId),
13
+ tooltip: useTooltip === false ? undefined : createTooltip(status, useTooltip),
14
14
  };
15
15
  }
16
16
  exports.createVisibilityStatus = createVisibilityStatus;
17
17
  /** @internal */
18
18
  function createTooltip(status, tooltipStringId) {
19
- const statusStringId = `modelsTree.visibilityTooltips.status.${status}`;
19
+ const statusStringId = `visibilityTooltips.status.${status}`;
20
20
  const statusString = TreeWidget_1.TreeWidget.translate(statusStringId);
21
21
  if (!tooltipStringId) {
22
22
  return statusString;
23
23
  }
24
- tooltipStringId = `modelsTree.visibilityTooltips.${tooltipStringId}`;
24
+ tooltipStringId = `visibilityTooltips.${tooltipStringId}`;
25
25
  const tooltipString = TreeWidget_1.TreeWidget.translate(tooltipStringId);
26
26
  return `${statusString}: ${tooltipString}`;
27
27
  }
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/Tooltip.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,oDAAiD;AAmBjD,SAAgB,sBAAsB,CAAC,MAA+B,EAAE,EAAE,UAAU,KAA8B,EAAE;IAClH,OAAO;QACL,KAAK,EAAE,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM;QAChD,UAAU,EAAE,MAAM,KAAK,UAAU;QACjC,OAAO,EAAE,UAAU,KAAK,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC;KAC9E,CAAC;AACJ,CAAC;AAND,wDAMC;AAED,gBAAgB;AAChB,SAAgB,aAAa,CAAC,MAA+B,EAAE,eAAmC;IAChG,MAAM,cAAc,GAAG,6BAA6B,MAAM,EAAE,CAAC;IAC7D,MAAM,YAAY,GAAG,uBAAU,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC;IAC1D,IAAI,CAAC,eAAe,EAAE;QACpB,OAAO,YAAY,CAAC;KACrB;IAED,eAAe,GAAG,sBAAsB,eAAe,EAAE,CAAC;IAC1D,MAAM,aAAa,GAAG,uBAAU,CAAC,SAAS,CAAC,eAAe,CAAC,CAAC;IAC5D,OAAO,GAAG,YAAY,KAAK,aAAa,EAAE,CAAC;AAC7C,CAAC;AAVD,sCAUC","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 { TreeWidget } from \"../../../TreeWidget\";\n\nimport type { VisibilityStatus } from \"./UseHierarchyVisibility\";\n\n/** @internal */\nexport type Visibility = \"visible\" | \"hidden\" | \"partial\";\n\n/** @internal */\nexport type NonPartialVisibilityStatus = Omit<VisibilityStatus, \"state\"> & { state: \"visible\" | \"hidden\" };\n\ninterface VisibilityStatusOptions {\n // id of localized string to use as an additional tooltip or false to not use tooltip at all\n // if undefined tooltip will be created based only on the visibility status\n useTooltip?: string | false;\n}\n\n/** @internal */\nexport function createVisibilityStatus(status: \"visible\" | \"hidden\", options?: VisibilityStatusOptions): NonPartialVisibilityStatus;\nexport function createVisibilityStatus(status: \"visible\" | \"hidden\" | \"partial\" | \"disabled\", options?: VisibilityStatusOptions): VisibilityStatus;\nexport function createVisibilityStatus(status: Visibility | \"disabled\", { useTooltip }: VisibilityStatusOptions = {}): VisibilityStatus {\n return {\n state: status === \"disabled\" ? \"hidden\" : status,\n isDisabled: status === \"disabled\",\n tooltip: useTooltip === false ? undefined : createTooltip(status, useTooltip),\n };\n}\n\n/** @internal */\nexport function createTooltip(status: Visibility | \"disabled\", tooltipStringId: string | undefined): string {\n const statusStringId = `visibilityTooltips.status.${status}`;\n const statusString = TreeWidget.translate(statusStringId);\n if (!tooltipStringId) {\n return statusString;\n }\n\n tooltipStringId = `visibilityTooltips.${tooltipStringId}`;\n const tooltipString = TreeWidget.translate(tooltipStringId);\n return `${statusString}: ${tooltipString}`;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"UseActiveViewport.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/UseActiveViewport.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,iCAA4C;AAE5C,wDAAiD;AAEjD;;;GAGG;AACH,SAAgB,iBAAiB;IAC/B,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAClD,yBAAS,CAAC,WAAW,CAAC,YAAY,CACnC,CAAC;IACF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,iBAAiB,CAAC,yBAAS,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACtD,OAAO,yBAAS,CAAC,WAAW,CAAC,yBAAyB,CAAC,WAAW,CAChE,CAAC,IAAI,EAAE,EAAE;YACP,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC,CACF,CAAC;IACJ,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,cAAc,CAAC;AACxB,CAAC;AAdD,8CAcC","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, useState } from \"react\";\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport { IModelApp } from \"@itwin/core-frontend\";\n\n/** \n * A copy of `useActiveViewport` from `@itwin/appui-react` package until X is fixed.\n * @internal\n */\nexport function useActiveViewport(): ScreenViewport | undefined {\n const [activeViewport, setActiveViewport] = useState(\n IModelApp.viewManager.selectedView\n );\n useEffect(() => {\n setActiveViewport(IModelApp.viewManager.selectedView);\n return IModelApp.viewManager.onSelectedViewportChanged.addListener(\n (args) => {\n setActiveViewport(args.current);\n }\n );\n }, []);\n\n return activeViewport;\n}\n"]}
1
+ {"version":3,"file":"UseActiveViewport.js","sourceRoot":"","sources":["../../../../../src/components/trees/common/UseActiveViewport.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;;;AAEhG,iCAA4C;AAE5C,wDAAiD;AAEjD;;;GAGG;AACH,SAAgB,iBAAiB;IAC/B,MAAM,CAAC,cAAc,EAAE,iBAAiB,CAAC,GAAG,IAAA,gBAAQ,EAAC,yBAAS,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;IACzF,IAAA,iBAAS,EAAC,GAAG,EAAE;QACb,iBAAiB,CAAC,yBAAS,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;QACtD,OAAO,yBAAS,CAAC,WAAW,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC,IAAI,EAAE,EAAE;YAC1E,iBAAiB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,cAAc,CAAC;AACxB,CAAC;AAVD,8CAUC","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, useState } from \"react\";\nimport type { ScreenViewport } from \"@itwin/core-frontend\";\nimport { IModelApp } from \"@itwin/core-frontend\";\n\n/**\n * A copy of `useActiveViewport` from `@itwin/appui-react` package until X is fixed.\n * @internal\n */\nexport function useActiveViewport(): ScreenViewport | undefined {\n const [activeViewport, setActiveViewport] = useState(IModelApp.viewManager.selectedView);\n useEffect(() => {\n setActiveViewport(IModelApp.viewManager.selectedView);\n return IModelApp.viewManager.onSelectedViewportChanged.addListener((args) => {\n setActiveViewport(args.current);\n });\n }, []);\n\n return activeViewport;\n}\n"]}
@@ -37,15 +37,15 @@ function useHierarchyVisibility({ visibilityHandlerFactory }) {
37
37
  }));
38
38
  };
39
39
  const subscription = calculate
40
- .pipe((0, rxjs_1.distinct)(undefined, visibilityChanged), (0, rxjs_1.observeOn)(rxjs_1.asyncScheduler), (0, rxjs_1.mergeMap)((node) => (0, rxjs_1.defer)(async () => ({ node, status: await handler.getVisibilityStatus(node.nodeData) })).pipe((0, rxjs_1.takeUntil)(visibilityChanged))), (0, rxjs_1.tap)({
41
- next: ({ node, status }) => {
40
+ .pipe((0, rxjs_1.distinct)(undefined, visibilityChanged), (0, rxjs_1.observeOn)(rxjs_1.asyncScheduler), (0, rxjs_1.mergeMap)((node) => (0, rxjs_1.defer)(async () => handler.getVisibilityStatus(node.nodeData)).pipe((0, rxjs_1.tap)({
41
+ next: (status) => {
42
42
  visibilityStatusMap.current.set(node.id, {
43
43
  node,
44
44
  status,
45
45
  needsRefresh: false,
46
46
  });
47
47
  },
48
- }), (0, rxjs_1.throttleTime)(100, undefined, { leading: true, trailing: true }))
48
+ }), (0, rxjs_1.takeUntil)(visibilityChanged), (0, rxjs_1.onErrorResumeNextWith)(rxjs_1.EMPTY))), (0, rxjs_1.throttleTime)(100, undefined, { leading: false, trailing: true }))
49
49
  .subscribe({
50
50
  next: () => {
51
51
  triggerCheckboxUpdate();
@@ -1 +1 @@
1
- {"version":3,"file":"UseHierarchyVisibility.js","sourceRoot":"","sources":["../../../../../src/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 { asyncScheduler, defer, distinct, from, lastValueFrom, mergeMap, observeOn, Subject, takeUntil, tap, throttleTime } from \"rxjs\";\nimport { useTelemetryContext } from \"./UseTelemetryContext\";\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 { TreeCheckboxProps } from \"./components/TreeNodeCheckbox\";\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({ visibilityHandlerFactory }: UseHierarchyVisibilityProps): TreeCheckboxProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeCheckboxProps & { triggerRefresh: () => void }>({\n getCheckboxState: () => ({ state: \"off\", isDisabled: true }),\n onCheckboxClicked: () => {},\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) => defer(async () => ({ node, status: await handler.getVisibilityStatus(node.nodeData) })).pipe(takeUntil(visibilityChanged))),\n tap({\n next: ({ node, status }) => {\n visibilityStatusMap.current.set(node.id, {\n node,\n status,\n needsRefresh: false,\n });\n },\n }),\n throttleTime(100, undefined, { leading: true, trailing: true }),\n )\n .subscribe({\n next: () => {\n triggerCheckboxUpdate();\n },\n });\n\n const changeVisibility = (node: PresentationHierarchyNode, checked: boolean) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n void handler.changeVisibility(node.nodeData, checked);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = checked ? \"visible\" : \"hidden\";\n entry.status.tooltip = undefined;\n triggerCheckboxUpdate();\n };\n\n setState({\n onCheckboxClicked: changeVisibility,\n getCheckboxState: 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): TreeCheckboxProps[\"getCheckboxState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"off\", isDisabled: true };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state === \"visible\" ? \"on\" : status.state === \"hidden\" ? \"off\" : \"partial\",\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/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\";\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 { TreeCheckboxProps } from \"./components/TreeNodeCheckbox\";\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({ visibilityHandlerFactory }: UseHierarchyVisibilityProps): TreeCheckboxProps & { triggerRefresh: () => void } {\n const visibilityStatusMap = useRef(new Map<string, { node: PresentationHierarchyNode; status: VisibilityStatus; needsRefresh: boolean }>());\n const [state, setState] = useState<TreeCheckboxProps & { triggerRefresh: () => void }>({\n getCheckboxState: () => ({ state: \"off\", isDisabled: true }),\n onCheckboxClicked: () => {},\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 = (node: PresentationHierarchyNode, checked: boolean) => {\n onFeatureUsed({ featureId: \"visibility-change\", reportInteraction: true });\n void handler.changeVisibility(node.nodeData, checked);\n const entry = visibilityStatusMap.current.get(node.id);\n if (!entry) {\n return;\n }\n entry.status.state = checked ? \"visible\" : \"hidden\";\n entry.status.tooltip = undefined;\n triggerCheckboxUpdate();\n };\n\n setState({\n onCheckboxClicked: changeVisibility,\n getCheckboxState: 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): TreeCheckboxProps[\"getCheckboxState\"] {\n return (node) => {\n const entry = map.current.get(node.id);\n if (entry === undefined) {\n calculateVisibility(node);\n return { state: \"off\", isDisabled: true };\n }\n if (entry.needsRefresh) {\n calculateVisibility(node);\n }\n\n const status = entry.status;\n return {\n state: status.state === \"visible\" ? \"on\" : status.state === \"hidden\" ? \"off\" : \"partial\",\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"]}
@@ -3,7 +3,7 @@ import type { FunctionProps } from "../Utils";
3
3
  import type { ReactNode } from "react";
4
4
  import type { IModelConnection } from "@itwin/core-frontend";
5
5
  import type { SchemaContext } from "@itwin/ecschema-metadata";
6
- import type { SelectionStorage, useIModelTree } from "@itwin/presentation-hierarchies-react";
6
+ import type { PresentationHierarchyNode, SelectionStorage, useIModelTree } from "@itwin/presentation-hierarchies-react";
7
7
  import type { HighlightInfo } from "../UseNodeHighlighting";
8
8
  import type { TreeRendererProps } from "./TreeRenderer";
9
9
  /** @beta */
@@ -16,6 +16,11 @@ export type TreeProps = Pick<FunctionProps<typeof useIModelTree>, "getFilteredPa
16
16
  treeName: string;
17
17
  /** Unified selection storage that should be used by tree to handle tree selection changes. */
18
18
  selectionStorage: SelectionStorage;
19
+ /**
20
+ * An optional predicate to allow or prohibit selection of a node.
21
+ * When not supplied, all nodes are selectable.
22
+ */
23
+ selectionPredicate?: (node: PresentationHierarchyNode) => boolean;
19
24
  /** Tree renderer that should be used to render tree data. */
20
25
  treeRenderer: (treeProps: Required<Pick<TreeRendererProps, "rootNodes" | "expandNode" | "onNodeClick" | "onNodeKeyDown" | "onFilterClick" | "isNodeSelected" | "getHierarchyLevelDetails" | "size" | "getLabel">>) => ReactNode;
21
26
  /** Custom iModel access that is stored outside tree component. If not provided it new iModel access will be created using `imodel` prop. */
@@ -32,11 +32,11 @@ function Tree({ getSchemaContext, hierarchyLevelSizeLimit, selectionStorage, imo
32
32
  return ((0, jsx_runtime_1.jsx)(presentation_components_1.SchemaMetadataContextProvider, { imodel: props.imodel, schemaContextProvider: getSchemaContext, children: (0, jsx_runtime_1.jsx)(presentation_hierarchies_react_1.UnifiedSelectionProvider, { storage: selectionStorage, children: (0, jsx_runtime_1.jsx)(TreeImpl, { ...props, imodelAccess: imodelAccess, defaultHierarchyLevelSizeLimit: defaultHierarchyLevelSizeLimit }) }) }));
33
33
  }
34
34
  exports.Tree = Tree;
35
- function TreeImpl({ imodel, imodelAccess, treeName, noDataMessage, getFilteredPaths, defaultHierarchyLevelSizeLimit, getHierarchyDefinition, selectionMode, onReload, treeRenderer, density, highlight, }) {
35
+ function TreeImpl({ imodel, imodelAccess, treeName, noDataMessage, getFilteredPaths, defaultHierarchyLevelSizeLimit, getHierarchyDefinition, selectionPredicate, selectionMode, onReload, treeRenderer, density, highlight, }) {
36
36
  const localizedStrings = (0, UseHierarchiesLocalization_1.useHierarchiesLocalization)();
37
37
  const { onFeatureUsed, onPerformanceMeasured } = (0, UseTelemetryContext_1.useTelemetryContext)();
38
38
  const [imodelChanged] = (0, react_1.useState)(new core_bentley_1.BeEvent());
39
- const { rootNodes, isLoading, selectNodes, setFormatter: _setFormatter, expandNode, ...treeProps } = (0, presentation_hierarchies_react_1.useIModelUnifiedSelectionTree)({
39
+ const { rootNodes, getNode, isLoading, selectNodes: selectNodesAction, setFormatter: _setFormatter, expandNode, ...treeProps } = (0, presentation_hierarchies_react_1.useIModelUnifiedSelectionTree)({
40
40
  imodelAccess,
41
41
  imodelChanged,
42
42
  getHierarchyDefinition,
@@ -53,8 +53,12 @@ function TreeImpl({ imodel, imodelAccess, treeName, noDataMessage, getFilteredPa
53
53
  onHierarchyLoadError: ({ type }) => onFeatureUsed({ featureId: `error-${type}`, reportInteraction: false }),
54
54
  });
55
55
  (0, UseIModelChangeListener_1.useIModelChangeListener)({ imodel, action: (0, react_1.useCallback)(() => imodelChanged.raiseEvent(), [imodelChanged]) });
56
- const reportingSelectNodes = (0, UseTelemetryContext_1.useReportingAction)({ action: selectNodes });
57
- const { onNodeClick, onNodeKeyDown } = (0, presentation_hierarchies_react_1.useSelectionHandler)({ rootNodes, selectNodes: reportingSelectNodes, selectionMode: selectionMode ?? "single" });
56
+ const selectNodes = useSelectionPredicate({
57
+ action: (0, UseTelemetryContext_1.useReportingAction)({ action: selectNodesAction }),
58
+ predicate: selectionPredicate,
59
+ getNode,
60
+ });
61
+ const { onNodeClick, onNodeKeyDown } = (0, presentation_hierarchies_react_1.useSelectionHandler)({ rootNodes, selectNodes, selectionMode: selectionMode ?? "single" });
58
62
  const { filteringDialog, onFilterClick } = (0, UseHierarchyFiltering_1.useHierarchyLevelFiltering)({
59
63
  imodel,
60
64
  defaultHierarchyLevelSizeLimit,
@@ -80,4 +84,10 @@ function TreeImpl({ imodel, imodelAccess, treeName, noDataMessage, getFilteredPa
80
84
  };
81
85
  return ((0, jsx_runtime_1.jsxs)("div", { style: { position: "relative", height: "100%", overflow: "hidden" }, children: [(0, jsx_runtime_1.jsxs)("div", { id: "tw-tree-renderer-container", style: { overflow: "auto", height: "100%" }, children: [treeRenderer(treeRendererProps), filteringDialog] }), (0, jsx_runtime_1.jsx)(Delayed_1.Delayed, { show: isLoading, children: (0, jsx_runtime_1.jsx)(ProgressOverlay_1.ProgressOverlay, {}) })] }));
82
86
  }
87
+ function useSelectionPredicate({ action, predicate, getNode, }) {
88
+ return (0, react_1.useCallback)((nodeIds, changeType) => action(nodeIds.filter((nodeId) => {
89
+ const node = getNode(nodeId);
90
+ return node && (!predicate || predicate(node));
91
+ }), changeType), [action, getNode, predicate]);
92
+ }
83
93
  //# sourceMappingURL=Tree.js.map