@itwin/tree-widget-react 1.2.2 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +26 -2
- package/README.md +1 -1
- package/lib/cjs/TreeWidget.d.ts +0 -1
- package/lib/cjs/TreeWidget.js +9 -10
- package/lib/cjs/TreeWidget.js.map +1 -1
- package/lib/cjs/components/SelectableTree.d.ts +9 -1
- package/lib/cjs/components/SelectableTree.js +28 -17
- package/lib/cjs/components/SelectableTree.js.map +1 -1
- package/lib/cjs/components/SelectableTree.scss +0 -16
- package/lib/cjs/components/TreeFilteringState.js +3 -3
- package/lib/cjs/components/TreeFilteringState.js.map +1 -1
- package/lib/cjs/components/TreeSelector.d.ts +28 -0
- package/lib/cjs/components/TreeSelector.js +27 -0
- package/lib/cjs/components/TreeSelector.js.map +1 -0
- package/lib/cjs/components/TreeSelector.scss +27 -0
- package/lib/cjs/components/TreeWidgetUiItemsProvider.d.ts +9 -1
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js +21 -14
- package/lib/cjs/components/TreeWidgetUiItemsProvider.js.map +1 -1
- package/lib/cjs/components/TreeWidgetUiItemsProvider.scss +1 -1
- package/lib/cjs/components/tree-header/TreeHeader.d.ts +3 -0
- package/lib/cjs/components/tree-header/TreeHeader.js +20 -15
- package/lib/cjs/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/cjs/components/tree-header/TreeHeader.scss +29 -1
- package/lib/cjs/components/trees/CategoriesVisibilityUtils.js +13 -8
- package/lib/cjs/components/trees/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/cjs/components/trees/VisibilityTreeBase.scss +1 -1
- package/lib/cjs/components/trees/VisibilityTreeEventHandler.d.ts +1 -1
- package/lib/cjs/components/trees/VisibilityTreeEventHandler.js +18 -10
- package/lib/cjs/components/trees/VisibilityTreeEventHandler.js.map +1 -1
- package/lib/cjs/components/trees/VisibilityTreeRenderer.d.ts +20 -4
- package/lib/cjs/components/trees/VisibilityTreeRenderer.js +28 -10
- package/lib/cjs/components/trees/VisibilityTreeRenderer.js.map +1 -1
- package/lib/cjs/components/trees/category-tree/CategoriesTree.d.ts +7 -2
- package/lib/cjs/components/trees/category-tree/CategoriesTree.js +47 -30
- package/lib/cjs/components/trees/category-tree/CategoriesTree.js.map +1 -1
- package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js +27 -18
- package/lib/cjs/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/category-tree/CategoryVisibilityHandler.d.ts +2 -2
- package/lib/cjs/components/trees/category-tree/CategoryVisibilityHandler.js +18 -13
- package/lib/cjs/components/trees/category-tree/CategoryVisibilityHandler.js.map +1 -1
- package/lib/cjs/components/trees/common/ContextMenu.js +4 -4
- package/lib/cjs/components/trees/common/ContextMenu.js.map +1 -1
- package/lib/cjs/components/trees/common/TreeNodeRenderer.d.ts +1 -1
- package/lib/cjs/components/trees/common/TreeNodeRenderer.js +4 -4
- package/lib/cjs/components/trees/common/TreeNodeRenderer.js.map +1 -1
- package/lib/cjs/components/trees/common/TreeRenderer.d.ts +15 -1
- package/lib/cjs/components/trees/common/TreeRenderer.js +17 -7
- package/lib/cjs/components/trees/common/TreeRenderer.js.map +1 -1
- package/lib/cjs/components/trees/common/TreeRenderer.scss +39 -2
- package/lib/cjs/components/trees/common/Types.d.ts +8 -0
- package/lib/cjs/components/trees/common/Types.js +3 -3
- package/lib/cjs/components/trees/common/Types.js.map +1 -1
- package/lib/cjs/components/trees/common/UseVisibilityTreeState.d.ts +36 -0
- package/lib/cjs/components/trees/common/UseVisibilityTreeState.js +47 -0
- package/lib/cjs/components/trees/common/UseVisibilityTreeState.js.map +1 -0
- package/lib/cjs/components/trees/common/Utils.js +7 -5
- package/lib/cjs/components/trees/common/Utils.js.map +1 -1
- package/lib/cjs/components/trees/external-sources-tree/ExternalSources.json +1 -3
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +9 -3
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.js +19 -7
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js +4 -4
- package/lib/cjs/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.d.ts +9 -3
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.js +16 -12
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTreeComponent.js +6 -5
- package/lib/cjs/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/index.js +3 -3
- package/lib/cjs/components/trees/index.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTree.d.ts +7 -2
- package/lib/cjs/components/trees/models-tree/ModelsTree.js +76 -62
- package/lib/cjs/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js +27 -29
- package/lib/cjs/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.d.ts +9 -0
- package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.js +31 -0
- package/lib/cjs/components/trees/models-tree/ModelsTreeEventHandler.js.map +1 -0
- package/lib/cjs/components/trees/models-tree/ModelsVisibilityHandler.js +125 -66
- package/lib/cjs/components/trees/models-tree/ModelsVisibilityHandler.js.map +1 -1
- package/lib/cjs/components/trees/models-tree/Utils.d.ts +4 -0
- package/lib/cjs/components/trees/models-tree/Utils.js +52 -58
- package/lib/cjs/components/trees/models-tree/Utils.js.map +1 -1
- package/lib/cjs/components/utils/AutoSizer.js +7 -5
- package/lib/cjs/components/utils/AutoSizer.js.map +1 -1
- package/lib/cjs/components/utils/IsPromiseLike.js +4 -4
- package/lib/cjs/components/utils/IsPromiseLike.js.map +1 -1
- package/lib/cjs/components/utils/UseTreeTransientState.js +3 -3
- package/lib/cjs/components/utils/UseTreeTransientState.js.map +1 -1
- package/lib/cjs/tree-widget-react.js +3 -3
- package/lib/cjs/tree-widget-react.js.map +1 -1
- package/lib/esm/TreeWidget.d.ts +0 -1
- package/lib/esm/TreeWidget.js +9 -10
- package/lib/esm/TreeWidget.js.map +1 -1
- package/lib/esm/components/SelectableTree.d.ts +9 -1
- package/lib/esm/components/SelectableTree.js +28 -17
- package/lib/esm/components/SelectableTree.js.map +1 -1
- package/lib/esm/components/SelectableTree.scss +0 -16
- package/lib/esm/components/TreeFilteringState.js +3 -3
- package/lib/esm/components/TreeFilteringState.js.map +1 -1
- package/lib/esm/components/TreeSelector.d.ts +28 -0
- package/lib/esm/components/TreeSelector.js +23 -0
- package/lib/esm/components/TreeSelector.js.map +1 -0
- package/lib/esm/components/TreeSelector.scss +27 -0
- package/lib/esm/components/TreeWidgetUiItemsProvider.d.ts +9 -1
- package/lib/esm/components/TreeWidgetUiItemsProvider.js +19 -13
- package/lib/esm/components/TreeWidgetUiItemsProvider.js.map +1 -1
- package/lib/esm/components/TreeWidgetUiItemsProvider.scss +1 -1
- package/lib/esm/components/tree-header/TreeHeader.d.ts +3 -0
- package/lib/esm/components/tree-header/TreeHeader.js +20 -15
- package/lib/esm/components/tree-header/TreeHeader.js.map +1 -1
- package/lib/esm/components/tree-header/TreeHeader.scss +29 -1
- package/lib/esm/components/trees/CategoriesVisibilityUtils.js +13 -8
- package/lib/esm/components/trees/CategoriesVisibilityUtils.js.map +1 -1
- package/lib/esm/components/trees/VisibilityTreeBase.scss +1 -1
- package/lib/esm/components/trees/VisibilityTreeEventHandler.d.ts +1 -1
- package/lib/esm/components/trees/VisibilityTreeEventHandler.js +18 -10
- package/lib/esm/components/trees/VisibilityTreeEventHandler.js.map +1 -1
- package/lib/esm/components/trees/VisibilityTreeRenderer.d.ts +20 -4
- package/lib/esm/components/trees/VisibilityTreeRenderer.js +27 -10
- package/lib/esm/components/trees/VisibilityTreeRenderer.js.map +1 -1
- package/lib/esm/components/trees/category-tree/CategoriesTree.d.ts +7 -2
- package/lib/esm/components/trees/category-tree/CategoriesTree.js +51 -34
- package/lib/esm/components/trees/category-tree/CategoriesTree.js.map +1 -1
- package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js +24 -18
- package/lib/esm/components/trees/category-tree/CategoriesTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/category-tree/CategoryVisibilityHandler.d.ts +2 -2
- package/lib/esm/components/trees/category-tree/CategoryVisibilityHandler.js +18 -13
- package/lib/esm/components/trees/category-tree/CategoryVisibilityHandler.js.map +1 -1
- package/lib/esm/components/trees/common/ContextMenu.js +4 -4
- package/lib/esm/components/trees/common/ContextMenu.js.map +1 -1
- package/lib/esm/components/trees/common/TreeNodeRenderer.d.ts +1 -1
- package/lib/esm/components/trees/common/TreeNodeRenderer.js +4 -4
- package/lib/esm/components/trees/common/TreeNodeRenderer.js.map +1 -1
- package/lib/esm/components/trees/common/TreeRenderer.d.ts +15 -1
- package/lib/esm/components/trees/common/TreeRenderer.js +15 -6
- package/lib/esm/components/trees/common/TreeRenderer.js.map +1 -1
- package/lib/esm/components/trees/common/TreeRenderer.scss +39 -2
- package/lib/esm/components/trees/common/Types.d.ts +8 -0
- package/lib/esm/components/trees/common/Types.js +3 -3
- package/lib/esm/components/trees/common/Types.js.map +1 -1
- package/lib/esm/components/trees/common/UseVisibilityTreeState.d.ts +36 -0
- package/lib/esm/components/trees/common/UseVisibilityTreeState.js +43 -0
- package/lib/esm/components/trees/common/UseVisibilityTreeState.js.map +1 -0
- package/lib/esm/components/trees/common/Utils.js +7 -5
- package/lib/esm/components/trees/common/Utils.js.map +1 -1
- package/lib/esm/components/trees/external-sources-tree/ExternalSources.json +1 -3
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.d.ts +9 -3
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.js +22 -10
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTree.js.map +1 -1
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js +4 -4
- package/lib/esm/components/trees/external-sources-tree/ExternalSourcesTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.d.ts +9 -3
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.js +19 -15
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTree.js.map +1 -1
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTreeComponent.js +6 -5
- package/lib/esm/components/trees/imodel-content-tree/IModelContentTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/index.js +3 -3
- package/lib/esm/components/trees/index.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTree.d.ts +7 -2
- package/lib/esm/components/trees/models-tree/ModelsTree.js +80 -66
- package/lib/esm/components/trees/models-tree/ModelsTree.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js +25 -30
- package/lib/esm/components/trees/models-tree/ModelsTreeComponent.js.map +1 -1
- package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.d.ts +9 -0
- package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.js +27 -0
- package/lib/esm/components/trees/models-tree/ModelsTreeEventHandler.js.map +1 -0
- package/lib/esm/components/trees/models-tree/ModelsVisibilityHandler.js +125 -66
- package/lib/esm/components/trees/models-tree/ModelsVisibilityHandler.js.map +1 -1
- package/lib/esm/components/trees/models-tree/Utils.d.ts +4 -0
- package/lib/esm/components/trees/models-tree/Utils.js +50 -57
- package/lib/esm/components/trees/models-tree/Utils.js.map +1 -1
- package/lib/esm/components/utils/AutoSizer.js +7 -5
- package/lib/esm/components/utils/AutoSizer.js.map +1 -1
- package/lib/esm/components/utils/IsPromiseLike.js +4 -4
- package/lib/esm/components/utils/IsPromiseLike.js.map +1 -1
- package/lib/esm/components/utils/UseTreeTransientState.js +3 -3
- package/lib/esm/components/utils/UseTreeTransientState.js.map +1 -1
- package/lib/esm/tree-widget-react.js +3 -3
- package/lib/esm/tree-widget-react.js.map +1 -1
- package/lib/public/locales/en/TreeWidget.json +1 -0
- package/package.json +47 -46
- package/lib/cjs/e2e-tests/TreeWidget.test.d.ts +0 -2
- package/lib/cjs/e2e-tests/TreeWidget.test.js +0 -51
- package/lib/cjs/e2e-tests/TreeWidget.test.js.map +0 -1
- package/lib/cjs/e2e-tests/utils.d.ts +0 -9
- package/lib/cjs/e2e-tests/utils.js +0 -51
- package/lib/cjs/e2e-tests/utils.js.map +0 -1
- package/lib/esm/e2e-tests/TreeWidget.test.d.ts +0 -2
- package/lib/esm/e2e-tests/TreeWidget.test.js +0 -46
- package/lib/esm/e2e-tests/TreeWidget.test.js.map +0 -1
- package/lib/esm/e2e-tests/utils.d.ts +0 -9
- package/lib/esm/e2e-tests/utils.js +0 -40
- package/lib/esm/e2e-tests/utils.js.map +0 -1
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
2
|
+
import "./TreeSelector.scss";
|
|
3
|
+
import type { TreeRenderProps } from "./SelectableTree";
|
|
4
|
+
/**
|
|
5
|
+
* A definition for trees displayed in [[TreeSelector]]
|
|
6
|
+
* @internal
|
|
7
|
+
*/
|
|
8
|
+
export interface TreeContentDefinition {
|
|
9
|
+
id: string;
|
|
10
|
+
label: string;
|
|
11
|
+
render: (props: TreeRenderProps) => React.ReactNode;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Props for [[TreeSelector]]
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export interface TreeSelectorProps {
|
|
18
|
+
defaultSelectedContentId: string;
|
|
19
|
+
trees: TreeContentDefinition[];
|
|
20
|
+
density?: "enlarged" | "default";
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* A component that accepts a list of trees and renders a select box at the top,
|
|
24
|
+
* allowing to choose which of the provided tree components should be rendered at the bottom.
|
|
25
|
+
* @internal
|
|
26
|
+
*/
|
|
27
|
+
export declare function TreeSelector(props: TreeSelectorProps): JSX.Element;
|
|
28
|
+
//# sourceMappingURL=TreeSelector.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
|
+
import "./TreeSelector.scss";
|
|
7
|
+
import { useMemo, useState } from "react";
|
|
8
|
+
import { MenuItem, Select } from "@itwin/itwinui-react";
|
|
9
|
+
/**
|
|
10
|
+
* A component that accepts a list of trees and renders a select box at the top,
|
|
11
|
+
* allowing to choose which of the provided tree components should be rendered at the bottom.
|
|
12
|
+
* @internal
|
|
13
|
+
*/
|
|
14
|
+
export function TreeSelector(props) {
|
|
15
|
+
const [selectedContentId, setSelectedContentId] = useState(props.defaultSelectedContentId);
|
|
16
|
+
const selectedContent = props.trees.find((c) => c.id === selectedContentId) ?? props.trees[0];
|
|
17
|
+
const isEnlarged = props.density === "enlarged";
|
|
18
|
+
const options = useMemo(() => {
|
|
19
|
+
return props.trees.map((c) => ({ label: c.label, value: c.id }));
|
|
20
|
+
}, [props.trees]);
|
|
21
|
+
return (_jsxs("div", { className: "presentation-components-tree-selector-content", children: [_jsx("div", { className: "presentation-components-tree-selector-content-header", children: options.length > 0 && (_jsx(Select, { onChange: setSelectedContentId, options: options, value: selectedContent.id, size: isEnlarged ? "large" : "small", itemRenderer: (option, itemProps) => (_jsx(MenuItem, { ...option, isSelected: itemProps.isSelected, size: isEnlarged ? "large" : "default", children: option.label })) })) }), _jsx("div", { className: "presentation-components-tree-selector-content-wrapper", children: selectedContent?.render({ density: props.density }) })] }));
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=TreeSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TreeSelector.js","sourceRoot":"","sources":["../../../src/components/TreeSelector.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,qBAAqB,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAyBxD;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,KAAwB;IACnD,MAAM,CAAC,iBAAiB,EAAE,oBAAoB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAC3F,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,iBAAiB,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC9F,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,KAAK,UAAU,CAAC;IAEhD,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,EAAE;QAC3B,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAA2B,CAAC;IAC7F,CAAC,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;IAElB,OAAO,CACL,eAAK,SAAS,EAAC,+CAA+C,aAC5D,cAAK,SAAS,EAAC,sDAAsD,YAClE,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,CACrB,KAAC,MAAM,IACL,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,EAAE,OAAO,EAChB,KAAK,EAAE,eAAe,CAAC,EAAE,EACzB,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EACpC,YAAY,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,CAAC,CACnC,KAAC,QAAQ,OAAK,MAAM,EAAE,UAAU,EAAE,SAAS,CAAC,UAAU,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,YAC3F,MAAM,CAAC,KAAK,GACJ,CACZ,GACD,CACH,GACG,EACN,cAAK,SAAS,EAAC,uDAAuD,YAAE,eAAe,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC,GAAO,IAC9H,CACP,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./TreeSelector.scss\";\nimport { useMemo, useState } from \"react\";\nimport { MenuItem, Select } from \"@itwin/itwinui-react\";\n\nimport type { SelectOption } from \"@itwin/itwinui-react\";\nimport type { TreeRenderProps } from \"./SelectableTree\";\n\n/**\n * A definition for trees displayed in [[TreeSelector]]\n * @internal\n */\nexport interface TreeContentDefinition {\n id: string;\n label: string;\n render: (props: TreeRenderProps) => React.ReactNode;\n}\n\n/**\n * Props for [[TreeSelector]]\n * @internal\n */\nexport interface TreeSelectorProps {\n defaultSelectedContentId: string;\n trees: TreeContentDefinition[];\n density?: \"enlarged\" | \"default\";\n}\n\n/**\n * A component that accepts a list of trees and renders a select box at the top,\n * allowing to choose which of the provided tree components should be rendered at the bottom.\n * @internal\n */\nexport function TreeSelector(props: TreeSelectorProps) {\n const [selectedContentId, setSelectedContentId] = useState(props.defaultSelectedContentId);\n const selectedContent = props.trees.find((c) => c.id === selectedContentId) ?? props.trees[0];\n const isEnlarged = props.density === \"enlarged\";\n\n const options = useMemo(() => {\n return props.trees.map((c) => ({ label: c.label, value: c.id })) as SelectOption<string>[];\n }, [props.trees]);\n\n return (\n <div className=\"presentation-components-tree-selector-content\">\n <div className=\"presentation-components-tree-selector-content-header\">\n {options.length > 0 && (\n <Select\n onChange={setSelectedContentId}\n options={options}\n value={selectedContent.id}\n size={isEnlarged ? \"large\" : \"small\"}\n itemRenderer={(option, itemProps) => (\n <MenuItem {...option} isSelected={itemProps.isSelected} size={isEnlarged ? \"large\" : \"default\"}>\n {option.label}\n </MenuItem>\n )}\n />\n )}\n </div>\n <div className=\"presentation-components-tree-selector-content-wrapper\">{selectedContent?.render({ density: props.density })}</div>\n </div>\n );\n}\n"]}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
|
|
6
|
+
.presentation-components-tree-selector-content {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-direction: column;
|
|
9
|
+
flex: 1;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
|
|
12
|
+
.presentation-components-tree-selector-content-header {
|
|
13
|
+
padding-bottom: var(--iui-size-2xs);
|
|
14
|
+
|
|
15
|
+
.presentation-components-tree-selector-content-selector {
|
|
16
|
+
width: 100%;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.presentation-components-tree-selector-content-wrapper {
|
|
21
|
+
display: flex;
|
|
22
|
+
flex-direction: column;
|
|
23
|
+
flex-grow: 1;
|
|
24
|
+
height: 100%;
|
|
25
|
+
overflow: hidden;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
/// <reference types="react" />
|
|
1
2
|
import "./TreeWidgetUiItemsProvider.scss";
|
|
2
3
|
import { StagePanelLocation, StagePanelSection } from "@itwin/appui-react";
|
|
3
4
|
import type { UiItemsProvider, Widget } from "@itwin/appui-react";
|
|
4
|
-
import type { TreeDefinition } from "./SelectableTree";
|
|
5
|
+
import type { SelectableTreeProps, TreeDefinition } from "./SelectableTree";
|
|
5
6
|
/**
|
|
6
7
|
* Parameters for creating a [[TreeWidgetUiItemsProvider]].
|
|
7
8
|
* @public
|
|
@@ -15,6 +16,8 @@ export interface TreeWidgetOptions {
|
|
|
15
16
|
defaultTreeWidgetPriority?: number;
|
|
16
17
|
/** Trees to show in the widget. Defaults to [[ModelsTreeComponent]] and [[CategoriesTreeComponent]]. */
|
|
17
18
|
trees?: TreeDefinition[];
|
|
19
|
+
/** Modifies the density of the tree widget. `enlarged` widget contains larger content */
|
|
20
|
+
density?: "enlarged" | "default";
|
|
18
21
|
}
|
|
19
22
|
/**
|
|
20
23
|
* Id of the tree widget created by [[TreeWidgetUiItemsProvider]].
|
|
@@ -31,4 +34,9 @@ export declare class TreeWidgetUiItemsProvider implements UiItemsProvider {
|
|
|
31
34
|
constructor(_treeWidgetOptions?: TreeWidgetOptions | undefined);
|
|
32
35
|
provideWidgets(_stageId: string, stageUsage: string, location: StagePanelLocation, section?: StagePanelSection): ReadonlyArray<Widget>;
|
|
33
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* Tree widget component which allows selecting which tree to render.
|
|
39
|
+
* @public
|
|
40
|
+
*/
|
|
41
|
+
export declare function TreeWidgetComponent(props: SelectableTreeProps): JSX.Element;
|
|
34
42
|
//# sourceMappingURL=TreeWidgetUiItemsProvider.d.ts.map
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
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
|
-
*--------------------------------------------------------------------------------------------*/
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
import "./TreeWidgetUiItemsProvider.scss";
|
|
7
|
-
import { ErrorBoundary } from "react-error-boundary";
|
|
8
7
|
import { StagePanelLocation, StagePanelSection, StageUsage } from "@itwin/appui-react";
|
|
9
8
|
import { SvgHierarchyTree } from "@itwin/itwinui-icons-react";
|
|
10
|
-
import { SvgError } from "@itwin/itwinui-illustrations-react";
|
|
11
|
-
import { Button, NonIdealState } from "@itwin/itwinui-react";
|
|
12
9
|
import { TreeWidget } from "../TreeWidget";
|
|
13
|
-
import { SelectableTree } from "./SelectableTree";
|
|
14
10
|
import { CategoriesTreeComponent } from "./trees/category-tree/CategoriesTreeComponent";
|
|
15
11
|
import { ModelsTreeComponent } from "./trees/models-tree/ModelsTreeComponent";
|
|
12
|
+
import { ErrorBoundary } from "react-error-boundary";
|
|
13
|
+
import { SelectableTree } from "./SelectableTree";
|
|
16
14
|
import { useTreeTransientState } from "./utils/UseTreeTransientState";
|
|
15
|
+
import { Button, NonIdealState } from "@itwin/itwinui-react";
|
|
16
|
+
import { SvgError } from "@itwin/itwinui-illustrations-react";
|
|
17
17
|
/**
|
|
18
18
|
* Id of the tree widget created by [[TreeWidgetUiItemsProvider]].
|
|
19
19
|
* @public
|
|
@@ -38,24 +38,30 @@ export class TreeWidgetUiItemsProvider {
|
|
|
38
38
|
{
|
|
39
39
|
id: ModelsTreeComponent.id,
|
|
40
40
|
getLabel: ModelsTreeComponent.getLabel,
|
|
41
|
-
render: () => _jsx(ModelsTreeComponent, {}),
|
|
41
|
+
render: (props) => _jsx(ModelsTreeComponent, { density: props.density }),
|
|
42
42
|
},
|
|
43
43
|
{
|
|
44
44
|
id: CategoriesTreeComponent.id,
|
|
45
45
|
getLabel: CategoriesTreeComponent.getLabel,
|
|
46
|
-
render: () => _jsx(CategoriesTreeComponent, {}),
|
|
46
|
+
render: (props) => _jsx(CategoriesTreeComponent, { density: props.density }),
|
|
47
47
|
},
|
|
48
48
|
];
|
|
49
|
-
return [
|
|
49
|
+
return [
|
|
50
|
+
{
|
|
50
51
|
id: TreeWidgetId,
|
|
51
52
|
label: TreeWidget.translate("treeview"),
|
|
52
|
-
content: _jsx(
|
|
53
|
+
content: _jsx(TreeWidgetComponent, { trees: trees, density: this._treeWidgetOptions?.density }),
|
|
53
54
|
icon: _jsx(SvgHierarchyTree, {}),
|
|
54
55
|
priority: this._treeWidgetOptions?.defaultTreeWidgetPriority,
|
|
55
|
-
}
|
|
56
|
+
},
|
|
57
|
+
];
|
|
56
58
|
}
|
|
57
59
|
}
|
|
58
|
-
|
|
60
|
+
/**
|
|
61
|
+
* Tree widget component which allows selecting which tree to render.
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export function TreeWidgetComponent(props) {
|
|
59
65
|
const ref = useTreeTransientState();
|
|
60
66
|
return (_jsx("div", { ref: ref, className: "tree-widget", children: _jsx(ErrorBoundary, { FallbackComponent: ErrorState, children: _jsx(SelectableTree, { ...props }) }) }));
|
|
61
67
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeWidgetUiItemsProvider.js","sourceRoot":"","sources":["../../../src/components/TreeWidgetUiItemsProvider.tsx"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"TreeWidgetUiItemsProvider.js","sourceRoot":"","sources":["../../../src/components/TreeWidgetUiItemsProvider.tsx"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./TreeWidgetUiItemsProvider.scss\";\nimport { StagePanelLocation, StagePanelSection, StageUsage } from \"@itwin/appui-react\";\nimport { SvgHierarchyTree } from \"@itwin/itwinui-icons-react\";\nimport { TreeWidget } from \"../TreeWidget\";\nimport { CategoriesTreeComponent } from \"./trees/category-tree/CategoriesTreeComponent\";\nimport { ModelsTreeComponent } from \"./trees/models-tree/ModelsTreeComponent\";\n\nimport type { UiItemsProvider, Widget } from \"@itwin/appui-react\";\nimport type { SelectableTreeProps, TreeDefinition } from \"./SelectableTree\";\nimport type { FallbackProps } from \"react-error-boundary\";\nimport { ErrorBoundary } from \"react-error-boundary\";\nimport { SelectableTree } from \"./SelectableTree\";\nimport { useTreeTransientState } from \"./utils/UseTreeTransientState\";\nimport { Button, NonIdealState } from \"@itwin/itwinui-react\";\nimport { SvgError } from \"@itwin/itwinui-illustrations-react\";\n/**\n * Parameters for creating a [[TreeWidgetUiItemsProvider]].\n * @public\n */\nexport interface TreeWidgetOptions {\n /** The stage panel to place the widget in. Defaults to `StagePanelLocation.Right`. */\n defaultPanelLocation?: StagePanelLocation;\n /** The stage panel section to place the widget in. Defaults to `StagePanelSection.Start`. */\n defaultPanelSection?: StagePanelSection;\n /** Widget priority in the stage panel. */\n defaultTreeWidgetPriority?: number;\n /** Trees to show in the widget. Defaults to [[ModelsTreeComponent]] and [[CategoriesTreeComponent]]. */\n trees?: TreeDefinition[];\n /** Modifies the density of the tree widget. `enlarged` widget contains larger content */\n density?: \"enlarged\" | \"default\";\n}\n\n/**\n * Id of the tree widget created by [[TreeWidgetUiItemsProvider]].\n * @public\n */\nexport const TreeWidgetId = \"tree-widget-react:trees\";\n\n/**\n * A [[UiItemsProvider]] implementation that provides a [[SelectableTree]] into a stage panel.\n * @public\n */\nexport class TreeWidgetUiItemsProvider implements UiItemsProvider {\n public readonly id = \"TreeWidgetUiItemsProvider\";\n\n constructor(private _treeWidgetOptions?: TreeWidgetOptions) {}\n\n public provideWidgets(_stageId: string, stageUsage: string, location: StagePanelLocation, section?: StagePanelSection): ReadonlyArray<Widget> {\n const preferredLocation = this._treeWidgetOptions?.defaultPanelLocation ?? StagePanelLocation.Right;\n const preferredPanelSection = this._treeWidgetOptions?.defaultPanelSection ?? StagePanelSection.Start;\n\n if (location !== preferredLocation || section !== preferredPanelSection || stageUsage !== StageUsage.General) {\n return [];\n }\n\n const trees: TreeDefinition[] = this._treeWidgetOptions?.trees ?? [\n {\n id: ModelsTreeComponent.id,\n getLabel: ModelsTreeComponent.getLabel,\n render: (props) => <ModelsTreeComponent density={props.density} />,\n },\n {\n id: CategoriesTreeComponent.id,\n getLabel: CategoriesTreeComponent.getLabel,\n render: (props) => <CategoriesTreeComponent density={props.density} />,\n },\n ];\n\n return [\n {\n id: TreeWidgetId,\n label: TreeWidget.translate(\"treeview\"),\n content: <TreeWidgetComponent trees={trees} density={this._treeWidgetOptions?.density} />,\n icon: <SvgHierarchyTree />,\n priority: this._treeWidgetOptions?.defaultTreeWidgetPriority,\n },\n ];\n }\n}\n\n/**\n * Tree widget component which allows selecting which tree to render.\n * @public\n */\nexport function TreeWidgetComponent(props: SelectableTreeProps) {\n const ref = useTreeTransientState<HTMLDivElement>();\n\n return (\n <div ref={ref} className=\"tree-widget\">\n <ErrorBoundary FallbackComponent={ErrorState}>\n <SelectableTree {...props} />\n </ErrorBoundary>\n </div>\n );\n}\n\nfunction ErrorState({ resetErrorBoundary }: FallbackProps) {\n return (\n <NonIdealState\n svg={<SvgError />}\n heading={TreeWidget.translate(\"error\")}\n description={TreeWidget.translate(\"generic-error-description\")}\n actions={\n <Button styleType={\"high-visibility\"} onClick={resetErrorBoundary}>\n {TreeWidget.translate(\"retry\")}\n </Button>\n }\n />\n );\n}"]}
|
|
@@ -5,6 +5,7 @@ import type { CommonProps } from "@itwin/core-react";
|
|
|
5
5
|
/** @internal */
|
|
6
6
|
export interface TreeHeaderButtonProps {
|
|
7
7
|
viewport: Viewport;
|
|
8
|
+
density?: "default" | "enlarged";
|
|
8
9
|
}
|
|
9
10
|
/** @internal */
|
|
10
11
|
export interface TreeHeaderProps extends CommonProps {
|
|
@@ -20,6 +21,8 @@ export interface TreeHeaderProps extends CommonProps {
|
|
|
20
21
|
onSelectedChanged: (index: number) => void;
|
|
21
22
|
/** Header buttons */
|
|
22
23
|
children?: React.ReactNode;
|
|
24
|
+
/** Modifies the density of tree header. `enlarged` header contains larger content */
|
|
25
|
+
density?: "default" | "enlarged";
|
|
23
26
|
}
|
|
24
27
|
/** @internal */
|
|
25
28
|
export declare function TreeHeader(props: TreeHeaderProps): JSX.Element;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
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
|
-
*--------------------------------------------------------------------------------------------*/
|
|
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
|
+
*--------------------------------------------------------------------------------------------*/
|
|
6
6
|
import "./TreeHeader.scss";
|
|
7
7
|
import classnames from "classnames";
|
|
8
8
|
import { Children, useEffect, useRef, useState } from "react";
|
|
@@ -11,11 +11,12 @@ import { ButtonGroup, Divider, DropdownMenu, IconButton, SearchBox } from "@itwi
|
|
|
11
11
|
import { TreeWidget } from "../../TreeWidget";
|
|
12
12
|
/** @internal */
|
|
13
13
|
export function TreeHeader(props) {
|
|
14
|
-
const { onFilterStart, onFilterClear, resultCount, selectedIndex, onSelectedChanged, children, className } = props;
|
|
14
|
+
const { onFilterStart, onFilterClear, resultCount, selectedIndex, onSelectedChanged, children, density, className } = props;
|
|
15
15
|
const [isSearchOpen, setIsSearchOpen] = useState(false);
|
|
16
|
-
|
|
16
|
+
const isEnlarged = density === "enlarged";
|
|
17
|
+
return (_jsxs("div", { className: classnames("tree-widget-tree-header", className, isEnlarged && "enlarge"), children: [_jsx(HeaderButtons, { contracted: isSearchOpen, isEnlarged: isEnlarged, children: children }), _jsx(DebouncedSearchBox, { isOpened: isSearchOpen, onOpen: () => setIsSearchOpen(true), onClose: () => setIsSearchOpen(false), onChange: (value) => (value ? onFilterStart(value) : onFilterClear()), delay: 500, selectedResultIndex: selectedIndex, resultCount: resultCount, onSelectedResultChanged: onSelectedChanged, size: isEnlarged ? "large" : "small" })] }));
|
|
17
18
|
}
|
|
18
|
-
function DebouncedSearchBox({ isOpened, selectedResultIndex, resultCount, onSelectedResultChanged, onChange, onOpen, onClose, delay }) {
|
|
19
|
+
function DebouncedSearchBox({ isOpened, selectedResultIndex, resultCount, onSelectedResultChanged, onChange, onOpen, onClose, delay, size, }) {
|
|
19
20
|
const [inputValue, setInputValue] = useState("");
|
|
20
21
|
const onChangeRef = useRef(onChange);
|
|
21
22
|
// save latest `onChange` reference into `useRef` to avoid restarting timeout when `onChange` reference changes.
|
|
@@ -32,27 +33,31 @@ function DebouncedSearchBox({ isOpened, selectedResultIndex, resultCount, onSele
|
|
|
32
33
|
clearTimeout(timeoutId);
|
|
33
34
|
};
|
|
34
35
|
}, [inputValue, delay]);
|
|
35
|
-
return _jsxs(SearchBox, { expandable: true, onExpand: onOpen, onCollapse: onClose, className: classnames("tree-widget-search-box", !isOpened && "contracted"), children: [_jsx(SearchBox.CollapsedState, { children: _jsx(SearchBox.ExpandButton, { title: TreeWidget.translate("searchBox.searchForSomething"), "aria-label": TreeWidget.translate("searchBox.open"), size:
|
|
36
|
+
return (_jsxs(SearchBox, { expandable: true, onExpand: onOpen, onCollapse: onClose, size: size, className: classnames("tree-widget-search-box", !isOpened && "contracted"), children: [_jsx(SearchBox.CollapsedState, { children: _jsx(SearchBox.ExpandButton, { title: TreeWidget.translate("searchBox.searchForSomething"), "aria-label": TreeWidget.translate("searchBox.open"), size: size }) }), _jsxs(SearchBox.ExpandedState, { children: [_jsx(SearchBox.Input, { placeholder: TreeWidget.translate("searchBox.search"), onChange: (e) => setInputValue(e.currentTarget.value) }), _jsx(SearchResultStepper, { selectedIndex: selectedResultIndex, total: resultCount, onStep: onSelectedResultChanged, size: size }), _jsx(SearchBox.CollapseButton, { onClick: () => {
|
|
36
37
|
setInputValue("");
|
|
37
38
|
onClose();
|
|
38
|
-
}, size:
|
|
39
|
+
}, size: size, "aria-label": TreeWidget.translate("searchBox.close") })] })] }));
|
|
39
40
|
}
|
|
40
41
|
function HeaderButtons(props) {
|
|
41
42
|
const className = classnames("button-container", props.contracted && "contracted");
|
|
43
|
+
const dropdownClassName = classnames("dropdown-item", props.isEnlarged && "enlarge");
|
|
42
44
|
return (_jsx(ButtonGroup, { className: className, overflowButton: (overflowStart) => (_jsx(DropdownMenu, { menuItems: () => Children.toArray(props.children)
|
|
43
|
-
.slice(overflowStart
|
|
44
|
-
.map((btn, index) => _jsx("li", { className:
|
|
45
|
+
.slice(overflowStart)
|
|
46
|
+
.map((btn, index) => (_jsx("li", { className: dropdownClassName, role: "menuitem", children: btn }, index))), className: "tree-header-button-dropdown-container", children: _jsx(IconButton, { title: TreeWidget.translate("dropdownMore"), styleType: "borderless", size: props.isEnlarged ? undefined : "small", children: _jsx(SvgMore, {}) }) })), children: props.children }));
|
|
45
47
|
}
|
|
46
48
|
function SearchResultStepper(props) {
|
|
47
49
|
const { selectedIndex = 1, total, onStep } = props;
|
|
48
|
-
if (!total)
|
|
50
|
+
if (!total) {
|
|
49
51
|
return null;
|
|
50
|
-
|
|
51
|
-
|
|
52
|
+
}
|
|
53
|
+
return (_jsxs(_Fragment, { children: [_jsx("span", { className: "searchbox-stepping-count", children: `${selectedIndex}/${total}` }), _jsx(Divider, { orientation: "vertical" }), _jsx(SearchBox.Button, { title: TreeWidget.translate("searchBox.previous"), size: props.size, onClick: () => {
|
|
54
|
+
if (selectedIndex > 1) {
|
|
52
55
|
onStep(selectedIndex - 1);
|
|
53
|
-
|
|
54
|
-
|
|
56
|
+
}
|
|
57
|
+
}, children: _jsx(SvgCaretUpSmall, {}) }), _jsx(SearchBox.Button, { title: TreeWidget.translate("searchBox.next"), size: props.size, onClick: () => {
|
|
58
|
+
if (selectedIndex < total) {
|
|
55
59
|
onStep(selectedIndex + 1);
|
|
60
|
+
}
|
|
56
61
|
}, children: _jsx(SvgCaretDownSmall, {}) })] }));
|
|
57
62
|
}
|
|
58
63
|
//# sourceMappingURL=TreeHeader.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TreeHeader.js","sourceRoot":"","sources":["../../../../src/components/tree-header/TreeHeader.tsx"],"names":[],"mappings":";AAAA;;;+FAG+F;AAE/F,OAAO,mBAAmB,CAAC;AAC3B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AA0B9C,gBAAgB;AAChB,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IACnH,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACjE,OAAO,CACL,eAAK,SAAS,EAAE,UAAU,CAAC,yBAAyB,EAAE,SAAS,CAAC,aAC9D,KAAC,aAAa,IAAC,UAAU,EAAE,YAAY,YACpC,QAAQ,GACK,EAChB,KAAC,kBAAkB,IACjB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EACnC,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,EACnE,KAAK,EAAE,GAAG,EACV,mBAAmB,EAAE,aAAa,EAClC,WAAW,EAAE,WAAW,EACxB,uBAAuB,EAAE,iBAAiB,GAC1C,IACE,CACP,CAAC;AACJ,CAAC;AAaD,SAAS,kBAAkB,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,WAAW,EAAE,uBAAuB,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAA2B;IAC5J,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,gHAAgH;IAChH,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,EAAE;YACf,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,OAAO;SACR;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAExB,OAAO,MAAC,SAAS,IACf,UAAU,QACV,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,OAAO,EACnB,SAAS,EAAE,UAAU,CAAC,wBAAwB,EAAE,CAAC,QAAQ,IAAI,YAAY,CAAC,aAE1E,KAAC,SAAS,CAAC,cAAc,cACvB,KAAC,SAAS,CAAC,YAAY,IACrB,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,8BAA8B,CAAC,gBAC/C,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAClD,IAAI,EAAC,OAAO,GACZ,GACuB,EAC3B,MAAC,SAAS,CAAC,aAAa,eACtB,KAAC,SAAS,CAAC,KAAK,IACd,WAAW,EAAE,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,EACrD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,EACrD,SAAS,EAAC,cAAc,GACxB,EACF,KAAC,mBAAmB,IAClB,aAAa,EAAE,mBAAmB,EAClC,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,uBAAuB,GAC/B,EACF,KAAC,SAAS,CAAC,cAAc,IACvB,OAAO,EAAE,GAAG,EAAE;4BACZ,aAAa,CAAC,EAAE,CAAC,CAAC;4BAClB,OAAO,EAAE,CAAC;wBACZ,CAAC,EACD,IAAI,EAAC,OAAO,gBACA,UAAU,CAAC,SAAS,CAAC,iBAAiB,CAAC,GACnD,IACsB,IAChB,CAAC;AACf,CAAC;AAOD,SAAS,aAAa,CAAC,KAAyB;IAC9C,MAAM,SAAS,GAAG,UAAU,CAC1B,kBAAkB,EAClB,KAAK,CAAC,UAAU,IAAI,YAAY,CACjC,CAAC;IAEF,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,CACjC,KAAC,YAAY,IACX,SAAS,EAAE,GAAG,EAAE,CACd,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;iBAC7B,KAAK,CAAC,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,GAAG,CAAC,CAAC;iBAC9D,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,aAAgB,SAAS,EAAC,eAAe,EAAC,IAAI,EAAC,UAAU,YAAE,GAAG,IAArD,KAAK,CAAsD,CAAC,EAE9F,SAAS,EAAC,uCAAuC,YAEjD,KAAC,UAAU,IAAC,SAAS,EAAC,YAAY,EAAC,IAAI,EAAC,OAAO,YAC7C,KAAC,OAAO,KAAG,GACA,GACA,CAChB,YAEA,KAAK,CAAC,QAAQ,GACH,CACf,CAAC;AACJ,CAAC;AAQD,SAAS,mBAAmB,CAAC,KAA+B;IAC1D,MAAM,EAAE,aAAa,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACnD,IAAI,CAAC,KAAK;QACR,OAAO,IAAI,CAAC;IAEd,OAAO,CACL,8BACE,eAAM,SAAS,EAAC,0BAA0B,YAAE,GAAG,aAAa,IAAI,KAAK,EAAE,GAAQ,EAC/E,KAAC,OAAO,IAAC,WAAW,EAAC,UAAU,GAAG,EAClC,KAAC,SAAS,CAAC,MAAM,IACf,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,oBAAoB,CAAC,EACjD,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,aAAa,GAAG,CAAC;wBACnB,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;gBAC9B,CAAC,YAED,KAAC,eAAe,KAAG,GACF,EACnB,KAAC,SAAS,CAAC,MAAM,IACf,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAC7C,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,aAAa,GAAG,KAAK;wBACvB,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;gBAC9B,CAAC,YAED,KAAC,iBAAiB,KAAG,GACJ,IAClB,CACJ,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n* Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n* See LICENSE.md in the project root for license terms and full copyright notice.\n*--------------------------------------------------------------------------------------------*/\n\nimport \"./TreeHeader.scss\";\nimport classnames from \"classnames\";\nimport { Children, useEffect, useRef, useState } from \"react\";\nimport { SvgCaretDownSmall, SvgCaretUpSmall, SvgMore } from \"@itwin/itwinui-icons-react\";\nimport { ButtonGroup, Divider, DropdownMenu, IconButton, SearchBox } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../TreeWidget\";\n\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { CommonProps } from \"@itwin/core-react\";\n\n/** @internal */\nexport interface TreeHeaderButtonProps {\n viewport: Viewport;\n}\n\n/** @internal */\nexport interface TreeHeaderProps extends CommonProps {\n /** Filtering is cleared after everything's loaded */\n onFilterStart: (newFilter: string) => void;\n /** listens for onClick event for Clear (x) icon */\n onFilterClear: () => void;\n /** Total number of results/entries */\n resultCount?: number;\n /** Current selected result index */\n selectedIndex?: number;\n /** Callback to currently selected result/entry change */\n onSelectedChanged: (index: number) => void;\n /** Header buttons */\n children?: React.ReactNode;\n}\n\n/** @internal */\nexport function TreeHeader(props: TreeHeaderProps) {\n const { onFilterStart, onFilterClear, resultCount, selectedIndex, onSelectedChanged, children, className } = props;\n const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);\n return (\n <div className={classnames(\"tree-widget-tree-header\", className)}>\n <HeaderButtons contracted={isSearchOpen}>\n {children}\n </HeaderButtons>\n <DebouncedSearchBox\n isOpened={isSearchOpen}\n onOpen={() => setIsSearchOpen(true)}\n onClose={() => setIsSearchOpen(false)}\n onChange={(value) => value ? onFilterStart(value) : onFilterClear()}\n delay={500}\n selectedResultIndex={selectedIndex}\n resultCount={resultCount}\n onSelectedResultChanged={onSelectedChanged}\n />\n </div>\n );\n}\n\ninterface DebouncedSearchBoxProps {\n isOpened: boolean;\n onOpen: () => void;\n onClose: () => void;\n onChange: (value: string) => void;\n delay: number;\n selectedResultIndex?: number;\n resultCount?: number;\n onSelectedResultChanged: (index: number) => void;\n}\n\nfunction DebouncedSearchBox({ isOpened, selectedResultIndex, resultCount, onSelectedResultChanged, onChange, onOpen, onClose, delay }: DebouncedSearchBoxProps) {\n const [inputValue, setInputValue] = useState<string>(\"\");\n const onChangeRef = useRef(onChange);\n // save latest `onChange` reference into `useRef` to avoid restarting timeout when `onChange` reference changes.\n onChangeRef.current = onChange;\n\n useEffect(() => {\n if (!inputValue) {\n onChangeRef.current(\"\");\n return;\n }\n\n const timeoutId = setTimeout(() => {\n onChangeRef.current(inputValue);\n }, delay);\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [inputValue, delay]);\n\n return <SearchBox\n expandable\n onExpand={onOpen}\n onCollapse={onClose}\n className={classnames(\"tree-widget-search-box\", !isOpened && \"contracted\")}\n >\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n title={TreeWidget.translate(\"searchBox.searchForSomething\")}\n aria-label={TreeWidget.translate(\"searchBox.open\")}\n size=\"small\"\n />\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState >\n <SearchBox.Input\n placeholder={TreeWidget.translate(\"searchBox.search\")}\n onChange={(e) => setInputValue(e.currentTarget.value)}\n className=\"search-input\"\n />\n <SearchResultStepper\n selectedIndex={selectedResultIndex}\n total={resultCount}\n onStep={onSelectedResultChanged}\n />\n <SearchBox.CollapseButton\n onClick={() => {\n setInputValue(\"\");\n onClose();\n }}\n size=\"small\"\n aria-label={TreeWidget.translate(\"searchBox.close\")}\n />\n </SearchBox.ExpandedState>\n </SearchBox>;\n}\n\ninterface HeaderButtonsProps {\n contracted: boolean;\n children?: React.ReactNode;\n}\n\nfunction HeaderButtons(props: HeaderButtonsProps) {\n const className = classnames(\n \"button-container\",\n props.contracted && \"contracted\",\n );\n\n return (\n <ButtonGroup\n className={className}\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={() =>\n Children.toArray(props.children)\n .slice(overflowStart === 0 ? overflowStart : overflowStart - 1)\n .map((btn, index) => <li key={index} className=\"dropdown-item\" role=\"menuitem\">{btn}</li>)\n }\n className=\"tree-header-button-dropdown-container\"\n >\n <IconButton styleType=\"borderless\" size=\"small\">\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.children}\n </ButtonGroup>\n );\n}\n\ninterface SearchResultStepperProps {\n total?: number;\n onStep: (newIndex: number) => void;\n selectedIndex?: number;\n}\n\nfunction SearchResultStepper(props: SearchResultStepperProps) {\n const { selectedIndex = 1, total, onStep } = props;\n if (!total)\n return null;\n\n return (\n <>\n <span className=\"searchbox-stepping-count\">{`${selectedIndex}/${total}`}</span>\n <Divider orientation=\"vertical\" />\n <SearchBox.Button\n title={TreeWidget.translate(\"searchBox.previous\")}\n size=\"small\"\n onClick={() => {\n if (selectedIndex > 1)\n onStep(selectedIndex - 1);\n }}\n >\n <SvgCaretUpSmall />\n </SearchBox.Button>\n <SearchBox.Button\n title={TreeWidget.translate(\"searchBox.next\")}\n size=\"small\"\n onClick={() => {\n if (selectedIndex < total)\n onStep(selectedIndex + 1);\n }}\n >\n <SvgCaretDownSmall />\n </SearchBox.Button>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"TreeHeader.js","sourceRoot":"","sources":["../../../../src/components/tree-header/TreeHeader.tsx"],"names":[],"mappings":";AAAA;;;gGAGgG;AAEhG,OAAO,mBAAmB,CAAC;AAC3B,OAAO,UAAU,MAAM,YAAY,CAAC;AACpC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACzF,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AA6B9C,gBAAgB;AAChB,MAAM,UAAU,UAAU,CAAC,KAAsB;IAC/C,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;IAC5H,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAU,KAAK,CAAC,CAAC;IACjE,MAAM,UAAU,GAAG,OAAO,KAAK,UAAU,CAAC;IAC1C,OAAO,CACL,eAAK,SAAS,EAAE,UAAU,CAAC,yBAAyB,EAAE,SAAS,EAAE,UAAU,IAAI,SAAS,CAAC,aACvF,KAAC,aAAa,IAAC,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,YAC5D,QAAQ,GACK,EAChB,KAAC,kBAAkB,IACjB,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EACnC,OAAO,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,EACrC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,EAAE,CAAC,EACrE,KAAK,EAAE,GAAG,EACV,mBAAmB,EAAE,aAAa,EAClC,WAAW,EAAE,WAAW,EACxB,uBAAuB,EAAE,iBAAiB,EAC1C,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,GACpC,IACE,CACP,CAAC;AACJ,CAAC;AAcD,SAAS,kBAAkB,CAAC,EAC1B,QAAQ,EACR,mBAAmB,EACnB,WAAW,EACX,uBAAuB,EACvB,QAAQ,EACR,MAAM,EACN,OAAO,EACP,KAAK,EACL,IAAI,GACoB;IACxB,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAS,EAAE,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,gHAAgH;IAChH,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,CAAC,UAAU,EAAE;YACf,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxB,OAAO;SACR;QAED,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE;YAChC,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAClC,CAAC,EAAE,KAAK,CAAC,CAAC;QAEV,OAAO,GAAG,EAAE;YACV,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;IAExB,OAAO,CACL,MAAC,SAAS,IAAC,UAAU,QAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,wBAAwB,EAAE,CAAC,QAAQ,IAAI,YAAY,CAAC,aACjJ,KAAC,SAAS,CAAC,cAAc,cACvB,KAAC,SAAS,CAAC,YAAY,IACrB,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,8BAA8B,CAAC,gBAC/C,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAClD,IAAI,EAAE,IAAI,GACV,GACuB,EAC3B,MAAC,SAAS,CAAC,aAAa,eACtB,KAAC,SAAS,CAAC,KAAK,IACd,WAAW,EAAE,UAAU,CAAC,SAAS,CAAC,kBAAkB,CAAC,EACrD,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,GACrD,EACF,KAAC,mBAAmB,IAAC,aAAa,EAAE,mBAAmB,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,uBAAuB,EAAE,IAAI,EAAE,IAAI,GAAI,EAC5H,KAAC,SAAS,CAAC,cAAc,IACvB,OAAO,EAAE,GAAG,EAAE;4BACZ,aAAa,CAAC,EAAE,CAAC,CAAC;4BAClB,OAAO,EAAE,CAAC;wBACZ,CAAC,EACD,IAAI,EAAE,IAAI,gBACE,UAAU,CAAC,SAAS,CAAC,iBAAiB,CAAC,GACnD,IACsB,IAChB,CACb,CAAC;AACJ,CAAC;AAQD,SAAS,aAAa,CAAC,KAAyB;IAC9C,MAAM,SAAS,GAAG,UAAU,CAAC,kBAAkB,EAAE,KAAK,CAAC,UAAU,IAAI,YAAY,CAAC,CAAC;IACnF,MAAM,iBAAiB,GAAG,UAAU,CAAC,eAAe,EAAE,KAAK,CAAC,UAAU,IAAI,SAAS,CAAC,CAAC;IAErF,OAAO,CACL,KAAC,WAAW,IACV,SAAS,EAAE,SAAS,EACpB,cAAc,EAAE,CAAC,aAAa,EAAE,EAAE,CAAC,CACjC,KAAC,YAAY,IACX,SAAS,EAAE,GAAG,EAAE,CACd,QAAQ,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;iBAC7B,KAAK,CAAC,aAAa,CAAC;iBACpB,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,CACnB,aAAgB,SAAS,EAAE,iBAAiB,EAAE,IAAI,EAAC,UAAU,YAC1D,GAAG,IADG,KAAK,CAET,CACN,CAAC,EAEN,SAAS,EAAC,uCAAuC,YAEjD,KAAC,UAAU,IAAC,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,cAAc,CAAC,EAAE,SAAS,EAAC,YAAY,EAAC,IAAI,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,YAC1H,KAAC,OAAO,KAAG,GACA,GACA,CAChB,YAEA,KAAK,CAAC,QAAQ,GACH,CACf,CAAC;AACJ,CAAC;AASD,SAAS,mBAAmB,CAAC,KAA+B;IAC1D,MAAM,EAAE,aAAa,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,KAAK,CAAC;IACnD,IAAI,CAAC,KAAK,EAAE;QACV,OAAO,IAAI,CAAC;KACb;IAED,OAAO,CACL,8BACE,eAAM,SAAS,EAAC,0BAA0B,YAAE,GAAG,aAAa,IAAI,KAAK,EAAE,GAAQ,EAC/E,KAAC,OAAO,IAAC,WAAW,EAAC,UAAU,GAAG,EAClC,KAAC,SAAS,CAAC,MAAM,IACf,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,oBAAoB,CAAC,EACjD,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,aAAa,GAAG,CAAC,EAAE;wBACrB,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;qBAC3B;gBACH,CAAC,YAED,KAAC,eAAe,KAAG,GACF,EACnB,KAAC,SAAS,CAAC,MAAM,IACf,KAAK,EAAE,UAAU,CAAC,SAAS,CAAC,gBAAgB,CAAC,EAC7C,IAAI,EAAE,KAAK,CAAC,IAAI,EAChB,OAAO,EAAE,GAAG,EAAE;oBACZ,IAAI,aAAa,GAAG,KAAK,EAAE;wBACzB,MAAM,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;qBAC3B;gBACH,CAAC,YAED,KAAC,iBAAiB,KAAG,GACJ,IAClB,CACJ,CAAC;AACJ,CAAC","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport \"./TreeHeader.scss\";\nimport classnames from \"classnames\";\nimport { Children, useEffect, useRef, useState } from \"react\";\nimport { SvgCaretDownSmall, SvgCaretUpSmall, SvgMore } from \"@itwin/itwinui-icons-react\";\nimport { ButtonGroup, Divider, DropdownMenu, IconButton, SearchBox } from \"@itwin/itwinui-react\";\nimport { TreeWidget } from \"../../TreeWidget\";\n\nimport type { Viewport } from \"@itwin/core-frontend\";\nimport type { CommonProps } from \"@itwin/core-react\";\n\n/** @internal */\nexport interface TreeHeaderButtonProps {\n viewport: Viewport;\n density?: \"default\" | \"enlarged\";\n}\n\n/** @internal */\nexport interface TreeHeaderProps extends CommonProps {\n /** Filtering is cleared after everything's loaded */\n onFilterStart: (newFilter: string) => void;\n /** listens for onClick event for Clear (x) icon */\n onFilterClear: () => void;\n /** Total number of results/entries */\n resultCount?: number;\n /** Current selected result index */\n selectedIndex?: number;\n /** Callback to currently selected result/entry change */\n onSelectedChanged: (index: number) => void;\n /** Header buttons */\n children?: React.ReactNode;\n /** Modifies the density of tree header. `enlarged` header contains larger content */\n density?: \"default\" | \"enlarged\";\n}\n\n/** @internal */\nexport function TreeHeader(props: TreeHeaderProps) {\n const { onFilterStart, onFilterClear, resultCount, selectedIndex, onSelectedChanged, children, density, className } = props;\n const [isSearchOpen, setIsSearchOpen] = useState<boolean>(false);\n const isEnlarged = density === \"enlarged\";\n return (\n <div className={classnames(\"tree-widget-tree-header\", className, isEnlarged && \"enlarge\")}>\n <HeaderButtons contracted={isSearchOpen} isEnlarged={isEnlarged}>\n {children}\n </HeaderButtons>\n <DebouncedSearchBox\n isOpened={isSearchOpen}\n onOpen={() => setIsSearchOpen(true)}\n onClose={() => setIsSearchOpen(false)}\n onChange={(value) => (value ? onFilterStart(value) : onFilterClear())}\n delay={500}\n selectedResultIndex={selectedIndex}\n resultCount={resultCount}\n onSelectedResultChanged={onSelectedChanged}\n size={isEnlarged ? \"large\" : \"small\"}\n />\n </div>\n );\n}\n\ninterface DebouncedSearchBoxProps {\n isOpened: boolean;\n onOpen: () => void;\n onClose: () => void;\n onChange: (value: string) => void;\n delay: number;\n selectedResultIndex?: number;\n resultCount?: number;\n onSelectedResultChanged: (index: number) => void;\n size?: \"large\" | \"small\";\n}\n\nfunction DebouncedSearchBox({\n isOpened,\n selectedResultIndex,\n resultCount,\n onSelectedResultChanged,\n onChange,\n onOpen,\n onClose,\n delay,\n size,\n}: DebouncedSearchBoxProps) {\n const [inputValue, setInputValue] = useState<string>(\"\");\n const onChangeRef = useRef(onChange);\n // save latest `onChange` reference into `useRef` to avoid restarting timeout when `onChange` reference changes.\n onChangeRef.current = onChange;\n\n useEffect(() => {\n if (!inputValue) {\n onChangeRef.current(\"\");\n return;\n }\n\n const timeoutId = setTimeout(() => {\n onChangeRef.current(inputValue);\n }, delay);\n\n return () => {\n clearTimeout(timeoutId);\n };\n }, [inputValue, delay]);\n\n return (\n <SearchBox expandable onExpand={onOpen} onCollapse={onClose} size={size} className={classnames(\"tree-widget-search-box\", !isOpened && \"contracted\")}>\n <SearchBox.CollapsedState>\n <SearchBox.ExpandButton\n title={TreeWidget.translate(\"searchBox.searchForSomething\")}\n aria-label={TreeWidget.translate(\"searchBox.open\")}\n size={size}\n />\n </SearchBox.CollapsedState>\n <SearchBox.ExpandedState>\n <SearchBox.Input\n placeholder={TreeWidget.translate(\"searchBox.search\")}\n onChange={(e) => setInputValue(e.currentTarget.value)}\n />\n <SearchResultStepper selectedIndex={selectedResultIndex} total={resultCount} onStep={onSelectedResultChanged} size={size} />\n <SearchBox.CollapseButton\n onClick={() => {\n setInputValue(\"\");\n onClose();\n }}\n size={size}\n aria-label={TreeWidget.translate(\"searchBox.close\")}\n />\n </SearchBox.ExpandedState>\n </SearchBox>\n );\n}\n\ninterface HeaderButtonsProps {\n contracted: boolean;\n children?: React.ReactNode;\n isEnlarged?: boolean;\n}\n\nfunction HeaderButtons(props: HeaderButtonsProps) {\n const className = classnames(\"button-container\", props.contracted && \"contracted\");\n const dropdownClassName = classnames(\"dropdown-item\", props.isEnlarged && \"enlarge\");\n\n return (\n <ButtonGroup\n className={className}\n overflowButton={(overflowStart) => (\n <DropdownMenu\n menuItems={() =>\n Children.toArray(props.children)\n .slice(overflowStart)\n .map((btn, index) => (\n <li key={index} className={dropdownClassName} role=\"menuitem\">\n {btn}\n </li>\n ))\n }\n className=\"tree-header-button-dropdown-container\"\n >\n <IconButton title={TreeWidget.translate(\"dropdownMore\")} styleType=\"borderless\" size={props.isEnlarged ? undefined : \"small\"}>\n <SvgMore />\n </IconButton>\n </DropdownMenu>\n )}\n >\n {props.children}\n </ButtonGroup>\n );\n}\n\ninterface SearchResultStepperProps {\n total?: number;\n onStep: (newIndex: number) => void;\n selectedIndex?: number;\n size?: \"large\" | \"small\";\n}\n\nfunction SearchResultStepper(props: SearchResultStepperProps) {\n const { selectedIndex = 1, total, onStep } = props;\n if (!total) {\n return null;\n }\n\n return (\n <>\n <span className=\"searchbox-stepping-count\">{`${selectedIndex}/${total}`}</span>\n <Divider orientation=\"vertical\" />\n <SearchBox.Button\n title={TreeWidget.translate(\"searchBox.previous\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex > 1) {\n onStep(selectedIndex - 1);\n }\n }}\n >\n <SvgCaretUpSmall />\n </SearchBox.Button>\n <SearchBox.Button\n title={TreeWidget.translate(\"searchBox.next\")}\n size={props.size}\n onClick={() => {\n if (selectedIndex < total) {\n onStep(selectedIndex + 1);\n }\n }}\n >\n <SvgCaretDownSmall />\n </SearchBox.Button>\n </>\n );\n}\n"]}
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
width: 100%;
|
|
15
15
|
height: var(--iui-size-xl);
|
|
16
16
|
|
|
17
|
+
&.enlarge {
|
|
18
|
+
height: calc(var(--iui-size-xl) + var(--iui-size-m));
|
|
19
|
+
}
|
|
20
|
+
|
|
17
21
|
> * {
|
|
18
22
|
width: 100%;
|
|
19
23
|
height: 100%;
|
|
@@ -66,4 +70,28 @@
|
|
|
66
70
|
width: var(--iui-size-xl);
|
|
67
71
|
}
|
|
68
72
|
}
|
|
69
|
-
|
|
73
|
+
|
|
74
|
+
&.enlarge {
|
|
75
|
+
--enlarged-header-height: calc(var(--iui-size-xl) + var(--iui-size-m));
|
|
76
|
+
|
|
77
|
+
height: var(--enlarged-header-height);
|
|
78
|
+
min-width: calc(100% - var(--enlarged-header-height));
|
|
79
|
+
|
|
80
|
+
.tree-widget-search-box {
|
|
81
|
+
height: var(--enlarged-header-height);
|
|
82
|
+
width: calc(100% - var(--enlarged-header-height));
|
|
83
|
+
|
|
84
|
+
&.contracted {
|
|
85
|
+
width: var(--enlarged-header-height);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.button-container {
|
|
90
|
+
width: calc(100% - var(--enlarged-header-height));
|
|
91
|
+
|
|
92
|
+
&.contracted {
|
|
93
|
+
width: var(--enlarged-header-height);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
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
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
5
|
import { QueryRowFormat } from "@itwin/core-common";
|
|
6
6
|
import { PerModelCategoryVisibility } from "@itwin/core-frontend";
|
|
7
7
|
const EMPTY_CATEGORIES_ARRAY = [];
|
|
@@ -14,8 +14,9 @@ export async function toggleAllCategories(viewManager, imodel, display, viewport
|
|
|
14
14
|
const activeView = viewport ?? viewManager.getFirstOpenView();
|
|
15
15
|
const ids = await getCategories(imodel, activeView);
|
|
16
16
|
// istanbul ignore if
|
|
17
|
-
if (ids.length === 0)
|
|
17
|
+
if (ids.length === 0) {
|
|
18
18
|
return;
|
|
19
|
+
}
|
|
19
20
|
await enableCategory(viewManager, imodel, ids, display, forAllViewports ?? false);
|
|
20
21
|
}
|
|
21
22
|
/**
|
|
@@ -31,8 +32,9 @@ export async function getCategories(imodel, viewport) {
|
|
|
31
32
|
* @internal
|
|
32
33
|
*/
|
|
33
34
|
export async function enableCategory(viewManager, imodel, ids, enabled, forAllViewports, enableAllSubCategories = true) {
|
|
34
|
-
if (!viewManager.selectedView)
|
|
35
|
+
if (!viewManager.selectedView) {
|
|
35
36
|
return;
|
|
37
|
+
}
|
|
36
38
|
const updateViewport = async (vp) => {
|
|
37
39
|
// Only act on viewports that are both 3D or both 2D. Important if we have multiple viewports opened and we
|
|
38
40
|
// are using 'allViewports' property
|
|
@@ -42,8 +44,9 @@ export async function enableCategory(viewManager, imodel, ids, enabled, forAllVi
|
|
|
42
44
|
const modelsContainingOverrides = [];
|
|
43
45
|
for (const ovr of vp.perModelCategoryVisibility) {
|
|
44
46
|
// istanbul ignore else
|
|
45
|
-
if (ids.findIndex((id) => id === ovr.categoryId) !== -1)
|
|
47
|
+
if (ids.findIndex((id) => id === ovr.categoryId) !== -1) {
|
|
46
48
|
modelsContainingOverrides.push(ovr.modelId);
|
|
49
|
+
}
|
|
47
50
|
}
|
|
48
51
|
vp.perModelCategoryVisibility.setOverride(modelsContainingOverrides, ids, PerModelCategoryVisibility.Override.None);
|
|
49
52
|
// changeCategoryDisplay only enables subcategories, it does not disabled them. So we must do that ourselves.
|
|
@@ -69,8 +72,9 @@ export async function enableCategory(viewManager, imodel, ids, enabled, forAllVi
|
|
|
69
72
|
* @internal
|
|
70
73
|
*/
|
|
71
74
|
export function enableSubCategory(viewManager, key, enabled, forAllViewports) {
|
|
72
|
-
if (!viewManager.selectedView)
|
|
75
|
+
if (!viewManager.selectedView) {
|
|
73
76
|
return;
|
|
77
|
+
}
|
|
74
78
|
const updateViewport = (vp) => {
|
|
75
79
|
// Only act on viewports that are both 3D or both 2D. Important if we have multiple viewports opened and we
|
|
76
80
|
// are using 'allViewports' property
|
|
@@ -90,8 +94,9 @@ export function enableSubCategory(viewManager, key, enabled, forAllViewports) {
|
|
|
90
94
|
}
|
|
91
95
|
/** @internal */
|
|
92
96
|
export async function loadCategoriesFromViewport(iModel, vp) {
|
|
93
|
-
if (!vp)
|
|
97
|
+
if (!vp) {
|
|
94
98
|
return EMPTY_CATEGORIES_ARRAY;
|
|
99
|
+
}
|
|
95
100
|
// Query categories and add them to state
|
|
96
101
|
const selectUsedSpatialCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId from BisCore.SpatialCategory)";
|
|
97
102
|
const selectUsedDrawingCategoryIds = "SELECT DISTINCT Category.Id as id from BisCore.GeometricElement2d WHERE Model.Id=? AND Category.Id IN (SELECT ECInstanceId from BisCore.DrawingCategory)";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../src/components/trees/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"CategoriesVisibilityUtils.js","sourceRoot":"","sources":["../../../../src/components/trees/CategoriesVisibilityUtils.ts"],"names":[],"mappings":"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","sourcesContent":["/*---------------------------------------------------------------------------------------------\n * Copyright (c) Bentley Systems, Incorporated. All rights reserved.\n * See LICENSE.md in the project root for license terms and full copyright notice.\n *--------------------------------------------------------------------------------------------*/\n\nimport { QueryRowFormat } from \"@itwin/core-common\";\nimport { PerModelCategoryVisibility } from \"@itwin/core-frontend\";\n\nimport type { IModelConnection, ViewManager, Viewport } from \"@itwin/core-frontend\";\nimport type { CategoryInfo } from \"./category-tree/CategoryVisibilityHandler\";\n\nconst EMPTY_CATEGORIES_ARRAY: CategoryInfo[] = [];\n\n/**\n * Toggles visibility of categories to show or hide.\n * @internal\n */\nexport async function toggleAllCategories(\n viewManager: ViewManager,\n imodel: IModelConnection,\n display: boolean,\n viewport?: Viewport,\n forAllViewports?: boolean,\n) {\n // istanbul ignore next\n const activeView = viewport ?? viewManager.getFirstOpenView();\n const ids = await getCategories(imodel, activeView);\n\n // istanbul ignore if\n if (ids.length === 0) {\n return;\n }\n\n await enableCategory(viewManager, imodel, ids, display, forAllViewports ?? false);\n}\n\n/**\n * Gets ids of all categories from specified imodel and viewport.\n * @internal\n */\nexport async function getCategories(imodel: IModelConnection, viewport?: Viewport) {\n const categories = await loadCategoriesFromViewport(imodel, viewport);\n return categories.map((category) => category.categoryId);\n}\n\n/**\n * Changes category display in the viewport.\n * @internal\n */\nexport async function enableCategory(\n viewManager: ViewManager,\n imodel: IModelConnection,\n ids: string[],\n enabled: boolean,\n forAllViewports: boolean,\n enableAllSubCategories = true,\n) {\n if (!viewManager.selectedView) {\n return;\n }\n\n const updateViewport = async (vp: Viewport) => {\n // Only act on viewports that are both 3D or both 2D. Important if we have multiple viewports opened and we\n // are using 'allViewports' property\n if (viewManager.selectedView && viewManager.selectedView.view.is3d() === vp.view.is3d()) {\n vp.changeCategoryDisplay(ids, enabled, enableAllSubCategories);\n\n // remove category overrides per model\n const modelsContainingOverrides: string[] = [];\n for (const ovr of vp.perModelCategoryVisibility) {\n // istanbul ignore else\n if (ids.findIndex((id) => id === ovr.categoryId) !== -1) {\n modelsContainingOverrides.push(ovr.modelId);\n }\n }\n vp.perModelCategoryVisibility.setOverride(modelsContainingOverrides, ids, PerModelCategoryVisibility.Override.None);\n\n // changeCategoryDisplay only enables subcategories, it does not disabled them. So we must do that ourselves.\n if (false === enabled) {\n (await imodel.categories.getCategoryInfo(ids)).forEach((categoryInfo) => {\n categoryInfo.subCategories.forEach((value) => enableSubCategory(viewManager, value.id, false, forAllViewports));\n });\n }\n }\n };\n\n // This property let us act on all viewports or just on the selected one, configurable by the app\n if (forAllViewports) {\n for (const viewport of viewManager) {\n await updateViewport(viewport);\n }\n } else {\n await updateViewport(viewManager.selectedView);\n }\n}\n\n/**\n * Changes subcategory display in the viewport\n * @internal\n */\nexport function enableSubCategory(viewManager: ViewManager, key: string, enabled: boolean, forAllViewports?: boolean) {\n if (!viewManager.selectedView) {\n return;\n }\n\n const updateViewport = (vp: Viewport) => {\n // Only act on viewports that are both 3D or both 2D. Important if we have multiple viewports opened and we\n // are using 'allViewports' property\n if (viewManager.selectedView && viewManager.selectedView.view.is3d() === vp.view.is3d()) {\n vp.changeSubCategoryDisplay(key, enabled);\n }\n };\n\n // This property let us act on all viewports or just on the selected one, configurable by the app\n if (forAllViewports) {\n for (const viewport of viewManager) {\n updateViewport(viewport);\n }\n } else {\n updateViewport(viewManager.selectedView);\n }\n}\n\n/** @internal */\nexport async function loadCategoriesFromViewport(iModel?: IModelConnection, vp?: Viewport) {\n if (!vp) {\n return EMPTY_CATEGORIES_ARRAY;\n }\n\n // Query categories and add them to state\n const selectUsedSpatialCategoryIds =\n \"SELECT DISTINCT Category.Id as id from BisCore.GeometricElement3d WHERE Category.Id IN (SELECT ECInstanceId from BisCore.SpatialCategory)\";\n const selectUsedDrawingCategoryIds =\n \"SELECT DISTINCT Category.Id as id from BisCore.GeometricElement2d WHERE Model.Id=? AND Category.Id IN (SELECT ECInstanceId from BisCore.DrawingCategory)\";\n const ecsql = vp.view.is3d() ? selectUsedSpatialCategoryIds : selectUsedDrawingCategoryIds;\n const ecsql2 = `SELECT ECInstanceId as id FROM ${vp.view.is3d() ? \"BisCore.SpatialCategory\" : \"BisCore.DrawingCategory\"} WHERE ECInstanceId IN (${ecsql})`;\n\n const categories: CategoryInfo[] = [];\n\n // istanbul ignore else\n if (iModel) {\n const rows = await iModel.createQueryReader(ecsql2, undefined, { rowFormat: QueryRowFormat.UseJsPropertyNames }).toArray();\n (await iModel.categories.getCategoryInfo(rows.map((row) => row.id))).forEach((val) => {\n categories.push({ categoryId: val.id, subCategoryIds: val.subCategories.size ? [...val.subCategories.keys()] : undefined });\n });\n }\n return categories;\n}\n"]}
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
.core-tree-node {
|
|
26
26
|
&.with-checkbox {
|
|
27
27
|
> .contents {
|
|
28
|
+
margin-left: 0 !important;
|
|
28
29
|
padding-left: calc(var(--iui-size-3xs) / 2);
|
|
29
30
|
}
|
|
30
31
|
}
|
|
@@ -61,7 +62,6 @@
|
|
|
61
62
|
}
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
|
|
65
65
|
&.is-selected {
|
|
66
66
|
> .contents {
|
|
67
67
|
> .visibility-tree-checkbox-container {
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
* @module IModelComponents
|
|
3
3
|
*/
|
|
4
4
|
import { UnifiedSelectionTreeEventHandler } from "@itwin/presentation-components";
|
|
5
|
-
import type { TreeCheckboxStateChangeEventArgs, TreeNodeItem, TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs } from "@itwin/components-react";
|
|
6
5
|
import type { BeEvent, IDisposable } from "@itwin/core-bentley";
|
|
6
|
+
import type { TreeCheckboxStateChangeEventArgs, TreeNodeItem, TreeSelectionModificationEventArgs, TreeSelectionReplacementEventArgs } from "@itwin/components-react";
|
|
7
7
|
import type { UnifiedSelectionTreeEventHandlerParams } from "@itwin/presentation-components";
|
|
8
8
|
/**
|
|
9
9
|
* Data structure that describes instance visibility status.
|