Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions desktop/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,11 +91,11 @@
},
"peerDependencies": {
"@fluentui/azure-themes": ">=8.6.34 < 9.0.0",
"@fluentui/react": ">=8.97.2 <9.0.0",
"@fluentui/react": ">=8.122.0 <9.0.0",
"mobx": "^6.3.2",
"mobx-react-lite": "^3.2.0",
"react": ">=17.0.2 <18.0.0",
"react-dom": ">=17.0.2 <18.0.0",
"react": ">=18.3.0 <19.0.0",
"react-dom": ">=18.3.0 <19.0.0",
"tslib": "^2.6.2"
},
"devDependencies": {
Expand Down
2 changes: 1 addition & 1 deletion desktop/src/app/app.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ export const routes: Routes = [
component: PlaygroundRouteComponent,
},
{
path: "playground/:component",
path: "demos/:component",
component: PlaygroundRouteComponent,
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { By } from "@angular/platform-browser";
import { Theme, ThemeDefinition, ThemeService } from "app/services";
import * as React from "react";
import { BehaviorSubject } from "rxjs";
import { waitFor } from "@testing-library/react";
import { ReactContainerComponent } from "./react-container.component";

interface SimpleMessageProps {
Expand Down Expand Up @@ -40,41 +41,60 @@ describe("ReactContainerComponent", () => {
testComponent = fixture.componentInstance;
});

afterEach(() => {
themeSubject.next(undefined);
testComponent.ngOnDestroy();
fixture.destroy();
});

function getRootEl() {
return fixture.debugElement.query(By.css(".react-root"));
const el = fixture.debugElement.query(By.css(".react-root")).nativeElement;
if (!el) {
throw new Error("Root element not found");
}
return el;
}

it("can render a simple react component", () => {
function getChildText() {
const rootEl = getRootEl();
if (rootEl.children.length === 0) {
throw new Error("No children found");
}
return rootEl.children[0].textContent;
}

it("can render a simple react component", async () => {
themeSubject.next(testTheme);

testComponent.component = SimpleMessage;
testComponent.props = {
message: "Hello world!"
};
fixture.detectChanges();
await fixture.whenStable();

expect(getRootEl()).toBeTruthy();

const rootEl: HTMLDivElement = getRootEl().nativeElement;
expect(rootEl).toBeDefined();
const rootEl = await waitFor(getRootEl);
expect(rootEl.tagName).toEqual("DIV");
expect(rootEl.children[0]).toBeDefined();
expect(rootEl.children[0].textContent).toEqual("Hello world!");

const childText = await waitFor(getChildText);
expect(childText).toEqual("Hello world!");
});

it("waits for theme to load before rendering", () => {
it("waits for theme to load before rendering", async () => {
testComponent.component = SimpleMessage;
testComponent.props = {
message: "Hello world!"
message: "Hello world!!"
};

expect(getRootEl()).toBeNull();
fixture.detectChanges();
await fixture.whenStable();
expect(() => getRootEl()).toThrowError();

themeSubject.next(testTheme);
fixture.detectChanges();
expect(getRootEl()).toBeTruthy();
expect(getRootEl().nativeElement.children[0].textContent).toEqual("Hello world!");
await fixture.whenStable();

const childText = await waitFor(getChildText);
expect(childText).toEqual("Hello world!!");
});

});
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import {
AfterViewChecked, ChangeDetectionStrategy
} from "@angular/core";
import * as React from "react";
import * as ReactDOM from "react-dom";
import {RootPane} from "@azure/bonito-ui/lib/components/layout";
import { Subscription } from "rxjs";
import { Theme, ThemeService } from "app/services";
import { ThemeName } from "@azure/bonito-ui/lib/theme";
import { createRoot, Root } from 'react-dom/client';

export const ReactWrapper: React.FC = props => {
export const ReactWrapper: React.FC<React.PropsWithChildren> = props => {
return React.createElement(RootPane, {theme: "explorerDark"}, props.children);
};

Expand Down Expand Up @@ -42,6 +42,8 @@ export class ReactContainerComponent<P> implements OnChanges, OnDestroy, AfterVi

private _themeService: ThemeService;

private _root: Root;

constructor(themeService: ThemeService) {
this._themeService = themeService;

Expand All @@ -67,11 +69,14 @@ export class ReactContainerComponent<P> implements OnChanges, OnDestroy, AfterVi
}

private _render() {
ReactDOM.render(
if (!this._root) {
this._root = createRoot(this.rootElement.nativeElement);
}
this._root.render(
React.createElement(RootPane, {theme : this._themeName},
React.createElement(this.component ?? NoComponentFound, this.props)
)
, this.rootElement.nativeElement);
);

}

Expand All @@ -81,7 +86,10 @@ export class ReactContainerComponent<P> implements OnChanges, OnDestroy, AfterVi
}

if (this._initialized && this.rootElement) {
ReactDOM.unmountComponentAtNode(this.rootElement.nativeElement);
if (this._root) {
this._root.unmount();
this._root = null;
}
}
}

Expand Down
Loading