@itwin/tree-widget-react 3.0.0-dev.3 → 3.0.0-dev.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +95 -6
- package/lib/cjs/components/tree-header/TreeHeader.d.ts +10 -8
- package/lib/cjs/components/tree-header/TreeHeader.js +4 -6
- package/lib/cjs/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/cjs/components/tree-header/TreeWithHeader.d.ts +13 -0
- package/lib/cjs/components/tree-header/TreeWithHeader.js +20 -0
- package/lib/cjs/components/tree-header/TreeWithHeader.js.map +1 -0
- package/lib/cjs/components/trees/categories-tree/CategoriesTree.d.ts +3 -7
- package/lib/cjs/components/trees/categories-tree/CategoriesTree.js +7 -63
- package/lib/cjs/components/trees/categories-tree/CategoriesTree.js.map +1 -1
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeButtons.d.ts +9 -2
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeButtons.js +24 -4
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeComponent.d.ts +0 -1
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeComponent.js +15 -18
- package/lib/cjs/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/categories-tree/CategoriesVisibilityHandler.d.ts +1 -9
- package/lib/cjs/components/trees/categories-tree/CategoriesVisibilityHandler.js +2 -6
- package/lib/cjs/components/trees/categories-tree/CategoriesVisibilityHandler.js.map +1 -1
- package/lib/cjs/components/trees/categories-tree/UseCategoriesTree.d.ts +25 -0
- package/lib/cjs/components/trees/categories-tree/UseCategoriesTree.js +89 -0
- package/lib/cjs/components/trees/categories-tree/UseCategoriesTree.js.map +1 -0
- package/lib/cjs/components/trees/common/CategoriesVisibilityUtils.d.ts +6 -6
- package/lib/cjs/components/trees/common/CategoriesVisibilityUtils.js +32 -78
- package/lib/cjs/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/cjs/components/trees/common/UseTelemetryContext.d.ts +1 -1
- package/lib/cjs/components/trees/common/UseTelemetryContext.js.map +1 -1
- package/lib/cjs/components/trees/common/components/Tree.d.ts +0 -2
- package/lib/cjs/components/trees/common/components/Tree.js +5 -4
- package/lib/cjs/components/trees/common/components/Tree.js.map +1 -1
- package/lib/cjs/components/trees/common/components/VisibilityTree.d.ts +2 -3
- package/lib/cjs/components/trees/common/components/VisibilityTree.js.map +1 -1
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +1 -1
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js +1 -2
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.d.ts +1 -1
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTreeComponent.js +1 -2
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/index.d.ts +4 -0
- package/lib/cjs/components/trees/index.js +9 -1
- package/lib/cjs/components/trees/index.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTree.d.ts +4 -4
- package/lib/cjs/components/trees/models-tree/ModelsTree.js +4 -203
- package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTreeButtons.d.ts +9 -3
- package/lib/cjs/components/trees/models-tree/ModelsTreeButtons.js +13 -3
- package/lib/cjs/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.d.ts +0 -1
- package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js +27 -20
- package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/UseModelsTree.d.ts +29 -0
- package/lib/cjs/components/trees/models-tree/UseModelsTree.js +233 -0
- package/lib/cjs/components/trees/models-tree/UseModelsTree.js.map +1 -0
- package/lib/cjs/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +1 -1
- package/lib/cjs/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/cjs/tree-widget-react.d.ts +1 -0
- package/lib/cjs/tree-widget-react.js +3 -1
- package/lib/cjs/tree-widget-react.js.map +1 -1
- package/lib/esm/components/tree-header/TreeHeader.d.ts +10 -8
- package/lib/esm/components/tree-header/TreeHeader.js +4 -6
- package/lib/esm/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/esm/components/tree-header/TreeWithHeader.d.ts +13 -0
- package/lib/esm/components/tree-header/TreeWithHeader.js +13 -0
- package/lib/esm/components/tree-header/TreeWithHeader.js.map +1 -0
- package/lib/esm/components/trees/categories-tree/CategoriesTree.d.ts +3 -7
- package/lib/esm/components/trees/categories-tree/CategoriesTree.js +7 -63
- package/lib/esm/components/trees/categories-tree/CategoriesTree.js.map +1 -1
- package/lib/esm/components/trees/categories-tree/CategoriesTreeButtons.d.ts +9 -2
- package/lib/esm/components/trees/categories-tree/CategoriesTreeButtons.js +22 -4
- package/lib/esm/components/trees/categories-tree/CategoriesTreeButtons.js.map +1 -1
- package/lib/esm/components/trees/categories-tree/CategoriesTreeComponent.d.ts +0 -1
- package/lib/esm/components/trees/categories-tree/CategoriesTreeComponent.js +16 -16
- package/lib/esm/components/trees/categories-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/categories-tree/CategoriesVisibilityHandler.d.ts +1 -9
- package/lib/esm/components/trees/categories-tree/CategoriesVisibilityHandler.js +2 -6
- package/lib/esm/components/trees/categories-tree/CategoriesVisibilityHandler.js.map +1 -1
- package/lib/esm/components/trees/categories-tree/UseCategoriesTree.d.ts +25 -0
- package/lib/esm/components/trees/categories-tree/UseCategoriesTree.js +85 -0
- package/lib/esm/components/trees/categories-tree/UseCategoriesTree.js.map +1 -0
- package/lib/esm/components/trees/common/CategoriesVisibilityUtils.d.ts +6 -6
- package/lib/esm/components/trees/common/CategoriesVisibilityUtils.js +33 -79
- package/lib/esm/components/trees/common/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/esm/components/trees/common/UseTelemetryContext.d.ts +1 -1
- package/lib/esm/components/trees/common/UseTelemetryContext.js.map +1 -1
- package/lib/esm/components/trees/common/components/Tree.d.ts +0 -2
- package/lib/esm/components/trees/common/components/Tree.js +5 -4
- package/lib/esm/components/trees/common/components/Tree.js.map +1 -1
- package/lib/esm/components/trees/common/components/VisibilityTree.d.ts +2 -3
- package/lib/esm/components/trees/common/components/VisibilityTree.js.map +1 -1
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +1 -1
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js +1 -2
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.d.ts +1 -1
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTreeComponent.js +1 -2
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/index.d.ts +4 -0
- package/lib/esm/components/trees/index.js +4 -0
- package/lib/esm/components/trees/index.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTree.d.ts +4 -4
- package/lib/esm/components/trees/models-tree/ModelsTree.js +5 -204
- package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTreeButtons.d.ts +9 -3
- package/lib/esm/components/trees/models-tree/ModelsTreeButtons.js +12 -2
- package/lib/esm/components/trees/models-tree/ModelsTreeButtons.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTreeComponent.d.ts +0 -1
- package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js +29 -19
- package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/models-tree/UseModelsTree.d.ts +29 -0
- package/lib/esm/components/trees/models-tree/UseModelsTree.js +229 -0
- package/lib/esm/components/trees/models-tree/UseModelsTree.js.map +1 -0
- package/lib/esm/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js +2 -2
- package/lib/esm/components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js.map +1 -1
- package/lib/esm/tree-widget-react.d.ts +1 -0
- package/lib/esm/tree-widget-react.js +1 -0
- package/lib/esm/tree-widget-react.js.map +1 -1
- package/package.json +11 -15
- package/lib/cjs/components/trees/categories-tree/UseCategories.d.ts +0 -8
- package/lib/cjs/components/trees/categories-tree/UseCategories.js +0 -22
- package/lib/cjs/components/trees/categories-tree/UseCategories.js.map +0 -1
- package/lib/cjs/components/utils/AutoSizer.d.ts +0 -13
- package/lib/cjs/components/utils/AutoSizer.js +0 -21
- package/lib/cjs/components/utils/AutoSizer.js.map +0 -1
- package/lib/esm/components/trees/categories-tree/UseCategories.d.ts +0 -8
- package/lib/esm/components/trees/categories-tree/UseCategories.js +0 -18
- package/lib/esm/components/trees/categories-tree/UseCategories.js.map +0 -1
- package/lib/esm/components/utils/AutoSizer.d.ts +0 -13
- package/lib/esm/components/utils/AutoSizer.js +0 -17
- package/lib/esm/components/utils/AutoSizer.js.map +0 -1
- /package/lib/cjs/components/{trees/Tree.scss → tree-header/TreeWithHeader.scss} +0 -0
- /package/lib/esm/components/{trees/Tree.scss → tree-header/TreeWithHeader.scss} +0 -0
package/README.md
CHANGED
|
@@ -152,6 +152,48 @@ The Models tree can be used in a "focus mode" where the tree is automatically fi
|
|
|
152
152
|
|
|
153
153
|

|
|
154
154
|
|
|
155
|
+
#### Custom models tree
|
|
156
|
+
|
|
157
|
+
This package provides building blocks for custom models tree:
|
|
158
|
+
|
|
159
|
+
- `useModelsTree` - hook for creating and managing models tree state.
|
|
160
|
+
- `useModelsTreeButtonProps` - hook for creating props for models tree buttons.
|
|
161
|
+
|
|
162
|
+
Example:
|
|
163
|
+
|
|
164
|
+
```tsx
|
|
165
|
+
function CustomModelsTreeComponent({ imodel, viewport, getSchemaContext, selectionStorage }: CustomModelsTreeProps) {
|
|
166
|
+
const buttonProps = useModelsTreeButtonProps({ imodel, viewport });
|
|
167
|
+
const { modelsTreeProps, rendererProps } = useModelsTree({ activeView: viewport });
|
|
168
|
+
|
|
169
|
+
return (
|
|
170
|
+
<TreeWithHeader buttons={[<ModelsTreeComponent.ShowAllButton {...buttonProps} />, <ModelsTreeComponent.HideAllButton {...buttonProps} />]}>
|
|
171
|
+
<VisibilityTree
|
|
172
|
+
{...modelsTreeProps}
|
|
173
|
+
getSchemaContext={getSchemaContext}
|
|
174
|
+
selectionStorage={selectionStorage}
|
|
175
|
+
imodel={imodel}
|
|
176
|
+
treeRenderer={(props) => <CustomModelsTreeRenderer {...props} {...rendererProps} />}
|
|
177
|
+
/>
|
|
178
|
+
</TreeWithHeader>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
type VisibilityTreeRendererProps = ComponentPropsWithoutRef<typeof VisibilityTreeRenderer>;
|
|
183
|
+
type CustomModelsTreeRendererProps = Parameters<ComponentPropsWithoutRef<typeof VisibilityTree>["treeRenderer"]>[0];
|
|
184
|
+
|
|
185
|
+
function CustomModelsTreeRenderer(props: CustomModelsTreeRendererProps) {
|
|
186
|
+
const getLabel = useCallback<Required<VisibilityTreeRendererProps>["getLabel"]>(
|
|
187
|
+
(node) => {
|
|
188
|
+
const originalLabel = props.getLabel(node);
|
|
189
|
+
return <>Custom node - {originalLabel}</>;
|
|
190
|
+
},
|
|
191
|
+
[props.getLabel],
|
|
192
|
+
);
|
|
193
|
+
return <VisibilityTreeRenderer {...props} getLabel={getLabel} getSublabel={getSublabel} />;
|
|
194
|
+
}
|
|
195
|
+
```
|
|
196
|
+
|
|
155
197
|
### Categories tree
|
|
156
198
|
|
|
157
199
|
The component, based on the active view, renders a hierarchy of either spatial (3d) or drawing (2d) categories. The hierarchy consists of two levels - the category (spatial or drawing) and its sub-categories. There's also a header that renders categories search box and various visibility control buttons.
|
|
@@ -200,6 +242,53 @@ Available header buttons:
|
|
|
200
242
|
- `ModelsTreeComponent.HideAllButton` makes all categories hidden.
|
|
201
243
|
- `ModelsTreeComponent.InvertButton` inverts display of all categories.
|
|
202
244
|
|
|
245
|
+
#### Custom categories tree
|
|
246
|
+
|
|
247
|
+
This package provides building blocks for custom categories tree:
|
|
248
|
+
|
|
249
|
+
- `useCategoriesTree` - hook for creating and managing categories tree state.
|
|
250
|
+
- `useCategoriesTreeButtonProps` - hook for creating props for categories tree buttons.
|
|
251
|
+
|
|
252
|
+
Example:
|
|
253
|
+
|
|
254
|
+
```tsx
|
|
255
|
+
function CustomCategoriesTreeComponent({ imodel, viewport, getSchemaContext, selectionStorage }: CustomCategoriesTreeProps) {
|
|
256
|
+
const buttonProps = useCategoriesTreeButtonProps({ imodel, viewport });
|
|
257
|
+
const { categoriesTreeProps, rendererProps } = useCategoriesTree({ activeView: viewport });
|
|
258
|
+
|
|
259
|
+
return (
|
|
260
|
+
<TreeWithHeader buttons={[<CategoriesTreeComponent.ShowAllButton {...buttonProps} />, <CategoriesTreeComponent.HideAllButton {...buttonProps} />]}>
|
|
261
|
+
<VisibilityTree
|
|
262
|
+
{...categoriesTreeProps}
|
|
263
|
+
getSchemaContext={getSchemaContext}
|
|
264
|
+
selectionStorage={selectionStorage}
|
|
265
|
+
imodel={imodel}
|
|
266
|
+
treeRenderer={(props) => <CustomCategoriesTreeRenderer {...props} {...rendererProps} />}
|
|
267
|
+
/>
|
|
268
|
+
</TreeWithHeader>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
type VisibilityTreeRendererProps = ComponentPropsWithoutRef<typeof VisibilityTreeRenderer>;
|
|
273
|
+
type CustomCategoriesTreeRendererProps = Parameters<ComponentPropsWithoutRef<typeof VisibilityTree>["treeRenderer"]>[0];
|
|
274
|
+
|
|
275
|
+
function CustomCategoriesTreeRenderer(props: CustomCategoriesTreeRendererProps) {
|
|
276
|
+
const getLabel = useCallback<Required<VisibilityTreeRendererProps>["getLabel"]>(
|
|
277
|
+
(node) => {
|
|
278
|
+
const originalLabel = props.getLabel(node);
|
|
279
|
+
return <>Custom node - {originalLabel}</>;
|
|
280
|
+
},
|
|
281
|
+
[props.getLabel],
|
|
282
|
+
);
|
|
283
|
+
|
|
284
|
+
const getSublabel = useCallback<Required<VisibilityTreeRendererProps>["getSublabel"]>(() => {
|
|
285
|
+
return <>Custom sub label</>;
|
|
286
|
+
}, []);
|
|
287
|
+
|
|
288
|
+
return <VisibilityTreeRenderer {...props} getLabel={getLabel} getSublabel={getSublabel} />;
|
|
289
|
+
}
|
|
290
|
+
```
|
|
291
|
+
|
|
203
292
|
### iModel content tree
|
|
204
293
|
|
|
205
294
|
The component renders a similar hierarchy to [Models tree](#models-tree), but with the following changes:
|
|
@@ -251,6 +340,7 @@ The package delivers a set of building blocks for creating trees that look and f
|
|
|
251
340
|
#### Custom basic tree
|
|
252
341
|
|
|
253
342
|
A "basic" tree is a tree that renders the hierarchy without visibility control - see [iModel content tree](#imodel-content-tree) for an example. Core components:
|
|
343
|
+
|
|
254
344
|
- `Tree` - component that manages tree state, selection and filtering.
|
|
255
345
|
- `TreeRenderer` - default renderer for tree data.
|
|
256
346
|
|
|
@@ -278,10 +368,8 @@ const getHierarchyDefinition: TreeProps["getHierarchyDefinition"] = ({ imodelAcc
|
|
|
278
368
|
// see https://github.com/iTwin/presentation/blob/master/packages/hierarchies/README.md#hierarchy-definition
|
|
279
369
|
}
|
|
280
370
|
|
|
281
|
-
function MyTree({
|
|
371
|
+
function MyTree({ imodel }: MyTreeProps) {
|
|
282
372
|
return <Tree
|
|
283
|
-
width={width}
|
|
284
|
-
height={height}
|
|
285
373
|
treeName="MyTree"
|
|
286
374
|
imodel={imodel}
|
|
287
375
|
selectionStorage={getUnifiedSelectionStorage()}
|
|
@@ -295,6 +383,7 @@ function MyTree({width, height, imodel}: MyTreeProps) {
|
|
|
295
383
|
#### Custom visibility tree
|
|
296
384
|
|
|
297
385
|
A visibility tree is a tree that renders the hierarchy and allows controlling visibility control through the use of "eye" checkboxes - see [Models](#models-tree) and [Categories](#categories-tree) trees. Core components:
|
|
386
|
+
|
|
298
387
|
- `VisibilityTree` - same as `Tree` component but additionally manages visibility of instances represented by tree nodes.
|
|
299
388
|
- `VisibilityTreeRenderer` - same as `TreeRenderer` but additionally renders checkboxes for visibility control.
|
|
300
389
|
|
|
@@ -339,10 +428,8 @@ const visibilityHandlerFactory: VisibilityTreeProps["visibilityHandlerFactory"]
|
|
|
339
428
|
};
|
|
340
429
|
}
|
|
341
430
|
|
|
342
|
-
function MyVisibilityTree({
|
|
431
|
+
function MyVisibilityTree({ imodel }: MyVisibilityTreeProps) {
|
|
343
432
|
return <VisibilityTree
|
|
344
|
-
width={width}
|
|
345
|
-
height={height}
|
|
346
433
|
treeName="MyVisibilityTree"
|
|
347
434
|
imodel={imodel}
|
|
348
435
|
selectionStorage={getUnifiedSelectionStorage()}
|
|
@@ -451,6 +538,8 @@ This can be achieved by passing `onFeatureUsed` function to `CategoriesTreeCompo
|
|
|
451
538
|
- `"choose-{tree}"` - when a tree is selected in the tree selector.
|
|
452
539
|
- `"use-{tree}"` - when an interaction with a tree hierarchy happens. This includes any kind of interaction with nodes, including them being expanded/collapsed, selected, filtered, their visibility change, etc.
|
|
453
540
|
- `"{tree}-visibility-change"` - when visibility is toggled using an "eye" button.
|
|
541
|
+
- `"{tree}-error-timeout"` - when a request timeouts while loading hierarchy or filtering.
|
|
542
|
+
- `"{tree}-error-unknown"` - when an unknown error occurs while loading hierarchy or filtering.
|
|
454
543
|
- `"models-tree-showall"` - when "Show All" button is used in `ModelsTreeComponent`.
|
|
455
544
|
- `"models-tree-hideall"` - when "Hide All" button is used in `ModelsTreeComponent`.
|
|
456
545
|
- `"models-tree-invert"` - when "Invert" button is used in `ModelsTreeComponent`.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
/// <reference types="react" />
|
|
2
1
|
import "./TreeHeader.scss";
|
|
2
|
+
import type { PropsWithChildren } from "react";
|
|
3
3
|
import type { Viewport } from "@itwin/core-frontend";
|
|
4
4
|
import type { CommonProps } from "@itwin/core-react";
|
|
5
5
|
/** @public */
|
|
@@ -8,8 +8,8 @@ export interface TreeHeaderButtonProps {
|
|
|
8
8
|
density?: "default" | "enlarged";
|
|
9
9
|
onFeatureUsed?: (feature: string) => void;
|
|
10
10
|
}
|
|
11
|
-
/** @
|
|
12
|
-
export interface
|
|
11
|
+
/** @beta */
|
|
12
|
+
export interface TreeFilteringProps {
|
|
13
13
|
/** Filtering is cleared after everything's loaded */
|
|
14
14
|
onFilterStart: (newFilter: string) => void;
|
|
15
15
|
/** listens for onClick event for Clear (x) icon */
|
|
@@ -19,12 +19,14 @@ export interface TreeHeaderProps extends CommonProps {
|
|
|
19
19
|
/** Current selected result index */
|
|
20
20
|
selectedIndex?: number;
|
|
21
21
|
/** Callback to currently selected result/entry change */
|
|
22
|
-
onSelectedChanged
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
onSelectedChanged?: (index: number) => void;
|
|
23
|
+
isDisabled?: boolean;
|
|
24
|
+
}
|
|
25
|
+
interface TreeHeaderProps extends CommonProps {
|
|
26
|
+
filteringProps?: TreeFilteringProps;
|
|
25
27
|
/** Modifies the density of tree header. `enlarged` header contains larger content */
|
|
26
28
|
density?: "default" | "enlarged";
|
|
27
29
|
}
|
|
28
|
-
|
|
29
|
-
export
|
|
30
|
+
export declare function TreeHeader(props: PropsWithChildren<TreeHeaderProps>): JSX.Element;
|
|
31
|
+
export {};
|
|
30
32
|
//# sourceMappingURL=TreeHeader.d.ts.map
|
|
@@ -16,20 +16,18 @@ const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
|
|
|
16
16
|
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
17
17
|
const TreeWidget_1 = require("../../TreeWidget");
|
|
18
18
|
const FocusedInstancesContext_1 = require("../trees/common/FocusedInstancesContext");
|
|
19
|
-
/** @internal */
|
|
20
19
|
function TreeHeader(props) {
|
|
21
|
-
const {
|
|
20
|
+
const { filteringProps, density, className, children } = props;
|
|
22
21
|
const [isSearchOpen, setIsSearchOpen] = (0, react_1.useState)(false);
|
|
23
22
|
const { enabled: instanceFocusEnabled } = (0, FocusedInstancesContext_1.useFocusedInstancesContext)();
|
|
24
23
|
const size = density === "enlarged" ? "large" : "small";
|
|
25
24
|
(0, react_1.useEffect)(() => {
|
|
26
25
|
// istanbul ignore if
|
|
27
|
-
if (
|
|
28
|
-
onFilterClear();
|
|
26
|
+
if (filteringProps?.isDisabled) {
|
|
29
27
|
setIsSearchOpen(false);
|
|
30
28
|
}
|
|
31
|
-
}, [
|
|
32
|
-
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)("tree-widget-tree-header", className), children: [(0, jsx_runtime_1.jsx)(HeaderButtons, { contracted: isSearchOpen, size: size, children: children }), (0, jsx_runtime_1.jsx)(DebouncedSearchBox, { isOpened: isSearchOpen, onOpen: () => setIsSearchOpen(true), onClose: () => setIsSearchOpen(false), onChange: (value) => (value ? onFilterStart(value) : onFilterClear()), delay: 500, selectedResultIndex: selectedIndex, resultCount: resultCount, onSelectedResultChanged: onSelectedChanged, size: size, isDisabled: instanceFocusEnabled })] }));
|
|
29
|
+
}, [filteringProps?.isDisabled]);
|
|
30
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)("tree-widget-tree-header", className), children: [(0, jsx_runtime_1.jsx)(HeaderButtons, { contracted: isSearchOpen, size: size, children: children }), filteringProps ? ((0, jsx_runtime_1.jsx)(DebouncedSearchBox, { isOpened: isSearchOpen, onOpen: () => setIsSearchOpen(true), onClose: () => setIsSearchOpen(false), onChange: (value) => (value ? filteringProps.onFilterStart(value) : filteringProps.onFilterClear()), delay: 500, selectedResultIndex: filteringProps.selectedIndex, resultCount: filteringProps.resultCount, onSelectedResultChanged: (index) => filteringProps.onSelectedChanged?.(index), size: size, isDisabled: instanceFocusEnabled })) : null] }));
|
|
33
31
|
}
|
|
34
32
|
exports.TreeHeader = TreeHeader;
|
|
35
33
|
function DebouncedSearchBox({ isOpened, selectedResultIndex, resultCount, onSelectedResultChanged, onChange, onOpen, onClose, delay, size, isDisabled, }) {
|
|
@@ -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 { Viewport } from \"@itwin/core-frontend\";\nimport type { CommonProps } from \"@itwin/core-react\";\n\n/** @public */\nexport interface TreeHeaderButtonProps {\n viewport: Viewport;\n density?: \"default\" | \"enlarged\";\n onFeatureUsed?: (feature: string) => void;\n}\n\n/** @internal */\nexport interface TreeHeaderProps extends CommonProps {\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 /** Header buttons */\n children?: React.ReactNode;\n /** Modifies the density of tree header. `enlarged` header contains larger content */\n density?: \"default\" | \"enlarged\";\n}\n\n/** @internal */\nexport function TreeHeader(props: TreeHeaderProps) {\n const { onFilterStart, onFilterClear, resultCount, selectedIndex, onSelectedChanged, children, density, className } = 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 (instanceFocusEnabled) {\n onFilterClear();\n setIsSearchOpen(false);\n }\n }, [instanceFocusEnabled, onFilterClear]);\n\n return (\n <div className={classnames(\"tree-widget-tree-header\", className)}>\n <HeaderButtons contracted={isSearchOpen} size={size}>\n {children}\n </HeaderButtons>\n <DebouncedSearchBox\n isOpened={isSearchOpen}\n onOpen={() => setIsSearchOpen(true)}\n onClose={() => setIsSearchOpen(false)}\n onChange={(value) => (value ? onFilterStart(value) : onFilterClear())}\n delay={500}\n selectedResultIndex={selectedIndex}\n resultCount={resultCount}\n onSelectedResultChanged={onSelectedChanged}\n size={size}\n isDisabled={instanceFocusEnabled}\n />\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 children?: React.ReactNode;\n size: \"large\" | \"small\";\n}\n\nfunction HeaderButtons(props: 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\";\nimport type { CommonProps } from \"@itwin/core-react\";\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 isDisabled?: boolean;\n}\n\ninterface TreeHeaderProps extends CommonProps {\n filteringProps?: TreeFilteringProps;\n /** Modifies the density of tree header. `enlarged` header contains larger content */\n density?: \"default\" | \"enlarged\";\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}\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"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import "./TreeWithHeader.scss";
|
|
2
|
+
import type { PropsWithChildren, ReactNode } from "react";
|
|
3
|
+
import type { TreeFilteringProps } from "./TreeHeader";
|
|
4
|
+
/** @beta */
|
|
5
|
+
interface TreeWithHeaderProps {
|
|
6
|
+
density?: "enlarged" | "default";
|
|
7
|
+
filteringProps?: TreeFilteringProps;
|
|
8
|
+
buttons?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/** @beta */
|
|
11
|
+
export declare function TreeWithHeader({ filteringProps, buttons, density, children }: PropsWithChildren<TreeWithHeaderProps>): JSX.Element;
|
|
12
|
+
export {};
|
|
13
|
+
//# sourceMappingURL=TreeWithHeader.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.TreeWithHeader = void 0;
|
|
7
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
8
|
+
/*---------------------------------------------------------------------------------------------
|
|
9
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
10
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
11
|
+
*--------------------------------------------------------------------------------------------*/
|
|
12
|
+
require("./TreeWithHeader.scss");
|
|
13
|
+
const classnames_1 = __importDefault(require("classnames"));
|
|
14
|
+
const TreeHeader_1 = require("./TreeHeader");
|
|
15
|
+
/** @beta */
|
|
16
|
+
function TreeWithHeader({ filteringProps, buttons, density, children }) {
|
|
17
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: (0, classnames_1.default)("tw-tree-with-header", density === "enlarged" && "enlarge"), children: [(0, jsx_runtime_1.jsx)(TreeHeader_1.TreeHeader, { filteringProps: filteringProps, density: density, children: buttons }), (0, jsx_runtime_1.jsx)("div", { className: "tw-tree-content", children: children })] }));
|
|
18
|
+
}
|
|
19
|
+
exports.TreeWithHeader = TreeWithHeader;
|
|
20
|
+
//# sourceMappingURL=TreeWithHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeWithHeader.js","sourceRoot":"","sources":["../../../../src/components/tree-header/TreeWithHeader.tsx"],"names":[],"mappings":";;;;;;;AAAA;;;gGAGgG;AAEhG,iCAA+B;AAC/B,4DAAoC;AACpC,6CAA0C;AAY1C,YAAY;AACZ,SAAgB,cAAc,CAAC,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAA0C;IACnH,OAAO,CACL,iCAAK,SAAS,EAAE,IAAA,oBAAU,EAAC,qBAAqB,EAAE,OAAO,KAAK,UAAU,IAAI,SAAS,CAAC,aACpF,uBAAC,uBAAU,IAAC,cAAc,EAAE,cAAc,EAAE,OAAO,EAAE,OAAO,YACzD,OAAO,GACG,EACb,gCAAK,SAAS,EAAC,iBAAiB,YAAE,QAAQ,GAAO,IAC7C,CACP,CAAC;AACJ,CAAC;AATD,wCASC","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 \"./TreeWithHeader.scss\";\nimport classNames from \"classnames\";\nimport { TreeHeader } from \"./TreeHeader\";\n\nimport type { PropsWithChildren, ReactNode } from \"react\";\nimport type { TreeFilteringProps } from \"./TreeHeader\";\n\n/** @beta */\ninterface TreeWithHeaderProps {\n density?: \"enlarged\" | \"default\";\n filteringProps?: TreeFilteringProps;\n buttons?: ReactNode;\n}\n\n/** @beta */\nexport function TreeWithHeader({ filteringProps, buttons, density, children }: PropsWithChildren<TreeWithHeaderProps>) {\n return (\n <div className={classNames(\"tw-tree-with-header\", density === \"enlarged\" && \"enlarge\")}>\n <TreeHeader filteringProps={filteringProps} density={density}>\n {buttons}\n </TreeHeader>\n <div className=\"tw-tree-content\">{children}</div>\n </div>\n );\n}\n"]}
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
import { VisibilityTree } from "../common/components/VisibilityTree";
|
|
2
|
-
import type { CategoryInfo } from "../common/CategoriesVisibilityUtils";
|
|
3
2
|
import type { ComponentPropsWithoutRef } from "react";
|
|
4
|
-
import type {
|
|
3
|
+
import type { Viewport } from "@itwin/core-frontend";
|
|
5
4
|
/** @beta */
|
|
6
5
|
interface CategoriesTreeOwnProps {
|
|
7
6
|
filter: string;
|
|
8
7
|
activeView: Viewport;
|
|
9
|
-
categories: CategoryInfo[];
|
|
10
|
-
viewManager?: ViewManager;
|
|
11
|
-
allViewports?: boolean;
|
|
12
8
|
hierarchyLevelConfig?: {
|
|
13
9
|
sizeLimit?: number;
|
|
14
10
|
};
|
|
@@ -16,8 +12,8 @@ interface CategoriesTreeOwnProps {
|
|
|
16
12
|
/** @beta */
|
|
17
13
|
type VisibilityTreeProps = ComponentPropsWithoutRef<typeof VisibilityTree>;
|
|
18
14
|
/** @beta */
|
|
19
|
-
type CategoriesTreeProps = CategoriesTreeOwnProps & Pick<VisibilityTreeProps, "imodel" | "getSchemaContext" | "selectionStorage" | "
|
|
15
|
+
type CategoriesTreeProps = CategoriesTreeOwnProps & Pick<VisibilityTreeProps, "imodel" | "getSchemaContext" | "selectionStorage" | "density" | "selectionMode">;
|
|
20
16
|
/** @beta */
|
|
21
|
-
export declare function CategoriesTree({ imodel,
|
|
17
|
+
export declare function CategoriesTree({ imodel, getSchemaContext, selectionStorage, activeView, filter, density, hierarchyLevelConfig, selectionMode, }: CategoriesTreeProps): JSX.Element;
|
|
22
18
|
export {};
|
|
23
19
|
//# sourceMappingURL=CategoriesTree.d.ts.map
|
|
@@ -6,72 +6,16 @@ const jsx_runtime_1 = require("react/jsx-runtime");
|
|
|
6
6
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
7
7
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
8
8
|
*--------------------------------------------------------------------------------------------*/
|
|
9
|
-
const react_1 = require("react");
|
|
10
|
-
const core_frontend_1 = require("@itwin/core-frontend");
|
|
11
|
-
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
|
|
12
|
-
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
13
|
-
const TreeWidget_1 = require("../../../TreeWidget");
|
|
14
9
|
const VisibilityTree_1 = require("../common/components/VisibilityTree");
|
|
15
10
|
const VisibilityTreeRenderer_1 = require("../common/components/VisibilityTreeRenderer");
|
|
16
|
-
const
|
|
17
|
-
const CategoriesTreeComponent_1 = require("./CategoriesTreeComponent");
|
|
18
|
-
const CategoriesTreeDefinition_1 = require("./CategoriesTreeDefinition");
|
|
19
|
-
const CategoriesVisibilityHandler_1 = require("./CategoriesVisibilityHandler");
|
|
11
|
+
const UseCategoriesTree_1 = require("./UseCategoriesTree");
|
|
20
12
|
/** @beta */
|
|
21
|
-
function CategoriesTree({ imodel,
|
|
22
|
-
const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
viewManager: viewManager ?? core_frontend_1.IModelApp.viewManager,
|
|
28
|
-
categories,
|
|
29
|
-
allViewports,
|
|
30
|
-
});
|
|
31
|
-
return {
|
|
32
|
-
getVisibilityStatus: async (node) => visibilityHandler.getVisibilityStatus(node),
|
|
33
|
-
changeVisibility: async (node, on) => visibilityHandler.changeVisibility(node, on),
|
|
34
|
-
onVisibilityChange: visibilityHandler.onVisibilityChange,
|
|
35
|
-
dispose: () => visibilityHandler.dispose(),
|
|
36
|
-
};
|
|
37
|
-
}, [activeView, allViewports, categories, imodel, viewManager]);
|
|
38
|
-
const { onFeatureUsed } = (0, UseTelemetryContext_1.useTelemetryContext)();
|
|
39
|
-
const getDefinitionsProvider = (0, react_1.useCallback)((props) => {
|
|
40
|
-
return new CategoriesTreeDefinition_1.CategoriesTreeDefinition({ ...props, viewType: activeView.view.is2d() ? "2d" : "3d" });
|
|
41
|
-
}, [activeView]);
|
|
42
|
-
const getSearchFilteredPaths = (0, react_1.useMemo)(() => {
|
|
43
|
-
setFilteringError(undefined);
|
|
44
|
-
if (!filter) {
|
|
45
|
-
return undefined;
|
|
46
|
-
}
|
|
47
|
-
return async ({ imodelAccess }) => {
|
|
48
|
-
onFeatureUsed({ featureId: "filtering", reportInteraction: true });
|
|
49
|
-
try {
|
|
50
|
-
return await CategoriesTreeDefinition_1.CategoriesTreeDefinition.createInstanceKeyPaths({ imodelAccess, label: filter, viewType: activeView.view.is2d() ? "2d" : "3d" });
|
|
51
|
-
}
|
|
52
|
-
catch (e) {
|
|
53
|
-
const newError = e instanceof Error && e.message.match(/Filter matches more than \d+ items/) ? "tooManyFilterMatches" : "unknownFilterError";
|
|
54
|
-
setFilteringError(newError);
|
|
55
|
-
return [];
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
}, [filter, activeView, onFeatureUsed]);
|
|
59
|
-
return ((0, jsx_runtime_1.jsx)(VisibilityTree_1.VisibilityTree, { height: height, width: width, imodel: imodel, treeName: CategoriesTreeComponent_1.CategoriesTreeComponent.id, selectionStorage: selectionStorage, getSchemaContext: getSchemaContext, visibilityHandlerFactory: visibilityHandlerFactory, getHierarchyDefinition: getDefinitionsProvider, getFilteredPaths: getSearchFilteredPaths, hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit, density: density, noDataMessage: getNoDataMessage(filter, filteringError), selectionMode: selectionMode ?? "none", highlight: filter === undefined ? undefined : { text: filter }, treeRenderer: (treeProps) => (0, jsx_runtime_1.jsx)(VisibilityTreeRenderer_1.VisibilityTreeRenderer, { ...treeProps, getIcon: getIcon, getSublabel: getSublabel }) }));
|
|
13
|
+
function CategoriesTree({ imodel, getSchemaContext, selectionStorage, activeView, filter, density, hierarchyLevelConfig, selectionMode, }) {
|
|
14
|
+
const { categoriesTreeProps, rendererProps } = (0, UseCategoriesTree_1.useCategoriesTree)({
|
|
15
|
+
filter,
|
|
16
|
+
activeView,
|
|
17
|
+
});
|
|
18
|
+
return ((0, jsx_runtime_1.jsx)(VisibilityTree_1.VisibilityTree, { ...categoriesTreeProps, imodel: imodel, selectionStorage: selectionStorage, getSchemaContext: getSchemaContext, hierarchyLevelSizeLimit: hierarchyLevelConfig?.sizeLimit, density: density, selectionMode: selectionMode ?? "none", treeRenderer: (treeProps) => (0, jsx_runtime_1.jsx)(VisibilityTreeRenderer_1.VisibilityTreeRenderer, { ...treeProps, ...rendererProps }) }));
|
|
60
19
|
}
|
|
61
20
|
exports.CategoriesTree = CategoriesTree;
|
|
62
|
-
function getNoDataMessage(filter, error) {
|
|
63
|
-
if (error) {
|
|
64
|
-
return (0, jsx_runtime_1.jsx)(itwinui_react_1.Text, { children: TreeWidget_1.TreeWidget.translate(`categoriesTree.filtering.${error}`) });
|
|
65
|
-
}
|
|
66
|
-
if (filter) {
|
|
67
|
-
return (0, jsx_runtime_1.jsx)(itwinui_react_1.Text, { children: TreeWidget_1.TreeWidget.translate("categoriesTree.filtering.noMatches", { filter }) });
|
|
68
|
-
}
|
|
69
|
-
return undefined;
|
|
70
|
-
}
|
|
71
|
-
function getIcon() {
|
|
72
|
-
return (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgLayers, {});
|
|
73
|
-
}
|
|
74
|
-
function getSublabel(node) {
|
|
75
|
-
return node.extendedData?.description;
|
|
76
|
-
}
|
|
77
21
|
//# sourceMappingURL=CategoriesTree.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTree.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,
|
|
1
|
+
{"version":3,"file":"CategoriesTree.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTree.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,wEAAqE;AACrE,wFAAqF;AACrF,2DAAwD;AAoBxD,YAAY;AACZ,SAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,gBAAgB,EAChB,gBAAgB,EAChB,UAAU,EACV,MAAM,EACN,OAAO,EACP,oBAAoB,EACpB,aAAa,GACO;IACpB,MAAM,EAAE,mBAAmB,EAAE,aAAa,EAAE,GAAG,IAAA,qCAAiB,EAAC;QAC/D,MAAM;QACN,UAAU;KACX,CAAC,CAAC;IAEH,OAAO,CACL,uBAAC,+BAAc,OACT,mBAAmB,EACvB,MAAM,EAAE,MAAM,EACd,gBAAgB,EAAE,gBAAgB,EAClC,gBAAgB,EAAE,gBAAgB,EAClC,uBAAuB,EAAE,oBAAoB,EAAE,SAAS,EACxD,OAAO,EAAE,OAAO,EAChB,aAAa,EAAE,aAAa,IAAI,MAAM,EACtC,YAAY,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,uBAAC,+CAAsB,OAAK,SAAS,KAAM,aAAa,GAAI,GACzF,CACH,CAAC;AACJ,CAAC;AA3BD,wCA2BC","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 { VisibilityTree } from \"../common/components/VisibilityTree\";\nimport { VisibilityTreeRenderer } from \"../common/components/VisibilityTreeRenderer\";\nimport { useCategoriesTree } from \"./UseCategoriesTree\";\n\nimport type { ComponentPropsWithoutRef } from \"react\";\nimport type { Viewport } from \"@itwin/core-frontend\";\n\n/** @beta */\ninterface CategoriesTreeOwnProps {\n filter: string;\n activeView: Viewport;\n hierarchyLevelConfig?: {\n sizeLimit?: number;\n };\n}\n\n/** @beta */\ntype VisibilityTreeProps = ComponentPropsWithoutRef<typeof VisibilityTree>;\n\n/** @beta */\ntype CategoriesTreeProps = CategoriesTreeOwnProps & Pick<VisibilityTreeProps, \"imodel\" | \"getSchemaContext\" | \"selectionStorage\" | \"density\" | \"selectionMode\">;\n\n/** @beta */\nexport function CategoriesTree({\n imodel,\n getSchemaContext,\n selectionStorage,\n activeView,\n filter,\n density,\n hierarchyLevelConfig,\n selectionMode,\n}: CategoriesTreeProps) {\n const { categoriesTreeProps, rendererProps } = useCategoriesTree({\n filter,\n activeView,\n });\n\n return (\n <VisibilityTree\n {...categoriesTreeProps}\n imodel={imodel}\n selectionStorage={selectionStorage}\n getSchemaContext={getSchemaContext}\n hierarchyLevelSizeLimit={hierarchyLevelConfig?.sizeLimit}\n density={density}\n selectionMode={selectionMode ?? \"none\"}\n treeRenderer={(treeProps) => <VisibilityTreeRenderer {...treeProps} {...rendererProps} />}\n />\n );\n}\n"]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
/// <reference types="react" />
|
|
2
2
|
import type { CategoryInfo } from "../common/CategoriesVisibilityUtils";
|
|
3
3
|
import type { TreeHeaderButtonProps } from "../../tree-header/TreeHeader";
|
|
4
|
+
import type { Viewport } from "@itwin/core-frontend";
|
|
4
5
|
/**
|
|
5
6
|
* Props that get passed to `CategoriesTreeComponent` header button renderer.
|
|
6
7
|
* @see CategoriesTreeComponentProps.headerButtons
|
|
@@ -9,13 +10,19 @@ import type { TreeHeaderButtonProps } from "../../tree-header/TreeHeader";
|
|
|
9
10
|
export interface CategoriesTreeHeaderButtonProps extends TreeHeaderButtonProps {
|
|
10
11
|
/** A list of categories available in the iModel */
|
|
11
12
|
categories: CategoryInfo[];
|
|
12
|
-
/** In case the tree is filtered, a list of filtered categories. */
|
|
13
|
-
filteredCategories?: CategoryInfo[];
|
|
14
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Custom hook that creates props required to render `CategoriesTreeComponent` header button.
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
export declare function useCategoriesTreeButtonProps({ viewport }: {
|
|
19
|
+
viewport: Viewport;
|
|
20
|
+
}): Pick<CategoriesTreeHeaderButtonProps, "categories" | "viewport">;
|
|
15
21
|
/** @public */
|
|
16
22
|
export declare function ShowAllButton(props: CategoriesTreeHeaderButtonProps): JSX.Element;
|
|
17
23
|
/** @public */
|
|
18
24
|
export declare function HideAllButton(props: CategoriesTreeHeaderButtonProps): JSX.Element;
|
|
19
25
|
/** @public */
|
|
20
26
|
export declare function InvertAllButton(props: CategoriesTreeHeaderButtonProps): JSX.Element;
|
|
27
|
+
export declare function useCategories(viewport: Viewport): CategoryInfo[];
|
|
21
28
|
//# sourceMappingURL=CategoriesTreeButtons.d.ts.map
|
|
@@ -1,20 +1,34 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.InvertAllButton = exports.HideAllButton = exports.ShowAllButton = void 0;
|
|
3
|
+
exports.useCategories = exports.InvertAllButton = exports.HideAllButton = exports.ShowAllButton = exports.useCategoriesTreeButtonProps = void 0;
|
|
4
4
|
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
5
|
/*---------------------------------------------------------------------------------------------
|
|
6
6
|
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
7
7
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
8
8
|
*--------------------------------------------------------------------------------------------*/
|
|
9
|
+
const react_1 = require("react");
|
|
10
|
+
const components_react_1 = require("@itwin/components-react");
|
|
9
11
|
const itwinui_icons_react_1 = require("@itwin/itwinui-icons-react");
|
|
10
12
|
const itwinui_react_1 = require("@itwin/itwinui-react");
|
|
11
13
|
const TreeWidget_1 = require("../../../TreeWidget");
|
|
12
14
|
const CategoriesVisibilityUtils_1 = require("../common/CategoriesVisibilityUtils");
|
|
15
|
+
/**
|
|
16
|
+
* Custom hook that creates props required to render `CategoriesTreeComponent` header button.
|
|
17
|
+
* @public
|
|
18
|
+
*/
|
|
19
|
+
function useCategoriesTreeButtonProps({ viewport }) {
|
|
20
|
+
const categories = useCategories(viewport);
|
|
21
|
+
return {
|
|
22
|
+
viewport,
|
|
23
|
+
categories,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
exports.useCategoriesTreeButtonProps = useCategoriesTreeButtonProps;
|
|
13
27
|
/** @public */
|
|
14
28
|
function ShowAllButton(props) {
|
|
15
29
|
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: () => {
|
|
16
30
|
props.onFeatureUsed?.(`categories-tree-showall`);
|
|
17
|
-
void (0, CategoriesVisibilityUtils_1.showAllCategories)(
|
|
31
|
+
void (0, CategoriesVisibilityUtils_1.showAllCategories)(props.categories.map((category) => category.categoryId), props.viewport);
|
|
18
32
|
}, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityShow, {}) }));
|
|
19
33
|
}
|
|
20
34
|
exports.ShowAllButton = ShowAllButton;
|
|
@@ -22,7 +36,7 @@ exports.ShowAllButton = ShowAllButton;
|
|
|
22
36
|
function HideAllButton(props) {
|
|
23
37
|
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: () => {
|
|
24
38
|
props.onFeatureUsed?.(`categories-tree-hideall`);
|
|
25
|
-
void (0, CategoriesVisibilityUtils_1.hideAllCategories)(
|
|
39
|
+
void (0, CategoriesVisibilityUtils_1.hideAllCategories)(props.categories.map((category) => category.categoryId), props.viewport);
|
|
26
40
|
}, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHide, {}) }));
|
|
27
41
|
}
|
|
28
42
|
exports.HideAllButton = HideAllButton;
|
|
@@ -30,8 +44,14 @@ exports.HideAllButton = HideAllButton;
|
|
|
30
44
|
function InvertAllButton(props) {
|
|
31
45
|
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: () => {
|
|
32
46
|
props.onFeatureUsed?.(`categories-tree-invert`);
|
|
33
|
-
void (0, CategoriesVisibilityUtils_1.invertAllCategories)(props.
|
|
47
|
+
void (0, CategoriesVisibilityUtils_1.invertAllCategories)(props.categories, props.viewport);
|
|
34
48
|
}, children: (0, jsx_runtime_1.jsx)(itwinui_icons_react_1.SvgVisibilityHalf, {}) }));
|
|
35
49
|
}
|
|
36
50
|
exports.InvertAllButton = InvertAllButton;
|
|
51
|
+
const EMPTY_CATEGORIES_ARRAY = [];
|
|
52
|
+
function useCategories(viewport) {
|
|
53
|
+
const categoriesPromise = (0, react_1.useMemo)(async () => (0, CategoriesVisibilityUtils_1.loadCategoriesFromViewport)(viewport), [viewport]);
|
|
54
|
+
return (0, components_react_1.useAsyncValue)(categoriesPromise) ?? EMPTY_CATEGORIES_ARRAY;
|
|
55
|
+
}
|
|
56
|
+
exports.useCategories = useCategories;
|
|
37
57
|
//# sourceMappingURL=CategoriesTreeButtons.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesTreeButtons.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTreeButtons.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,oEAAqG;AACrG,wDAAkD;AAClD,oDAAiD;AACjD,
|
|
1
|
+
{"version":3,"file":"CategoriesTreeButtons.js","sourceRoot":"","sources":["../../../../../src/components/trees/categories-tree/CategoriesTreeButtons.tsx"],"names":[],"mappings":";;;;AAAA;;;gGAGgG;AAEhG,iCAAgC;AAChC,8DAAwD;AACxD,oEAAqG;AACrG,wDAAkD;AAClD,oDAAiD;AACjD,mFAA4I;AAgB5I;;;GAGG;AACH,SAAgB,4BAA4B,CAAC,EAAE,QAAQ,EAA0B;IAC/E,MAAM,UAAU,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IAC3C,OAAO;QACL,QAAQ;QACR,UAAU;KACX,CAAC;AACJ,CAAC;AAND,oEAMC;AAED,cAAc;AACd,SAAgB,aAAa,CAAC,KAAsC;IAClE,OAAO,CACL,uBAAC,0BAAU,IACT,IAAI,EAAE,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EACtD,SAAS,EAAC,YAAY,EACtB,KAAK,EAAE,uBAAU,CAAC,SAAS,CAAC,wCAAwC,CAAC,EACrE,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,aAAa,EAAE,CAAC,yBAAyB,CAAC,CAAC;YACjD,KAAK,IAAA,6CAAiB,EACpB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EACvD,KAAK,CAAC,QAAQ,CACf,CAAC;QACJ,CAAC,YAED,uBAAC,uCAAiB,KAAG,GACV,CACd,CAAC;AACJ,CAAC;AAjBD,sCAiBC;AAED,cAAc;AACd,SAAgB,aAAa,CAAC,KAAsC;IAClE,OAAO,CACL,uBAAC,0BAAU,IACT,IAAI,EAAE,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EACtD,SAAS,EAAC,YAAY,EACtB,KAAK,EAAE,uBAAU,CAAC,SAAS,CAAC,wCAAwC,CAAC,EACrE,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,aAAa,EAAE,CAAC,yBAAyB,CAAC,CAAC;YACjD,KAAK,IAAA,6CAAiB,EACpB,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,EACvD,KAAK,CAAC,QAAQ,CACf,CAAC;QACJ,CAAC,YAED,uBAAC,uCAAiB,KAAG,GACV,CACd,CAAC;AACJ,CAAC;AAjBD,sCAiBC;AAED,cAAc;AACd,SAAgB,eAAe,CAAC,KAAsC;IACpE,OAAO,CACL,uBAAC,0BAAU,IACT,KAAK,EAAE,uBAAU,CAAC,SAAS,CAAC,uCAAuC,CAAC,EACpE,IAAI,EAAE,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EACtD,SAAS,EAAC,YAAY,EACtB,OAAO,EAAE,GAAG,EAAE;YACZ,KAAK,CAAC,aAAa,EAAE,CAAC,wBAAwB,CAAC,CAAC;YAChD,KAAK,IAAA,+CAAmB,EAAC,KAAK,CAAC,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC7D,CAAC,YAED,uBAAC,uCAAiB,KAAG,GACV,CACd,CAAC;AACJ,CAAC;AAdD,0CAcC;AAED,MAAM,sBAAsB,GAAmB,EAAE,CAAC;AAElD,SAAgB,aAAa,CAAC,QAAkB;IAC9C,MAAM,iBAAiB,GAAG,IAAA,eAAO,EAAC,KAAK,IAAI,EAAE,CAAC,IAAA,sDAA0B,EAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAChG,OAAO,IAAA,gCAAa,EAAC,iBAAiB,CAAC,IAAI,sBAAsB,CAAC;AACpE,CAAC;AAHD,sCAGC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { useMemo } from \"react\";\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 * @public\n */\nexport function useCategoriesTreeButtonProps({ viewport }: { viewport: Viewport }): Pick<CategoriesTreeHeaderButtonProps, \"categories\" | \"viewport\"> {\n const categories = useCategories(viewport);\n return {\n viewport,\n categories,\n };\n}\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"]}
|