From 76510b2b676f3712255d7029703ab836a42a6828 Mon Sep 17 00:00:00 2001 From: Daniel Ortiz Lira Date: Tue, 21 Sep 2021 11:50:27 -0500 Subject: [PATCH] Add documentation on how to override Backstage components Signed-off-by: Daniel Ortiz Lira --- docs/getting-started/app-custom-theme.md | 128 ++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/docs/getting-started/app-custom-theme.md b/docs/getting-started/app-custom-theme.md index ecd9e4ac21..633144c38c 100644 --- a/docs/getting-started/app-custom-theme.md +++ b/docs/getting-started/app-custom-theme.md @@ -37,9 +37,7 @@ exported by [@backstage/theme](https://www.npmjs.com/package/@backstage/theme) in combination with [createTheme](https://material-ui.com/customization/theming/#createmuitheme-options-args-theme) from [@material-ui/core](https://www.npmjs.com/package/@material-ui/core). See -the -[@backstage/theme source](https://github.com/backstage/backstage/tree/master/packages/theme/src) -and the implementation of the `createTheme` function for how this is done. +the "Overriding Backstage and Material UI css rules" section below. You can also create a theme from scratch that matches the `BackstageTheme` type exported by [@backstage/theme](https://www.npmjs.com/package/@backstage/theme). @@ -136,6 +134,130 @@ const themeOptions = createThemeOptions({ }); ``` +## Overriding Backstage and Material UI components styles + +When creating a custom theme you would be applying different values to +component's css rules that use the theme object. For example, a Backstage +component's styles might look like this: + +```ts +const useStyles = makeStyles( + theme => ({ + header: { + padding: theme.spacing(3), + boxShadow: '0 0 8px 3px rgba(20, 20, 20, 0.3)', + backgroundImage: theme.page.backgroundImage, + }, + }), + { name: 'BackstageHeader' }, +); +``` + +Notice how the `padding` is getting its value from `theme.spacing`, that means +that setting a value for spacing in your custom theme would affect this +component padding property and the same goes for `backgroundImage` which uses +`theme.page.backgroundImage`. However, the `boxShadow` property doesn't +reference any value from the theme, that means that creating a custom theme +wouldn't be enough to alter the `box-shadow` property or to add css rules that +aren't already defined like a margin. For these cases you should also create an +override. + +_Creating your custom overrides_ + +```ts +import { + BackstageTheme, + createThemeOverrides as createBackstageOverrides, +} from '@backstage/theme'; + +/** + * The `@backstage/core-components` package exposes this type that + * contains all Backstage and `material-ui` components that can be + * overridden along with the classes key those components use. + */ +import { BackstageOverrides } from '@backstage/core-components'; + +export const createCustomThemeOverrides = ( + _: BackstageTheme, +): BackstageOverrides => { + return { + /** + * You can reference the component by the name it passed to the makeStyles function. + * in the previous example it was { name: 'BackstageHeader' } + */ + BackstageHeader: { + header: { + margin: '20px', + boxShadow: 'none', + }, + }, + }; +}; + +export const createOverrides = (theme: BackstageTheme): BackstageOverrides => ({ + ...createBackstageOverrides(theme), // These are the overrides that Backstage applies to `material-ui` components + ...createCustomThemeOverrides(theme), // These are your custom overrides, either to `material-ui` components or to Backstage components. +}); +``` + +_Your custom theme that uses the overrides_ + +```ts +import { createTheme as createMuiTheme } from '@material-ui/core'; +import { AppTheme } from '@backstage/core-plugin-api'; +import { + BackstagePaletteOptions, + BackstageTheme, + BackstageThemeOptions, + PageTheme, + shapes, +} from '@backstage/theme'; + +import { createOverrides } from './customThemeOverrides'; +import { THEME_OPTIONS } from './themeOptions'; // This is the object created in the "Example of a custom theme" section + +export const createTheme = ( + paletteOptions: BackstagePaletteOptions, +): BackstageTheme => { + const pageTheme: PageTheme = { + colors: [], + shape: shapes.round, + backgroundImage: '', + }; + + const themeOptions: BackstageThemeOptions = { + palette: paletteOptions, + page: pageTheme, + getPageTheme: _ => pageTheme, + }; + + const baseTheme = createMuiTheme(themeOptions) as BackstageTheme; + const overrides = createOverrides(baseTheme); + + return { ...baseTheme, overrides } as BackstageTheme; +}; + +export const CustomTheme: AppTheme = { + id: 'custom-theme', + title: 'Custom Theme', + variant: 'light', + theme: createTheme(THEME_OPTIONS), +}; +``` + +_Aplying your custom theme with overrides_ + +```ts +import { createApp } from '@backstage/core-app-api'; +import { CustomTheme } from './theme/customTheme'; + +const app = createApp({ + apis, + themes: [CustomTheme], + plugins: Object.values(plugins), + ... +``` + ## Custom Logo In addition to a custom theme, you can also customize the logo displayed at the