frontend-plugin-api: move app blueprints to new app-react package

Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
Patrik Oldsberg
2026-01-16 10:58:04 +01:00
parent d15524f895
commit 9ccf84e219
33 changed files with 653 additions and 34 deletions
+1
View File
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
+5
View File
@@ -0,0 +1,5 @@
# @backstage/plugin-app-react
Welcome to the web library package for the app plugin!
_This plugin was created through the Backstage CLI_
+10
View File
@@ -0,0 +1,10 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: backstage-plugin-app-react
title: '@backstage/plugin-app-react'
description: Web library for the app plugin
spec:
lifecycle: experimental
type: backstage-web-library
owner: framework-maintainers
+68
View File
@@ -0,0 +1,68 @@
{
"name": "@backstage/plugin-app-react",
"version": "0.0.0",
"description": "Web library for the app plugin",
"backstage": {
"role": "web-library",
"pluginId": "app",
"pluginPackages": [
"@backstage/plugin-app",
"@backstage/plugin-app-backend",
"@backstage/plugin-app-node",
"@backstage/plugin-app-react"
]
},
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
"repository": {
"type": "git",
"url": "https://github.com/backstage/backstage",
"directory": "plugins/app-react"
},
"license": "Apache-2.0",
"sideEffects": false,
"main": "src/index.ts",
"types": "src/index.ts",
"files": [
"dist"
],
"scripts": {
"build": "backstage-cli package build",
"clean": "backstage-cli package clean",
"lint": "backstage-cli package lint",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack",
"start": "backstage-cli package start",
"test": "backstage-cli package test"
},
"dependencies": {
"@backstage/core-plugin-api": "workspace:^",
"@backstage/frontend-plugin-api": "workspace:^",
"@material-ui/core": "^4.9.13"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
"@backstage/frontend-test-utils": "workspace:^",
"@backstage/test-utils": "workspace:^",
"@testing-library/jest-dom": "^6.0.0",
"@testing-library/react": "^16.0.0",
"@types/react": "^18.0.0",
"react": "^18.0.2",
"react-dom": "^18.0.2",
"react-router-dom": "^6.3.0"
},
"peerDependencies": {
"@types/react": "^17.0.0 || ^18.0.0",
"react": "^17.0.0 || ^18.0.0",
"react-dom": "^17.0.0 || ^18.0.0",
"react-router-dom": "^6.3.0"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
}
}
}
+234
View File
@@ -0,0 +1,234 @@
## API Report File for "@backstage/plugin-app-react"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
import { AppTheme } 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 { IconComponent } from '@backstage/frontend-plugin-api';
import { NavContentComponent } from '@backstage/frontend-plugin-api';
import { NavContentComponentProps } from '@backstage/frontend-plugin-api';
import { ReactNode } from 'react';
import { SignInPageProps } from '@backstage/frontend-plugin-api';
import { SwappableComponentRef } from '@backstage/frontend-plugin-api';
import { TranslationMessages } from '@backstage/frontend-plugin-api';
import { TranslationResource } from '@backstage/frontend-plugin-api';
// @public
export const IconBundleBlueprint: ExtensionBlueprint<{
kind: 'icon-bundle';
params: {
icons: { [key in string]: IconComponent };
};
output: ExtensionDataRef<
{
[x: string]: IconComponent;
},
'core.icons',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
icons: ConfigurableExtensionDataRef<
{
[x: string]: IconComponent;
},
'core.icons',
{}
>;
};
}>;
// @public
export const NavContentBlueprint: ExtensionBlueprint<{
kind: 'nav-content';
params: {
component: NavContentComponent;
};
output: ExtensionDataRef<
NavContentComponent,
'core.nav-content.component',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
component: ConfigurableExtensionDataRef<
NavContentComponent,
'core.nav-content.component',
{}
>;
};
}>;
export { NavContentComponent };
export { NavContentComponentProps };
// @public
export const RouterBlueprint: ExtensionBlueprint<{
kind: 'app-router-component';
params: {
Component?: [error: 'Use the `component` parameter instead'];
component: (props: { children: ReactNode }) => JSX.Element | null;
};
output: ExtensionDataRef<
(props: { children: ReactNode }) => JSX.Element | null,
'app.router.wrapper',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
component: ConfigurableExtensionDataRef<
(props: { children: ReactNode }) => JSX.Element | null,
'app.router.wrapper',
{}
>;
};
}>;
// @public
export const SignInPageBlueprint: ExtensionBlueprint<{
kind: 'sign-in-page';
params: {
loader: () => Promise<ComponentType<SignInPageProps>>;
};
output: ExtensionDataRef<
ComponentType<SignInPageProps>,
'core.sign-in-page.component',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
component: ConfigurableExtensionDataRef<
ComponentType<SignInPageProps>,
'core.sign-in-page.component',
{}
>;
};
}>;
export { SignInPageProps };
// @public
export const SwappableComponentBlueprint: ExtensionBlueprint<{
kind: 'component';
params: <Ref extends SwappableComponentRef<any>>(params: {
component: Ref extends SwappableComponentRef<
any,
infer IExternalComponentProps
>
? {
ref: Ref;
} & ((props: IExternalComponentProps) => JSX.Element | null)
: never;
loader: Ref extends SwappableComponentRef<infer IInnerComponentProps, any>
?
| (() => (props: IInnerComponentProps) => JSX.Element | null)
| (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>)
: never;
}) => ExtensionBlueprintParams<{
component: Ref extends SwappableComponentRef<
any,
infer IExternalComponentProps
>
? {
ref: Ref;
} & ((props: IExternalComponentProps) => JSX.Element | null)
: never;
loader: Ref extends SwappableComponentRef<infer IInnerComponentProps, any>
?
| (() => (props: IInnerComponentProps) => JSX.Element | null)
| (() => Promise<(props: IInnerComponentProps) => JSX.Element | null>)
: never;
}>;
output: ExtensionDataRef<
{
ref: SwappableComponentRef;
loader:
| (() => (props: {}) => JSX.Element | null)
| (() => Promise<(props: {}) => JSX.Element | null>);
},
'core.swappableComponent',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
component: ConfigurableExtensionDataRef<
{
ref: SwappableComponentRef;
loader:
| (() => (props: {}) => JSX.Element | null)
| (() => Promise<(props: {}) => JSX.Element | null>);
},
'core.swappableComponent',
{}
>;
};
}>;
// @public
export const ThemeBlueprint: ExtensionBlueprint<{
kind: 'theme';
params: {
theme: AppTheme;
};
output: ExtensionDataRef<AppTheme, 'core.theme.theme', {}>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
theme: ConfigurableExtensionDataRef<AppTheme, 'core.theme.theme', {}>;
};
}>;
// @public
export const TranslationBlueprint: ExtensionBlueprint<{
kind: 'translation';
params: {
resource: TranslationResource | TranslationMessages;
};
output: ExtensionDataRef<
| TranslationResource<string>
| TranslationMessages<
string,
{
[x: string]: string;
},
boolean
>,
'core.translation.translation',
{}
>;
inputs: {};
config: {};
configInput: {};
dataRefs: {
translation: ConfigurableExtensionDataRef<
| TranslationResource<string>
| TranslationMessages<
string,
{
[x: string]: string;
},
boolean
>,
'core.translation.translation',
{}
>;
};
}>;
```
+98
View File
@@ -0,0 +1,98 @@
/*
* Copyright 2026 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 {
IconBundleBlueprint as _IconBundleBlueprint,
NavContentBlueprint as _NavContentBlueprint,
type NavContentComponent,
type NavContentComponentProps,
RouterBlueprint as _RouterBlueprint,
SignInPageBlueprint as _SignInPageBlueprint,
type SignInPageProps,
SwappableComponentBlueprint as _SwappableComponentBlueprint,
ThemeBlueprint as _ThemeBlueprint,
TranslationBlueprint as _TranslationBlueprint,
} from '@backstage/frontend-plugin-api';
/**
* Creates an extension that adds/replaces an app theme. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const ThemeBlueprint = _ThemeBlueprint;
/**
* Blueprint for creating swappable components from a SwappableComponentRef and a loader. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const SwappableComponentBlueprint = _SwappableComponentBlueprint;
/**
* Creates an extension that replaces the sign in page. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const SignInPageBlueprint = _SignInPageBlueprint;
/**
* Creates an extension that replaces the router component. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const RouterBlueprint = _RouterBlueprint;
/**
* Creates an extension that replaces the entire nav bar with your own component. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const NavContentBlueprint = _NavContentBlueprint;
/**
* Creates an extension that adds icon bundles to your app. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const IconBundleBlueprint = _IconBundleBlueprint;
/**
* Props for the `SignInPage` component.
*
* @public
*/
export type { SignInPageProps };
/**
* The props for the {@link NavContentComponent}.
*
* @public
*/
export type { NavContentComponentProps };
/**
* A component that renders the nav bar content, to be passed to the {@link NavContentBlueprint}.
*
* @public
*/
export type { NavContentComponent };
/**
* Creates an extension that adds translations to your app. This blueprint is limited to use by the app plugin.
*
* @public
*/
export const TranslationBlueprint = _TranslationBlueprint;
+23
View File
@@ -0,0 +1,23 @@
/*
* Copyright 2026 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.
*/
/**
* Web library for the app plugin.
*
* @packageDocumentation
*/
export * from './blueprints';
+16
View File
@@ -0,0 +1,16 @@
/*
* Copyright 2026 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 '@testing-library/jest-dom';