frontend-plugin-api: migration to IconElement + API reports

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-02-11 22:02:28 +01:00
parent c47f8402b9
commit abd0a5ad52
30 changed files with 260 additions and 100 deletions
+25 -22
View File
@@ -16,8 +16,8 @@ import { ExtensionDataRef as ExtensionDataRef_2 } from '@backstage/frontend-plug
import { ExtensionInput as ExtensionInput_2 } from '@backstage/frontend-plugin-api';
import { JsonObject } from '@backstage/types';
import { JsonValue } from '@backstage/types';
import { JSX as JSX_2 } from 'react/jsx-runtime';
import { JSX as JSX_3 } from 'react';
import { JSX as JSX_2 } from 'react';
import { JSX as JSX_3 } from 'react/jsx-runtime';
import { Observable } from '@backstage/types';
import { PropsWithChildren } from 'react';
import { ReactNode } from 'react';
@@ -52,7 +52,7 @@ export const analyticsApiRef: ApiRef<AnalyticsApi>;
export const AnalyticsContext: (options: {
attributes: Partial<AnalyticsContextValue>;
children: ReactNode;
}) => JSX_2.Element;
}) => JSX_3.Element;
// @public
export interface AnalyticsContextValue {
@@ -263,7 +263,7 @@ export const AppRootElementBlueprint: ExtensionBlueprint_2<{
params: {
element: JSX.Element;
};
output: ExtensionDataRef_2<JSX_3, 'core.reactElement', {}>;
output: ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>;
inputs: {};
config: {};
configInput: {};
@@ -389,9 +389,9 @@ export interface ConfigurableExtensionDataRef<
// @public (undocumented)
export const coreExtensionData: {
title: ConfigurableExtensionDataRef_2<string, 'core.title', {}>;
icon: ConfigurableExtensionDataRef_2<IconComponent, 'core.icon', {}>;
icon: ConfigurableExtensionDataRef_2<IconElement, 'core.icon', {}>;
reactElement: ConfigurableExtensionDataRef_2<
JSX_3.Element,
JSX_2.Element,
'core.reactElement',
{}
>;
@@ -1103,7 +1103,7 @@ export type ExtensionBlueprintParams<T extends object = object> = {
};
// @public (undocumented)
export function ExtensionBoundary(props: ExtensionBoundaryProps): JSX_2.Element;
export function ExtensionBoundary(props: ExtensionBoundaryProps): JSX_3.Element;
// @public (undocumented)
export namespace ExtensionBoundary {
@@ -1369,7 +1369,7 @@ export interface FrontendPlugin<
readonly $$type: '@backstage/FrontendPlugin';
// (undocumented)
readonly externalRoutes: TExternalRoutes;
readonly icon?: IconComponent;
readonly icon?: IconElement;
// @deprecated
readonly id: string;
info(): Promise<FrontendPluginInfo>;
@@ -1430,18 +1430,21 @@ export const HeaderActionBlueprint: ExtensionBlueprint_2<{
params: {
loader: () => Promise<JSX.Element>;
};
output: ExtensionDataRef_2<JSX_3, 'core.reactElement', {}>;
output: ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>;
inputs: {};
config: {};
configInput: {};
dataRefs: never;
}>;
// @public
// @public @deprecated
export type IconComponent = ComponentType<{
fontSize?: 'medium' | 'large' | 'small' | 'inherit';
}>;
// @public
export type IconElement = JSX_2.Element | null;
// @public
export interface IconsApi {
// (undocumented)
@@ -1716,9 +1719,9 @@ export interface OverridableFrontendPlugin<
): OverridableExtensionDefinition<TExtensionMap[TId]['T']>;
// (undocumented)
withOverrides(options: {
extensions: Array<ExtensionDefinition>;
extensions?: Array<ExtensionDefinition>;
title?: string;
icon?: IconComponent;
icon?: IconElement;
info?: FrontendPluginInfoOptions;
}): OverridableFrontendPlugin<TRoutes, TExternalRoutes, TExtensionMap>;
}
@@ -1730,7 +1733,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
defaultPath?: [Error: `Use the 'path' param instead`];
path: string;
title?: string;
icon?: IconComponent;
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
};
@@ -1743,7 +1746,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
optional: true;
}
>
| ExtensionDataRef_2<JSX_3, 'core.reactElement', {}>
| ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
| ExtensionDataRef_2<
string,
'core.title',
@@ -1752,7 +1755,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
}
>
| ExtensionDataRef_2<
IconComponent,
IconElement,
'core.icon',
{
optional: true;
@@ -1760,7 +1763,7 @@ export const PageBlueprint: ExtensionBlueprint_2<{
>;
inputs: {
pages: ExtensionInput_2<
| ConfigurableExtensionDataRef_2<JSX_3, 'core.reactElement', {}>
| ConfigurableExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
| ConfigurableExtensionDataRef_2<string, 'core.routing.path', {}>
| ConfigurableExtensionDataRef_2<
RouteRef<AnyRouteRefParams_2>,
@@ -1805,7 +1808,7 @@ export interface PageLayoutProps {
// (undocumented)
children?: ReactNode;
// (undocumented)
icon?: IconComponent;
icon?: IconElement;
// (undocumented)
tabs?: PageTab[];
// (undocumented)
@@ -1848,7 +1851,7 @@ export interface PluginOptions<
externalRoutes?: TExternalRoutes;
// (undocumented)
featureFlags?: FeatureFlagConfig[];
icon?: IconComponent;
icon?: IconElement;
// (undocumented)
info?: FrontendPluginInfoOptions;
// (undocumented)
@@ -2009,7 +2012,7 @@ export const SubPageBlueprint: ExtensionBlueprint_2<{
optional: true;
}
>
| ExtensionDataRef_2<JSX_3, 'core.reactElement', {}>
| ExtensionDataRef_2<JSX_2, 'core.reactElement', {}>
| ExtensionDataRef_2<string, 'core.title', {}>;
inputs: {};
config: {
@@ -2105,9 +2108,9 @@ export type TranslationFunction<
NestedMessageKeys<TKey, IMessages>,
PluralKeys<TMessages>,
IMessages,
string | JSX_3.Element
string | JSX_2.Element
>
): JSX_3.Element;
): JSX_2.Element;
}
: never;
@@ -2283,7 +2286,7 @@ export function withApis<T extends {}>(
): <TProps extends T>(
WrappedComponent: ComponentType<TProps>,
) => {
(props: PropsWithChildren<Omit<TProps, keyof T>>): JSX_2.Element;
(props: PropsWithChildren<Omit<TProps, keyof T>>): JSX_3.Element;
displayName: string;
};
```
@@ -15,7 +15,7 @@
*/
import { Routes, Route, Navigate } from 'react-router-dom';
import { IconComponent } from '../icons/types';
import { IconElement } from '../icons/types';
import { RouteRef } from '../routing';
import {
coreExtensionData,
@@ -61,7 +61,7 @@ export const PageBlueprint = createExtensionBlueprint({
defaultPath?: [Error: `Use the 'path' param instead`];
path: string;
title?: string;
icon?: IconComponent;
icon?: IconElement;
loader?: () => Promise<JSX.Element>;
routeRef?: RouteRef;
},
@@ -15,7 +15,7 @@
*/
import { ReactNode } from 'react';
import { IconComponent } from '../icons/types';
import { IconElement } from '../icons/types';
import { createSwappableComponent } from './createSwappableComponent';
/**
@@ -35,7 +35,7 @@ export interface PageTab {
*/
export interface PageLayoutProps {
title?: string;
icon?: IconComponent;
icon?: IconElement;
tabs?: PageTab[];
children?: ReactNode;
}
@@ -44,7 +44,7 @@ export interface PageLayoutProps {
* Default implementation of PageLayout using plain HTML elements
*/
function DefaultPageLayout(props: PageLayoutProps): JSX.Element {
const { title, icon: Icon, tabs, children } = props;
const { title, icon, tabs, children } = props;
return (
<div
@@ -75,7 +75,7 @@ function DefaultPageLayout(props: PageLayoutProps): JSX.Element {
fontWeight: 500,
}}
>
{Icon && <Icon fontSize="small" />}
{icon}
{title}
</div>
)}
@@ -15,14 +15,14 @@
*/
import { JSX } from 'react';
import { IconComponent } from '../icons/types';
import { IconElement } from '../icons/types';
import { RouteRef } from '../routing/RouteRef';
import { createExtensionDataRef } from './createExtensionDataRef';
/** @public */
export const coreExtensionData = {
title: createExtensionDataRef<string>().with({ id: 'core.title' }),
icon: createExtensionDataRef<IconComponent>().with({ id: 'core.icon' }),
icon: createExtensionDataRef<IconElement>().with({ id: 'core.icon' }),
reactElement: createExtensionDataRef<JSX.Element>().with({
id: 'core.reactElement',
}),
@@ -29,7 +29,7 @@ import {
import { FeatureFlagConfig } from './types';
import { MakeSortedExtensionsMap } from './MakeSortedExtensionsMap';
import { JsonObject } from '@backstage/types';
import { IconComponent } from '../icons/types';
import { IconElement } from '../icons/types';
import { RouteRef, SubRouteRef, ExternalRouteRef } from '../routing';
import { ID_PATTERN } from './constants';
@@ -123,7 +123,7 @@ export interface OverridableFrontendPlugin<
/**
* Overrides the display icon of the plugin.
*/
icon?: IconComponent;
icon?: IconElement;
/**
* Overrides the original info loaders of the plugin one by one.
@@ -160,7 +160,7 @@ export interface FrontendPlugin<
/**
* The display icon of the plugin, used in page headers and navigation.
*/
readonly icon?: IconComponent;
readonly icon?: IconElement;
readonly routes: TRoutes;
readonly externalRoutes: TExternalRoutes;
@@ -186,7 +186,7 @@ export interface PluginOptions<
/**
* The display icon of the plugin, used in page headers and navigation.
*/
icon?: IconComponent;
icon?: IconElement;
routes?: TRoutes;
externalRoutes?: TExternalRoutes;
extensions?: TExtensions;