core-app-api: added app.createRoot()
Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -2,4 +2,49 @@
|
||||
'@backstage/core-app-api': minor
|
||||
---
|
||||
|
||||
Added a new `AppRouter` component that replaces the same component currently created through `app.getRouter()`.
|
||||
Added a new `AppRouter` component and `app.createRoot()` method that replaces `app.getRouter()` and `app.getProvider()`, which are now deprecated. The new `AppRouter` component is a drop-in replacement for the old router component, while the new `app.createRoot()` method is used instead of the old provider component.
|
||||
|
||||
An old app setup might look like this:
|
||||
|
||||
```tsx
|
||||
const app = createApp(/* ... */);
|
||||
|
||||
const AppProvider = app.getProvider();
|
||||
const AppRouter = app.getRouter();
|
||||
|
||||
const routes = ...;
|
||||
|
||||
const App = () => (
|
||||
<AppProvider>
|
||||
<AlertDisplay />
|
||||
<OAuthRequestDialog />
|
||||
<AppRouter>
|
||||
<Root>{routes}</Root>
|
||||
</AppRouter>
|
||||
</AppProvider>
|
||||
);
|
||||
|
||||
export default App;
|
||||
```
|
||||
|
||||
With these new APIs, the setup now looks like this:
|
||||
|
||||
```tsx
|
||||
import { AppRouter } from '@backstage/core-app-api';
|
||||
|
||||
const app = createApp(/* ... */);
|
||||
|
||||
const routes = ...;
|
||||
|
||||
export default app.createRoot(
|
||||
<>
|
||||
<AlertDisplay />
|
||||
<OAuthRequestDialog />
|
||||
<AppRouter>
|
||||
<Root>{routes}</Root>
|
||||
</AppRouter>
|
||||
</>,
|
||||
);
|
||||
```
|
||||
|
||||
Note that `app.createRoot()` accepts a React element, rather than a component.
|
||||
|
||||
@@ -262,6 +262,7 @@ export type AuthApiCreateOptions = {
|
||||
export type BackstageApp = {
|
||||
getPlugins(): BackstagePlugin[];
|
||||
getSystemIcon(key: string): IconComponent | undefined;
|
||||
createRoot(element: JSX.Element): ComponentType<{}>;
|
||||
getProvider(): ComponentType<{}>;
|
||||
getRouter(): ComponentType<{}>;
|
||||
};
|
||||
|
||||
@@ -248,7 +248,23 @@ export class AppManager implements BackstageApp {
|
||||
return this.components;
|
||||
}
|
||||
|
||||
createRoot(element: JSX.Element): ComponentType<{}> {
|
||||
const AppProvider = this.getProvider();
|
||||
const AppRoot = () => {
|
||||
return <AppProvider>{element}</AppProvider>;
|
||||
};
|
||||
return AppRoot;
|
||||
}
|
||||
|
||||
#getProviderCalled = false;
|
||||
getProvider(): ComponentType<{}> {
|
||||
if (this.#getProviderCalled) {
|
||||
throw new Error(
|
||||
'app.getProvider() or app.createRoot() has already been called, and can only be called once',
|
||||
);
|
||||
}
|
||||
this.#getProviderCalled = true;
|
||||
|
||||
const appContext = new AppContextImpl(this);
|
||||
|
||||
// We only validate routes once
|
||||
|
||||
@@ -298,9 +298,36 @@ export type BackstageApp = {
|
||||
*/
|
||||
getSystemIcon(key: string): IconComponent | undefined;
|
||||
|
||||
/**
|
||||
* Creates the root component that renders the entire app.
|
||||
*
|
||||
* @remarks
|
||||
*
|
||||
* This method must only be called once, and you have to provide it the entire
|
||||
* app element tree. The element tree will be analyzed to discover plugins,
|
||||
* routes, and other app features. The returned component will render all
|
||||
* of the app elements wrapped within the app context provider.
|
||||
*
|
||||
* @example
|
||||
* ```tsx
|
||||
* export default app.createRoot(
|
||||
* <>
|
||||
* <AlertDisplay />
|
||||
* <OAuthRequestDialog />
|
||||
* <AppRouter>
|
||||
* <Root>{routes}</Root>
|
||||
* </AppRouter>
|
||||
* </>,
|
||||
* );
|
||||
* ```
|
||||
*/
|
||||
createRoot(element: JSX.Element): ComponentType<{}>;
|
||||
|
||||
/**
|
||||
* Provider component that should wrap the Router created with getRouter()
|
||||
* and any other components that need to be within the app context.
|
||||
*
|
||||
* @deprecated Use {@link BackstageApp.createRoot} instead.
|
||||
*/
|
||||
getProvider(): ComponentType<{}>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user