core-{app,plugin}-api: refactor AppTheme to use provider + defaultAppThemes
Co-authored-by: Johan Haals <johan.haals@gmail.com> Signed-off-by: Patrik Oldsberg <poldsberg@gmail.com>
This commit is contained in:
@@ -126,7 +126,7 @@ type FullAppOptions = {
|
||||
icons: NonNullable<AppOptions['icons']>;
|
||||
plugins: BackstagePlugin<any, any>[];
|
||||
components: AppComponents;
|
||||
themes: AppTheme[];
|
||||
themes: (Partial<AppTheme> & Omit<AppTheme, 'theme'>)[];
|
||||
configLoader?: AppConfigLoader;
|
||||
defaultApis: Iterable<AnyApiFactory>;
|
||||
bindRoutes?: AppOptions['bindRoutes'];
|
||||
@@ -206,7 +206,7 @@ export class PrivateAppImpl implements BackstageApp {
|
||||
this.icons = options.icons;
|
||||
this.plugins = new Set(options.plugins);
|
||||
this.components = options.components;
|
||||
this.themes = options.themes;
|
||||
this.themes = options.themes as AppTheme[];
|
||||
this.configLoader = options.configLoader;
|
||||
this.defaultApis = options.defaultApis;
|
||||
this.bindRoutes = options.bindRoutes;
|
||||
|
||||
@@ -90,6 +90,17 @@ export function AppThemeProvider({ children }: PropsWithChildren<{}>) {
|
||||
throw new Error('App has no themes');
|
||||
}
|
||||
|
||||
if (appTheme.Provider) {
|
||||
return <appTheme.Provider children={children} />;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
"DEPRECATION WARNING: A provided app theme is using the deprecated 'theme' property " +
|
||||
'and should be migrated to use a Provider instead. ' +
|
||||
'See https://backstage.io/docs/deprecations/TODO for more info.',
|
||||
);
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={appTheme.theme}>
|
||||
<CssBaseline>{children}</CssBaseline>
|
||||
|
||||
@@ -19,11 +19,8 @@ import { JsonObject } from '@backstage/types';
|
||||
import {
|
||||
defaultAppComponents,
|
||||
defaultAppIcons,
|
||||
defaultAppThemes,
|
||||
} from '@backstage/core-components';
|
||||
import { darkTheme, lightTheme } from '@backstage/theme';
|
||||
import DarkIcon from '@material-ui/icons/Brightness2';
|
||||
import LightIcon from '@material-ui/icons/WbSunny';
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { PrivateAppImpl } from './App';
|
||||
import { AppThemeProvider } from './AppThemeProvider';
|
||||
@@ -129,6 +126,15 @@ export function createApp(options?: AppOptions) {
|
||||
);
|
||||
}
|
||||
|
||||
if (!options?.themes) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn(
|
||||
'DEPRECATION WARNING: The createApp options will soon require themes to be provided. ' +
|
||||
'Themes can be created using defaultAppThemes from @backstage/core-components ' +
|
||||
'and then passed along like this: createApp({ theme: defaultAppThemes() })',
|
||||
);
|
||||
}
|
||||
|
||||
const apis = options?.apis ?? [];
|
||||
const plugins = options?.plugins ?? [];
|
||||
const components = {
|
||||
@@ -137,22 +143,6 @@ export function createApp(options?: AppOptions) {
|
||||
ThemeProvider: AppThemeProvider,
|
||||
...options?.components,
|
||||
};
|
||||
const themes = options?.themes ?? [
|
||||
{
|
||||
id: 'light',
|
||||
title: 'Light Theme',
|
||||
variant: 'light',
|
||||
theme: lightTheme,
|
||||
icon: <LightIcon />,
|
||||
},
|
||||
{
|
||||
id: 'dark',
|
||||
title: 'Dark Theme',
|
||||
variant: 'dark',
|
||||
theme: darkTheme,
|
||||
icon: <DarkIcon />,
|
||||
},
|
||||
];
|
||||
const configLoader = options?.configLoader ?? defaultConfigLoader;
|
||||
|
||||
return new PrivateAppImpl({
|
||||
@@ -160,7 +150,7 @@ export function createApp(options?: AppOptions) {
|
||||
icons: { ...appIcons, ...options?.icons },
|
||||
plugins: plugins as BackstagePlugin<any, any>[],
|
||||
components,
|
||||
themes,
|
||||
themes: options?.themes ?? defaultAppThemes(),
|
||||
configLoader,
|
||||
defaultApis,
|
||||
bindRoutes: options?.bindRoutes,
|
||||
|
||||
@@ -226,18 +226,26 @@ export type AppOptions = {
|
||||
* id: 'light',
|
||||
* title: 'Light Theme',
|
||||
* variant: 'light',
|
||||
* theme: lightTheme,
|
||||
* icon: <LightIcon />,
|
||||
* Provider: ({ children }) => (
|
||||
* <ThemeProvider theme={lightTheme}>
|
||||
* <CssBaseline>{children}</CssBaseline>
|
||||
* </ThemeProvider>
|
||||
* ),
|
||||
* }, {
|
||||
* id: 'dark',
|
||||
* title: 'Dark Theme',
|
||||
* variant: 'dark',
|
||||
* theme: darkTheme,
|
||||
* icon: <DarkIcon />,
|
||||
* Provider: ({ children }) => (
|
||||
* <ThemeProvider theme={darkTheme}>
|
||||
* <CssBaseline>{children}</CssBaseline>
|
||||
* </ThemeProvider>
|
||||
* ),
|
||||
* }]
|
||||
* ```
|
||||
*/
|
||||
themes?: AppTheme[];
|
||||
themes?: (Partial<AppTheme> & Omit<AppTheme, 'theme'>)[];
|
||||
|
||||
/**
|
||||
* A function that loads in App configuration that will be accessible via
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2021 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 React from 'react';
|
||||
import { darkTheme, lightTheme } from '@backstage/theme';
|
||||
import DarkIcon from '@material-ui/icons/Brightness2';
|
||||
import LightIcon from '@material-ui/icons/WbSunny';
|
||||
import { ThemeProvider } from '@material-ui/core/styles';
|
||||
import CssBaseline from '@material-ui/core/CssBaseline';
|
||||
import { AppTheme } from '@backstage/core-plugin-api';
|
||||
|
||||
export function defaultAppThemes(): AppTheme[] {
|
||||
return [
|
||||
{
|
||||
id: 'light',
|
||||
title: 'Light Theme',
|
||||
variant: 'light',
|
||||
icon: <LightIcon />,
|
||||
theme: lightTheme,
|
||||
Provider: ({ children }) => (
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<CssBaseline>{children}</CssBaseline>
|
||||
</ThemeProvider>
|
||||
),
|
||||
},
|
||||
{
|
||||
id: 'dark',
|
||||
title: 'Dark Theme',
|
||||
variant: 'dark',
|
||||
icon: <DarkIcon />,
|
||||
theme: darkTheme,
|
||||
Provider: ({ children }) => (
|
||||
<ThemeProvider theme={darkTheme}>
|
||||
<CssBaseline>{children}</CssBaseline>
|
||||
</ThemeProvider>
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
@@ -27,3 +27,4 @@ export * from './layout';
|
||||
export * from './overridableComponents';
|
||||
export { defaultAppComponents } from './defaultAppComponents';
|
||||
export { defaultAppIcons } from './defaultAppIcons';
|
||||
export { defaultAppThemes } from './defaultAppThemes';
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { ReactNode } from 'react';
|
||||
import { ApiRef, createApiRef } from '../system';
|
||||
import { BackstageTheme } from '@backstage/theme';
|
||||
import { Observable } from '@backstage/types';
|
||||
@@ -41,6 +42,7 @@ export type AppTheme = {
|
||||
|
||||
/**
|
||||
* The specialized MaterialUI theme instance.
|
||||
* @deprecated use Provider instead, see https://backstage.io/docs/deprecations/TODO
|
||||
*/
|
||||
theme: BackstageTheme;
|
||||
|
||||
@@ -48,6 +50,8 @@ export type AppTheme = {
|
||||
* An Icon for the theme mode setting.
|
||||
*/
|
||||
icon?: React.ReactElement;
|
||||
|
||||
Provider?(props: { children: ReactNode }): JSX.Element | null;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user