diff --git a/.changeset/green-lies-invite copy.md b/.changeset/green-lies-invite copy.md new file mode 100644 index 0000000000..469ed2fbac --- /dev/null +++ b/.changeset/green-lies-invite copy.md @@ -0,0 +1,39 @@ +--- +'@backstage/frontend-plugin-api': minor +--- + +**BREAKING**: In an attempt to align some of the API's around providing components to `Blueprints`, we've renamed the parameters for both the `RouterBlueprint` and `AppRootWrapperBlueprint` from `Component` to `component`. + +```tsx +// old +RouterBlueprint.make({ + params: { + Component: ({ children }) =>
{children}
, + }, +}); + +// new +RouterBlueprint.make({ + params: { + component: ({ children }) =>
{children}
, + }, +}); +``` + +```tsx +// old +AppRootWrapperBlueprint.make({ + params: { + Component: ({ children }) =>
{children}
, + }, +}); + +// new +AppRootWrapperBlueprint.make({ + params: { + component: ({ children }) =>
{children}
, + }, +}); +``` + +As part of this change, the type for `component` has also changed from `ComponentType>` to `(props: { children: ReactNode }) => JSX.Element | null` which is not breaking, just a little more reflective of the actual expected component. diff --git a/.changeset/green-lies-invite.md b/.changeset/green-lies-invite.md new file mode 100644 index 0000000000..92ccc2324d --- /dev/null +++ b/.changeset/green-lies-invite.md @@ -0,0 +1,7 @@ +--- +'@backstage/frontend-test-utils': patch +'@backstage/core-compat-api': patch +'@backstage/plugin-app': patch +--- + +Updated the usage of the `RouterBlueprint` and `AppRootWrapperBlueprint` to use the lowercase `component` parameter diff --git a/packages/core-compat-api/src/convertLegacyAppOptions.tsx b/packages/core-compat-api/src/convertLegacyAppOptions.tsx index c98875464c..9da935957a 100644 --- a/packages/core-compat-api/src/convertLegacyAppOptions.tsx +++ b/packages/core-compat-api/src/convertLegacyAppOptions.tsx @@ -139,7 +139,7 @@ export function convertLegacyAppOptions( if (Router) { extensions.push( RouterBlueprint.make({ - params: { Component: componentCompatWrapper(Router) }, + params: { component: componentCompatWrapper(Router) }, }), ); } diff --git a/packages/frontend-plugin-api/report.api.md b/packages/frontend-plugin-api/report.api.md index 5ebdda66a6..d9244a6ff4 100644 --- a/packages/frontend-plugin-api/report.api.md +++ b/packages/frontend-plugin-api/report.api.md @@ -71,7 +71,6 @@ import { OpenIdConnectApi } from '@backstage/core-plugin-api'; import { PendingOAuthRequest } from '@backstage/core-plugin-api'; import { ProfileInfo } from '@backstage/core-plugin-api'; import { ProfileInfoApi } from '@backstage/core-plugin-api'; -import { PropsWithChildren } from 'react'; import { ReactNode } from 'react'; import { RouteRef as RouteRef_2 } from '@backstage/frontend-plugin-api'; import { SessionApi } from '@backstage/core-plugin-api'; @@ -268,12 +267,11 @@ export const AppRootWrapperBlueprint: ExtensionBlueprint<{ kind: 'app-root-wrapper'; name: undefined; params: { - Component: ComponentType>; + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; }; output: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.root.wrapper', {} >; @@ -282,9 +280,7 @@ export const AppRootWrapperBlueprint: ExtensionBlueprint<{ configInput: {}; dataRefs: { component: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.root.wrapper', {} >; @@ -1726,12 +1722,11 @@ export const RouterBlueprint: ExtensionBlueprint<{ kind: 'app-router-component'; name: undefined; params: { - Component: ComponentType>; + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; }; output: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.router.wrapper', {} >; @@ -1740,9 +1735,7 @@ export const RouterBlueprint: ExtensionBlueprint<{ configInput: {}; dataRefs: { component: ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.router.wrapper', {} >; diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx index d46975abd9..b4ad8ed2d2 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.test.tsx @@ -27,7 +27,7 @@ describe('AppRootWrapperBlueprint', () => { it('should return an extension with sensible defaults', () => { const extension = AppRootWrapperBlueprint.make({ params: { - Component: () =>
Hello
, + component: () =>
Hello
, }, }); @@ -59,7 +59,7 @@ describe('AppRootWrapperBlueprint', () => { const extension = AppRootWrapperBlueprint.make({ name: 'test', params: { - Component: () =>
Hello
, + component: () =>
Hello
, }, }); @@ -80,7 +80,7 @@ describe('AppRootWrapperBlueprint', () => { }, *factory(originalFactory, { inputs, config }) { yield* originalFactory({ - Component: ({ children }) => ( + component: ({ children }) => (
{children} {inputs.children.flatMap(c => diff --git a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx index 481be1bc0b..493fba05f6 100644 --- a/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx +++ b/packages/frontend-plugin-api/src/blueprints/AppRootWrapperBlueprint.tsx @@ -14,11 +14,11 @@ * limitations under the License. */ -import { ComponentType, PropsWithChildren } from 'react'; +import { ReactNode } from 'react'; import { createExtensionBlueprint, createExtensionDataRef } from '../wiring'; const componentDataRef = createExtensionDataRef< - ComponentType> + (props: { children: ReactNode }) => JSX.Element | null >().with({ id: 'app.root.wrapper' }); /** @@ -35,12 +35,11 @@ export const AppRootWrapperBlueprint = createExtensionBlueprint({ dataRefs: { component: componentDataRef, }, - *factory(params: { Component: ComponentType> }) { - // todo(blam): not sure that this wrapping is even necessary anymore. - const Component = (props: PropsWithChildren<{}>) => { - return {props.children}; - }; - - yield componentDataRef(Component); + *factory(params: { + /** @deprecated use the `component` parameter instead */ + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; + }) { + yield componentDataRef(params.component); }, }); diff --git a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx index 00015d0c3d..f2e5199124 100644 --- a/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx +++ b/packages/frontend-plugin-api/src/blueprints/RouterBlueprint.test.tsx @@ -27,7 +27,7 @@ describe('RouterBlueprint', () => { it('should return an extension when calling make with sensible defaults', () => { const extension = RouterBlueprint.make({ params: { - Component: props =>
{props.children}
, + component: props =>
{props.children}
, }, }); @@ -58,7 +58,7 @@ describe('RouterBlueprint', () => { it('should work with simple options', async () => { const extension = RouterBlueprint.make({ params: { - Component: ({ children }) => ( + component: ({ children }) => (
{children}
@@ -94,7 +94,7 @@ describe('RouterBlueprint', () => { }, *factory(originalFactory, { inputs, config }) { yield* originalFactory({ - Component: ({ children }) => ( + component: ({ children }) => (
> + (props: { children: ReactNode }) => JSX.Element | null >().with({ id: 'app.router.wrapper' }); /** @public */ @@ -29,7 +29,11 @@ export const RouterBlueprint = createExtensionBlueprint({ dataRefs: { component: componentDataRef, }, - *factory({ Component }: { Component: ComponentType> }) { - yield componentDataRef(Component); + *factory(params: { + /** @deprecated use the `component` parameter instead */ + Component?: [error: 'Use the `component` parameter instead']; + component: (props: { children: ReactNode }) => JSX.Element | null; + }) { + yield componentDataRef(params.component); }, }); diff --git a/packages/frontend-test-utils/src/app/renderInTestApp.tsx b/packages/frontend-test-utils/src/app/renderInTestApp.tsx index d4010a92ad..e308cf9741 100644 --- a/packages/frontend-test-utils/src/app/renderInTestApp.tsx +++ b/packages/frontend-test-utils/src/app/renderInTestApp.tsx @@ -160,7 +160,7 @@ export function renderInTestApp( }), RouterBlueprint.make({ params: { - Component: ({ children }) => ( + component: ({ children }) => ( {children} diff --git a/plugins/app/report.api.md b/plugins/app/report.api.md index 15001d2961..4eb1ff76fc 100644 --- a/plugins/app/report.api.md +++ b/plugins/app/report.api.md @@ -130,9 +130,7 @@ const appPlugin: FrontendPlugin< inputs: { router: ExtensionInput< ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.router.wrapper', {} >, @@ -168,9 +166,7 @@ const appPlugin: FrontendPlugin< >; wrappers: ExtensionInput< ConfigurableExtensionDataRef< - ComponentType<{ - children?: ReactNode | undefined; - }>, + (props: { children: ReactNode }) => JSX.Element | null, 'app.root.wrapper', {} >, diff --git a/plugins/app/src/extensions/AppRoot.tsx b/plugins/app/src/extensions/AppRoot.tsx index 17e8aa3b1f..9ce2b055dd 100644 --- a/plugins/app/src/extensions/AppRoot.tsx +++ b/plugins/app/src/extensions/AppRoot.tsx @@ -182,7 +182,7 @@ type RouteResolverProxy = { export interface AppRouterProps { children?: ReactNode; SignInPageComponent?: ComponentType; - RouterComponent?: ComponentType>; + RouterComponent?: (props: { children: ReactNode }) => JSX.Element | null; extraElements?: Array; }