@itwin/tree-widget-react 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +19 -2
- package/lib/cjs/components/trees/VisibilityTreeBase.scss +27 -27
- package/lib/cjs/components/trees/VisibilityTreeEventHandler.js +7 -18
- package/lib/cjs/components/trees/VisibilityTreeEventHandler.js.map +1 -1
- package/lib/cjs/components/trees/common/TreeRenderer.scss +25 -15
- package/lib/cjs/e2e-tests/TreeWidget.test.js +15 -10
- package/lib/cjs/e2e-tests/TreeWidget.test.js.map +1 -1
- package/lib/cjs/e2e-tests/utils.d.ts +1 -0
- package/lib/cjs/e2e-tests/utils.js +12 -1
- package/lib/cjs/e2e-tests/utils.js.map +1 -1
- package/lib/esm/components/trees/VisibilityTreeBase.scss +27 -27
- package/lib/esm/components/trees/VisibilityTreeEventHandler.js +4 -15
- package/lib/esm/components/trees/VisibilityTreeEventHandler.js.map +1 -1
- package/lib/esm/components/trees/common/TreeRenderer.scss +25 -15
- package/lib/esm/e2e-tests/TreeWidget.test.js +16 -11
- package/lib/esm/e2e-tests/TreeWidget.test.js.map +1 -1
- package/lib/esm/e2e-tests/utils.d.ts +1 -0
- package/lib/esm/e2e-tests/utils.js +10 -0
- package/lib/esm/e2e-tests/utils.js.map +1 -1
- package/package.json +68 -61
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,24 @@
|
|
|
1
1
|
# Change Log - @itwin/tree-widget-react
|
|
2
2
|
|
|
3
|
-
This log was last generated on Tue,
|
|
3
|
+
This log was last generated on Tue, 30 Jan 2024 13:20:25 GMT and should not be manually modified.
|
|
4
|
+
|
|
5
|
+
<!-- Start content -->
|
|
6
|
+
|
|
7
|
+
## 1.2.2
|
|
8
|
+
|
|
9
|
+
Tue, 30 Jan 2024 13:20:25 GMT
|
|
10
|
+
|
|
11
|
+
### Patches
|
|
12
|
+
|
|
13
|
+
- Fixed `onCheckboxStateChanged` event handling when multiple `rxjs` versions are present. ([#750](https://github.com/iTwin/viewer-components-react/pull/750))
|
|
14
|
+
|
|
15
|
+
## 1.2.1
|
|
16
|
+
Fri, 01 Dec 2023 13:46:38 GMT
|
|
17
|
+
|
|
18
|
+
### Patches
|
|
19
|
+
|
|
20
|
+
- Fix padding for icons when elements are enlarged.
|
|
21
|
+
- Fix progress indicator sizing in `enlarged` layout
|
|
4
22
|
|
|
5
23
|
## 1.2.0
|
|
6
24
|
Tue, 19 Sep 2023 14:55:43 GMT
|
|
@@ -253,4 +271,3 @@ Wed, 12 Jan 2022 13:59:35 GMT
|
|
|
253
271
|
### Patches
|
|
254
272
|
|
|
255
273
|
- iTwin.js 3.0 first rc.
|
|
256
|
-
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
|
|
6
6
|
.tree-widget-visibility-tree-base {
|
|
7
7
|
.tree-widget-tree-nodes-list {
|
|
8
|
+
&.enlarge {
|
|
9
|
+
.without-expander {
|
|
10
|
+
.visibility-tree-checkbox-container + * {
|
|
11
|
+
margin-left: var(--enlarged-node-expander-additional-padding);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.visibility-tree-checkbox-container {
|
|
16
|
+
height: var(--enlarged-node-height);
|
|
17
|
+
width: var(--enlarged-node-height);
|
|
18
|
+
|
|
19
|
+
.visibility-tree-checkbox {
|
|
20
|
+
--iui-checkbox-target-size: var(--enlarged-node-height);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
.core-tree-node {
|
|
9
26
|
&.with-checkbox {
|
|
10
27
|
> .contents {
|
|
@@ -14,28 +31,13 @@
|
|
|
14
31
|
|
|
15
32
|
&.disable-expander {
|
|
16
33
|
> .contents {
|
|
34
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
17
35
|
> .core-tree-expansionToggle {
|
|
18
36
|
display: none;
|
|
19
37
|
}
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
&.is-selected {
|
|
24
|
-
> .contents {
|
|
25
|
-
> .visibility-tree-checkbox-container {
|
|
26
|
-
background-color: var(--iui-color-background-accent-muted);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
&:not(.is-selected) {
|
|
32
|
-
> .contents:hover {
|
|
33
|
-
> .visibility-tree-checkbox-container {
|
|
34
|
-
background-color: var(--iui-color-background-hover);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
41
|
.visibility-tree-checkbox-container {
|
|
40
42
|
height: var(--iui-size-l);
|
|
41
43
|
width: var(--iui-size-l);
|
|
@@ -58,23 +60,21 @@
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
}
|
|
62
63
|
|
|
63
|
-
&.enlarge {
|
|
64
|
-
.core-tree-node {
|
|
65
|
-
.visibility-tree-checkbox-container {
|
|
66
|
-
height: var(--enlarged-node-height);
|
|
67
|
-
width: var(--enlarged-node-height);
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
&.is-selected {
|
|
66
|
+
> .contents {
|
|
67
|
+
> .visibility-tree-checkbox-container {
|
|
68
|
+
background-color: var(--iui-color-background-accent-muted);
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
|
|
73
|
+
&:not(.is-selected) {
|
|
74
|
+
> .contents:hover {
|
|
75
|
+
> .visibility-tree-checkbox-container {
|
|
76
|
+
background-color: var(--iui-color-background-hover);
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -9,9 +9,6 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.VisibilityTreeEventHandler = void 0;
|
|
11
11
|
const rxjs_1 = require("rxjs");
|
|
12
|
-
const from_1 = require("rxjs/internal/observable/from");
|
|
13
|
-
const map_1 = require("rxjs/internal/operators/map");
|
|
14
|
-
const mergeMap_1 = require("rxjs/internal/operators/mergeMap");
|
|
15
12
|
const core_react_1 = require("@itwin/core-react");
|
|
16
13
|
const presentation_components_1 = require("@itwin/presentation-components");
|
|
17
14
|
const IsPromiseLike_1 = require("../utils/IsPromiseLike");
|
|
@@ -47,7 +44,7 @@ class VisibilityTreeEventHandler extends presentation_components_1.UnifiedSelect
|
|
|
47
44
|
return items.filter((item) => this._selectionPredicate(item));
|
|
48
45
|
}
|
|
49
46
|
onSelectionModified({ modifications }) {
|
|
50
|
-
const filteredModification = new rxjs_1.Observable((subscriber) => modifications.subscribe(subscriber)).pipe((0,
|
|
47
|
+
const filteredModification = new rxjs_1.Observable((subscriber) => modifications.subscribe(subscriber)).pipe((0, rxjs_1.map)(({ selectedNodeItems, deselectedNodeItems }) => {
|
|
51
48
|
return {
|
|
52
49
|
selectedNodeItems: this.filterSelectionItems(selectedNodeItems),
|
|
53
50
|
deselectedNodeItems: this.filterSelectionItems(deselectedNodeItems),
|
|
@@ -56,7 +53,7 @@ class VisibilityTreeEventHandler extends presentation_components_1.UnifiedSelect
|
|
|
56
53
|
return super.onSelectionModified({ modifications: filteredModification });
|
|
57
54
|
}
|
|
58
55
|
onSelectionReplaced({ replacements }) {
|
|
59
|
-
const filteredReplacements = new rxjs_1.Observable((subscriber) => replacements.subscribe(subscriber)).pipe((0,
|
|
56
|
+
const filteredReplacements = new rxjs_1.Observable((subscriber) => replacements.subscribe(subscriber)).pipe((0, rxjs_1.map)(({ selectedNodeItems }) => {
|
|
60
57
|
return {
|
|
61
58
|
selectedNodeItems: this.filterSelectionItems(selectedNodeItems),
|
|
62
59
|
};
|
|
@@ -68,12 +65,8 @@ class VisibilityTreeEventHandler extends presentation_components_1.UnifiedSelect
|
|
|
68
65
|
this._isChangingVisibility = false;
|
|
69
66
|
void this.updateCheckboxes();
|
|
70
67
|
};
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
.pipe(
|
|
74
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
75
|
-
(0, mergeMap_1.mergeMap)((changes) => this.changeVisibility(changes)))
|
|
76
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
68
|
+
new rxjs_1.Observable((subscriber) => event.stateChanges.subscribe(subscriber))
|
|
69
|
+
.pipe((0, rxjs_1.mergeMap)((changes) => this.changeVisibility(changes)))
|
|
77
70
|
.subscribe({
|
|
78
71
|
complete: handleStateChanged,
|
|
79
72
|
error: handleStateChanged,
|
|
@@ -81,14 +74,10 @@ class VisibilityTreeEventHandler extends presentation_components_1.UnifiedSelect
|
|
|
81
74
|
return undefined;
|
|
82
75
|
}
|
|
83
76
|
changeVisibility(changes) {
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
.pipe(
|
|
87
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
88
|
-
(0, mergeMap_1.mergeMap)(({ nodeItem, newState }) => {
|
|
77
|
+
return (0, rxjs_1.from)(changes)
|
|
78
|
+
.pipe((0, rxjs_1.mergeMap)(({ nodeItem, newState }) => {
|
|
89
79
|
this._isChangingVisibility = true;
|
|
90
|
-
|
|
91
|
-
return (0, from_1.from)(this._visibilityHandler.changeVisibility(nodeItem, newState === core_react_1.CheckBoxState.On));
|
|
80
|
+
return (0, rxjs_1.from)(this._visibilityHandler.changeVisibility(nodeItem, newState === core_react_1.CheckBoxState.On));
|
|
92
81
|
}, 1));
|
|
93
82
|
}
|
|
94
83
|
async updateCheckboxes(affectedNodes, visibilityStatus) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisibilityTreeEventHandler.js","sourceRoot":"","sources":["../../../../src/components/trees/VisibilityTreeEventHandler.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/** @packageDocumentation\n * @module IModelComponents\n */\n\nimport { Observable } from \"rxjs\";\nimport { from } from \"rxjs/internal/observable/from\";\nimport { map } from \"rxjs/internal/operators/map\";\nimport { mergeMap } from \"rxjs/internal/operators/mergeMap\";\nimport { CheckBoxState } from \"@itwin/core-react\";\nimport { UnifiedSelectionTreeEventHandler } from \"@itwin/presentation-components\";\nimport { isPromiseLike } from \"../utils/IsPromiseLike\";\n\nimport type {\n CheckBoxInfo, CheckboxStateChange, TreeCheckboxStateChangeEventArgs, TreeModelNode, TreeNodeItem, TreeSelectionChange,\n TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs,\n} from \"@itwin/components-react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { UnifiedSelectionTreeEventHandlerParams } from \"@itwin/presentation-components\";\n\n/**\n * Data structure that describes instance visibility status.\n * @public\n */\nexport interface VisibilityStatus {\n state: \"visible\" | \"partial\" | \"hidden\";\n isDisabled?: boolean;\n tooltip?: string;\n}\n\n/**\n * Type definition of visibility change event listener.\n * @public\n */\nexport type VisibilityChangeListener = (nodeIds?: string[], visibilityStatus?: Map<string, VisibilityStatus>) => void;\n\n/**\n * Visibility handler used to change or get visibility of instances represented by the tree node.\n * @public\n */\nexport interface IVisibilityHandler extends IDisposable {\n getVisibilityStatus(node: TreeNodeItem): VisibilityStatus | Promise<VisibilityStatus>;\n changeVisibility(node: TreeNodeItem, shouldDisplay: boolean): Promise<void>;\n onVisibilityChange: BeEvent<VisibilityChangeListener>;\n}\n\n/**\n * Type definition of predicate used to decide if node can be selected.\n * @public\n */\nexport type VisibilityTreeSelectionPredicate = (node: TreeNodeItem) => boolean;\n\n/**\n * Parameters for [[VisibilityTreeEventHandler]]\n * @public\n */\nexport interface VisibilityTreeEventHandlerParams extends UnifiedSelectionTreeEventHandlerParams {\n visibilityHandler: IVisibilityHandler;\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n}\n\n/**\n * Base event handler for visibility tree.\n * @public\n */\nexport class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler {\n private _visibilityHandler: IVisibilityHandler;\n private _selectionPredicate?: VisibilityTreeSelectionPredicate;\n private _listeners = new Array<() => void>();\n private _isChangingVisibility: boolean;\n\n constructor(params: VisibilityTreeEventHandlerParams) {\n super(params);\n this._visibilityHandler = params.visibilityHandler;\n this._selectionPredicate = params.selectionPredicate;\n this._isChangingVisibility = false;\n this._listeners.push(this._visibilityHandler.onVisibilityChange.addListener(async (nodeIds, visibilityStatus) => {\n if (this._isChangingVisibility)\n return;\n void this.updateCheckboxes(nodeIds, visibilityStatus);\n }));\n this._listeners.push(this.modelSource.onModelChanged.addListener(async ([_, changes]) => {\n void this.updateCheckboxes([...changes.addedNodeIds, ...changes.modifiedNodeIds]);\n }));\n this.updateCheckboxes(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }\n\n public override dispose() {\n super.dispose();\n this._listeners.forEach((disposeFunc) => disposeFunc());\n }\n\n private filterSelectionItems(items: TreeNodeItem[]) {\n // istanbul ignore if\n if (!this._selectionPredicate)\n return items;\n\n return items.filter((item) => this._selectionPredicate!(item));\n }\n\n public override onSelectionModified({ modifications }: TreeSelectionModificationEventArgs) {\n const filteredModification = new Observable<TreeSelectionChange>((subscriber) => modifications.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems, deselectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n deselectedNodeItems: this.filterSelectionItems(deselectedNodeItems),\n };\n }),\n );\n return super.onSelectionModified({ modifications: filteredModification });\n }\n\n public override onSelectionReplaced({ replacements }: TreeSelectionReplacementEventArgs) {\n const filteredReplacements = new Observable<{ selectedNodeItems: TreeNodeItem[] }>((subscriber) => replacements.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n };\n }),\n );\n return super.onSelectionReplaced({ replacements: filteredReplacements });\n }\n\n public override onCheckboxStateChanged(event: TreeCheckboxStateChangeEventArgs) {\n const handleStateChanged = () => {\n this._isChangingVisibility = false;\n void this.updateCheckboxes();\n };\n\n // eslint-disable-next-line deprecation/deprecation\n from(event.stateChanges)\n .pipe(\n // eslint-disable-next-line deprecation/deprecation\n mergeMap((changes) => this.changeVisibility(changes)),\n )\n // eslint-disable-next-line deprecation/deprecation\n .subscribe({\n complete: handleStateChanged,\n error: handleStateChanged,\n });\n return undefined;\n }\n\n private changeVisibility(changes: CheckboxStateChange[]) {\n // eslint-disable-next-line deprecation/deprecation\n return from(changes)\n .pipe(\n // eslint-disable-next-line deprecation/deprecation\n mergeMap(({ nodeItem, newState }) => {\n this._isChangingVisibility = true;\n // eslint-disable-next-line deprecation/deprecation\n return from(this._visibilityHandler.changeVisibility(nodeItem, newState === CheckBoxState.On));\n }, 1),\n );\n }\n\n private async updateCheckboxes(affectedNodes?: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const changes = await (affectedNodes ? this.collectAffectedNodesCheckboxInfos(affectedNodes, visibilityStatus) : this.collectAllNodesCheckboxInfos(visibilityStatus));\n this.updateModel(changes);\n }\n\n private updateModel(changes: Map<string, CheckBoxInfo>) {\n this.modelSource.modifyModel((model) => {\n for (const [nodeId, checkboxInfo] of changes) {\n const node = model.getNode(nodeId);\n // istanbul ignore if\n if (!node)\n continue;\n\n node.checkbox.isDisabled = checkboxInfo.isDisabled;\n node.checkbox.isVisible = checkboxInfo.isVisible;\n node.checkbox.state = checkboxInfo.state;\n node.checkbox.tooltip = checkboxInfo.tooltip;\n }\n });\n }\n\n private async collectAffectedNodesCheckboxInfos(affectedNodes: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n if (affectedNodes.length === 0)\n return nodeStates;\n\n await Promise.all(affectedNodes.map(async (nodeId) => {\n const node = this.modelSource.getModel().getNode(nodeId);\n // istanbul ignore else\n if (node)\n nodeStates.set(nodeId, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }));\n return nodeStates;\n }\n\n private async collectAllNodesCheckboxInfos(visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n for (const node of this.modelSource.getModel().iterateTreeModelNodes()) {\n nodeStates.set(node.id, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }\n return nodeStates;\n }\n\n private async getNodeCheckBoxInfo(node: TreeModelNode, visibilityStatus?: Map<string, VisibilityStatus>): Promise<CheckBoxInfo> {\n const result = visibilityStatus?.get(node.id) ?? this._visibilityHandler.getVisibilityStatus(node.item);\n\n if (isPromiseLike(result))\n return this.createCheckboxInfo(await result);\n return this.createCheckboxInfo(result);\n }\n\n private createCheckboxInfo(status: VisibilityStatus): CheckBoxInfo {\n return {\n state: visibilityStateToCheckboxState(status),\n isDisabled: status.isDisabled || false,\n isVisible: true,\n tooltip: status.tooltip,\n };\n }\n}\n\nconst visibilityStateToCheckboxState = (status: VisibilityStatus) => {\n switch (status.state) {\n case \"visible\":\n return CheckBoxState.On;\n // istanbul ignore next\n case \"partial\":\n return CheckBoxState.Partial;\n case \"hidden\":\n default:\n return CheckBoxState.Off;\n }\n};\n"]}
|
|
1
|
+
{"version":3,"file":"VisibilityTreeEventHandler.js","sourceRoot":"","sources":["../../../../src/components/trees/VisibilityTreeEventHandler.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/** @packageDocumentation\n * @module IModelComponents\n */\n\nimport { from, map, mergeMap, Observable } from \"rxjs\";\nimport { CheckBoxState } from \"@itwin/core-react\";\nimport { UnifiedSelectionTreeEventHandler } from \"@itwin/presentation-components\";\nimport { isPromiseLike } from \"../utils/IsPromiseLike\";\n\nimport type {\n CheckBoxInfo, CheckboxStateChange, TreeCheckboxStateChangeEventArgs, TreeModelNode, TreeNodeItem, TreeSelectionChange,\n TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs,\n} from \"@itwin/components-react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { UnifiedSelectionTreeEventHandlerParams } from \"@itwin/presentation-components\";\n\n/**\n * Data structure that describes instance visibility status.\n * @public\n */\nexport interface VisibilityStatus {\n state: \"visible\" | \"partial\" | \"hidden\";\n isDisabled?: boolean;\n tooltip?: string;\n}\n\n/**\n * Type definition of visibility change event listener.\n * @public\n */\nexport type VisibilityChangeListener = (nodeIds?: string[], visibilityStatus?: Map<string, VisibilityStatus>) => void;\n\n/**\n * Visibility handler used to change or get visibility of instances represented by the tree node.\n * @public\n */\nexport interface IVisibilityHandler extends IDisposable {\n getVisibilityStatus(node: TreeNodeItem): VisibilityStatus | Promise<VisibilityStatus>;\n changeVisibility(node: TreeNodeItem, shouldDisplay: boolean): Promise<void>;\n onVisibilityChange: BeEvent<VisibilityChangeListener>;\n}\n\n/**\n * Type definition of predicate used to decide if node can be selected.\n * @public\n */\nexport type VisibilityTreeSelectionPredicate = (node: TreeNodeItem) => boolean;\n\n/**\n * Parameters for [[VisibilityTreeEventHandler]]\n * @public\n */\nexport interface VisibilityTreeEventHandlerParams extends UnifiedSelectionTreeEventHandlerParams {\n visibilityHandler: IVisibilityHandler;\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n}\n\n/**\n * Base event handler for visibility tree.\n * @public\n */\nexport class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler {\n private _visibilityHandler: IVisibilityHandler;\n private _selectionPredicate?: VisibilityTreeSelectionPredicate;\n private _listeners = new Array<() => void>();\n private _isChangingVisibility: boolean;\n\n constructor(params: VisibilityTreeEventHandlerParams) {\n super(params);\n this._visibilityHandler = params.visibilityHandler;\n this._selectionPredicate = params.selectionPredicate;\n this._isChangingVisibility = false;\n this._listeners.push(this._visibilityHandler.onVisibilityChange.addListener(async (nodeIds, visibilityStatus) => {\n if (this._isChangingVisibility)\n return;\n void this.updateCheckboxes(nodeIds, visibilityStatus);\n }));\n this._listeners.push(this.modelSource.onModelChanged.addListener(async ([_, changes]) => {\n void this.updateCheckboxes([...changes.addedNodeIds, ...changes.modifiedNodeIds]);\n }));\n this.updateCheckboxes(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }\n\n public override dispose() {\n super.dispose();\n this._listeners.forEach((disposeFunc) => disposeFunc());\n }\n\n private filterSelectionItems(items: TreeNodeItem[]) {\n // istanbul ignore if\n if (!this._selectionPredicate)\n return items;\n\n return items.filter((item) => this._selectionPredicate!(item));\n }\n\n public override onSelectionModified({ modifications }: TreeSelectionModificationEventArgs) {\n const filteredModification = new Observable<TreeSelectionChange>((subscriber) => modifications.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems, deselectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n deselectedNodeItems: this.filterSelectionItems(deselectedNodeItems),\n };\n }),\n );\n return super.onSelectionModified({ modifications: filteredModification });\n }\n\n public override onSelectionReplaced({ replacements }: TreeSelectionReplacementEventArgs) {\n const filteredReplacements = new Observable<{ selectedNodeItems: TreeNodeItem[] }>((subscriber) => replacements.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n };\n }),\n );\n return super.onSelectionReplaced({ replacements: filteredReplacements });\n }\n\n public override onCheckboxStateChanged(event: TreeCheckboxStateChangeEventArgs) {\n const handleStateChanged = () => {\n this._isChangingVisibility = false;\n void this.updateCheckboxes();\n };\n\n new Observable<CheckboxStateChange[]>((subscriber) => event.stateChanges.subscribe(subscriber))\n .pipe(\n mergeMap((changes) => this.changeVisibility(changes)),\n )\n .subscribe({\n complete: handleStateChanged,\n error: handleStateChanged,\n });\n return undefined;\n }\n\n private changeVisibility(changes: CheckboxStateChange[]) {\n return from(changes)\n .pipe(\n mergeMap(({ nodeItem, newState }) => {\n this._isChangingVisibility = true;\n return from(this._visibilityHandler.changeVisibility(nodeItem, newState === CheckBoxState.On));\n }, 1),\n );\n }\n\n private async updateCheckboxes(affectedNodes?: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const changes = await (affectedNodes ? this.collectAffectedNodesCheckboxInfos(affectedNodes, visibilityStatus) : this.collectAllNodesCheckboxInfos(visibilityStatus));\n this.updateModel(changes);\n }\n\n private updateModel(changes: Map<string, CheckBoxInfo>) {\n this.modelSource.modifyModel((model) => {\n for (const [nodeId, checkboxInfo] of changes) {\n const node = model.getNode(nodeId);\n // istanbul ignore if\n if (!node)\n continue;\n\n node.checkbox.isDisabled = checkboxInfo.isDisabled;\n node.checkbox.isVisible = checkboxInfo.isVisible;\n node.checkbox.state = checkboxInfo.state;\n node.checkbox.tooltip = checkboxInfo.tooltip;\n }\n });\n }\n\n private async collectAffectedNodesCheckboxInfos(affectedNodes: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n if (affectedNodes.length === 0)\n return nodeStates;\n\n await Promise.all(affectedNodes.map(async (nodeId) => {\n const node = this.modelSource.getModel().getNode(nodeId);\n // istanbul ignore else\n if (node)\n nodeStates.set(nodeId, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }));\n return nodeStates;\n }\n\n private async collectAllNodesCheckboxInfos(visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n for (const node of this.modelSource.getModel().iterateTreeModelNodes()) {\n nodeStates.set(node.id, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }\n return nodeStates;\n }\n\n private async getNodeCheckBoxInfo(node: TreeModelNode, visibilityStatus?: Map<string, VisibilityStatus>): Promise<CheckBoxInfo> {\n const result = visibilityStatus?.get(node.id) ?? this._visibilityHandler.getVisibilityStatus(node.item);\n\n if (isPromiseLike(result))\n return this.createCheckboxInfo(await result);\n return this.createCheckboxInfo(result);\n }\n\n private createCheckboxInfo(status: VisibilityStatus): CheckBoxInfo {\n return {\n state: visibilityStateToCheckboxState(status),\n isDisabled: status.isDisabled || false,\n isVisible: true,\n tooltip: status.tooltip,\n };\n }\n}\n\nconst visibilityStateToCheckboxState = (status: VisibilityStatus) => {\n switch (status.state) {\n case \"visible\":\n return CheckBoxState.On;\n // istanbul ignore next\n case \"partial\":\n return CheckBoxState.Partial;\n case \"hidden\":\n default:\n return CheckBoxState.Off;\n }\n};\n"]}
|
|
@@ -20,31 +20,37 @@
|
|
|
20
20
|
height: 100%;
|
|
21
21
|
width: 100%;
|
|
22
22
|
|
|
23
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
23
24
|
.ReactWindow__VariableSizeList {
|
|
24
|
-
>div {
|
|
25
|
+
> div {
|
|
25
26
|
min-width: max-content !important; // to override inline class
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
.core-tree-node {
|
|
31
|
+
&.without-expander {
|
|
32
|
+
>.contents {
|
|
33
|
+
>.core-tree-node-icon {
|
|
34
|
+
margin-left: 5px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
&.enlarge {
|
|
30
41
|
--enlarged-node-height: calc(var(--iui-size-l) + var(--iui-size-m) + var(--iui-size-3xs));
|
|
31
42
|
--enlarged-node-icon-size: var(--iui-size-m);
|
|
32
43
|
--enlarged-node-icon-padding: calc(var(--enlarged-node-height) - var(--enlarged-node-icon-size));
|
|
33
|
-
--enlarged-node-expander-additional-padding: calc(var(--iui-size-
|
|
44
|
+
--enlarged-node-expander-additional-padding: calc(var(--iui-size-l) - var(--iui-size-3xs) / 2);
|
|
34
45
|
|
|
35
46
|
.core-tree-node {
|
|
36
|
-
|
|
37
|
-
>.contents {
|
|
38
|
-
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
>.contents {
|
|
47
|
+
> .contents {
|
|
43
48
|
height: var(--enlarged-node-height);
|
|
44
49
|
font-size: var(--iui-font-size-2);
|
|
45
50
|
|
|
51
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
46
52
|
.core-tree-expansionToggle {
|
|
47
|
-
|
|
53
|
+
> .icon {
|
|
48
54
|
height: var(--enlarged-node-height);
|
|
49
55
|
width: var(--enlarged-node-height);
|
|
50
56
|
padding: calc(var(--enlarged-node-icon-padding) / 2);
|
|
@@ -56,11 +62,14 @@
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
&.without-expander {
|
|
66
|
+
> .contents {
|
|
67
|
+
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
.iui-progress-indicator-radial {
|
|
60
|
-
|
|
61
|
-
width: var(--enlarged-node-height);
|
|
62
|
-
padding: calc(var(--enlarged-node-icon-padding) / 2 - 1px); // need to reduce padding by `1px` to make sure icon is centered
|
|
63
|
-
margin: 0;
|
|
72
|
+
margin: 0 calc(var(--enlarged-node-icon-padding) / 2);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -74,6 +83,7 @@
|
|
|
74
83
|
flex-direction: column;
|
|
75
84
|
position: relative;
|
|
76
85
|
|
|
86
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
77
87
|
.filteredTreeOverlay {
|
|
78
88
|
position: absolute;
|
|
79
89
|
top: 0;
|
|
@@ -99,4 +109,4 @@
|
|
|
99
109
|
font-weight: bold;
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
}
|
|
112
|
+
}
|
|
@@ -1,46 +1,51 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
8
|
};
|
|
5
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const test_1 = require("@playwright/test");
|
|
7
10
|
const assert_1 = __importDefault(require("assert"));
|
|
11
|
+
const test_1 = require("@playwright/test");
|
|
8
12
|
const utils_1 = require("./utils");
|
|
9
13
|
let treeWidget;
|
|
10
14
|
test_1.test.beforeEach(async ({ page, baseURL }) => {
|
|
11
15
|
(0, assert_1.default)(baseURL);
|
|
12
|
-
await page.goto(baseURL);
|
|
16
|
+
await page.goto(baseURL, { waitUntil: "networkidle" });
|
|
17
|
+
await page.evaluate(async () => document.fonts.ready);
|
|
13
18
|
// expand panel size to ~300px
|
|
14
19
|
await (0, utils_1.expandStagePanel)(page, "right", 100);
|
|
15
20
|
treeWidget = (0, utils_1.locateWidget)(page, "tree");
|
|
16
21
|
await treeWidget.waitFor();
|
|
17
22
|
});
|
|
18
23
|
test_1.test.describe("should match image snapshot", () => {
|
|
19
|
-
(0, test_1.test)("initial tree", async () => {
|
|
24
|
+
(0, test_1.test)("initial tree", async ({ page }) => {
|
|
20
25
|
// wait for element to be visible in the tree
|
|
21
26
|
await (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
|
|
22
|
-
await (0,
|
|
27
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
23
28
|
});
|
|
24
|
-
(0, test_1.test)("expanded tree node", async () => {
|
|
29
|
+
(0, test_1.test)("expanded tree node", async ({ page }) => {
|
|
25
30
|
const node = (0, utils_1.locateNode)(treeWidget, "ProcessPhysicalModel");
|
|
26
31
|
await node.getByTestId("tree-node-expansion-toggle").click();
|
|
27
32
|
// wait for node at the bottom to be visible/loaded
|
|
28
33
|
await (0, utils_1.locateNode)(treeWidget, "Tag-Category").waitFor();
|
|
29
|
-
await (0,
|
|
34
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
30
35
|
});
|
|
31
|
-
(0, test_1.test)("selected node", async () => {
|
|
36
|
+
(0, test_1.test)("selected node", async ({ page }) => {
|
|
32
37
|
const node = (0, utils_1.locateNode)(treeWidget, "BayTown");
|
|
33
38
|
await node.click();
|
|
34
39
|
// wait for node to become selected
|
|
35
40
|
await (0, test_1.expect)(node).toHaveClass(/is-selected/);
|
|
36
|
-
await (0,
|
|
41
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
37
42
|
});
|
|
38
|
-
(0, test_1.test)("search", async () => {
|
|
43
|
+
(0, test_1.test)("search", async ({ page }) => {
|
|
39
44
|
await treeWidget.getByText("BayTown").waitFor();
|
|
40
45
|
await treeWidget.getByTitle("Search for something").click();
|
|
41
46
|
await treeWidget.getByPlaceholder("Search...").fill("Model");
|
|
42
47
|
await treeWidget.locator(".components-activehighlight").waitFor();
|
|
43
|
-
await (0,
|
|
48
|
+
await (0, utils_1.takeScreenshot)(page, treeWidget);
|
|
44
49
|
});
|
|
45
50
|
});
|
|
46
51
|
//# sourceMappingURL=TreeWidget.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;AAGhG,oDAA4B;AAC5B,2CAAgD;AAChD,mCAAqF;AAErF,IAAI,UAAmB,CAAC;AACxB,WAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1C,IAAA,gBAAM,EAAC,OAAO,CAAC,CAAC;IAChB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IACvD,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtD,8BAA8B;IAC9B,MAAM,IAAA,wBAAgB,EAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,UAAU,GAAG,IAAA,oBAAY,EAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,WAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAEhD,IAAA,WAAI,EAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtC,6CAA6C;QAC7C,MAAM,IAAA,kBAAU,EAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACvH,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;QAE7D,mDAAmD;QACnD,MAAM,IAAA,kBAAU,EAAC,UAAU,EAAE,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,eAAe,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,IAAA,kBAAU,EAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,mCAAmC;QACnC,MAAM,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAI,EAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAChC,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,UAAU,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,UAAU,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,IAAA,sBAAc,EAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { Locator } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL, { waitUntil: \"networkidle\" });\n await page.evaluate(async () => document.fonts.ready);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n});\n"]}
|
|
@@ -4,5 +4,6 @@ export declare const locateWidget: (page: Page | Locator, widgetName: string) =>
|
|
|
4
4
|
type PanelSide = "left" | "right" | "top" | "bottom";
|
|
5
5
|
export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
|
|
6
6
|
export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
|
|
7
|
+
export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/*---------------------------------------------------------------------------------------------
|
|
3
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
4
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
5
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
6
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
7
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
8
|
};
|
|
5
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.expandStagePanel = exports.locatePanel = exports.locateWidget = exports.locateNode = void 0;
|
|
10
|
+
exports.takeScreenshot = exports.expandStagePanel = exports.locatePanel = exports.locateWidget = exports.locateNode = void 0;
|
|
7
11
|
const assert_1 = __importDefault(require("assert"));
|
|
12
|
+
const test_1 = require("@playwright/test");
|
|
8
13
|
const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
|
|
9
14
|
exports.locateNode = locateNode;
|
|
10
15
|
const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
|
|
@@ -37,4 +42,10 @@ const expandStagePanel = async (page, side, px) => {
|
|
|
37
42
|
await page.mouse.up();
|
|
38
43
|
};
|
|
39
44
|
exports.expandStagePanel = expandStagePanel;
|
|
45
|
+
async function takeScreenshot(page, component) {
|
|
46
|
+
const boundingBox = await component.boundingBox();
|
|
47
|
+
(0, assert_1.default)(boundingBox);
|
|
48
|
+
await (0, test_1.expect)(page).toHaveScreenshot({ clip: boundingBox });
|
|
49
|
+
}
|
|
50
|
+
exports.takeScreenshot = takeScreenshot;
|
|
40
51
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":";AAAA;;;gGAGgG;;;;;;AAEhG,oDAA4B;AAC5B,2CAA0C;AAInC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AAA1F,QAAA,UAAU,cAAgF;AAChG,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAAnG,QAAA,YAAY,gBAAuF;AAGzG,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAAjG,QAAA,WAAW,eAAsF;AAEvG,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,IAAA,mBAAW,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW;SAChC,OAAO,CAAC,oBAAoB,CAAC;SAC7B,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,EAAE,CAAC;IACjB,IAAA,gBAAM,EAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AA1BW,QAAA,gBAAgB,oBA0B3B;AAEK,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,IAAA,gBAAM,EAAC,WAAW,CAAC,CAAC;IACpB,MAAM,IAAA,aAAM,EAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC;AAJD,wCAIC","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 assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel\n .locator(\".nz-grip-container\")\n .locator(\".nz-handle\")\n .boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}
|
|
@@ -5,6 +5,23 @@
|
|
|
5
5
|
|
|
6
6
|
.tree-widget-visibility-tree-base {
|
|
7
7
|
.tree-widget-tree-nodes-list {
|
|
8
|
+
&.enlarge {
|
|
9
|
+
.without-expander {
|
|
10
|
+
.visibility-tree-checkbox-container + * {
|
|
11
|
+
margin-left: var(--enlarged-node-expander-additional-padding);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.visibility-tree-checkbox-container {
|
|
16
|
+
height: var(--enlarged-node-height);
|
|
17
|
+
width: var(--enlarged-node-height);
|
|
18
|
+
|
|
19
|
+
.visibility-tree-checkbox {
|
|
20
|
+
--iui-checkbox-target-size: var(--enlarged-node-height);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
8
25
|
.core-tree-node {
|
|
9
26
|
&.with-checkbox {
|
|
10
27
|
> .contents {
|
|
@@ -14,28 +31,13 @@
|
|
|
14
31
|
|
|
15
32
|
&.disable-expander {
|
|
16
33
|
> .contents {
|
|
34
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
17
35
|
> .core-tree-expansionToggle {
|
|
18
36
|
display: none;
|
|
19
37
|
}
|
|
20
38
|
}
|
|
21
39
|
}
|
|
22
40
|
|
|
23
|
-
&.is-selected {
|
|
24
|
-
> .contents {
|
|
25
|
-
> .visibility-tree-checkbox-container {
|
|
26
|
-
background-color: var(--iui-color-background-accent-muted);
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
&:not(.is-selected) {
|
|
32
|
-
> .contents:hover {
|
|
33
|
-
> .visibility-tree-checkbox-container {
|
|
34
|
-
background-color: var(--iui-color-background-hover);
|
|
35
|
-
}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
41
|
.visibility-tree-checkbox-container {
|
|
40
42
|
height: var(--iui-size-l);
|
|
41
43
|
width: var(--iui-size-l);
|
|
@@ -58,23 +60,21 @@
|
|
|
58
60
|
}
|
|
59
61
|
}
|
|
60
62
|
}
|
|
61
|
-
}
|
|
62
63
|
|
|
63
|
-
&.enlarge {
|
|
64
|
-
.core-tree-node {
|
|
65
|
-
.visibility-tree-checkbox-container {
|
|
66
|
-
height: var(--enlarged-node-height);
|
|
67
|
-
width: var(--enlarged-node-height);
|
|
68
64
|
|
|
69
|
-
|
|
70
|
-
|
|
65
|
+
&.is-selected {
|
|
66
|
+
> .contents {
|
|
67
|
+
> .visibility-tree-checkbox-container {
|
|
68
|
+
background-color: var(--iui-color-background-accent-muted);
|
|
71
69
|
}
|
|
72
70
|
}
|
|
73
71
|
}
|
|
74
72
|
|
|
75
|
-
.
|
|
76
|
-
.
|
|
77
|
-
|
|
73
|
+
&:not(.is-selected) {
|
|
74
|
+
> .contents:hover {
|
|
75
|
+
> .visibility-tree-checkbox-container {
|
|
76
|
+
background-color: var(--iui-color-background-hover);
|
|
77
|
+
}
|
|
78
78
|
}
|
|
79
79
|
}
|
|
80
80
|
}
|
|
@@ -5,10 +5,7 @@
|
|
|
5
5
|
/** @packageDocumentation
|
|
6
6
|
* @module IModelComponents
|
|
7
7
|
*/
|
|
8
|
-
import { Observable } from "rxjs";
|
|
9
|
-
import { from } from "rxjs/internal/observable/from";
|
|
10
|
-
import { map } from "rxjs/internal/operators/map";
|
|
11
|
-
import { mergeMap } from "rxjs/internal/operators/mergeMap";
|
|
8
|
+
import { from, map, mergeMap, Observable } from "rxjs";
|
|
12
9
|
import { CheckBoxState } from "@itwin/core-react";
|
|
13
10
|
import { UnifiedSelectionTreeEventHandler } from "@itwin/presentation-components";
|
|
14
11
|
import { isPromiseLike } from "../utils/IsPromiseLike";
|
|
@@ -65,12 +62,8 @@ export class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler
|
|
|
65
62
|
this._isChangingVisibility = false;
|
|
66
63
|
void this.updateCheckboxes();
|
|
67
64
|
};
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.pipe(
|
|
71
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
72
|
-
mergeMap((changes) => this.changeVisibility(changes)))
|
|
73
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
65
|
+
new Observable((subscriber) => event.stateChanges.subscribe(subscriber))
|
|
66
|
+
.pipe(mergeMap((changes) => this.changeVisibility(changes)))
|
|
74
67
|
.subscribe({
|
|
75
68
|
complete: handleStateChanged,
|
|
76
69
|
error: handleStateChanged,
|
|
@@ -78,13 +71,9 @@ export class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler
|
|
|
78
71
|
return undefined;
|
|
79
72
|
}
|
|
80
73
|
changeVisibility(changes) {
|
|
81
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
82
74
|
return from(changes)
|
|
83
|
-
.pipe(
|
|
84
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
85
|
-
mergeMap(({ nodeItem, newState }) => {
|
|
75
|
+
.pipe(mergeMap(({ nodeItem, newState }) => {
|
|
86
76
|
this._isChangingVisibility = true;
|
|
87
|
-
// eslint-disable-next-line deprecation/deprecation
|
|
88
77
|
return from(this._visibilityHandler.changeVisibility(nodeItem, newState === CheckBoxState.On));
|
|
89
78
|
}, 1));
|
|
90
79
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisibilityTreeEventHandler.js","sourceRoot":"","sources":["../../../../src/components/trees/VisibilityTreeEventHandler.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/** @packageDocumentation\n * @module IModelComponents\n */\n\nimport { Observable } from \"rxjs\";\nimport { from } from \"rxjs/internal/observable/from\";\nimport { map } from \"rxjs/internal/operators/map\";\nimport { mergeMap } from \"rxjs/internal/operators/mergeMap\";\nimport { CheckBoxState } from \"@itwin/core-react\";\nimport { UnifiedSelectionTreeEventHandler } from \"@itwin/presentation-components\";\nimport { isPromiseLike } from \"../utils/IsPromiseLike\";\n\nimport type {\n CheckBoxInfo, CheckboxStateChange, TreeCheckboxStateChangeEventArgs, TreeModelNode, TreeNodeItem, TreeSelectionChange,\n TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs,\n} from \"@itwin/components-react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { UnifiedSelectionTreeEventHandlerParams } from \"@itwin/presentation-components\";\n\n/**\n * Data structure that describes instance visibility status.\n * @public\n */\nexport interface VisibilityStatus {\n state: \"visible\" | \"partial\" | \"hidden\";\n isDisabled?: boolean;\n tooltip?: string;\n}\n\n/**\n * Type definition of visibility change event listener.\n * @public\n */\nexport type VisibilityChangeListener = (nodeIds?: string[], visibilityStatus?: Map<string, VisibilityStatus>) => void;\n\n/**\n * Visibility handler used to change or get visibility of instances represented by the tree node.\n * @public\n */\nexport interface IVisibilityHandler extends IDisposable {\n getVisibilityStatus(node: TreeNodeItem): VisibilityStatus | Promise<VisibilityStatus>;\n changeVisibility(node: TreeNodeItem, shouldDisplay: boolean): Promise<void>;\n onVisibilityChange: BeEvent<VisibilityChangeListener>;\n}\n\n/**\n * Type definition of predicate used to decide if node can be selected.\n * @public\n */\nexport type VisibilityTreeSelectionPredicate = (node: TreeNodeItem) => boolean;\n\n/**\n * Parameters for [[VisibilityTreeEventHandler]]\n * @public\n */\nexport interface VisibilityTreeEventHandlerParams extends UnifiedSelectionTreeEventHandlerParams {\n visibilityHandler: IVisibilityHandler;\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n}\n\n/**\n * Base event handler for visibility tree.\n * @public\n */\nexport class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler {\n private _visibilityHandler: IVisibilityHandler;\n private _selectionPredicate?: VisibilityTreeSelectionPredicate;\n private _listeners = new Array<() => void>();\n private _isChangingVisibility: boolean;\n\n constructor(params: VisibilityTreeEventHandlerParams) {\n super(params);\n this._visibilityHandler = params.visibilityHandler;\n this._selectionPredicate = params.selectionPredicate;\n this._isChangingVisibility = false;\n this._listeners.push(this._visibilityHandler.onVisibilityChange.addListener(async (nodeIds, visibilityStatus) => {\n if (this._isChangingVisibility)\n return;\n void this.updateCheckboxes(nodeIds, visibilityStatus);\n }));\n this._listeners.push(this.modelSource.onModelChanged.addListener(async ([_, changes]) => {\n void this.updateCheckboxes([...changes.addedNodeIds, ...changes.modifiedNodeIds]);\n }));\n this.updateCheckboxes(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }\n\n public override dispose() {\n super.dispose();\n this._listeners.forEach((disposeFunc) => disposeFunc());\n }\n\n private filterSelectionItems(items: TreeNodeItem[]) {\n // istanbul ignore if\n if (!this._selectionPredicate)\n return items;\n\n return items.filter((item) => this._selectionPredicate!(item));\n }\n\n public override onSelectionModified({ modifications }: TreeSelectionModificationEventArgs) {\n const filteredModification = new Observable<TreeSelectionChange>((subscriber) => modifications.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems, deselectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n deselectedNodeItems: this.filterSelectionItems(deselectedNodeItems),\n };\n }),\n );\n return super.onSelectionModified({ modifications: filteredModification });\n }\n\n public override onSelectionReplaced({ replacements }: TreeSelectionReplacementEventArgs) {\n const filteredReplacements = new Observable<{ selectedNodeItems: TreeNodeItem[] }>((subscriber) => replacements.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n };\n }),\n );\n return super.onSelectionReplaced({ replacements: filteredReplacements });\n }\n\n public override onCheckboxStateChanged(event: TreeCheckboxStateChangeEventArgs) {\n const handleStateChanged = () => {\n this._isChangingVisibility = false;\n void this.updateCheckboxes();\n };\n\n // eslint-disable-next-line deprecation/deprecation\n from(event.stateChanges)\n .pipe(\n // eslint-disable-next-line deprecation/deprecation\n mergeMap((changes) => this.changeVisibility(changes)),\n )\n // eslint-disable-next-line deprecation/deprecation\n .subscribe({\n complete: handleStateChanged,\n error: handleStateChanged,\n });\n return undefined;\n }\n\n private changeVisibility(changes: CheckboxStateChange[]) {\n // eslint-disable-next-line deprecation/deprecation\n return from(changes)\n .pipe(\n // eslint-disable-next-line deprecation/deprecation\n mergeMap(({ nodeItem, newState }) => {\n this._isChangingVisibility = true;\n // eslint-disable-next-line deprecation/deprecation\n return from(this._visibilityHandler.changeVisibility(nodeItem, newState === CheckBoxState.On));\n }, 1),\n );\n }\n\n private async updateCheckboxes(affectedNodes?: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const changes = await (affectedNodes ? this.collectAffectedNodesCheckboxInfos(affectedNodes, visibilityStatus) : this.collectAllNodesCheckboxInfos(visibilityStatus));\n this.updateModel(changes);\n }\n\n private updateModel(changes: Map<string, CheckBoxInfo>) {\n this.modelSource.modifyModel((model) => {\n for (const [nodeId, checkboxInfo] of changes) {\n const node = model.getNode(nodeId);\n // istanbul ignore if\n if (!node)\n continue;\n\n node.checkbox.isDisabled = checkboxInfo.isDisabled;\n node.checkbox.isVisible = checkboxInfo.isVisible;\n node.checkbox.state = checkboxInfo.state;\n node.checkbox.tooltip = checkboxInfo.tooltip;\n }\n });\n }\n\n private async collectAffectedNodesCheckboxInfos(affectedNodes: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n if (affectedNodes.length === 0)\n return nodeStates;\n\n await Promise.all(affectedNodes.map(async (nodeId) => {\n const node = this.modelSource.getModel().getNode(nodeId);\n // istanbul ignore else\n if (node)\n nodeStates.set(nodeId, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }));\n return nodeStates;\n }\n\n private async collectAllNodesCheckboxInfos(visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n for (const node of this.modelSource.getModel().iterateTreeModelNodes()) {\n nodeStates.set(node.id, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }\n return nodeStates;\n }\n\n private async getNodeCheckBoxInfo(node: TreeModelNode, visibilityStatus?: Map<string, VisibilityStatus>): Promise<CheckBoxInfo> {\n const result = visibilityStatus?.get(node.id) ?? this._visibilityHandler.getVisibilityStatus(node.item);\n\n if (isPromiseLike(result))\n return this.createCheckboxInfo(await result);\n return this.createCheckboxInfo(result);\n }\n\n private createCheckboxInfo(status: VisibilityStatus): CheckBoxInfo {\n return {\n state: visibilityStateToCheckboxState(status),\n isDisabled: status.isDisabled || false,\n isVisible: true,\n tooltip: status.tooltip,\n };\n }\n}\n\nconst visibilityStateToCheckboxState = (status: VisibilityStatus) => {\n switch (status.state) {\n case \"visible\":\n return CheckBoxState.On;\n // istanbul ignore next\n case \"partial\":\n return CheckBoxState.Partial;\n case \"hidden\":\n default:\n return CheckBoxState.Off;\n }\n};\n"]}
|
|
1
|
+
{"version":3,"file":"VisibilityTreeEventHandler.js","sourceRoot":"","sources":["../../../../src/components/trees/VisibilityTreeEventHandler.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/** @packageDocumentation\n * @module IModelComponents\n */\n\nimport { from, map, mergeMap, Observable } from \"rxjs\";\nimport { CheckBoxState } from \"@itwin/core-react\";\nimport { UnifiedSelectionTreeEventHandler } from \"@itwin/presentation-components\";\nimport { isPromiseLike } from \"../utils/IsPromiseLike\";\n\nimport type {\n CheckBoxInfo, CheckboxStateChange, TreeCheckboxStateChangeEventArgs, TreeModelNode, TreeNodeItem, TreeSelectionChange,\n TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs,\n} from \"@itwin/components-react\";\nimport type { BeEvent, IDisposable } from \"@itwin/core-bentley\";\nimport type { UnifiedSelectionTreeEventHandlerParams } from \"@itwin/presentation-components\";\n\n/**\n * Data structure that describes instance visibility status.\n * @public\n */\nexport interface VisibilityStatus {\n state: \"visible\" | \"partial\" | \"hidden\";\n isDisabled?: boolean;\n tooltip?: string;\n}\n\n/**\n * Type definition of visibility change event listener.\n * @public\n */\nexport type VisibilityChangeListener = (nodeIds?: string[], visibilityStatus?: Map<string, VisibilityStatus>) => void;\n\n/**\n * Visibility handler used to change or get visibility of instances represented by the tree node.\n * @public\n */\nexport interface IVisibilityHandler extends IDisposable {\n getVisibilityStatus(node: TreeNodeItem): VisibilityStatus | Promise<VisibilityStatus>;\n changeVisibility(node: TreeNodeItem, shouldDisplay: boolean): Promise<void>;\n onVisibilityChange: BeEvent<VisibilityChangeListener>;\n}\n\n/**\n * Type definition of predicate used to decide if node can be selected.\n * @public\n */\nexport type VisibilityTreeSelectionPredicate = (node: TreeNodeItem) => boolean;\n\n/**\n * Parameters for [[VisibilityTreeEventHandler]]\n * @public\n */\nexport interface VisibilityTreeEventHandlerParams extends UnifiedSelectionTreeEventHandlerParams {\n visibilityHandler: IVisibilityHandler;\n selectionPredicate?: VisibilityTreeSelectionPredicate;\n}\n\n/**\n * Base event handler for visibility tree.\n * @public\n */\nexport class VisibilityTreeEventHandler extends UnifiedSelectionTreeEventHandler {\n private _visibilityHandler: IVisibilityHandler;\n private _selectionPredicate?: VisibilityTreeSelectionPredicate;\n private _listeners = new Array<() => void>();\n private _isChangingVisibility: boolean;\n\n constructor(params: VisibilityTreeEventHandlerParams) {\n super(params);\n this._visibilityHandler = params.visibilityHandler;\n this._selectionPredicate = params.selectionPredicate;\n this._isChangingVisibility = false;\n this._listeners.push(this._visibilityHandler.onVisibilityChange.addListener(async (nodeIds, visibilityStatus) => {\n if (this._isChangingVisibility)\n return;\n void this.updateCheckboxes(nodeIds, visibilityStatus);\n }));\n this._listeners.push(this.modelSource.onModelChanged.addListener(async ([_, changes]) => {\n void this.updateCheckboxes([...changes.addedNodeIds, ...changes.modifiedNodeIds]);\n }));\n this.updateCheckboxes(); // eslint-disable-line @typescript-eslint/no-floating-promises\n }\n\n public override dispose() {\n super.dispose();\n this._listeners.forEach((disposeFunc) => disposeFunc());\n }\n\n private filterSelectionItems(items: TreeNodeItem[]) {\n // istanbul ignore if\n if (!this._selectionPredicate)\n return items;\n\n return items.filter((item) => this._selectionPredicate!(item));\n }\n\n public override onSelectionModified({ modifications }: TreeSelectionModificationEventArgs) {\n const filteredModification = new Observable<TreeSelectionChange>((subscriber) => modifications.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems, deselectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n deselectedNodeItems: this.filterSelectionItems(deselectedNodeItems),\n };\n }),\n );\n return super.onSelectionModified({ modifications: filteredModification });\n }\n\n public override onSelectionReplaced({ replacements }: TreeSelectionReplacementEventArgs) {\n const filteredReplacements = new Observable<{ selectedNodeItems: TreeNodeItem[] }>((subscriber) => replacements.subscribe(subscriber)).pipe(\n map(({ selectedNodeItems }) => {\n return {\n selectedNodeItems: this.filterSelectionItems(selectedNodeItems),\n };\n }),\n );\n return super.onSelectionReplaced({ replacements: filteredReplacements });\n }\n\n public override onCheckboxStateChanged(event: TreeCheckboxStateChangeEventArgs) {\n const handleStateChanged = () => {\n this._isChangingVisibility = false;\n void this.updateCheckboxes();\n };\n\n new Observable<CheckboxStateChange[]>((subscriber) => event.stateChanges.subscribe(subscriber))\n .pipe(\n mergeMap((changes) => this.changeVisibility(changes)),\n )\n .subscribe({\n complete: handleStateChanged,\n error: handleStateChanged,\n });\n return undefined;\n }\n\n private changeVisibility(changes: CheckboxStateChange[]) {\n return from(changes)\n .pipe(\n mergeMap(({ nodeItem, newState }) => {\n this._isChangingVisibility = true;\n return from(this._visibilityHandler.changeVisibility(nodeItem, newState === CheckBoxState.On));\n }, 1),\n );\n }\n\n private async updateCheckboxes(affectedNodes?: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const changes = await (affectedNodes ? this.collectAffectedNodesCheckboxInfos(affectedNodes, visibilityStatus) : this.collectAllNodesCheckboxInfos(visibilityStatus));\n this.updateModel(changes);\n }\n\n private updateModel(changes: Map<string, CheckBoxInfo>) {\n this.modelSource.modifyModel((model) => {\n for (const [nodeId, checkboxInfo] of changes) {\n const node = model.getNode(nodeId);\n // istanbul ignore if\n if (!node)\n continue;\n\n node.checkbox.isDisabled = checkboxInfo.isDisabled;\n node.checkbox.isVisible = checkboxInfo.isVisible;\n node.checkbox.state = checkboxInfo.state;\n node.checkbox.tooltip = checkboxInfo.tooltip;\n }\n });\n }\n\n private async collectAffectedNodesCheckboxInfos(affectedNodes: string[], visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n if (affectedNodes.length === 0)\n return nodeStates;\n\n await Promise.all(affectedNodes.map(async (nodeId) => {\n const node = this.modelSource.getModel().getNode(nodeId);\n // istanbul ignore else\n if (node)\n nodeStates.set(nodeId, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }));\n return nodeStates;\n }\n\n private async collectAllNodesCheckboxInfos(visibilityStatus?: Map<string, VisibilityStatus>) {\n const nodeStates = new Map<string, CheckBoxInfo>();\n for (const node of this.modelSource.getModel().iterateTreeModelNodes()) {\n nodeStates.set(node.id, await this.getNodeCheckBoxInfo(node, visibilityStatus));\n }\n return nodeStates;\n }\n\n private async getNodeCheckBoxInfo(node: TreeModelNode, visibilityStatus?: Map<string, VisibilityStatus>): Promise<CheckBoxInfo> {\n const result = visibilityStatus?.get(node.id) ?? this._visibilityHandler.getVisibilityStatus(node.item);\n\n if (isPromiseLike(result))\n return this.createCheckboxInfo(await result);\n return this.createCheckboxInfo(result);\n }\n\n private createCheckboxInfo(status: VisibilityStatus): CheckBoxInfo {\n return {\n state: visibilityStateToCheckboxState(status),\n isDisabled: status.isDisabled || false,\n isVisible: true,\n tooltip: status.tooltip,\n };\n }\n}\n\nconst visibilityStateToCheckboxState = (status: VisibilityStatus) => {\n switch (status.state) {\n case \"visible\":\n return CheckBoxState.On;\n // istanbul ignore next\n case \"partial\":\n return CheckBoxState.Partial;\n case \"hidden\":\n default:\n return CheckBoxState.Off;\n }\n};\n"]}
|
|
@@ -20,31 +20,37 @@
|
|
|
20
20
|
height: 100%;
|
|
21
21
|
width: 100%;
|
|
22
22
|
|
|
23
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
23
24
|
.ReactWindow__VariableSizeList {
|
|
24
|
-
>div {
|
|
25
|
+
> div {
|
|
25
26
|
min-width: max-content !important; // to override inline class
|
|
26
27
|
}
|
|
27
28
|
}
|
|
28
29
|
|
|
30
|
+
.core-tree-node {
|
|
31
|
+
&.without-expander {
|
|
32
|
+
>.contents {
|
|
33
|
+
>.core-tree-node-icon {
|
|
34
|
+
margin-left: 5px;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
29
40
|
&.enlarge {
|
|
30
41
|
--enlarged-node-height: calc(var(--iui-size-l) + var(--iui-size-m) + var(--iui-size-3xs));
|
|
31
42
|
--enlarged-node-icon-size: var(--iui-size-m);
|
|
32
43
|
--enlarged-node-icon-padding: calc(var(--enlarged-node-height) - var(--enlarged-node-icon-size));
|
|
33
|
-
--enlarged-node-expander-additional-padding: calc(var(--iui-size-
|
|
44
|
+
--enlarged-node-expander-additional-padding: calc(var(--iui-size-l) - var(--iui-size-3xs) / 2);
|
|
34
45
|
|
|
35
46
|
.core-tree-node {
|
|
36
|
-
|
|
37
|
-
>.contents {
|
|
38
|
-
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
>.contents {
|
|
47
|
+
> .contents {
|
|
43
48
|
height: var(--enlarged-node-height);
|
|
44
49
|
font-size: var(--iui-font-size-2);
|
|
45
50
|
|
|
51
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
46
52
|
.core-tree-expansionToggle {
|
|
47
|
-
|
|
53
|
+
> .icon {
|
|
48
54
|
height: var(--enlarged-node-height);
|
|
49
55
|
width: var(--enlarged-node-height);
|
|
50
56
|
padding: calc(var(--enlarged-node-icon-padding) / 2);
|
|
@@ -56,11 +62,14 @@
|
|
|
56
62
|
}
|
|
57
63
|
}
|
|
58
64
|
|
|
65
|
+
&.without-expander {
|
|
66
|
+
> .contents {
|
|
67
|
+
padding-left: var(--enlarged-node-expander-additional-padding);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
59
71
|
.iui-progress-indicator-radial {
|
|
60
|
-
|
|
61
|
-
width: var(--enlarged-node-height);
|
|
62
|
-
padding: calc(var(--enlarged-node-icon-padding) / 2 - 1px); // need to reduce padding by `1px` to make sure icon is centered
|
|
63
|
-
margin: 0;
|
|
72
|
+
margin: 0 calc(var(--enlarged-node-icon-padding) / 2);
|
|
64
73
|
}
|
|
65
74
|
}
|
|
66
75
|
}
|
|
@@ -74,6 +83,7 @@
|
|
|
74
83
|
flex-direction: column;
|
|
75
84
|
position: relative;
|
|
76
85
|
|
|
86
|
+
/* stylelint-disable-next-line selector-class-pattern */
|
|
77
87
|
.filteredTreeOverlay {
|
|
78
88
|
position: absolute;
|
|
79
89
|
top: 0;
|
|
@@ -99,4 +109,4 @@
|
|
|
99
109
|
font-weight: bold;
|
|
100
110
|
}
|
|
101
111
|
}
|
|
102
|
-
}
|
|
112
|
+
}
|
|
@@ -1,41 +1,46 @@
|
|
|
1
|
-
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
2
5
|
import assert from "assert";
|
|
3
|
-
import {
|
|
6
|
+
import { expect, test } from "@playwright/test";
|
|
7
|
+
import { expandStagePanel, locateNode, locateWidget, takeScreenshot } from "./utils";
|
|
4
8
|
let treeWidget;
|
|
5
9
|
test.beforeEach(async ({ page, baseURL }) => {
|
|
6
10
|
assert(baseURL);
|
|
7
|
-
await page.goto(baseURL);
|
|
11
|
+
await page.goto(baseURL, { waitUntil: "networkidle" });
|
|
12
|
+
await page.evaluate(async () => document.fonts.ready);
|
|
8
13
|
// expand panel size to ~300px
|
|
9
14
|
await expandStagePanel(page, "right", 100);
|
|
10
15
|
treeWidget = locateWidget(page, "tree");
|
|
11
16
|
await treeWidget.waitFor();
|
|
12
17
|
});
|
|
13
18
|
test.describe("should match image snapshot", () => {
|
|
14
|
-
test("initial tree", async () => {
|
|
19
|
+
test("initial tree", async ({ page }) => {
|
|
15
20
|
// wait for element to be visible in the tree
|
|
16
21
|
await locateNode(treeWidget, "ProcessPhysicalModel").getByRole("checkbox", { name: "Visible", exact: true }).waitFor();
|
|
17
|
-
await
|
|
22
|
+
await takeScreenshot(page, treeWidget);
|
|
18
23
|
});
|
|
19
|
-
test("expanded tree node", async () => {
|
|
24
|
+
test("expanded tree node", async ({ page }) => {
|
|
20
25
|
const node = locateNode(treeWidget, "ProcessPhysicalModel");
|
|
21
26
|
await node.getByTestId("tree-node-expansion-toggle").click();
|
|
22
27
|
// wait for node at the bottom to be visible/loaded
|
|
23
28
|
await locateNode(treeWidget, "Tag-Category").waitFor();
|
|
24
|
-
await
|
|
29
|
+
await takeScreenshot(page, treeWidget);
|
|
25
30
|
});
|
|
26
|
-
test("selected node", async () => {
|
|
31
|
+
test("selected node", async ({ page }) => {
|
|
27
32
|
const node = locateNode(treeWidget, "BayTown");
|
|
28
33
|
await node.click();
|
|
29
34
|
// wait for node to become selected
|
|
30
35
|
await expect(node).toHaveClass(/is-selected/);
|
|
31
|
-
await
|
|
36
|
+
await takeScreenshot(page, treeWidget);
|
|
32
37
|
});
|
|
33
|
-
test("search", async () => {
|
|
38
|
+
test("search", async ({ page }) => {
|
|
34
39
|
await treeWidget.getByText("BayTown").waitFor();
|
|
35
40
|
await treeWidget.getByTitle("Search for something").click();
|
|
36
41
|
await treeWidget.getByPlaceholder("Search...").fill("Model");
|
|
37
42
|
await treeWidget.locator(".components-activehighlight").waitFor();
|
|
38
|
-
await
|
|
43
|
+
await takeScreenshot(page, treeWidget);
|
|
39
44
|
});
|
|
40
45
|
});
|
|
41
46
|
//# sourceMappingURL=TreeWidget.test.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TreeWidget.test.js","sourceRoot":"","sources":["../../../src/e2e-tests/TreeWidget.test.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAGhG,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAErF,IAAI,UAAmB,CAAC;AACxB,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE;IAC1C,MAAM,CAAC,OAAO,CAAC,CAAC;IAChB,MAAM,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,aAAa,EAAE,CAAC,CAAC;IACvD,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,IAAI,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtD,8BAA8B;IAC9B,MAAM,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,CAAC,CAAC;IAC3C,UAAU,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACxC,MAAM,UAAU,CAAC,OAAO,EAAE,CAAC;AAC7B,CAAC,CAAC,CAAC;AAEH,IAAI,CAAC,QAAQ,CAAC,6BAA6B,EAAE,GAAG,EAAE;IAEhD,IAAI,CAAC,cAAc,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACtC,6CAA6C;QAC7C,MAAM,UAAU,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;QACvH,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,oBAAoB,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAC5C,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,sBAAsB,CAAC,CAAC;QAC5D,MAAM,IAAI,CAAC,WAAW,CAAC,4BAA4B,CAAC,CAAC,KAAK,EAAE,CAAC;QAE7D,mDAAmD;QACnD,MAAM,UAAU,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC,OAAO,EAAE,CAAC;QACvD,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,eAAe,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QACvC,MAAM,IAAI,GAAG,UAAU,CAAC,UAAU,EAAE,SAAS,CAAC,CAAC;QAC/C,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,mCAAmC;QACnC,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,WAAW,CAAC,aAAa,CAAC,CAAC;QAC9C,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE;QAChC,MAAM,UAAU,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC;QAChD,MAAM,UAAU,CAAC,UAAU,CAAC,sBAAsB,CAAC,CAAC,KAAK,EAAE,CAAC;QAC5D,MAAM,UAAU,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,UAAU,CAAC,OAAO,CAAC,6BAA6B,CAAC,CAAC,OAAO,EAAE,CAAC;QAClE,MAAM,cAAc,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;AAEL,CAAC,CAAC,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport type { Locator } from \"@playwright/test\";\nimport assert from \"assert\";\nimport { expect, test } from \"@playwright/test\";\nimport { expandStagePanel, locateNode, locateWidget, takeScreenshot } from \"./utils\";\n\nlet treeWidget: Locator;\ntest.beforeEach(async ({ page, baseURL }) => {\n assert(baseURL);\n await page.goto(baseURL, { waitUntil: \"networkidle\" });\n await page.evaluate(async () => document.fonts.ready);\n // expand panel size to ~300px\n await expandStagePanel(page, \"right\", 100);\n treeWidget = locateWidget(page, \"tree\");\n await treeWidget.waitFor();\n});\n\ntest.describe(\"should match image snapshot\", () => {\n\n test(\"initial tree\", async ({ page }) => {\n // wait for element to be visible in the tree\n await locateNode(treeWidget, \"ProcessPhysicalModel\").getByRole(\"checkbox\", { name: \"Visible\", exact: true }).waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"expanded tree node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"ProcessPhysicalModel\");\n await node.getByTestId(\"tree-node-expansion-toggle\").click();\n\n // wait for node at the bottom to be visible/loaded\n await locateNode(treeWidget, \"Tag-Category\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"selected node\", async ({ page }) => {\n const node = locateNode(treeWidget, \"BayTown\");\n await node.click();\n\n // wait for node to become selected\n await expect(node).toHaveClass(/is-selected/);\n await takeScreenshot(page, treeWidget);\n });\n\n test(\"search\", async ({ page }) => {\n await treeWidget.getByText(\"BayTown\").waitFor();\n await treeWidget.getByTitle(\"Search for something\").click();\n await treeWidget.getByPlaceholder(\"Search...\").fill(\"Model\");\n await treeWidget.locator(\".components-activehighlight\").waitFor();\n await takeScreenshot(page, treeWidget);\n });\n\n});\n"]}
|
|
@@ -4,5 +4,6 @@ export declare const locateWidget: (page: Page | Locator, widgetName: string) =>
|
|
|
4
4
|
type PanelSide = "left" | "right" | "top" | "bottom";
|
|
5
5
|
export declare const locatePanel: (page: Page, side: PanelSide) => Locator;
|
|
6
6
|
export declare const expandStagePanel: (page: Page, side: PanelSide, px: number) => Promise<void>;
|
|
7
|
+
export declare function takeScreenshot(page: Page, component: Locator): Promise<void>;
|
|
7
8
|
export {};
|
|
8
9
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
1
5
|
import assert from "assert";
|
|
6
|
+
import { expect } from "@playwright/test";
|
|
2
7
|
export const locateNode = (tree, name) => tree.getByRole("treeitem", { name });
|
|
3
8
|
export const locateWidget = (page, widgetName) => page.locator(`.${widgetName}-widget`);
|
|
4
9
|
export const locatePanel = (page, side) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);
|
|
@@ -27,4 +32,9 @@ export const expandStagePanel = async (page, side, px) => {
|
|
|
27
32
|
}
|
|
28
33
|
await page.mouse.up();
|
|
29
34
|
};
|
|
35
|
+
export async function takeScreenshot(page, component) {
|
|
36
|
+
const boundingBox = await component.boundingBox();
|
|
37
|
+
assert(boundingBox);
|
|
38
|
+
await expect(page).toHaveScreenshot({ clip: boundingBox });
|
|
39
|
+
}
|
|
30
40
|
//# sourceMappingURL=utils.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/e2e-tests/utils.ts"],"names":[],"mappings":"AAAA;;;gGAGgG;AAEhG,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAI1C,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,IAAoB,EAAE,IAAY,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC;AACvG,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,IAAoB,EAAE,UAAkB,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,SAAS,CAAC,CAAC;AAGhH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,IAAU,EAAE,IAAe,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,6BAA6B,IAAI,EAAE,CAAC,CAAC;AAE9G,MAAM,CAAC,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAAU,EAAE,IAAe,EAAE,EAAU,EAAE,EAAE;IAChF,MAAM,WAAW,GAAG,WAAW,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,SAAS,GAAG,MAAM,WAAW;SAChC,OAAO,CAAC,oBAAoB,CAAC;SAC7B,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,EAAE,CAAC;IACjB,MAAM,CAAC,SAAS,CAAC,CAAC;IAElB,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;IAExB,QAAQ,IAAI,EAAE;QACZ,KAAK,MAAM;YACT,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,OAAO;YACV,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,KAAK;YACR,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;QACR,KAAK,QAAQ;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,SAAS,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;YACrD,MAAM;KACT;IACD,MAAM,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC;AACxB,CAAC,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAU,EAAE,SAAkB;IACjE,MAAM,WAAW,GAAG,MAAM,SAAS,CAAC,WAAW,EAAE,CAAC;IAClD,MAAM,CAAC,WAAW,CAAC,CAAC;IACpB,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;AAC7D,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport assert from \"assert\";\nimport { expect } from \"@playwright/test\";\n\nimport type { Locator, Page } from \"@playwright/test\";\n\nexport const locateNode = (tree: Page | Locator, name: string) => tree.getByRole(\"treeitem\", { name });\nexport const locateWidget = (page: Page | Locator, widgetName: string) => page.locator(`.${widgetName}-widget`);\n\ntype PanelSide = \"left\" | \"right\" | \"top\" | \"bottom\";\nexport const locatePanel = (page: Page, side: PanelSide) => page.locator(`.nz-widgetPanels-panel.nz-${side}`);\n\nexport const expandStagePanel = async (page: Page, side: PanelSide, px: number) => {\n const widgetPanel = locatePanel(page, side);\n const handlePos = await widgetPanel\n .locator(\".nz-grip-container\")\n .locator(\".nz-handle\")\n .boundingBox();\n assert(handlePos);\n\n await page.mouse.move(handlePos.x, handlePos.y);\n await page.mouse.down();\n\n switch (side) {\n case \"left\":\n await page.mouse.move(handlePos.x + px, handlePos.y);\n break;\n case \"right\":\n await page.mouse.move(handlePos.x - px, handlePos.y);\n break;\n case \"top\":\n await page.mouse.move(handlePos.x, handlePos.y - px);\n break;\n case \"bottom\":\n await page.mouse.move(handlePos.x, handlePos.y + px);\n break;\n }\n await page.mouse.up();\n};\n\nexport async function takeScreenshot(page: Page, component: Locator) {\n const boundingBox = await component.boundingBox();\n assert(boundingBox);\n await expect(page).toHaveScreenshot({ clip: boundingBox });\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/tree-widget-react",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.2",
|
|
4
4
|
"description": "Tree Widget React",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Bentley",
|
|
@@ -20,6 +20,41 @@
|
|
|
20
20
|
"main": "lib/cjs/tree-widget-react.js",
|
|
21
21
|
"module": "lib/esm/tree-widget-react.js",
|
|
22
22
|
"typings": "lib/cjs/tree-widget-react",
|
|
23
|
+
"scripts": {
|
|
24
|
+
"start:test-viewer": "node ./scripts/start-test-viewer.js",
|
|
25
|
+
"start:test-viewer:watch": "node ./scripts/start-test-viewer.js --watch",
|
|
26
|
+
"build": "npm run -s dual-build && npm run -s copy:assets",
|
|
27
|
+
"dual-build": "npm run -s build:cjs && npm run -s build:esm",
|
|
28
|
+
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
|
|
29
|
+
"build:esm": "tsc 1>&2 --module ES2020 --outDir lib/esm",
|
|
30
|
+
"copy:assets": "npm run -s copy:public && npm run -s copy:cjs && npm run -s copy:esm",
|
|
31
|
+
"copy:public": "cpx \"./public/**/*\" ./lib/public",
|
|
32
|
+
"copy:cjs": "cpx \"./src/**/*.{scss,json}\" ./lib/cjs",
|
|
33
|
+
"copy:esm": "cpx \"./src/**/*.{scss,json}\" ./lib/esm",
|
|
34
|
+
"cover": "nyc npm run test",
|
|
35
|
+
"extract-api": "betools extract-api --entry=tree-widget-react --apiReportFolder=./api --apiReportTempFolder=./api/temp --apiSummaryFolder=./api",
|
|
36
|
+
"lint": "npm run lint:eslint && npm run lint:stylelint",
|
|
37
|
+
"lint:eslint": "eslint -f visualstudio \"./src/**/*.{ts,tsx}\" 1>&2",
|
|
38
|
+
"lint:stylelint": "stylelint \"./src/**/*.scss\"",
|
|
39
|
+
"lint:fix": "npm run lint:eslint -- --fix && npm run lint:stylelint -- --fix",
|
|
40
|
+
"pseudolocalize": "betools pseudolocalize --englishDir ./public/locales/en --out ./lib/public/locales/en-PSEUDO",
|
|
41
|
+
"test": "mocha \"./lib/cjs/test/**/*.test.js\"",
|
|
42
|
+
"test:e2e": "node ../../../scripts/run-e2e-with-docker.js tree-widget",
|
|
43
|
+
"test:e2e:local": "node ../../../scripts/run-e2e-tests.js",
|
|
44
|
+
"test:e2e:debug": "cross-env PWDEBUG=1 playwright test --ui",
|
|
45
|
+
"clean": "rimraf lib",
|
|
46
|
+
"rebuild": "npm run clean && npm run build"
|
|
47
|
+
},
|
|
48
|
+
"peerDependencies": {
|
|
49
|
+
"@itwin/appui-abstract": "^4.0.0",
|
|
50
|
+
"@itwin/appui-react": "^4.3.0",
|
|
51
|
+
"@itwin/components-react": "^4.3.0",
|
|
52
|
+
"@itwin/core-frontend": "^4.0.0",
|
|
53
|
+
"@itwin/core-react": "^4.3.0",
|
|
54
|
+
"@itwin/presentation-components": "^4.0.0",
|
|
55
|
+
"react": "^17.0.0",
|
|
56
|
+
"react-dom": "^17.0.0"
|
|
57
|
+
},
|
|
23
58
|
"dependencies": {
|
|
24
59
|
"@bentley/icons-generic": "^1.0.34",
|
|
25
60
|
"@itwin/itwinui-icons-react": "^2.1.0",
|
|
@@ -28,36 +63,35 @@
|
|
|
28
63
|
"classnames": "^2.3.1",
|
|
29
64
|
"i18next": "^10.2.2",
|
|
30
65
|
"react-error-boundary": "^4.0.10",
|
|
31
|
-
"rxjs": "^
|
|
66
|
+
"rxjs": "^7.8.1"
|
|
32
67
|
},
|
|
33
68
|
"devDependencies": {
|
|
34
|
-
"@itwin/appui-abstract": "^4.
|
|
69
|
+
"@itwin/appui-abstract": "^4.1.2",
|
|
35
70
|
"@itwin/appui-layout-react": "^4.5.0",
|
|
36
71
|
"@itwin/appui-react": "^4.5.0",
|
|
37
|
-
"@itwin/build-tools": "^4.
|
|
72
|
+
"@itwin/build-tools": "^4.1.2",
|
|
38
73
|
"@itwin/components-react": "^4.5.0",
|
|
39
|
-
"@itwin/core-backend": "^4.
|
|
40
|
-
"@itwin/core-bentley": "^4.
|
|
41
|
-
"@itwin/core-common": "^4.
|
|
42
|
-
"@itwin/core-frontend": "^4.
|
|
43
|
-
"@itwin/core-geometry": "^4.
|
|
44
|
-
"@itwin/core-i18n": "^4.
|
|
45
|
-
"@itwin/core-markup": "^4.
|
|
46
|
-
"@itwin/core-orbitgt": "^4.
|
|
47
|
-
"@itwin/core-quantity": "^4.
|
|
74
|
+
"@itwin/core-backend": "^4.1.2",
|
|
75
|
+
"@itwin/core-bentley": "^4.1.2",
|
|
76
|
+
"@itwin/core-common": "^4.1.2",
|
|
77
|
+
"@itwin/core-frontend": "^4.1.2",
|
|
78
|
+
"@itwin/core-geometry": "^4.1.2",
|
|
79
|
+
"@itwin/core-i18n": "^4.1.2",
|
|
80
|
+
"@itwin/core-markup": "^4.1.2",
|
|
81
|
+
"@itwin/core-orbitgt": "^4.1.2",
|
|
82
|
+
"@itwin/core-quantity": "^4.1.2",
|
|
48
83
|
"@itwin/core-react": "^4.5.0",
|
|
49
|
-
"@itwin/core-telemetry": "^4.
|
|
50
|
-
"@itwin/ecschema-metadata": "^4.
|
|
84
|
+
"@itwin/core-telemetry": "^4.1.2",
|
|
85
|
+
"@itwin/ecschema-metadata": "^4.1.2",
|
|
51
86
|
"@itwin/eslint-plugin": "^4.0.0-dev.38",
|
|
52
87
|
"@itwin/imodel-components-react": "^4.5.0",
|
|
53
|
-
"@itwin/presentation-backend": "^4.
|
|
54
|
-
"@itwin/presentation-common": "^4.
|
|
88
|
+
"@itwin/presentation-backend": "^4.1.2",
|
|
89
|
+
"@itwin/presentation-common": "^4.1.2",
|
|
55
90
|
"@itwin/presentation-components": "^4.1.0",
|
|
56
|
-
"@itwin/presentation-frontend": "^4.
|
|
91
|
+
"@itwin/presentation-frontend": "^4.1.2",
|
|
57
92
|
"@itwin/presentation-testing": "^4.0.0",
|
|
58
|
-
"@itwin/webgl-compatibility": "^4.
|
|
93
|
+
"@itwin/webgl-compatibility": "^4.1.2",
|
|
59
94
|
"@playwright/test": "^1.36.2",
|
|
60
|
-
"@rushstack/eslint-patch": "1.2.0",
|
|
61
95
|
"@testing-library/dom": "^8.12.0",
|
|
62
96
|
"@testing-library/react": "^12.0.0",
|
|
63
97
|
"@testing-library/react-hooks": "^7.0.2",
|
|
@@ -67,12 +101,13 @@
|
|
|
67
101
|
"@types/chai-subset": "1.3.3",
|
|
68
102
|
"@types/deep-equal": "^1.0.1",
|
|
69
103
|
"@types/i18next": "^8.4.2",
|
|
70
|
-
"@types/jsdom
|
|
71
|
-
"@types/mocha": "^10.0.
|
|
104
|
+
"@types/jsdom": "^21.1.6",
|
|
105
|
+
"@types/mocha": "^10.0.6",
|
|
106
|
+
"@types/node": "^18.18.10",
|
|
72
107
|
"@types/react": "^17.0.19",
|
|
73
108
|
"@types/react-dom": "^17.0.9",
|
|
74
|
-
"@types/sinon": "^
|
|
75
|
-
"@types/sinon-chai": "^3.2.
|
|
109
|
+
"@types/sinon": "^17.0.2",
|
|
110
|
+
"@types/sinon-chai": "^3.2.12",
|
|
76
111
|
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
|
77
112
|
"@typescript-eslint/parser": "^5.59.8",
|
|
78
113
|
"chai": "^4.3.7",
|
|
@@ -81,12 +116,14 @@
|
|
|
81
116
|
"cpx2": "^3.0.0",
|
|
82
117
|
"cross-env": "^7.0.3",
|
|
83
118
|
"deep-equal": "^1.0.0",
|
|
119
|
+
"dotenv": "^16.3.1",
|
|
84
120
|
"eslint": "^8.41.0",
|
|
121
|
+
"eslint-plugin-import": "^2.29.0",
|
|
122
|
+
"eslint-plugin-react": "^7.33.2",
|
|
85
123
|
"eslint-plugin-unused-imports": "^2.0.0",
|
|
86
|
-
"
|
|
124
|
+
"global-jsdom": "~9.1.0",
|
|
87
125
|
"ignore-styles": "^5.0.1",
|
|
88
126
|
"jsdom": "^22.1.0",
|
|
89
|
-
"jsdom-global": "3.0.2",
|
|
90
127
|
"mocha": "^10.2.0",
|
|
91
128
|
"nyc": "15.1.0",
|
|
92
129
|
"raf": "^3.4.0",
|
|
@@ -95,48 +132,18 @@
|
|
|
95
132
|
"react-redux": "^7.2.2",
|
|
96
133
|
"redux": "^4.1.0",
|
|
97
134
|
"rimraf": "^3.0.2",
|
|
98
|
-
"sinon": "^
|
|
135
|
+
"sinon": "^17.0.1",
|
|
99
136
|
"sinon-chai": "^3.7.0",
|
|
100
137
|
"source-map-support": "^0.5.6",
|
|
138
|
+
"stylelint": "^15.11.0",
|
|
139
|
+
"stylelint-config-standard-scss": "^11.1.0",
|
|
101
140
|
"typemoq": "^2.1.0",
|
|
102
141
|
"typescript": "~5.0.0",
|
|
103
142
|
"xmlhttprequest": "^1.8.0"
|
|
104
143
|
},
|
|
105
|
-
"peerDependencies": {
|
|
106
|
-
"@itwin/appui-abstract": "^4.0.0",
|
|
107
|
-
"@itwin/appui-react": "^4.3.0",
|
|
108
|
-
"@itwin/components-react": "^4.3.0",
|
|
109
|
-
"@itwin/core-frontend": "^4.0.0",
|
|
110
|
-
"@itwin/core-react": "^4.3.0",
|
|
111
|
-
"@itwin/presentation-components": "^4.0.0",
|
|
112
|
-
"react": "^17.0.0",
|
|
113
|
-
"react-dom": "^17.0.0"
|
|
114
|
-
},
|
|
115
144
|
"eslintConfig": {
|
|
116
145
|
"extends": [
|
|
117
146
|
".eslintrc.js"
|
|
118
147
|
]
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
"start:test-viewer": "node ./scripts/start-test-viewer.js",
|
|
122
|
-
"build": "npm run -s dual-build && npm run -s copy:assets",
|
|
123
|
-
"dual-build": "npm run -s build:cjs && npm run -s build:esm",
|
|
124
|
-
"build:cjs": "tsc 1>&2 --outDir lib/cjs",
|
|
125
|
-
"build:esm": "tsc 1>&2 --module ES2020 --outDir lib/esm",
|
|
126
|
-
"copy:assets": "npm run -s copy:public && npm run -s copy:cjs && npm run -s copy:esm",
|
|
127
|
-
"copy:public": "cpx \"./public/**/*\" ./lib/public",
|
|
128
|
-
"copy:cjs": "cpx \"./src/**/*.{scss,json}\" ./lib/cjs",
|
|
129
|
-
"copy:esm": "cpx \"./src/**/*.{scss,json}\" ./lib/esm",
|
|
130
|
-
"cover": "nyc npm run test",
|
|
131
|
-
"extract-api": "betools extract-api --entry=tree-widget-react",
|
|
132
|
-
"lint": "eslint -f visualstudio \"./src/**/*.{ts,tsx}\" 1>&2",
|
|
133
|
-
"lint:fix": "npm run lint -- --fix",
|
|
134
|
-
"pseudolocalize": "betools pseudolocalize --englishDir ./public/locales/en --out ./lib/public/locales/en-PSEUDO",
|
|
135
|
-
"test": "mocha \"./lib/cjs/test/**/*.test.js\"",
|
|
136
|
-
"test:e2e": "playwright test",
|
|
137
|
-
"test:e2e:debug": "cross-env PWDEBUG=1 playwright test --ui",
|
|
138
|
-
"clean": "rimraf lib .rush/temp/package-deps*.json",
|
|
139
|
-
"rebuild": "npm run clean && npm run build"
|
|
140
|
-
},
|
|
141
|
-
"readme": "# @itwin/tree-widget-react\n\nCopyright © Bentley Systems, Incorporated. All rights reserved.\n\nThe `@itwin/tree-widget-react` package provides React components to build a widget with tree components' selector, along with all the building blocks that can be used individually.\n\n\n\n## Usage\n\nTypically, the package is used with an [AppUI](https://github.com/iTwin/appui/tree/master/ui/appui-react) based application, but the building blocks may as well be used with any other iTwin.js React app.\n\nIn any case, **before** using any APIs or components delivered with the package, it needs to be initialized:\n\n```ts\nimport { IModelApp } from \"@itwin/core-frontend\";\nimport { TreeWidget } from \"@itwin/tree-widget-react\";\n...\nawait TreeWidget.initialize(IModelApp.localization);\n```\n\nIn [AppUI](https://github.com/iTwin/appui/tree/master/ui/appui-react) based applications widgets are typically provided using `UiItemsProvider` implementations. The `@itwin/tree-widget-react` package delivers `TreeWidgetUiItemsProvider` that can be used to add the tree widget to UI:\n\n```ts\nimport { UiItemsManager } from \"@itwin/appui-react\";\nimport { TreeWidgetUiItemsProvider } from \"@itwin/tree-widget-react\";\n...\nUiItemsManager.register(\n new TreeWidgetUiItemsProvider()\n);\n```\n\nThe above example uses default widget parameters and results in a component similar to the one visible at the top of this README. Customization is also possible:\n\n```ts\nimport { UiItemsManager } from \"@itwin/appui-react\";\nimport { TreeWidgetUiItemsProvider, ModelsTreeComponent } from \"@itwin/tree-widget-react\";\n...\nUiItemsManager.register(\n new TreeWidgetUiItemsProvider({\n // defaults to `StagePanelLocation.Right`\n defaultPanelLocation: StagePanelLocation.Left,\n // defaults to `StagePanelSection.Start`\n defaultPanelSection: StagePanelSection.End,\n // defaults to whatever the default `Widget.priority` in AppUI is\n defaultTreeWidgetPriority: 1000,\n // defaults to `ModelsTreeComponent` and `CategoriesTreeComponent`\n trees: [{\n id: ModelsTreeComponent.id,\n getLabel: ModelsTreeComponent.getLabel,\n render: () => <ModelsTreeComponent />,\n }, {\n id: \"my-tree-id\",\n getLabel: \"My Custom Tree\",\n render: () => <>This is my custom tree.</>,\n }];\n })\n);\n```\n\nAs seen in the above code snippet, `TreeWidgetUiItemsProvider` takes a list of trees that are displayed in the widget. This package delivers a number of tree components for everyone's use (see below), but providing custom trees is also an option.\n\n## Components\n\nWhile we expect this package to be mostly used with [AppUI](https://github.com/iTwin/appui/tree/master/ui/appui-react) and widget created through `TreeWidgetUiItemsProvider`, the package delivers components used within the widget to meet other use cases:\n\n- `SelectableTree` renders a tree selector and selected tree (based on the `trees` prop).\n\n- Visibility tree components help you build trees that look and feel like [Models](#models-tree) and [Categories](#categories-tree) trees, letting you control display of elements in the hierarchy.\n\n - `createVisibilityTreeRenderer` returns a tree renderer that renders nodes with \"eye\" checkboxes. Its building blocks:\n - `createVisibilityTreeNodeRenderer`\n - `VisibilityTreeNodeCheckbox`\n - `useVisibilityTreeFiltering` is used to filter the hierarchy.\n - `VisibilityTreeNoFilteredData` is used to render a \"no results\" when filtering.\n - `VisibilityTreeEventHandler` is an extension of [UnifiedSelectionTreeEventHandler](https://www.itwinjs.org/reference/presentation-components/tree/unifiedselectiontreeeventhandler/), that additionally handles checkbox events and calls provided `IVisibilityHandler` to get/set display of the elements in the hierarchy.\n - `useTreeTransientState` is used to persist tree scroll position when tree is used in [AppUI](https://github.com/iTwin/appui/tree/master/ui/appui-react) widget.\n\n### Models tree\n\nThe component renders a tree that tries to replicate how a typical \"Models\" tree of the iModel would look like in the source application. There's also a header that renders models search box and various visibility control buttons.\n\n\n\nTypical usage:\n\n```tsx\nimport { ModelsTreeComponent, ClassGroupingOption } from \"@itwin/tree-widget-react\";\nimport { SelectionMode } from \"@itwin/components-react\";\n...\nfunction MyWidget() {\n return (\n <ModelsTreeComponent\n headerButtons={[\n (props) => <ModelsTreeComponent.ShowAllButton {...props} />,\n (props) => <ModelsTreeComponent.HideAllButton {...props} />,\n (props) => <MyCustomButton />,\n ]}\n selectionMode={SelectionMode.Extended}\n hierarchyConfig={{\n enableElementsClassGrouping: ClassGroupingOption.Yes,\n }}\n />\n );\n}\n```\n\nAvailable header buttons:\n\n- `ModelsTreeComponent.ShowAllButton` makes everything in the iModel displayed.\n- `ModelsTreeComponent.HideAllButton` makes everything in the iModel hidden by turning off all models.\n- `ModelsTreeComponent.InvertButton` inverts display of all models.\n- `ModelsTreeComponent.View2DButton` toggles plan projection models' display.\n- `ModelsTreeComponent.View3DButton` toggles non-plan projection models' display.\n\n`ModelsTreeComponent` building blocks:\n\n- `ModelsTree` renders the tree without the header.\n- `ModelsVisibilityHandler` knows how to get and control display of various concepts displayed in the Models tree: Subjects, Models, Categories, Elements.\n\n### Categories tree\n\nThe 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.\n\n\n\nTypical usage:\n\n```tsx\nimport { CategoriesTreeComponent } from \"@itwin/tree-widget-react\";\n...\nfunction MyWidget() {\n return (\n <CategoriesTreeComponent\n headerButtons={[\n (props) => <CategoriesTreeComponent.ShowAllButton {...props} />,\n (props) => <CategoriesTreeComponent.HideAllButton {...props} />,\n (props) => <MyCustomButton />,\n ]}\n />\n );\n}\n```\n\nAvailable header buttons:\n\n- `ModelsTreeComponent.ShowAllButton` makes all categories and their subcategories displayed.\n- `ModelsTreeComponent.HideAllButton` makes all categories hidden.\n- `ModelsTreeComponent.InvertButton` inverts display of all categories.\n\n`CategoriesTreeComponent` building blocks:\n\n- `CategoryTree` renders the tree without the header.\n- `CategoryVisibilityHandler` knows how to get and control display of Categories and SubCategories.\n\n### IModel content tree\n\nThe component renders a similar hierarchy to [Models tree](#models-tree), but with the following changes:\n\n- Only the hierarchy, without a header is rendered.\n- Visibility control is not allowed.\n- There's less hiding of `Subject` and `Model` nodes.\n- Show not only geometric, but all Models.\n\nIn general, the component is expected to be used by advanced users to inspect contents of the iModel.\n\n\n\nTypical usage:\n\n```tsx\nimport { IModelContentTreeComponent } from \"@itwin/tree-widget-react\";\n...\nfunction MyWidget() {\n return (\n <IModelContentTreeComponent />\n );\n}\n```\n"
|
|
142
|
-
}
|
|
148
|
+
}
|
|
149
|
+
}
|