frontend-plugin-api: move new PluginWrapper to alpha

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-01-16 16:56:47 +01:00
parent 7b7e547d46
commit d194acb0e3
12 changed files with 115 additions and 68 deletions
+1 -1
View File
@@ -2,4 +2,4 @@
'@backstage/frontend-plugin-api': patch
---
Added `PluginWrapperBlueprint`, which can install components that will wrap all plugin elements. The `AppRootWrapperBlueprint` has also been deprecated and should be replaced either with the new plugin wrapper, or for app overrides, the new blueprint with the same name from `@backstage/plugin-app-react`.
Added an alpha `PluginWrapperBlueprint` exported from `@backstage/frontend-plugin-api/alpha`, which can install components that will wrap all plugin elements. The `AppRootWrapperBlueprint` has also been deprecated and should be replaced either with the new plugin wrapper, or for app overrides, the new blueprint with the same name from `@backstage/plugin-app-react`.
@@ -16,12 +16,16 @@
"sideEffects": false,
"exports": {
".": "./src/index.ts",
"./alpha": "./src/alpha.ts",
"./package.json": "./package.json"
},
"main": "src/index.ts",
"types": "src/index.ts",
"typesVersions": {
"*": {
"alpha": [
"src/alpha.ts"
],
"package.json": [
"package.json"
]
@@ -0,0 +1,68 @@
## API Report File for "@backstage/frontend-plugin-api"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { ApiRef } from '@backstage/frontend-plugin-api';
import { ComponentType } from 'react';
import { ConfigurableExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ExtensionBlueprint } from '@backstage/frontend-plugin-api';
import { ExtensionBlueprintParams } from '@backstage/frontend-plugin-api';
import { ExtensionDataRef } from '@backstage/frontend-plugin-api';
import { ReactNode } from 'react';
// @alpha
export type PluginWrapperApi = {
getPluginWrapper(pluginId: string):
| ComponentType<{
children: ReactNode;
}>
| undefined;
};
// @alpha
export const pluginWrapperApiRef: ApiRef<PluginWrapperApi>;
// @alpha
export const PluginWrapperBlueprint: ExtensionBlueprint<{
kind: 'plugin-wrapper';
params: (params: {
loader: () => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>;
}) => ExtensionBlueprintParams<{
loader: () => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>;
}>;
output: ExtensionDataRef<
() => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>,
'core.plugin-wrapper.loader',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
wrapper: ConfigurableExtensionDataRef<
() => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>,
'core.plugin-wrapper.loader',
{}
>;
};
}>;
// (No @packageDocumentation comment for this package)
```
@@ -1868,59 +1868,6 @@ export interface PluginOptions<
routes?: TRoutes;
}
// @public
export type PluginWrapperApi = {
getPluginWrapper(pluginId: string):
| ComponentType<{
children: ReactNode;
}>
| undefined;
};
// @public
export const pluginWrapperApiRef: ApiRef<PluginWrapperApi>;
// @public
export const PluginWrapperBlueprint: ExtensionBlueprint_2<{
kind: 'plugin-wrapper';
params: (params: {
loader: () => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>;
}) => ExtensionBlueprintParams_2<{
loader: () => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>;
}>;
output: ExtensionDataRef_2<
() => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>,
'core.plugin-wrapper.loader',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
wrapper: ConfigurableExtensionDataRef_2<
() => Promise<{
component: ComponentType<{
children: ReactNode;
}>;
}>,
'core.plugin-wrapper.loader',
{}
>;
};
}>;
// @public (undocumented)
export type PortableSchema<TOutput, TInput = TOutput> = {
parse: (input: TInput) => TOutput;
+27
View File
@@ -0,0 +1,27 @@
/*
* Copyright 2024 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.
*/
/**
* Alpha exports for plugin wrapper functionality.
*
* @alpha
*/
export { PluginWrapperBlueprint } from './blueprints/PluginWrapperBlueprint';
export {
type PluginWrapperApi,
pluginWrapperApiRef,
} from './apis/definitions/PluginWrapperApi';
@@ -15,7 +15,7 @@
*/
import { ComponentType, ReactNode } from 'react';
import { ApiRef, createApiRef } from '../system';
import { createApiRef } from '@backstage/frontend-plugin-api';
/**
* The Plugin Wrapper API is used to wrap plugin extensions with providers,
@@ -27,7 +27,7 @@ import { ApiRef, createApiRef } from '../system';
* system, but can be used for advanced use-cases. If you do override it, be
* sure to include the default implementation as well.
*
* @public
* @alpha
*/
export type PluginWrapperApi = {
/**
@@ -43,8 +43,8 @@ export type PluginWrapperApi = {
/**
* The API reference of {@link PluginWrapperApi}.
*
* @public
* @alpha
*/
export const pluginWrapperApiRef: ApiRef<PluginWrapperApi> = createApiRef({
id: 'core.plugin-wrapper',
export const pluginWrapperApiRef = createApiRef<PluginWrapperApi>({
id: 'core.plugin-wrapper.alpha',
});
@@ -49,4 +49,3 @@ export * from './RouteResolutionApi';
export * from './StorageApi';
export * from './AnalyticsApi';
export * from './TranslationApi';
export * from './PluginWrapperApi';
@@ -27,10 +27,11 @@ const componentDataRef = createExtensionDataRef<
* and similar.
*
* @public
* @deprecated Use {@link PluginWrapperBlueprint} instead if you want to wrap
* all plugin components in the same wrapper. If you want to wrap the entire
* app, use the `AppRootWrapperBlueprint` from `@backstage/plugin-app-react`
* instead, although note that only app modules are able to use that blueprint.
* @deprecated Use `PluginWrapperBlueprint` from
* `@backstage/frontend-plugin-api/alpha` instead if you want to wrap all plugin
* components in the same wrapper. If you want to wrap the entire app, use the
* `AppRootWrapperBlueprint` from `@backstage/plugin-app-react` instead,
* although note that only app modules are able to use that blueprint.
*/
export const AppRootWrapperBlueprint = createExtensionBlueprint({
kind: 'app-root-wrapper',
@@ -28,7 +28,7 @@ const wrapperDataRef = createExtensionDataRef<
/**
* Creates extensions that wrap plugin extensions with providers.
*
* @public
* @alpha
*/
export const PluginWrapperBlueprint = createExtensionBlueprint({
kind: 'plugin-wrapper',
@@ -21,7 +21,6 @@ export {
export { ApiBlueprint } from './ApiBlueprint';
export { AppRootElementBlueprint } from './AppRootElementBlueprint';
export { AppRootWrapperBlueprint } from './AppRootWrapperBlueprint';
export { PluginWrapperBlueprint } from './PluginWrapperBlueprint';
export { IconBundleBlueprint } from './IconBundleBlueprint';
export {
NavContentBlueprint,
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { PluginWrapperApi } from '@backstage/frontend-plugin-api';
import { PluginWrapperApi } from '@backstage/frontend-plugin-api/alpha';
import { ComponentType, ReactNode, useEffect, useState } from 'react';
type WrapperInput = {
@@ -16,9 +16,11 @@
import {
PluginWrapperBlueprint,
pluginWrapperApiRef,
} from '@backstage/frontend-plugin-api/alpha';
import {
createExtensionInput,
ApiBlueprint,
pluginWrapperApiRef,
} from '@backstage/frontend-plugin-api';
import { DefaultPluginWrapperApi } from '../apis/PluginWrapperApi';