diff --git a/plugins/home-react/src/alpha.ts b/plugins/home-react/src/alpha.ts index 88f318a3f8..2766ef83a9 100644 --- a/plugins/home-react/src/alpha.ts +++ b/plugins/home-react/src/alpha.ts @@ -26,7 +26,10 @@ export { homeReactTranslationRef } from './translation'; export { HomepageWidgetBlueprint, - widgetMetadataRef, type HomepageWidgetBlueprintParams, } from './alpha/blueprints/HomepageWidgetBlueprint'; +export { + homePageWidgetDataRef, + type HomePageWidgetData, +} from './alpha/dataRefs'; export type { ComponentParts, CardLayout, CardSettings } from './extensions'; diff --git a/plugins/home-react/src/alpha/blueprints/HomepageWidgetBlueprint.tsx b/plugins/home-react/src/alpha/blueprints/HomepageWidgetBlueprint.tsx index 553a6b3249..0cb898a5f8 100644 --- a/plugins/home-react/src/alpha/blueprints/HomepageWidgetBlueprint.tsx +++ b/plugins/home-react/src/alpha/blueprints/HomepageWidgetBlueprint.tsx @@ -17,9 +17,7 @@ import { lazy, ReactElement } from 'react'; import { compatWrapper } from '@backstage/core-compat-api'; import { - coreExtensionData, createExtensionBlueprint, - createExtensionDataRef, ExtensionBoundary, } from '@backstage/frontend-plugin-api'; import { @@ -29,6 +27,7 @@ import { CardSettings, ComponentParts, } from '../../extensions'; +import { homePageWidgetDataRef } from '../dataRefs'; /** @alpha */ export interface HomepageWidgetBlueprintParams { @@ -68,18 +67,6 @@ const DEFAULT_WIDGET_ATTACH_POINT = { input: 'widgets', } as const; -/** - * Extension data ref for widget metadata. - * @alpha - */ -export const widgetMetadataRef = createExtensionDataRef<{ - name?: string; - title?: string; - description?: string; - layout?: CardLayout; - settings?: CardSettings; -}>().with({ id: 'home.widget.metadata' }); - /** * Creates widgets that can be installed into the home page grid. * @@ -88,7 +75,7 @@ export const widgetMetadataRef = createExtensionDataRef<{ export const HomepageWidgetBlueprint = createExtensionBlueprint({ kind: 'home-widget', attachTo: DEFAULT_WIDGET_ATTACH_POINT, - output: [coreExtensionData.reactElement, widgetMetadataRef], + output: [homePageWidgetDataRef], *factory(params: HomepageWidgetBlueprintParams, { node }) { const isCustomizable = params.settings?.schema !== undefined; const LazyCard = lazy(() => @@ -113,11 +100,8 @@ export const HomepageWidgetBlueprint = createExtensionBlueprint({ , ); - yield coreExtensionData.reactElement( - , - ); - - yield widgetMetadataRef({ + yield homePageWidgetDataRef({ + component: , name: params.name, title: params.title, description: params.description, diff --git a/plugins/home-react/src/alpha/dataRefs.ts b/plugins/home-react/src/alpha/dataRefs.ts new file mode 100644 index 0000000000..00b221994f --- /dev/null +++ b/plugins/home-react/src/alpha/dataRefs.ts @@ -0,0 +1,66 @@ +/* + * Copyright 2025 The Backstage Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { createExtensionDataRef } from '@backstage/frontend-plugin-api'; +import { ReactElement } from 'react'; +import type { CardLayout, CardSettings } from '../extensions'; + +/** + * Extension data for homepage widgets, bundling the rendered component + * with its metadata. + * + * @alpha + */ +export interface HomePageWidgetData { + /** + * The rendered widget component (typically a card with header, content, etc.) + */ + component: ReactElement; + /** + * Optional name identifier for the widget + */ + name?: string; + /** + * Optional title displayed in the widget header + */ + title?: string; + /** + * Optional description shown in widget catalogs or configuration UIs + */ + description?: string; + /** + * Optional layout hints for positioning and sizing + */ + layout?: CardLayout; + /** + * Optional settings schema for widget configuration + */ + settings?: CardSettings; +} + +/** + * Extension data ref for homepage widgets. + * + * This follows the pattern from FormFieldBlueprint, bundling the component + * and metadata into a single comprehensive data ref rather than outputting + * them separately. + * + * @alpha + */ +export const homePageWidgetDataRef = + createExtensionDataRef().with({ + id: 'home.widget.data', + }); diff --git a/plugins/home/src/alpha/HomepageBlueprint.tsx b/plugins/home/src/alpha/HomepageBlueprint.tsx index 8eabae2153..b72ff4d587 100644 --- a/plugins/home/src/alpha/HomepageBlueprint.tsx +++ b/plugins/home/src/alpha/HomepageBlueprint.tsx @@ -25,6 +25,7 @@ import { import { Fragment, type ReactElement, type ReactNode } from 'react'; import { CustomHomepageGrid } from '../components'; import type { CustomHomepageGridProps } from '../components'; +import { homePageWidgetDataRef } from '@backstage/plugin-home-react/alpha'; /** * Arguments provided to the homepage renderer. @@ -78,13 +79,13 @@ export const HomepageBlueprint = createExtensionBlueprint({ attachTo: DEFAULT_ATTACH_POINT, output: [coreExtensionData.reactElement, coreExtensionData.title.optional()], inputs: { - widgets: createExtensionInput([coreExtensionData.reactElement]), + widgets: createExtensionInput([homePageWidgetDataRef]), }, *factory(params: HomepageBlueprintParams = {}, { inputs, node }) { const widgetOutputs = inputs.widgets ?? []; const widgetElements = widgetOutputs.map((widget, index) => ( - {widget.get(coreExtensionData.reactElement)} + {widget.get(homePageWidgetDataRef).component} ));