frontend-plugin-api: refactor coreExtensionData.reactComponent -> .reactElement

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2023-09-13 12:07:46 +02:00
parent f4c98b07e6
commit 5fb348af52
14 changed files with 46 additions and 55 deletions
@@ -23,7 +23,7 @@ import {
export const ExamplePage = createPageExtension({
id: 'example.page',
defaultPath: '/example',
component: () => import('./Component').then(m => <m.Component />),
loader: () => import('./Component').then(m => <m.Component />),
});
/** @public */
@@ -36,7 +36,7 @@ const IndexPage = createPageExtension({
id: 'index',
defaultPath: '/',
routeRef: indexRouteRef,
component: async () => {
loader: async () => {
const Component = () => {
const page1Link = useRouteRef(page1RouteRef);
return (
@@ -59,7 +59,7 @@ const Page1 = createPageExtension({
id: 'page1',
defaultPath: '/page1',
routeRef: page1RouteRef,
component: async () => {
loader: async () => {
const Component = () => {
const indexLink = useRouteRef(indexRouteRef);
// const page2Link = useRouteRef(page2RouteRef);
+2 -3
View File
@@ -3,16 +3,15 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="react" />
import { BackstagePlugin } from '@backstage/frontend-plugin-api';
import { ConfigApi } from '@backstage/core-plugin-api';
import { JSX as JSX_2 } from 'react';
// @public (undocumented)
export function createApp(options: {
plugins: BackstagePlugin[];
config?: ConfigApi;
}): {
createRoot(): JSX.Element;
createRoot(): JSX_2.Element;
};
```
+2 -2
View File
@@ -24,8 +24,7 @@
},
"devDependencies": {
"@backstage/cli": "workspace:^",
"@testing-library/jest-dom": "^5.10.1",
"@types/react": "^16.13.1 || ^17.0.0"
"@testing-library/jest-dom": "^5.10.1"
},
"configSchema": "config.d.ts",
"files": [
@@ -41,6 +40,7 @@
"@backstage/plugin-graphiql": "workspace:^",
"@backstage/types": "workspace:^",
"@material-ui/core": "^4.12.4",
"@types/react": "^16.13.1 || ^17.0.0",
"lodash": "^4.17.21"
},
"peerDependencies": {
@@ -27,17 +27,17 @@ export const CoreLayout = createExtension({
inputs: {
nav: {
extensionData: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
},
content: {
extensionData: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
},
},
output: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
factory({ bind, inputs }) {
// TODO: Support this as part of the core system
@@ -46,21 +46,18 @@ export const CoreLayout = createExtension({
`Extension 'core.layout' did not receive exactly one 'nav' input, got ${inputs.nav.length}`,
);
}
const Nav = inputs.nav[0].component;
if (inputs.content.length !== 1) {
throw Error(
`Extension 'core.layout' did not receive exactly one 'content' input, got ${inputs.content.length}`,
);
}
const Content = inputs.content[0].component;
bind({
// TODO: set base path using the logic from AppRouter
component: () => (
element: (
<SidebarPage>
<Nav />
<Content />
{inputs.nav[0].element}
{inputs.content[0].element}
</SidebarPage>
),
});
@@ -67,12 +67,12 @@ export const CoreNav = createExtension({
at: 'core.layout/nav',
inputs: {},
output: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
factory({ bind }) {
bind({
// TODO: set base path using the logic from AppRouter
component: () => (
element: (
<Sidebar>
<SidebarLogo />
<SidebarDivider />
@@ -29,26 +29,26 @@ export const CoreRoutes = createExtension({
extensionData: {
path: coreExtensionData.routePath,
ref: coreExtensionData.routeRef,
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
},
},
output: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
factory({ bind, inputs }) {
const Routes = () => {
const element = useRoutes(
inputs.routes.map(route => ({
path: route.path,
element: <route.component />,
element: route.element,
})),
);
return element;
};
bind({
component: () => <Routes />,
element: <Routes />,
});
},
});
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import React from 'react';
import React, { JSX } from 'react';
import { ConfigReader } from '@backstage/config';
import {
BackstagePlugin,
@@ -173,20 +173,16 @@ export function createApp(options: {
return {
createRoot() {
const rootComponents = rootInstances
.map(e => e.getData(coreExtensionData.reactComponent))
.filter((x): x is React.ComponentType => !!x);
const rootElements = rootInstances
.map(e => e.getData(coreExtensionData.reactElement))
.filter((x): x is JSX.Element => !!x);
return (
<ApiProvider apis={apiHolder}>
<AppContextProvider appContext={appContext}>
<AppThemeProvider>
<RoutingProvider routePaths={routePaths}>
{/* TODO: set base path using the logic from AppRouter */}
<BrowserRouter>
{rootComponents.map((Component, i) => (
<Component key={i} />
))}
</BrowserRouter>
<BrowserRouter>{rootElements}</BrowserRouter>
</RoutingProvider>
</AppThemeProvider>
</AppContextProvider>
+3 -3
View File
@@ -7,8 +7,8 @@
import { AnyApiFactory } from '@backstage/core-plugin-api';
import { AnyApiRef } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
import { JsonObject } from '@backstage/types';
import { JSX as JSX_2 } from 'react';
import { default as React_2 } from 'react';
import { ReactNode } from 'react';
import { RouteRef } from '@backstage/core-plugin-api';
@@ -49,7 +49,7 @@ export interface ConfigurableExtensionDataRef<
// @public (undocumented)
export const coreExtensionData: {
reactComponent: ConfigurableExtensionDataRef<ComponentType<{}>, {}>;
reactElement: ConfigurableExtensionDataRef<JSX_2.Element, {}>;
routePath: ConfigurableExtensionDataRef<string, {}>;
apiFactory: ConfigurableExtensionDataRef<AnyApiFactory, {}>;
routeRef: ConfigurableExtensionDataRef<RouteRef<any>, {}>;
@@ -158,7 +158,7 @@ export function createPageExtension<
disabled?: boolean;
inputs?: TInputs;
routeRef?: RouteRef;
component: (props: {
loader: (options: {
config: TConfig;
inputs: ExtensionDataInputValues<TInputs>;
}) => Promise<JSX.Element>;
@@ -30,7 +30,7 @@ describe('createPageExtension', () => {
createPageExtension({
id: 'test',
configSchema,
component: async () => <div />,
loader: async () => <div />,
}),
).toEqual({
$$type: '@backstage/Extension',
@@ -40,7 +40,7 @@ describe('createPageExtension', () => {
disabled: false,
inputs: {},
output: {
component: expect.anything(),
element: expect.anything(),
path: expect.anything(),
routeRef: expect.anything(),
},
@@ -55,10 +55,10 @@ describe('createPageExtension', () => {
configSchema,
inputs: {
first: {
extensionData: { component: coreExtensionData.reactComponent },
extensionData: { element: coreExtensionData.reactElement },
},
},
component: async () => <div />,
loader: async () => <div />,
}),
).toEqual({
$$type: '@backstage/Extension',
@@ -68,11 +68,11 @@ describe('createPageExtension', () => {
disabled: true,
inputs: {
first: {
extensionData: { component: coreExtensionData.reactComponent },
extensionData: { element: coreExtensionData.reactElement },
},
},
output: {
component: expect.anything(),
element: expect.anything(),
path: expect.anything(),
routeRef: expect.anything(),
},
@@ -83,7 +83,7 @@ describe('createPageExtension', () => {
createPageExtension({
id: 'test',
defaultPath: '/here',
component: async () => <div />,
loader: async () => <div />,
}),
).toEqual({
$$type: '@backstage/Extension',
@@ -93,7 +93,7 @@ describe('createPageExtension', () => {
disabled: false,
inputs: {},
output: {
component: expect.anything(),
element: expect.anything(),
path: expect.anything(),
routeRef: expect.anything(),
},
@@ -48,7 +48,7 @@ export function createPageExtension<
disabled?: boolean;
inputs?: TInputs;
routeRef?: RouteRef;
component: (props: {
loader: (options: {
config: TConfig;
inputs: ExtensionDataInputValues<TInputs>;
}) => Promise<JSX.Element>;
@@ -66,7 +66,7 @@ export function createPageExtension<
at: options.at ?? 'core.routes/routes',
disabled: options.disabled,
output: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
path: coreExtensionData.routePath,
routeRef: coreExtensionData.routeRef.optional(),
},
@@ -75,13 +75,13 @@ export function createPageExtension<
factory({ bind, config, inputs, source }) {
const LazyComponent = React.lazy(() =>
options
.component({ config, inputs })
.loader({ config, inputs })
.then(element => ({ default: () => element })),
);
bind({
path: config.path,
component: () => (
element: (
<ExtensionBoundary source={source}>
<React.Suspense fallback="...">
<LazyComponent />
@@ -15,12 +15,12 @@
*/
import { AnyApiFactory, RouteRef } from '@backstage/core-plugin-api';
import { ComponentType } from 'react';
import { JSX } from 'react';
import { createExtensionDataRef } from './createExtensionDataRef';
/** @public */
export const coreExtensionData = {
reactComponent: createExtensionDataRef<ComponentType>('core.reactComponent'),
reactElement: createExtensionDataRef<JSX.Element>('core.reactElement'),
routePath: createExtensionDataRef<string>('core.routing.path'),
apiFactory: createExtensionDataRef<AnyApiFactory>('core.api.factory'),
routeRef: createExtensionDataRef<RouteRef>('core.routing.ref'),
@@ -95,14 +95,13 @@ const outputExtension = createExtension({
},
},
output: {
component: coreExtensionData.reactComponent,
element: coreExtensionData.reactElement,
},
factory({ bind, inputs }) {
bind({
component: () =>
React.createElement('span', {}, [
`Names: ${inputs.names.map(n => n.name).join(', ')}`,
]),
element: React.createElement('span', {}, [
`Names: ${inputs.names.map(n => n.name).join(', ')}`,
]),
});
},
});
+1 -1
View File
@@ -35,7 +35,7 @@ import { createApiFactory } from '@backstage/core-plugin-api';
export const GraphiqlPage = createPageExtension({
id: 'plugin.graphiql.page',
defaultPath: '/graphiql',
component: () => import('./components').then(m => <m.GraphiQLPage />),
loader: () => import('./components').then(m => <m.GraphiQLPage />),
});
/** @internal */