Skip to content

Commit e001025

Browse files
committed
add support for appui@5
1 parent 0fa1a6c commit e001025

File tree

8 files changed

+170
-269
lines changed

8 files changed

+170
-269
lines changed
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "minor",
3+
"comment": "Add support for AppUI 5.x",
4+
"packageName": "@itwin/tree-widget-react",
5+
"email": "35135765+grigasp@users.noreply.github.com",
6+
"dependentChangeType": "patch"
7+
}

node-hooks/ignore-styles/hook.cjs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,14 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
const STYLE_FILE_EXTENSIONS = [".css", ".scss", ".less", ".sass"];
7+
const ICONS_FILE_EXTENSIONS = [".svg"];
78

89
exports.load = (url, context, next) => {
910
if (STYLE_FILE_EXTENSIONS.some((ext) => url.endsWith(ext))) {
10-
return { format: "module", shortCircuit: true, source: "" };
11+
return { format: "module", shortCircuit: true, source: "export default null;" };
12+
}
13+
if (ICONS_FILE_EXTENSIONS.some((ext) => url.endsWith(ext))) {
14+
return { format: "module", shortCircuit: true, source: "export default null;" };
1115
}
1216
return next(url, context);
1317
};

packages/itwin/tree-widget/package.json

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,9 @@
5656
},
5757
"peerDependencies": {
5858
"@itwin/appui-abstract": "^4.0.0",
59-
"@itwin/appui-react": "^4.10.0",
60-
"@itwin/components-react": "^4.10.0",
59+
"@itwin/appui-react": "^4.10.0 || ^5.0.0",
60+
"@itwin/components-react": "^4.10.0 || ^5.0.0",
6161
"@itwin/core-frontend": "^4.0.0",
62-
"@itwin/core-react": "^4.10.0",
6362
"@itwin/ecschema-metadata": "^4.0.0",
6463
"@itwin/itwinui-react": "^3.11.0",
6564
"@itwin/presentation-components": "^5.0.0",
@@ -80,9 +79,9 @@
8079
},
8180
"devDependencies": {
8281
"@itwin/appui-abstract": "^4.10.2",
83-
"@itwin/appui-react": "^4.17.6",
82+
"@itwin/appui-react": "^5.0.5",
8483
"@itwin/build-tools": "^4.10.2",
85-
"@itwin/components-react": "^4.17.6",
84+
"@itwin/components-react": "^5.0.5",
8685
"@itwin/core-backend": "^4.10.2",
8786
"@itwin/core-bentley": "^4.10.2",
8887
"@itwin/core-common": "^4.10.2",
@@ -92,13 +91,14 @@
9291
"@itwin/core-markup": "^4.10.2",
9392
"@itwin/core-orbitgt": "^4.10.2",
9493
"@itwin/core-quantity": "^4.10.2",
95-
"@itwin/core-react": "^4.17.6",
94+
"@itwin/core-react": "^5.0.5",
9695
"@itwin/core-telemetry": "^4.10.2",
9796
"@itwin/ecschema-metadata": "^4.10.2",
9897
"@itwin/ecschema-rpcinterface-common": "^4.10.2",
9998
"@itwin/ecschema-rpcinterface-impl": "^4.10.2",
10099
"@itwin/eslint-plugin": "^4.1.1",
101-
"@itwin/imodel-components-react": "^4.17.6",
100+
"@itwin/imodel-components-react": "^5.0.5",
101+
"@itwin/itwinui-react": "^3.16.5",
102102
"@itwin/oidc-signin-tool": "^4.4.0",
103103
"@itwin/presentation-backend": "^4.10.2",
104104
"@itwin/presentation-common": "^4.10.2",

packages/itwin/tree-widget/pnpm-lock.yaml

Lines changed: 105 additions & 198 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/itwin/tree-widget/src/test/TreeWidgetUiItemsProvider.test.tsx

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,21 @@
66
import { expect } from "chai";
77
import sinon from "sinon";
88
import * as td from "testdouble";
9-
import { UiFramework } from "@itwin/appui-react";
109
import { BeEvent } from "@itwin/core-bentley";
10+
import { EmptyLocalization } from "@itwin/core-common";
1111
import { IModelApp } from "@itwin/core-frontend";
1212
import * as selectableTreeModule from "../components/SelectableTree.js";
13-
import * as treeWidgetModule from "../TreeWidget.js";
14-
import { render, TestUtils, waitFor } from "./TestUtils.js";
13+
import { render, waitFor } from "./TestUtils.js";
1514

1615
import type { IModelConnection } from "@itwin/core-frontend";
1716

1817
describe("createTreeWidget", () => {
1918
beforeEach(async () => {
2019
sinon.stub(IModelApp, "viewManager").get(() => ({ onSelectedViewportChanged: new BeEvent() }));
2120
sinon.stub(IModelApp, "toolAdmin").get(() => ({ activeToolChanged: new BeEvent() }));
22-
await td.replaceEsm("../TreeWidget.js", { ...treeWidgetModule });
23-
await TestUtils.initialize();
2421
});
2522

2623
afterEach(() => {
27-
TestUtils.terminate();
2824
sinon.restore();
2925
td.reset();
3026
});
@@ -35,23 +31,24 @@ describe("createTreeWidget", () => {
3531
...selectableTreeModule,
3632
SelectableTree: stubSelectableTree,
3733
});
34+
const { createTreeWidget } = await initialize();
35+
3836
const trees: selectableTreeModule.SelectableTreeDefinition[] = [
3937
{
4038
id: "tree",
4139
getLabel: () => "Tree Label",
4240
render: () => <div>Tree Content</div>,
4341
},
4442
];
45-
const createTreeWidget = (await import("../components/TreeWidgetUiItemsProvider.js")).createTreeWidget;
4643
const widget = createTreeWidget({ trees });
4744
render(<>{widget.content}</>);
48-
4945
expect(stubSelectableTree).to.be.called;
5046
const [props] = stubSelectableTree.args[0];
5147
expect(props.trees).to.be.eq(trees);
5248
});
5349

5450
it("renders error message if tree component throws", async () => {
51+
const { UiFramework, TreeWidget, createTreeWidget } = await initialize();
5552
UiFramework.setIModelConnection({
5653
isBlankConnection: () => true,
5754
selectionSet: {
@@ -71,10 +68,20 @@ describe("createTreeWidget", () => {
7168
render: () => <TestTree />,
7269
},
7370
];
74-
const createTreeWidget = (await import("../components/TreeWidgetUiItemsProvider.js")).createTreeWidget;
7571
const widget = createTreeWidget({ trees });
7672
const { queryByText } = render(<>{widget.content}</>);
77-
78-
await waitFor(() => expect(queryByText(treeWidgetModule.TreeWidget.translate("errorState.title"))).to.not.be.null);
73+
await waitFor(() => expect(queryByText(TreeWidget.translate("errorState.title"))).to.not.be.null);
7974
});
75+
76+
async function initialize() {
77+
const UiFramework = (await import("@itwin/appui-react")).UiFramework;
78+
await UiFramework.initialize();
79+
80+
const TreeWidget = (await import("../TreeWidget.js")).TreeWidget;
81+
await TreeWidget.initialize(new EmptyLocalization());
82+
83+
const createTreeWidget = (await import("../components/TreeWidgetUiItemsProvider.js")).createTreeWidget;
84+
85+
return { UiFramework, TreeWidget, createTreeWidget };
86+
}
8087
});

packages/itwin/tree-widget/src/test/tree-header/TreeHeader.test.tsx

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -53,38 +53,6 @@ describe("<TreeHeader />", () => {
5353
});
5454
});
5555

56-
it("handles buttons overflow when only dropdown button can be seen", async () => {
57-
sinon.stub(HTMLElement.prototype, "scrollWidth").get(() => 200);
58-
sinon.stub(HTMLElement.prototype, "offsetWidth").get(() => 32);
59-
60-
const { queryByRole } = render(
61-
<TreeHeader {...defaultProps}>
62-
<Button>Button1</Button>
63-
<Button>Button2</Button>
64-
</TreeHeader>,
65-
);
66-
67-
expect(queryByRole("button", { name: "Button1" })).to.be.null;
68-
expect(queryByRole("button", { name: "Button2" })).to.be.null;
69-
});
70-
71-
it("handles buttons overflow when provided buttons and dropdown button can be seen", async () => {
72-
sinon.stub(HTMLElement.prototype, "scrollWidth").get(() => 200);
73-
sinon.stub(HTMLElement.prototype, "offsetWidth").get(() => 200);
74-
75-
const { queryByRole } = render(
76-
<TreeHeader {...defaultProps}>
77-
<Button>Button1</Button>
78-
<Button>Button2</Button>
79-
<Button>Button3</Button>
80-
</TreeHeader>,
81-
);
82-
83-
expect(queryByRole("button", { name: "Button1" })).to.not.be.null;
84-
expect(queryByRole("button", { name: "Button2" })).to.be.null;
85-
expect(queryByRole("button", { name: "Button3" })).to.be.null;
86-
});
87-
8856
describe("search box", () => {
8957
it("renders search box", async () => {
9058
const { getByRole, user } = render(<TreeHeader {...defaultProps} filteringProps={{ ...filteringProps, selectedIndex: 5, resultCount: 10 }} />);

packages/itwin/tree-widget/src/test/trees/categories-tree/CategoriesTreeComponent.test.tsx

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,13 @@ import { expect } from "chai";
77
import { Children } from "react";
88
import sinon from "sinon";
99
import * as td from "testdouble";
10-
import { UiFramework } from "@itwin/appui-react";
1110
import { BeEvent } from "@itwin/core-bentley";
12-
import { IModelApp, NoRenderApp } from "@itwin/core-frontend";
1311
import { Presentation } from "@itwin/presentation-frontend";
1412
import * as treeHeaderModule from "../../../components/tree-header/TreeHeader.js";
1513
import * as categoriesTreeModule from "../../../components/trees/categories-tree/CategoriesTree.js";
1614
import * as categoriesVisibilityUtilsModule from "../../../components/trees/common/CategoriesVisibilityUtils.js";
1715
import * as treeWidgetModule from "../../../TreeWidget.js";
18-
import { mockPresentationManager, render, TestUtils, waitFor } from "../../TestUtils.js";
16+
import { mockPresentationManager, render, waitFor } from "../../TestUtils.js";
1917

2018
import type * as categoriesTreeComponentModule from "../../../components/trees/categories-tree/CategoriesTreeComponent.js";
2119
import type { ComponentPropsWithoutRef } from "react";
@@ -26,15 +24,15 @@ import type { IModelConnection, Viewport } from "@itwin/core-frontend";
2624
type TreeHeaderProps = ComponentPropsWithoutRef<typeof treeHeaderModule.TreeHeader>;
2725

2826
describe("<CategoriesTreeComponent />", () => {
29-
before(async () => {
27+
async function initialize() {
28+
const { IModelApp, NoRenderApp } = await import("@itwin/core-frontend");
3029
await NoRenderApp.startup();
31-
await TestUtils.initialize();
32-
});
3330

34-
after(async () => {
35-
TestUtils.terminate();
36-
await IModelApp.shutdown();
37-
});
31+
const { UiFramework } = await import("@itwin/appui-react");
32+
await UiFramework.initialize();
33+
34+
return { IModelApp, UiFramework };
35+
}
3836

3937
const defaultCategoriesTreeComponentProps: ComponentPropsWithoutRef<typeof categoriesTreeComponentModule.CategoriesTreeComponent> = {
4038
getSchemaContext: () => ({}) as any,
@@ -121,20 +119,23 @@ describe("<CategoriesTreeComponent />", () => {
121119
} as unknown as Viewport;
122120

123121
it("returns null if iModel is undefined", async () => {
122+
const { IModelApp } = await initialize();
124123
sinon.stub(IModelApp.viewManager, "selectedView").get(() => ({}) as Viewport);
125124
const result = render(<CategoriesTreeComponent {...defaultCategoriesTreeComponentProps} />);
126125
expect(result.container.children).to.be.empty;
127126
expect(stubCategoriesTree).to.not.be.called;
128127
});
129128

130129
it("returns null if viewport is undefined", async () => {
130+
const { UiFramework } = await initialize();
131131
sinon.stub(UiFramework, "getIModelConnection").returns({} as IModelConnection);
132132
const result = render(<CategoriesTreeComponent {...defaultCategoriesTreeComponentProps} />);
133133
expect(result.container.children).to.be.empty;
134134
expect(stubCategoriesTree).to.not.be.called;
135135
});
136136

137137
it("renders `CategoryTree` when iModel and viewport are defined", async () => {
138+
const { IModelApp, UiFramework } = await initialize();
138139
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
139140
sinon.stub(UiFramework, "getIModelConnection").returns(iModel);
140141
const result = render(<CategoriesTreeComponent {...defaultCategoriesTreeComponentProps} density="enlarged" />);
@@ -151,6 +152,7 @@ describe("<CategoriesTreeComponent />", () => {
151152

152153
describe("header buttons", () => {
153154
it("renders default tree header buttons", async () => {
155+
const { IModelApp, UiFramework } = await initialize();
154156
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
155157
sinon.stub(UiFramework, "getIModelConnection").returns(iModel);
156158
render(<CategoriesTreeComponent {...defaultCategoriesTreeComponentProps} />);
@@ -160,6 +162,7 @@ describe("<CategoriesTreeComponent />", () => {
160162
});
161163

162164
it("renders user provided tree header buttons", async () => {
165+
const { IModelApp, UiFramework } = await initialize();
163166
const spy = sinon.stub().returns(<></>);
164167
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
165168
sinon.stub(UiFramework, "getIModelConnection").returns(iModel);

packages/itwin/tree-widget/src/test/trees/models-tree/ModelsTreeComponent.test.tsx

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,12 @@ import { Children } from "react";
88
import sinon from "sinon";
99
import * as td from "testdouble";
1010
import * as moq from "typemoq";
11-
import { UiFramework } from "@itwin/appui-react";
1211
import { BeEvent } from "@itwin/core-bentley";
13-
import { IModelApp, NoRenderApp } from "@itwin/core-frontend";
1412
import * as treeHeaderModule from "../../../components/tree-header/TreeHeader.js";
1513
import * as modelsVisibilityHandlerModule from "../../../components/trees/models-tree/internal/ModelsTreeVisibilityHandler.js";
1614
import * as modelsTreeModule from "../../../components/trees/models-tree/ModelsTree.js";
1715
import * as treeWidgetModule from "../../../TreeWidget.js";
18-
import { mockViewport, render, TestUtils, waitFor } from "../../TestUtils.js";
16+
import { mockViewport, render, waitFor } from "../../TestUtils.js";
1917

2018
import type { ComponentPropsWithoutRef } from "react";
2119
import type { IModelConnection, Viewport } from "@itwin/core-frontend";
@@ -25,15 +23,15 @@ import type * as modelsTreeComponentModule from "../../../components/trees/model
2523
type TreeHeaderProps = ComponentPropsWithoutRef<typeof treeHeaderModule.TreeHeader>;
2624

2725
describe("<ModelsTreeComponent />", () => {
28-
before(async () => {
26+
async function initialize() {
27+
const { IModelApp, NoRenderApp } = await import("@itwin/core-frontend");
2928
await NoRenderApp.startup();
30-
await TestUtils.initialize();
31-
});
3229

33-
after(async () => {
34-
TestUtils.terminate();
35-
await IModelApp.shutdown();
36-
});
30+
const { UiFramework } = await import("@itwin/appui-react");
31+
await UiFramework.initialize();
32+
33+
return { IModelApp, UiFramework };
34+
}
3735

3836
const defaultModelsTreeComponentProps: ComponentPropsWithoutRef<typeof modelsTreeComponentModule.ModelsTreeComponent> = {
3937
getSchemaContext: () => ({}) as any,
@@ -106,6 +104,7 @@ describe("<ModelsTreeComponent />", () => {
106104
});
107105

108106
it("returns null if iModel is undefined", async () => {
107+
const { IModelApp } = await initialize();
109108
sinon.stub(IModelApp.viewManager, "selectedView").get(() => ({}) as Viewport);
110109
const result = render(<ModelsTreeComponent {...defaultModelsTreeComponentProps} />);
111110
await waitFor(() => {
@@ -115,6 +114,7 @@ describe("<ModelsTreeComponent />", () => {
115114
});
116115

117116
it("returns null if viewport is undefined", async () => {
117+
const { UiFramework } = await initialize();
118118
sinon.stub(UiFramework, "getIModelConnection").returns({} as IModelConnection);
119119
const result = render(<ModelsTreeComponent {...defaultModelsTreeComponentProps} />);
120120
await waitFor(() => {
@@ -124,6 +124,7 @@ describe("<ModelsTreeComponent />", () => {
124124
});
125125

126126
it("renders `ModelsTree` when iModel and viewport are defined", async () => {
127+
const { IModelApp, UiFramework } = await initialize();
127128
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
128129
sinon.stub(UiFramework, "getIModelConnection").returns({} as IModelConnection);
129130
const result = render(<ModelsTreeComponent {...defaultModelsTreeComponentProps} />);
@@ -140,6 +141,7 @@ describe("<ModelsTreeComponent />", () => {
140141

141142
describe("available models", () => {
142143
it("renders button with available models", async () => {
144+
const { IModelApp, UiFramework } = await initialize();
143145
const iModel = {
144146
models: {
145147
queryProps: async () => [
@@ -165,6 +167,7 @@ describe("<ModelsTreeComponent />", () => {
165167
});
166168

167169
it("renders button with empty available models list if error if thrown while querying available models", async () => {
170+
const { IModelApp, UiFramework } = await initialize();
168171
const spy = sinon.stub().returns(<></>);
169172
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
170173
sinon.stub(UiFramework, "getIModelConnection").returns({
@@ -181,6 +184,7 @@ describe("<ModelsTreeComponent />", () => {
181184

182185
describe("header buttons", () => {
183186
it("renders default tree header buttons", async () => {
187+
const { IModelApp, UiFramework } = await initialize();
184188
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
185189
sinon.stub(UiFramework, "getIModelConnection").returns({} as IModelConnection);
186190
render(<ModelsTreeComponent {...defaultModelsTreeComponentProps} />);
@@ -190,6 +194,7 @@ describe("<ModelsTreeComponent />", () => {
190194
});
191195

192196
it("renders user provided tree header buttons", async () => {
197+
const { IModelApp, UiFramework } = await initialize();
193198
const spy = sinon.stub().returns(<></>);
194199
sinon.stub(IModelApp.viewManager, "selectedView").get(() => viewport);
195200
sinon.stub(UiFramework, "getIModelConnection").returns({} as IModelConnection);

0 commit comments

Comments
 (0)