diff --git a/.changeset/weak-snails-spar.md b/.changeset/weak-snails-spar.md
new file mode 100644
index 0000000000..3cd930d5b0
--- /dev/null
+++ b/.changeset/weak-snails-spar.md
@@ -0,0 +1,5 @@
+---
+'@backstage/plugin-techdocs-addons-test-utils': patch
+---
+
+Avoiding re-running tests on cleanup.
diff --git a/.changeset/weak-snails-spark.md b/.changeset/weak-snails-spark.md
new file mode 100644
index 0000000000..c82626ea39
--- /dev/null
+++ b/.changeset/weak-snails-spark.md
@@ -0,0 +1,5 @@
+---
+'@backstage/test-utils': minor
+---
+
+Test App Wrapper is now using `UnifiedThemeProvider` for supporting MUI v5 next to MUI v4 in tests.
diff --git a/.changeset/weak-snails-sparkl.md b/.changeset/weak-snails-sparkl.md
new file mode 100644
index 0000000000..9bbc7d843b
--- /dev/null
+++ b/.changeset/weak-snails-sparkl.md
@@ -0,0 +1,17 @@
+---
+'@backstage/app-defaults': minor
+'@backstage/theme': minor
+---
+
+**MUI v5 Support:** Adding platform-wide support for MUI v5 allowing a transition phase for migrating central plugins & components over. We still support v4 instances & plugins by adding a
+
+To allow the future support of plugins & components using MUI v5 you want to upgrade your `AppTheme`'s to using the `UnifiedThemeProvider`
+
+```diff
+ Provider: ({ children }) => (
+-
+- {children}
+-
++
+ ),
+```
diff --git a/.changeset/weak-snails-sparkle.md b/.changeset/weak-snails-sparkle.md
new file mode 100644
index 0000000000..95a2255e56
--- /dev/null
+++ b/.changeset/weak-snails-sparkle.md
@@ -0,0 +1,5 @@
+---
+'@backstage/cli': patch
+---
+
+Enforcing MUI v5 specific linting to minimize bundle size.
diff --git a/docs/local-dev/cli-build-system.md b/docs/local-dev/cli-build-system.md
index a5df84f8dc..61e94e9ef4 100644
--- a/docs/local-dev/cli-build-system.md
+++ b/docs/local-dev/cli-build-system.md
@@ -165,16 +165,17 @@ module.exports = require('@backstage/cli/config/eslint-factory')(__dirname, {
The configuration factory also provides utilities for extending the configuration in ways that are otherwise very cumbersome to do with plain ESLint, particularly for rules like `no-restricted-syntax`. These are the extra keys that are available:
-| Key | Description |
-| ----------------------- | ------------------------------------------------------------------ |
-| `tsRules` | Additional rules to apply to TypeScript files |
-| `testRules` | Additional rules to apply to tests files |
-| `restrictedImports` | Additional paths to add to `no-restricted-imports` |
-| `restrictedSrcImports` | Additional paths to add to `no-restricted-imports` in src files |
-| `restrictedTestImports` | Additional paths to add to `no-restricted-imports` in test files |
-| `restrictedSyntax` | Additional patterns to add to `no-restricted-syntax` |
-| `restrictedSrcSyntax` | Additional patterns to add to `no-restricted-syntax` in src files |
-| `restrictedTestSyntax` | Additional patterns to add to `no-restricted-syntax` in test files |
+| Key | Description |
+| -------------------------- | ------------------------------------------------------------------ |
+| `tsRules` | Additional rules to apply to TypeScript files |
+| `testRules` | Additional rules to apply to tests files |
+| `restrictedImports` | Additional paths to add to `no-restricted-imports` |
+| `restrictedImportPatterns` | Additional patterns to add to `no-restricted-imports` |
+| `restrictedSrcImports` | Additional paths to add to `no-restricted-imports` in src files |
+| `restrictedTestImports` | Additional paths to add to `no-restricted-imports` in test files |
+| `restrictedSyntax` | Additional patterns to add to `no-restricted-syntax` |
+| `restrictedSrcSyntax` | Additional patterns to add to `no-restricted-syntax` in src files |
+| `restrictedTestSyntax` | Additional patterns to add to `no-restricted-syntax` in test files |
## Type Checking
diff --git a/packages/app-defaults/src/defaults/themes.tsx b/packages/app-defaults/src/defaults/themes.tsx
index 397c160168..10368bd3bc 100644
--- a/packages/app-defaults/src/defaults/themes.tsx
+++ b/packages/app-defaults/src/defaults/themes.tsx
@@ -15,11 +15,12 @@
*/
import React from 'react';
-import { darkTheme, lightTheme } from '@backstage/theme';
+import {
+ UnifiedThemeProvider,
+ themes as builtinThemes,
+} 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 const themes: AppTheme[] = [
@@ -29,9 +30,7 @@ export const themes: AppTheme[] = [
variant: 'light',
icon: ,
Provider: ({ children }) => (
-
- {children}
-
+
),
},
{
@@ -40,9 +39,7 @@ export const themes: AppTheme[] = [
variant: 'dark',
icon: ,
Provider: ({ children }) => (
-
- {children}
-
+
),
},
];
diff --git a/packages/cli/config/eslint-factory.js b/packages/cli/config/eslint-factory.js
index dde853fdff..36b51324fc 100644
--- a/packages/cli/config/eslint-factory.js
+++ b/packages/cli/config/eslint-factory.js
@@ -24,6 +24,7 @@ const { join: joinPath } = require('path');
* - `tsRules`: Additional ESLint rules to apply to TypeScript
* - `testRules`: Additional ESLint rules to apply to tests
* - `restrictedImports`: Additional paths to add to no-restricted-imports
+ * - `restrictedImportsPattern`: Additional patterns to add to no-restricted-imports
* - `restrictedSrcImports`: Additional paths to add to no-restricted-imports in src files
* - `restrictedTestImports`: Additional paths to add to no-restricted-imports in test files
* - `restrictedSyntax`: Additional patterns to add to no-restricted-syntax
@@ -44,6 +45,7 @@ function createConfig(dir, extraConfig = {}) {
testRules,
restrictedImports,
+ restrictedImportPatterns,
restrictedSrcImports,
restrictedTestImports,
restrictedSyntax,
@@ -114,6 +116,7 @@ function createConfig(dir, extraConfig = {}) {
'*.test*',
'**/__testUtils__/**',
'**/__mocks__/**',
+ ...(restrictedImportPatterns ?? []),
],
},
],
@@ -208,9 +211,19 @@ function createConfigForRole(dir, role, extraConfig = {}) {
name: '@material-ui/icons/', // because this is possible too ._.
message: "Please import '@material-ui/icons/' instead.",
},
+ {
+ // https://mui.com/material-ui/guides/minimizing-bundle-size/
+ name: '@mui/material',
+ message: "Please import '@mui/material/...' instead.",
+ },
...require('module').builtinModules,
...(extraConfig.restrictedImports ?? []),
],
+ // https://mui.com/material-ui/guides/minimizing-bundle-size/
+ restrictedImportPatterns: [
+ '@mui/*/*/*',
+ ...(extraConfig.restrictedImportPatterns ?? []),
+ ],
tsRules: {
'react/prop-types': 0,
...extraConfig.tsRules,
diff --git a/packages/core-app-api/src/app/types.ts b/packages/core-app-api/src/app/types.ts
index 3d9005b0c0..c34407ca3a 100644
--- a/packages/core-app-api/src/app/types.ts
+++ b/packages/core-app-api/src/app/types.ts
@@ -236,21 +236,13 @@ export type AppOptions = {
* title: 'Light Theme',
* variant: 'light',
* icon: ,
- * Provider: ({ children }) => (
- *
- * {children}
- *
- * ),
+ * Provider: ({ children }) => ,
* }, {
* id: 'dark',
* title: 'Dark Theme',
* variant: 'dark',
* icon: ,
- * Provider: ({ children }) => (
- *
- * {children}
- *
- * ),
+ * Provider: ({ children }) => ,
* }]
* ```
*/
diff --git a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx
index 0159d8f503..8fdace3766 100644
--- a/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx
+++ b/packages/core-components/src/components/OAuthRequestDialog/OAuthRequestDialog.tsx
@@ -89,7 +89,11 @@ export function OAuthRequestDialog(_props: {}) {
classes={{ root: classes.title }}
id="oauth-req-dialog-title"
>
-
+
Login Required
{authRedirect ? (
diff --git a/packages/test-utils/src/testUtils/appWrappers.tsx b/packages/test-utils/src/testUtils/appWrappers.tsx
index 8b644ad2d1..6545cc312a 100644
--- a/packages/test-utils/src/testUtils/appWrappers.tsx
+++ b/packages/test-utils/src/testUtils/appWrappers.tsx
@@ -17,9 +17,7 @@
import React, { ComponentType, ReactNode, ReactElement } from 'react';
import { MemoryRouter } from 'react-router-dom';
import { Route } from 'react-router-dom';
-import { lightTheme } from '@backstage/theme';
-import { ThemeProvider } from '@material-ui/core/styles';
-import { CssBaseline } from '@material-ui/core';
+import { UnifiedThemeProvider, themes } from '@backstage/theme';
import MockIcon from '@material-ui/icons/AcUnit';
import { createSpecializedApp } from '@backstage/core-app-api';
import {
@@ -142,9 +140,9 @@ export function createTestAppWrapper(
title: 'Test App Theme',
variant: 'light',
Provider: ({ children }) => (
-
- {children}
-
+
+ {children}
+
),
},
],
diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md
index 863ab81b68..fe05ca6b4e 100644
--- a/packages/theme/api-report.md
+++ b/packages/theme/api-report.md
@@ -3,13 +3,19 @@
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
+import type { ComponentsProps } from '@material-ui/core/styles/props';
import { Overrides } from '@material-ui/core/styles/overrides';
-import { Palette } from '@material-ui/core/styles/createPalette';
-import { PaletteOptions } from '@material-ui/core/styles/createPalette';
-import { Theme } from '@material-ui/core';
-import { ThemeOptions } from '@material-ui/core';
+import type { Palette } from '@material-ui/core/styles/createPalette';
+import type { PaletteOptions } from '@material-ui/core/styles/createPalette';
+import { PaletteOptions as PaletteOptions_2 } from '@mui/material/styles';
+import { ReactNode } from 'react';
+import { Theme } from '@mui/material/styles';
+import { Theme as Theme_2 } from '@material-ui/core';
+import { ThemeOptions } from '@mui/material/styles';
+import { ThemeOptions as ThemeOptions_2 } from '@material-ui/core/styles';
+import type { ThemeOptions as ThemeOptions_3 } from '@material-ui/core';
-// @public
+// @public @deprecated
export type BackstagePalette = Palette & BackstagePaletteAdditions;
// @public
@@ -75,12 +81,12 @@ export type BackstagePaletteAdditions = {
};
};
-// @public
+// @public @deprecated
export type BackstagePaletteOptions = PaletteOptions &
BackstagePaletteAdditions;
-// @public
-export interface BackstageTheme extends Theme {
+// @public @deprecated
+export interface BackstageTheme extends Theme_2 {
// (undocumented)
getPageTheme: (selector: PageThemeSelector) => PageTheme;
// (undocumented)
@@ -90,7 +96,13 @@ export interface BackstageTheme extends Theme {
}
// @public
-export interface BackstageThemeOptions extends ThemeOptions {
+export type BackstageThemeAdditions = {
+ page: PageTheme;
+ getPageTheme: (selector: PageThemeSelector) => PageTheme;
+};
+
+// @public @deprecated
+export interface BackstageThemeOptions extends ThemeOptions_3 {
// (undocumented)
getPageTheme: (selector: PageThemeSelector) => PageTheme;
// (undocumented)
@@ -99,22 +111,86 @@ export interface BackstageThemeOptions extends ThemeOptions {
palette: BackstagePaletteOptions;
}
+// @public
+export interface BaseThemeOptionsInput {
+ // (undocumented)
+ defaultPageTheme?: string;
+ // (undocumented)
+ fontFamily?: string;
+ // (undocumented)
+ htmlFontSize?: number;
+ // (undocumented)
+ pageTheme?: Record;
+ // (undocumented)
+ palette: PaletteOptions;
+}
+
// @public
export const colorVariants: Record;
// @public
-export function createTheme(options: SimpleThemeOptions): BackstageTheme;
+export function createBaseThemeOptions(
+ options: BaseThemeOptionsInput,
+): {
+ palette: PaletteOptions;
+ typography: {
+ htmlFontSize: number;
+ fontFamily: string;
+ h1: {
+ fontSize: number;
+ fontWeight: number;
+ marginBottom: number;
+ };
+ h2: {
+ fontSize: number;
+ fontWeight: number;
+ marginBottom: number;
+ };
+ h3: {
+ fontSize: number;
+ fontWeight: number;
+ marginBottom: number;
+ };
+ h4: {
+ fontWeight: number;
+ fontSize: number;
+ marginBottom: number;
+ };
+ h5: {
+ fontWeight: number;
+ fontSize: number;
+ marginBottom: number;
+ };
+ h6: {
+ fontWeight: number;
+ fontSize: number;
+ marginBottom: number;
+ };
+ };
+ page: PageTheme;
+ getPageTheme: ({ themeId }: PageThemeSelector) => PageTheme;
+};
+
+// @public @deprecated
+export function createTheme(options: SimpleThemeOptions): Theme_2;
+
+// @public @deprecated
+export function createThemeOptions(options: SimpleThemeOptions): ThemeOptions_3;
+
+// @public @deprecated
+export function createThemeOverrides(theme: Theme_2): Overrides;
// @public
-export function createThemeOptions(
- options: SimpleThemeOptions,
-): BackstageThemeOptions;
+export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme;
// @public
-export function createThemeOverrides(theme: BackstageTheme): Overrides;
+export function createUnifiedThemeFromV4(options: ThemeOptions_2): UnifiedTheme;
+
+// @public @deprecated
+export const darkTheme: Theme_2;
// @public
-export const darkTheme: BackstageTheme;
+export const defaultComponentThemes: ThemeOptions['components'];
// @public
export function genPageTheme(props: {
@@ -125,8 +201,8 @@ export function genPageTheme(props: {
};
}): PageTheme;
-// @public
-export const lightTheme: BackstageTheme;
+// @public @deprecated
+export const lightTheme: Theme_2;
// @public
export type PageTheme = {
@@ -145,14 +221,214 @@ export type PageThemeSelector = {
};
// @public
-export const shapes: Record;
+export const palettes: {
+ light: {
+ type: 'light';
+ mode: 'light';
+ background: {
+ default: string;
+ paper: string;
+ };
+ status: {
+ ok: string;
+ warning: string;
+ error: string;
+ running: string;
+ pending: string;
+ aborted: string;
+ };
+ bursts: {
+ fontColor: string;
+ slackChannelText: string;
+ backgroundColor: {
+ default: string;
+ };
+ gradient: {
+ linear: string;
+ };
+ };
+ primary: {
+ main: string;
+ };
+ banner: {
+ info: string;
+ error: string;
+ text: string;
+ link: string;
+ closeButtonColor: string;
+ warning: string;
+ };
+ border: string;
+ textContrast: string;
+ textVerySubtle: string;
+ textSubtle: string;
+ highlight: string;
+ errorBackground: string;
+ warningBackground: string;
+ infoBackground: string;
+ errorText: string;
+ infoText: string;
+ warningText: string;
+ linkHover: string;
+ link: string;
+ gold: string;
+ navigation: {
+ background: string;
+ indicator: string;
+ color: string;
+ selectedColor: string;
+ navItem: {
+ hoverBackground: string;
+ };
+ submenu: {
+ background: string;
+ };
+ };
+ pinSidebarButton: {
+ icon: string;
+ background: string;
+ };
+ tabbar: {
+ indicator: string;
+ };
+ };
+ dark: {
+ type: 'dark';
+ mode: 'dark';
+ background: {
+ default: string;
+ paper: string;
+ };
+ status: {
+ ok: string;
+ warning: string;
+ error: string;
+ running: string;
+ pending: string;
+ aborted: string;
+ };
+ bursts: {
+ fontColor: string;
+ slackChannelText: string;
+ backgroundColor: {
+ default: string;
+ };
+ gradient: {
+ linear: string;
+ };
+ };
+ primary: {
+ main: string;
+ dark: string;
+ };
+ secondary: {
+ main: string;
+ };
+ banner: {
+ info: string;
+ error: string;
+ text: string;
+ link: string;
+ closeButtonColor: string;
+ warning: string;
+ };
+ border: string;
+ textContrast: string;
+ textVerySubtle: string;
+ textSubtle: string;
+ highlight: string;
+ errorBackground: string;
+ warningBackground: string;
+ infoBackground: string;
+ errorText: string;
+ infoText: string;
+ warningText: string;
+ linkHover: string;
+ link: string;
+ gold: string;
+ navigation: {
+ background: string;
+ indicator: string;
+ color: string;
+ selectedColor: string;
+ navItem: {
+ hoverBackground: string;
+ };
+ submenu: {
+ background: string;
+ };
+ };
+ pinSidebarButton: {
+ icon: string;
+ background: string;
+ };
+ tabbar: {
+ indicator: string;
+ };
+ };
+};
// @public
+export const shapes: Record;
+
+// @public @deprecated
export type SimpleThemeOptions = {
- palette: BackstagePaletteOptions;
- defaultPageTheme: string;
+ palette: PaletteOptions;
+ defaultPageTheme?: string;
pageTheme?: Record;
fontFamily?: string;
htmlFontSize?: number;
};
+
+// @public
+export const themes: {
+ light: UnifiedTheme;
+ dark: UnifiedTheme;
+};
+
+// @public
+export function transformV5ComponentThemesToV4(
+ theme: Theme,
+ components?: ThemeOptions['components'],
+): {
+ overrides: Overrides;
+ props: ComponentsProps;
+};
+
+// @public
+export interface UnifiedTheme {
+ // (undocumented)
+ getTheme(version: string): unknown | undefined;
+}
+
+// @public
+export interface UnifiedThemeOptions {
+ // (undocumented)
+ components?: ThemeOptions['components'];
+ // (undocumented)
+ defaultPageTheme?: string;
+ // (undocumented)
+ fontFamily?: string;
+ // (undocumented)
+ htmlFontSize?: number;
+ // (undocumented)
+ pageTheme?: Record;
+ // (undocumented)
+ palette: PaletteOptions & PaletteOptions_2;
+}
+
+// @public
+export function UnifiedThemeProvider(
+ props: UnifiedThemeProviderProps,
+): JSX.Element;
+
+// @public
+export interface UnifiedThemeProviderProps {
+ // (undocumented)
+ children: ReactNode;
+ // (undocumented)
+ noCssBaseline?: boolean;
+ // (undocumented)
+ theme: UnifiedTheme;
+}
```
diff --git a/packages/theme/package.json b/packages/theme/package.json
index fbc767fb2f..52def665d6 100644
--- a/packages/theme/package.json
+++ b/packages/theme/package.json
@@ -32,9 +32,13 @@
"test": "backstage-cli package test"
},
"dependencies": {
- "@material-ui/core": "^4.12.2"
+ "@emotion/react": "^11.10.5",
+ "@emotion/styled": "^11.10.5",
+ "@mui/material": "^5.12.2"
},
"peerDependencies": {
+ "@material-ui/core": "^4.12.2",
+ "@types/react": "^16.13.1 || ^17.0.0",
"react": "^16.13.1 || ^17.0.0",
"react-dom": "^16.13.1 || ^17.0.0"
},
diff --git a/packages/theme/src/base/createBaseThemeOptions.ts b/packages/theme/src/base/createBaseThemeOptions.ts
new file mode 100644
index 0000000000..e54e920deb
--- /dev/null
+++ b/packages/theme/src/base/createBaseThemeOptions.ts
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2022 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 { PageTheme, PageThemeSelector } from './types';
+import { pageTheme as defaultPageThemes } from './pageTheme';
+
+const DEFAULT_HTML_FONT_SIZE = 16;
+const DEFAULT_FONT_FAMILY =
+ '"Helvetica Neue", Helvetica, Roboto, Arial, sans-serif';
+const DEFAULT_PAGE_THEME = 'home';
+
+/**
+ * Options for {@link createBaseThemeOptions}.
+ *
+ * @public
+ */
+export interface BaseThemeOptionsInput {
+ palette: PaletteOptions;
+ defaultPageTheme?: string;
+ pageTheme?: Record;
+ fontFamily?: string;
+ htmlFontSize?: number;
+}
+
+/**
+ * A helper for creating theme options.
+ *
+ * @public
+ */
+export function createBaseThemeOptions(
+ options: BaseThemeOptionsInput,
+) {
+ const {
+ palette,
+ htmlFontSize = DEFAULT_HTML_FONT_SIZE,
+ fontFamily = DEFAULT_FONT_FAMILY,
+ defaultPageTheme = DEFAULT_PAGE_THEME,
+ pageTheme = defaultPageThemes,
+ } = options;
+
+ if (!pageTheme[defaultPageTheme]) {
+ throw new Error(`${defaultPageTheme} is not defined in pageTheme.`);
+ }
+
+ return {
+ palette,
+ typography: {
+ htmlFontSize,
+ fontFamily,
+ h1: {
+ fontSize: 54,
+ fontWeight: 700,
+ marginBottom: 10,
+ },
+ h2: {
+ fontSize: 40,
+ fontWeight: 700,
+ marginBottom: 8,
+ },
+ h3: {
+ fontSize: 32,
+ fontWeight: 700,
+ marginBottom: 6,
+ },
+ h4: {
+ fontWeight: 700,
+ fontSize: 28,
+ marginBottom: 6,
+ },
+ h5: {
+ fontWeight: 700,
+ fontSize: 24,
+ marginBottom: 4,
+ },
+ h6: {
+ fontWeight: 700,
+ fontSize: 20,
+ marginBottom: 2,
+ },
+ },
+ page: pageTheme[defaultPageTheme],
+ getPageTheme: ({ themeId }: PageThemeSelector) =>
+ pageTheme[themeId] ?? pageTheme[defaultPageTheme],
+ };
+}
diff --git a/packages/theme/src/base/index.ts b/packages/theme/src/base/index.ts
new file mode 100644
index 0000000000..4bb80aa42b
--- /dev/null
+++ b/packages/theme/src/base/index.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 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.
+ */
+
+export { createBaseThemeOptions } from './createBaseThemeOptions';
+export type { BaseThemeOptionsInput } from './createBaseThemeOptions';
+export { colorVariants, genPageTheme, pageTheme, shapes } from './pageTheme';
+export { palettes } from './palettes';
+export type {
+ BackstageThemeAdditions,
+ BackstagePaletteAdditions,
+ PageTheme,
+ PageThemeSelector,
+} from './types';
diff --git a/packages/theme/src/pageTheme.ts b/packages/theme/src/base/pageTheme.ts
similarity index 99%
rename from packages/theme/src/pageTheme.ts
rename to packages/theme/src/base/pageTheme.ts
index dd36d7641b..12a73b6089 100644
--- a/packages/theme/src/pageTheme.ts
+++ b/packages/theme/src/base/pageTheme.ts
@@ -13,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
import { PageTheme } from './types';
/**
diff --git a/packages/theme/src/themes.ts b/packages/theme/src/base/palettes.ts
similarity index 87%
rename from packages/theme/src/themes.ts
rename to packages/theme/src/base/palettes.ts
index 23438a1c14..5e70afd7b8 100644
--- a/packages/theme/src/themes.ts
+++ b/packages/theme/src/base/palettes.ts
@@ -14,20 +14,18 @@
* limitations under the License.
*/
-import { createTheme } from './baseTheme';
-import { pageTheme } from './pageTheme';
-import { yellow } from '@material-ui/core/colors';
-
/**
- * The default Backstage light theme.
+ * Built-in Backstage color palettes.
*
* @public
*/
-export const lightTheme = createTheme({
- palette: {
- type: 'light',
+export const palettes = {
+ light: {
+ type: 'light' as const,
+ mode: 'light' as const,
background: {
default: '#F8F8F8',
+ paper: '#FFFFFF',
},
status: {
ok: '#1DB954',
@@ -71,7 +69,7 @@ export const lightTheme = createTheme({
warningText: '#000000',
linkHover: '#2196F3',
link: '#0A6EBE',
- gold: yellow.A700,
+ gold: '#FFD600',
navigation: {
background: '#171717',
indicator: '#9BF0E1',
@@ -92,20 +90,12 @@ export const lightTheme = createTheme({
indicator: '#9BF0E1',
},
},
- defaultPageTheme: 'home',
- pageTheme,
-});
-
-/**
- * The default Backstage dark theme.
- *
- * @public
- */
-export const darkTheme = createTheme({
- palette: {
- type: 'dark',
+ dark: {
+ type: 'dark' as const,
+ mode: 'dark' as const,
background: {
default: '#333333',
+ paper: '#424242',
},
status: {
ok: '#71CF88',
@@ -153,7 +143,7 @@ export const darkTheme = createTheme({
warningText: '#000000',
linkHover: '#82BAFD',
link: '#9CC9FF',
- gold: yellow.A700,
+ gold: '#FFD600',
navigation: {
background: '#424242',
indicator: '#9BF0E1',
@@ -174,6 +164,4 @@ export const darkTheme = createTheme({
indicator: '#9BF0E1',
},
},
- defaultPageTheme: 'home',
- pageTheme,
-});
+};
diff --git a/packages/theme/src/types.ts b/packages/theme/src/base/types.ts
similarity index 63%
rename from packages/theme/src/types.ts
rename to packages/theme/src/base/types.ts
index 0295e491f1..8f71ce4292 100644
--- a/packages/theme/src/types.ts
+++ b/packages/theme/src/base/types.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2022 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.
@@ -14,12 +14,6 @@
* limitations under the License.
*/
-import { Theme, ThemeOptions } from '@material-ui/core';
-import {
- PaletteOptions,
- Palette,
-} from '@material-ui/core/styles/createPalette';
-
/**
* Backstage specific additions to the material-ui palette.
*
@@ -90,21 +84,6 @@ export type BackstagePaletteAdditions = {
};
};
-/**
- * The full Backstage palette.
- *
- * @public
- */
-export type BackstagePalette = Palette & BackstagePaletteAdditions;
-
-/**
- * The full Backstage palette options.
- *
- * @public
- */
-export type BackstagePaletteOptions = PaletteOptions &
- BackstagePaletteAdditions;
-
/**
* Selector for what page theme to use.
*
@@ -114,48 +93,6 @@ export type PageThemeSelector = {
themeId: string;
};
-/**
- * A Backstage theme.
- *
- * @public
- */
-export interface BackstageTheme extends Theme {
- palette: BackstagePalette;
- page: PageTheme;
- getPageTheme: (selector: PageThemeSelector) => PageTheme;
-}
-
-/**
- * Backstage theme options.
- *
- * @public
- * @remarks
- *
- * This is essentially a partial theme definition made by the user, that then
- * gets merged together with defaults and other values to form the final
- * {@link BackstageTheme}.
- *
- */
-export interface BackstageThemeOptions extends ThemeOptions {
- palette: BackstagePaletteOptions;
- page: PageTheme;
- getPageTheme: (selector: PageThemeSelector) => PageTheme;
-}
-
-/**
- * A simpler configuration for creating a new theme that just tweaks some parts
- * of the backstage one.
- *
- * @public
- */
-export type SimpleThemeOptions = {
- palette: BackstagePaletteOptions;
- defaultPageTheme: string;
- pageTheme?: Record;
- fontFamily?: string;
- htmlFontSize?: number;
-};
-
/**
* The theme definitions for a given layout page.
*
@@ -167,3 +104,13 @@ export type PageTheme = {
backgroundImage: string;
fontColor: string;
};
+
+/**
+ * Backstage specific additions to the material-ui theme.
+ *
+ * @public
+ */
+export type BackstageThemeAdditions = {
+ page: PageTheme;
+ getPageTheme: (selector: PageThemeSelector) => PageTheme;
+};
diff --git a/packages/theme/src/index.ts b/packages/theme/src/index.ts
index 41f827bf43..b0e3590273 100644
--- a/packages/theme/src/index.ts
+++ b/packages/theme/src/index.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2022 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.
@@ -20,7 +20,7 @@
* @packageDocumentation
*/
-export * from './themes';
-export * from './baseTheme';
-export * from './types';
-export * from './pageTheme';
+export * from './unified';
+export * from './base';
+export * from './v4';
+export * from './v5';
diff --git a/packages/theme/src/unified/MuiClassNameSetup.ts b/packages/theme/src/unified/MuiClassNameSetup.ts
new file mode 100644
index 0000000000..42b948af32
--- /dev/null
+++ b/packages/theme/src/unified/MuiClassNameSetup.ts
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2022 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 { unstable_ClassNameGenerator as ClassNameGenerator } from '@mui/material/className';
+
+/**
+ * This API is introduced in @mui/material (v5.0.5) as a replacement of deprecated createGenerateClassName & only affects v5 MUI components from `@mui/*`
+ */
+ClassNameGenerator.configure(componentName => {
+ return `v5-${componentName}`;
+});
diff --git a/packages/theme/src/unified/UnifiedTheme.tsx b/packages/theme/src/unified/UnifiedTheme.tsx
new file mode 100644
index 0000000000..0c5f80357a
--- /dev/null
+++ b/packages/theme/src/unified/UnifiedTheme.tsx
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2022 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 {
+ Theme as Mui4Theme,
+ ThemeOptions as ThemeOptionsV4,
+ createTheme,
+} from '@material-ui/core/styles';
+import type { PaletteOptions as PaletteOptionsV4 } from '@material-ui/core/styles/createPalette';
+import { PaletteOptions as PaletteOptionsV5 } from '@mui/material/styles';
+import {
+ adaptV4Theme,
+ Theme as Mui5Theme,
+ createTheme as createV5Theme,
+ ThemeOptions as ThemeOptionsV5,
+} from '@mui/material/styles';
+import { transformV5ComponentThemesToV4 } from './overrides';
+import { PageTheme } from '../base/types';
+import { defaultComponentThemes } from '../v5';
+import { createBaseThemeOptions } from '../base/createBaseThemeOptions';
+import { UnifiedTheme } from './types';
+
+export class UnifiedThemeHolder implements UnifiedTheme {
+ #themes = new Map();
+
+ constructor(v4?: Mui4Theme, v5?: Mui5Theme) {
+ this.#themes = new Map();
+ if (v4) {
+ this.#themes.set('v4', v4);
+ }
+ if (v5) {
+ this.#themes.set('v5', v5);
+ }
+ }
+
+ getTheme(version: string): unknown | undefined {
+ return this.#themes.get(version);
+ }
+}
+
+/**
+ * Options for creating a new {@link UnifiedTheme}.
+ *
+ * @public
+ */
+export interface UnifiedThemeOptions {
+ palette: PaletteOptionsV4 & PaletteOptionsV5;
+ defaultPageTheme?: string;
+ pageTheme?: Record;
+ fontFamily?: string;
+ htmlFontSize?: number;
+ components?: ThemeOptionsV5['components'];
+}
+
+/**
+ * Creates a new {@link UnifiedTheme} using the provided options.
+ *
+ * @public
+ */
+export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme {
+ const themeOptions = createBaseThemeOptions(options);
+ const components = { ...defaultComponentThemes, ...options.components };
+ const v5Theme = createV5Theme({ ...themeOptions, components });
+
+ // TODO: Not super relevant in the beginning
+ /* const mui4Styles = maybeLoadMui4Styles();
+ if (!mui4Styles) {
+ return new UnifiedThemeHolder(undefined, v5Theme);
+ } */
+
+ const v4Overrides = transformV5ComponentThemesToV4(v5Theme, components);
+ const v4Theme = { ...createTheme(themeOptions), ...v4Overrides };
+ return new UnifiedThemeHolder(v4Theme, v5Theme);
+}
+
+/**
+ * Creates a new {@link UnifiedTheme} using MUI v4 theme options.
+ * Note that this uses `adaptV4Theme` from MUI v5, which is deprecated.
+ *
+ * @public
+ */
+export function createUnifiedThemeFromV4(
+ options: ThemeOptionsV4,
+): UnifiedTheme {
+ const v5Theme = adaptV4Theme(options as any);
+ const v4Theme = createTheme(options);
+ return new UnifiedThemeHolder(v4Theme, v5Theme);
+}
diff --git a/packages/theme/src/unified/UnifiedThemeProvider.tsx b/packages/theme/src/unified/UnifiedThemeProvider.tsx
new file mode 100644
index 0000000000..c7054e0e55
--- /dev/null
+++ b/packages/theme/src/unified/UnifiedThemeProvider.tsx
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2022 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, { ReactNode } from 'react';
+import './MuiClassNameSetup';
+import { ThemeProvider } from '@material-ui/core/styles';
+import {
+ StyledEngineProvider,
+ ThemeProvider as Mui5Provider,
+} from '@mui/material/styles';
+import CSSBaseline from '@mui/material/CssBaseline';
+import { UnifiedTheme } from './types';
+
+/**
+ * Props for {@link UnifiedThemeProvider}.
+ *
+ * @public
+ */
+export interface UnifiedThemeProviderProps {
+ children: ReactNode;
+ theme: UnifiedTheme;
+ noCssBaseline?: boolean;
+}
+
+/**
+ * Provides themes for all MUI versions supported by the provided unified theme.
+ *
+ * @public
+ */
+export function UnifiedThemeProvider(
+ props: UnifiedThemeProviderProps,
+): JSX.Element {
+ const { children, theme, noCssBaseline = false } = props;
+
+ const v4Theme = theme.getTheme('v4');
+ const v5Theme = theme.getTheme('v5');
+
+ let cssBaseline: JSX.Element | undefined = undefined;
+ if (!noCssBaseline) {
+ cssBaseline = ;
+ }
+
+ let result = (
+ <>
+ {cssBaseline}
+ {children}
+ >
+ );
+
+ if (v4Theme) {
+ result = {result};
+ }
+
+ if (v5Theme) {
+ result = (
+
+ {result}
+
+ );
+ }
+
+ return result;
+}
diff --git a/packages/theme/src/unified/index.ts b/packages/theme/src/unified/index.ts
new file mode 100644
index 0000000000..f5c805d3ed
--- /dev/null
+++ b/packages/theme/src/unified/index.ts
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2022 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.
+ */
+
+export { transformV5ComponentThemesToV4 } from './overrides';
+export { createUnifiedTheme, createUnifiedThemeFromV4 } from './UnifiedTheme';
+export type { UnifiedThemeOptions } from './UnifiedTheme';
+export { themes } from './themes';
+export { UnifiedThemeProvider } from './UnifiedThemeProvider';
+export type { UnifiedThemeProviderProps } from './UnifiedThemeProvider';
+export type { UnifiedTheme } from './types';
diff --git a/packages/theme/src/unified/overrides.test.ts b/packages/theme/src/unified/overrides.test.ts
new file mode 100644
index 0000000000..e84cedade6
--- /dev/null
+++ b/packages/theme/src/unified/overrides.test.ts
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2022 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 { Theme } from '@mui/material/styles';
+import { transformV5ComponentThemesToV4 } from './overrides';
+
+describe('transformV5ComponentThemesToV4', () => {
+ const mockTheme = {
+ palette: {
+ primary: {
+ main: 'red',
+ },
+ },
+ } as unknown as Theme;
+ it('transforms empty component themes', () => {
+ expect(transformV5ComponentThemesToV4(mockTheme)).toEqual({
+ overrides: {},
+ props: {},
+ });
+ expect(transformV5ComponentThemesToV4(mockTheme, {})).toEqual({
+ overrides: {},
+ props: {},
+ });
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiButton: {
+ styleOverrides: undefined,
+ defaultProps: undefined,
+ },
+ }),
+ ).toEqual({ overrides: {}, props: {} });
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiButton: {
+ styleOverrides: {},
+ defaultProps: {},
+ },
+ }),
+ ).toEqual({ overrides: { MuiButton: {} }, props: { MuiButton: {} } });
+ });
+
+ it('transforms component themes', () => {
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ color: 'green',
+ },
+ },
+ defaultProps: {
+ disableRipple: true,
+ },
+ },
+ }),
+ ).toEqual({
+ overrides: {
+ MuiButton: {
+ root: {
+ color: 'green',
+ },
+ },
+ },
+ props: {
+ MuiButton: {
+ disableRipple: true,
+ },
+ },
+ });
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiButton: {
+ styleOverrides: {
+ root: ({ theme }) => ({
+ color: theme.palette.primary.main,
+ }),
+ },
+ },
+ }),
+ ).toEqual({
+ overrides: {
+ MuiButton: {
+ root: {
+ color: 'red',
+ },
+ },
+ },
+ props: {},
+ });
+ });
+
+ it('transforms CSSBaseline theme', () => {
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiCssBaseline: {
+ styleOverrides: theme => ({
+ html: {
+ color: theme.palette.primary.main,
+ },
+ }),
+ defaultProps: {
+ enableColorScheme: true,
+ },
+ },
+ }),
+ ).toEqual({
+ overrides: {
+ MuiCssBaseline: {
+ '@global': {
+ html: {
+ color: 'red',
+ },
+ },
+ },
+ },
+ props: {
+ MuiCssBaseline: {
+ enableColorScheme: true,
+ },
+ },
+ });
+ });
+
+ it('transform state styles', () => {
+ expect(
+ transformV5ComponentThemesToV4(mockTheme, {
+ MuiButton: {
+ styleOverrides: {
+ root: {
+ color: 'green',
+ '&.Mui-disabled': {
+ color: 'red',
+ },
+ },
+ },
+ },
+ }),
+ ).toEqual({
+ overrides: {
+ MuiButton: {
+ root: {
+ color: 'green',
+ },
+ disabled: {
+ color: 'red',
+ },
+ },
+ },
+ props: {},
+ });
+ });
+});
diff --git a/packages/theme/src/unified/overrides.ts b/packages/theme/src/unified/overrides.ts
new file mode 100644
index 0000000000..7417fccedc
--- /dev/null
+++ b/packages/theme/src/unified/overrides.ts
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2022 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 type { Overrides } from '@material-ui/core/styles/overrides';
+import type { ComponentsProps } from '@material-ui/core/styles/props';
+import { ComponentsOverrides, Theme, ThemeOptions } from '@mui/material/styles';
+import { CSSProperties } from 'react';
+
+type V5Override = ComponentsOverrides[Exclude<
+ keyof ComponentsOverrides,
+ 'MuiCssBaseline'
+>];
+type V4Override = Overrides[keyof Overrides];
+type StaticStyleRules = Record<
+ string,
+ CSSProperties | Record
+>;
+
+// Converts callback-based overrides to static styles, e.g.
+// { root: theme => ({ color: theme.color }) } -> { root: { color: 'red' } }
+function adaptV5CssBaselineOverride(
+ theme: Theme,
+ overrides: ComponentsOverrides['MuiCssBaseline'],
+): StaticStyleRules | undefined {
+ if (!overrides || typeof overrides === 'string') {
+ return undefined;
+ }
+
+ const styles = typeof overrides === 'function' ? overrides(theme) : overrides;
+ if (styles) {
+ return { '@global': styles } as StaticStyleRules;
+ }
+
+ return undefined;
+}
+
+// Converts callback-based overrides to static styles, e.g.
+// { root: theme => ({ color: theme.color }) } -> { root: { color: 'red' } }
+function adaptV5Override(
+ theme: Theme,
+ overrides: V5Override,
+): StaticStyleRules | undefined {
+ if (!overrides || typeof overrides === 'string') {
+ return undefined;
+ }
+ if (typeof overrides === 'object') {
+ return Object.fromEntries(
+ Object.entries(overrides).map(([className, style]) => {
+ if (typeof style === 'function') {
+ return [className, style({ theme })];
+ }
+ return [className, style];
+ }),
+ );
+ }
+ return overrides as StaticStyleRules;
+}
+
+const stateStyleKeyPattern = /^&.Mui-([\w-]+)$/;
+
+// Move state style overrides to the top level, e.g.
+// { root: { '&.Mui-active': { color: 'red' } } } -> { active: { color: 'red' } }
+function extractV5StateOverrides(
+ overrides: StaticStyleRules | undefined,
+): StaticStyleRules | undefined {
+ let output = overrides;
+ if (!overrides || typeof overrides !== 'object') {
+ return output;
+ }
+ for (const className of Object.keys(overrides)) {
+ const styles = overrides[className];
+ if (!styles || typeof styles !== 'object') {
+ continue;
+ }
+ for (const _styleKey of Object.keys(styles)) {
+ const styleKey = _styleKey as keyof typeof styles;
+ const match = styleKey.match(stateStyleKeyPattern);
+ if (match) {
+ const [, state] = match;
+ const { [styleKey]: stateStyles, ...restStyles } = styles;
+ if (stateStyles) {
+ output = {
+ ...output,
+ [className]: restStyles,
+ [state]: stateStyles,
+ };
+ }
+ }
+ }
+ }
+ return output;
+}
+
+/**
+ * Transform MUI v5 component themes into a v4 theme props and overrides.
+ *
+ * @public
+ */
+export function transformV5ComponentThemesToV4(
+ theme: Theme,
+ components: ThemeOptions['components'] = {},
+): { overrides: Overrides; props: ComponentsProps } {
+ const overrides: Record = {};
+ const props: Record = {};
+
+ for (const name of Object.keys(components)) {
+ const component = components[name as keyof typeof components];
+ if (!component) {
+ continue;
+ }
+ if ('styleOverrides' in component) {
+ if (name === 'MuiCssBaseline') {
+ overrides[name] = adaptV5CssBaselineOverride(
+ theme,
+ component.styleOverrides as ComponentsOverrides['MuiCssBaseline'],
+ );
+ } else {
+ overrides[name] = extractV5StateOverrides(
+ adaptV5Override(theme, component.styleOverrides as V5Override),
+ );
+ }
+ }
+ if ('defaultProps' in component) {
+ props[name] = component.defaultProps;
+ }
+ }
+
+ return { overrides, props };
+}
diff --git a/packages/theme/src/unified/themes.ts b/packages/theme/src/unified/themes.ts
new file mode 100644
index 0000000000..24e1b1026b
--- /dev/null
+++ b/packages/theme/src/unified/themes.ts
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2022 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 { palettes } from '../base';
+import { createUnifiedTheme } from './UnifiedTheme';
+
+/**
+ * Built-in Backstage MUI themes.
+ *
+ * @public
+ */
+export const themes = {
+ light: createUnifiedTheme({ palette: palettes.light }),
+ dark: createUnifiedTheme({ palette: palettes.dark }),
+};
diff --git a/packages/theme/src/unified/types.ts b/packages/theme/src/unified/types.ts
new file mode 100644
index 0000000000..f090a99b83
--- /dev/null
+++ b/packages/theme/src/unified/types.ts
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2022 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.
+ */
+
+/**
+ * A container of one theme for multiple different MUI versions.
+ *
+ * Currently known keys are 'v4' and 'v5'.
+ *
+ * @public
+ */
+export interface UnifiedTheme {
+ getTheme(version: string): unknown | undefined;
+}
diff --git a/packages/theme/src/v4/baseTheme.ts b/packages/theme/src/v4/baseTheme.ts
new file mode 100644
index 0000000000..8143183ec0
--- /dev/null
+++ b/packages/theme/src/v4/baseTheme.ts
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2020 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 { Theme as Mui5Theme } from '@mui/material/styles';
+import { createTheme as createMuiTheme } from '@material-ui/core/styles';
+import type {
+ GridProps,
+ SwitchProps,
+ Theme,
+ ThemeOptions,
+} from '@material-ui/core';
+import { Overrides } from '@material-ui/core/styles/overrides';
+import { SimpleThemeOptions } from './types';
+import { createBaseThemeOptions } from '../base';
+import { defaultComponentThemes } from '../v5';
+import { transformV5ComponentThemesToV4 } from '../unified/overrides';
+
+/**
+ * An old helper for creating MUI v4 theme options.
+ *
+ * @public
+ * @deprecated Use {@link createBaseThemeOptions} instead.
+ */
+export function createThemeOptions(options: SimpleThemeOptions): ThemeOptions {
+ return {
+ props: {
+ MuiGrid: defaultComponentThemes?.MuiGrid
+ ?.defaultProps as Partial,
+ MuiSwitch: defaultComponentThemes?.MuiSwitch
+ ?.defaultProps as Partial,
+ },
+ ...createBaseThemeOptions(options),
+ };
+}
+
+/**
+ * * An old helper for creating MUI v4 theme overrides.
+ *
+ * @public
+ * @deprecated Use {@link defaultComponentThemes} with {@link transformV5ComponentThemesToV4} instead.
+ */
+export function createThemeOverrides(theme: Theme): Overrides {
+ return transformV5ComponentThemesToV4(
+ // Safe but we have to make sure we don't use mui5 specific stuff in the default component themes
+ theme as unknown as Mui5Theme,
+ defaultComponentThemes,
+ ).overrides;
+}
+
+/**
+ * The old method to create a Backstage MUI v4 theme using a palette.
+ * The theme is created with the common Backstage options and component styles.
+ *
+ * @public
+ * @deprecated Use {@link createUnifiedTheme} instead.
+ */
+export function createTheme(options: SimpleThemeOptions): Theme {
+ const themeOptions = createThemeOptions(options);
+ const baseTheme = createMuiTheme(themeOptions);
+ const overrides = createThemeOverrides(baseTheme);
+ const theme = { ...baseTheme, overrides };
+ return theme;
+}
diff --git a/packages/theme/src/v4/index.ts b/packages/theme/src/v4/index.ts
new file mode 100644
index 0000000000..fad349b849
--- /dev/null
+++ b/packages/theme/src/v4/index.ts
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 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.
+ */
+
+export { darkTheme, lightTheme } from './themes';
+export {
+ createTheme,
+ createThemeOptions,
+ createThemeOverrides,
+} from './baseTheme';
+export type {
+ BackstagePalette,
+ BackstagePaletteOptions,
+ BackstageTheme,
+ BackstageThemeOptions,
+ SimpleThemeOptions,
+} from './types';
diff --git a/packages/theme/src/v4/themes.ts b/packages/theme/src/v4/themes.ts
new file mode 100644
index 0000000000..488ee58831
--- /dev/null
+++ b/packages/theme/src/v4/themes.ts
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2020 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 { createTheme } from './baseTheme';
+import { palettes } from '../base';
+
+/**
+ * The old MUI v4 Backstage light theme.
+ *
+ * @public
+ * @deprecated Use {@link themes.light} instead.
+ */
+export const lightTheme = createTheme({
+ palette: palettes.light,
+});
+
+/**
+ * The old MUI v4 Backstage dark theme.
+ *
+ * @public
+ * @deprecated Use {@link themes.dark} instead.
+ */
+export const darkTheme = createTheme({
+ palette: palettes.dark,
+});
diff --git a/packages/theme/src/v4/types.ts b/packages/theme/src/v4/types.ts
new file mode 100644
index 0000000000..8bca5b8c3b
--- /dev/null
+++ b/packages/theme/src/v4/types.ts
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2020 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 type {
+ Theme as MuiTheme,
+ ThemeOptions as MuiThemeOptions,
+} from '@material-ui/core';
+import type {
+ PaletteOptions as MuiPaletteOptions,
+ Palette as MuiPalette,
+} from '@material-ui/core/styles/createPalette';
+import {
+ BackstagePaletteAdditions,
+ BackstageThemeAdditions,
+ PageTheme,
+ PageThemeSelector,
+} from '../base/types';
+
+/**
+ * The full Backstage palette.
+ *
+ * @public
+ * @deprecated This type is deprecated, the MUI Palette type is now always extended instead.
+ */
+export type BackstagePalette = MuiPalette & BackstagePaletteAdditions;
+
+/**
+ * The full Backstage palette options.
+ *
+ * @public
+ * @deprecated This type is deprecated, the MUI PaletteOptions type is now always extended instead.
+ */
+export type BackstagePaletteOptions = MuiPaletteOptions &
+ BackstagePaletteAdditions;
+
+/**
+ * Backstage theme options.
+ *
+ * @public
+ * @deprecated This type is deprecated, the MUI ThemeOptions type is now always extended instead.
+ * @remarks
+ *
+ * This is essentially a partial theme definition made by the user, that then
+ * gets merged together with defaults and other values to form the final
+ * {@link BackstageTheme}.
+ *
+ */
+export interface BackstageThemeOptions extends MuiThemeOptions {
+ palette: BackstagePaletteOptions;
+ page: PageTheme;
+ getPageTheme: (selector: PageThemeSelector) => PageTheme;
+}
+
+/**
+ * A Backstage theme.
+ *
+ * @public
+ * @deprecated This type is deprecated, the MUI Theme type is now always extended instead.
+ */
+export interface BackstageTheme extends MuiTheme {
+ palette: BackstagePalette;
+ page: PageTheme;
+ getPageTheme: (selector: PageThemeSelector) => PageTheme;
+}
+
+/**
+ * A simpler configuration for creating a new theme that just tweaks some parts
+ * of the backstage one.
+ *
+ * @public
+ * @deprecated Use {@link BaseThemeOptionsInput} instead.
+ */
+export type SimpleThemeOptions = {
+ palette: MuiPaletteOptions;
+ defaultPageTheme?: string;
+ pageTheme?: Record;
+ fontFamily?: string;
+ htmlFontSize?: number;
+};
+
+declare module '@material-ui/core/styles/createPalette' {
+ interface Palette extends BackstagePaletteAdditions {}
+
+ interface PaletteOptions extends BackstagePaletteAdditions {}
+}
+
+declare module '@material-ui/core/styles/createTheme' {
+ interface Theme extends BackstageThemeAdditions {}
+
+ interface ThemeOptions extends BackstageThemeAdditions {}
+}
diff --git a/packages/theme/src/baseTheme.ts b/packages/theme/src/v5/defaultComponentThemes.ts
similarity index 50%
rename from packages/theme/src/baseTheme.ts
rename to packages/theme/src/v5/defaultComponentThemes.ts
index c0a9022bd0..14656b007d 100644
--- a/packages/theme/src/baseTheme.ts
+++ b/packages/theme/src/v5/defaultComponentThemes.ts
@@ -1,5 +1,5 @@
/*
- * Copyright 2020 The Backstage Authors
+ * Copyright 2022 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.
@@ -14,121 +14,51 @@
* limitations under the License.
*/
-import { createTheme as createMuiTheme } from '@material-ui/core/styles';
-import { darken, lighten } from '@material-ui/core/styles/colorManipulator';
-import { Overrides } from '@material-ui/core/styles/overrides';
-import {
- BackstageTheme,
- BackstageThemeOptions,
- SimpleThemeOptions,
-} from './types';
-import { pageTheme as defaultPageThemes } from './pageTheme';
-
-const DEFAULT_HTML_FONT_SIZE = 16;
-const DEFAULT_FONT_FAMILY =
- '"Helvetica Neue", Helvetica, Roboto, Arial, sans-serif';
-
-/**
- * A helper for creating theme options.
- *
- * @public
- */
-export function createThemeOptions(
- options: SimpleThemeOptions,
-): BackstageThemeOptions {
- const {
- palette,
- htmlFontSize = DEFAULT_HTML_FONT_SIZE,
- fontFamily = DEFAULT_FONT_FAMILY,
- defaultPageTheme,
- pageTheme = defaultPageThemes,
- } = options;
-
- if (!pageTheme[defaultPageTheme]) {
- throw new Error(`${defaultPageTheme} is not defined in pageTheme.`);
- }
-
- return {
- palette,
- props: {
- MuiGrid: {
- spacing: 2,
- },
- MuiSwitch: {
- color: 'primary',
- },
- },
- typography: {
- htmlFontSize,
- fontFamily,
- h6: {
- fontWeight: 700,
- fontSize: 20,
- marginBottom: 2,
- },
- h5: {
- fontWeight: 700,
- fontSize: 24,
- marginBottom: 4,
- },
- h4: {
- fontWeight: 700,
- fontSize: 28,
- marginBottom: 6,
- },
- h3: {
- fontSize: 32,
- fontWeight: 700,
- marginBottom: 6,
- },
- h2: {
- fontSize: 40,
- fontWeight: 700,
- marginBottom: 8,
- },
- h1: {
- fontSize: 54,
- fontWeight: 700,
- marginBottom: 10,
- },
- },
- page: pageTheme[defaultPageTheme],
- getPageTheme: ({ themeId }) =>
- pageTheme[themeId] ?? pageTheme[defaultPageTheme],
- };
-}
+import { darken, lighten, ThemeOptions } from '@mui/material/styles';
/**
* A helper for creating theme overrides.
*
* @public
*/
-export function createThemeOverrides(theme: BackstageTheme): Overrides {
- return {
- MuiCssBaseline: {
- '@global': {
- html: {
- height: '100%',
- fontFamily: theme.typography.fontFamily,
- },
- body: {
- height: '100%',
- fontFamily: theme.typography.fontFamily,
- 'overscroll-behavior-y': 'none',
- },
- a: {
- color: 'inherit',
- textDecoration: 'none',
- },
+export const defaultComponentThemes: ThemeOptions['components'] = {
+ MuiCssBaseline: {
+ styleOverrides: theme => ({
+ html: {
+ height: '100%',
+ fontFamily: theme.typography.fontFamily,
},
+ body: {
+ height: '100%',
+ fontFamily: theme.typography.fontFamily,
+ overscrollBehaviorY: 'none',
+ fontSize: '0.875rem',
+ lineHeight: 1.43,
+ },
+ a: {
+ color: 'inherit',
+ textDecoration: 'none',
+ },
+ }),
+ },
+ MuiGrid: {
+ defaultProps: {
+ spacing: 2,
},
- MuiTableRow: {
+ },
+ MuiSwitch: {
+ defaultProps: {
+ color: 'primary',
+ },
+ },
+ MuiTableRow: {
+ styleOverrides: {
// Alternating row backgrounds
- root: {
+ root: ({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.background.default,
},
- },
+ }),
// Use pointer for hoverable rows
hover: {
'&:hover': {
@@ -136,15 +66,17 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
},
},
// Alternating head backgrounds
- head: {
+ head: ({ theme }) => ({
'&:nth-of-type(odd)': {
backgroundColor: theme.palette.background.paper,
},
- },
+ }),
},
- // Tables are more dense than default mui tables
- MuiTableCell: {
- root: {
+ },
+ // Tables are more dense than default mui tables
+ MuiTableCell: {
+ styleOverrides: {
+ root: ({ theme }) => ({
wordBreak: 'break-word',
overflow: 'hidden',
verticalAlign: 'middle',
@@ -152,26 +84,31 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
margin: 0,
padding: theme.spacing(3, 2, 3, 2.5),
borderBottom: 0,
- },
- sizeSmall: {
+ }),
+ sizeSmall: ({ theme }) => ({
padding: theme.spacing(1.5, 2, 1.5, 2.5),
- },
- head: {
+ }),
+ head: ({ theme }) => ({
wordBreak: 'break-word',
overflow: 'hidden',
+ color: theme.palette.textSubtle,
fontWeight: 'normal',
lineHeight: '1',
- },
+ }),
},
- MuiTabs: {
+ },
+ MuiTabs: {
+ styleOverrides: {
// Tabs are smaller than default mui tab rows
root: {
minHeight: 24,
},
},
- MuiTab: {
+ },
+ MuiTab: {
+ styleOverrides: {
// Tabs are smaller and have a hover background
- root: {
+ root: ({ theme }) => ({
color: theme.palette.link,
minHeight: 24,
textTransform: 'initial',
@@ -185,25 +122,33 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
fontSize: theme.typography.pxToRem(14),
fontWeight: 500,
},
- },
- textColorPrimary: {
+ }),
+ textColorPrimary: ({ theme }) => ({
color: theme.palette.link,
- },
+ }),
},
- MuiTableSortLabel: {
+ },
+ MuiTableSortLabel: {
+ styleOverrides: {
// No color change on hover, just rely on the arrow showing up instead.
root: {
color: 'inherit',
'&:hover': {
color: 'inherit',
},
- },
- // Bold font for highlighting selected column
- active: {
- fontWeight: 'bold',
+ '&:focus': {
+ color: 'inherit',
+ },
+ // Bold font for highlighting selected column
+ '&.Mui-active': {
+ fontWeight: 'bold',
+ color: 'inherit',
+ },
},
},
- MuiListItemText: {
+ },
+ MuiListItemText: {
+ styleOverrides: {
dense: {
// Default dense list items to adding ellipsis for really long str...
whiteSpace: 'nowrap',
@@ -211,44 +156,50 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
textOverflow: 'ellipsis',
},
},
- MuiButton: {
+ },
+ MuiButton: {
+ styleOverrides: {
text: {
// Text buttons have less padding by default, but we want to keep the original padding
padding: undefined,
},
},
- MuiChip: {
- root: {
+ },
+ MuiChip: {
+ styleOverrides: {
+ root: ({ theme }) => ({
backgroundColor: '#D9D9D9',
// By default there's no margin, but it's usually wanted, so we add some trailing margin
marginRight: theme.spacing(1),
marginBottom: theme.spacing(1),
color: theme.palette.grey[900],
- },
- outlined: {
+ }),
+ outlined: ({ theme }) => ({
color: theme.palette.text.primary,
- },
- label: {
- lineHeight: `${theme.spacing(2.5)}px`,
+ }),
+ label: ({ theme }) => ({
+ lineHeight: theme.spacing(2.5),
fontWeight: theme.typography.fontWeightMedium,
- fontSize: `${theme.spacing(1.75)}px`,
- },
- labelSmall: {
- fontSize: `${theme.spacing(1.5)}px`,
- },
- deleteIcon: {
+ fontSize: theme.spacing(1.75),
+ }),
+ labelSmall: ({ theme }) => ({
+ fontSize: theme.spacing(1.5),
+ }),
+ deleteIcon: ({ theme }) => ({
color: theme.palette.grey[500],
- width: `${theme.spacing(3)}px`,
- height: `${theme.spacing(3)}px`,
- margin: `0 ${theme.spacing(0.75)}px 0 -${theme.spacing(0.75)}px`,
- },
- deleteIconSmall: {
- width: `${theme.spacing(2)}px`,
- height: `${theme.spacing(2)}px`,
- margin: `0 ${theme.spacing(0.5)}px 0 -${theme.spacing(0.5)}px`,
- },
+ width: theme.spacing(3),
+ height: theme.spacing(3),
+ margin: `0 ${theme.spacing(0.75)} 0 -${theme.spacing(0.75)}`,
+ }),
+ deleteIconSmall: ({ theme }) => ({
+ width: theme.spacing(2),
+ height: theme.spacing(2),
+ margin: `0 ${theme.spacing(0.5)} 0 -${theme.spacing(0.5)}`,
+ }),
},
- MuiCard: {
+ },
+ MuiCard: {
+ styleOverrides: {
root: {
// When cards have a forced size, such as when they are arranged in a
// CSS grid, the content needs to flex such that the actions (buttons
@@ -258,13 +209,17 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
flexDirection: 'column',
},
},
- MuiCardHeader: {
+ },
+ MuiCardHeader: {
+ styleOverrides: {
root: {
// Reduce padding between header and content
paddingBottom: 0,
},
},
- MuiCardContent: {
+ },
+ MuiCardContent: {
+ styleOverrides: {
root: {
// When cards have a forced size, such as when they are arranged in a
// CSS grid, the content needs to flex such that the actions (buttons
@@ -276,25 +231,13 @@ export function createThemeOverrides(theme: BackstageTheme): Overrides {
},
},
},
- MuiCardActions: {
+ },
+ MuiCardActions: {
+ styleOverrides: {
root: {
// We default to putting the card actions at the end
justifyContent: 'flex-end',
},
},
- };
-}
-
-/**
- * Creates a Backstage MUI theme using a palette. The theme is created with the
- * common Backstage options and component styles.
- *
- * @public
- */
-export function createTheme(options: SimpleThemeOptions): BackstageTheme {
- const themeOptions = createThemeOptions(options);
- const baseTheme = createMuiTheme(themeOptions) as BackstageTheme;
- const overrides = createThemeOverrides(baseTheme);
- const theme = { ...baseTheme, overrides };
- return theme;
-}
+ },
+};
diff --git a/packages/theme/src/v5/index.ts b/packages/theme/src/v5/index.ts
new file mode 100644
index 0000000000..eee5d852b1
--- /dev/null
+++ b/packages/theme/src/v5/index.ts
@@ -0,0 +1,18 @@
+/*
+ * Copyright 2022 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.
+ */
+
+export * from './types';
+export { defaultComponentThemes } from './defaultComponentThemes';
diff --git a/packages/theme/src/v5/types.ts b/packages/theme/src/v5/types.ts
new file mode 100644
index 0000000000..31fe72b5b9
--- /dev/null
+++ b/packages/theme/src/v5/types.ts
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2022 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 { Theme } from '@mui/material/styles';
+import {
+ BackstagePaletteAdditions,
+ BackstageThemeAdditions,
+} from '../base/types';
+
+declare module '@mui/material/styles' {
+ interface Palette extends BackstagePaletteAdditions {}
+
+ interface PaletteOptions extends BackstagePaletteAdditions {}
+}
+
+declare module '@mui/material/styles' {
+ interface Theme extends BackstageThemeAdditions {}
+
+ interface ThemeOptions extends BackstageThemeAdditions {}
+}
+
+declare module '@mui/private-theming/defaultTheme' {
+ interface DefaultTheme extends Theme {}
+}
diff --git a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx
index 6592c6195e..cc47c8850b 100644
--- a/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx
+++ b/plugins/catalog-graph/src/components/EntityRelationsGraph/EntityKindIcon.test.tsx
@@ -24,7 +24,7 @@ describe('', () => {
,
);
- expect(baseElement.querySelector('.MuiSvgIcon-root')).toBeInTheDocument();
+ expect(baseElement.querySelector('svg')).toBeInTheDocument();
});
it('renders without exploding for unknown kind', async () => {
@@ -32,6 +32,6 @@ describe('', () => {
,
);
- expect(baseElement.querySelector('.MuiSvgIcon-root')).toBeInTheDocument();
+ expect(baseElement.querySelector('svg')).toBeInTheDocument();
});
});
diff --git a/plugins/techdocs-addons-test-utils/src/test-utils.tsx b/plugins/techdocs-addons-test-utils/src/test-utils.tsx
index e60a96402c..1a921437b1 100644
--- a/plugins/techdocs-addons-test-utils/src/test-utils.tsx
+++ b/plugins/techdocs-addons-test-utils/src/test-utils.tsx
@@ -278,7 +278,7 @@ export class TechDocsAddonTester {
render(this.build());
});
- const shadowHost = screen.getByTestId('techdocs-native-shadowroot');
+ const shadowHost = await screen.findByTestId('techdocs-native-shadowroot');
return {
...screen,
diff --git a/yarn.lock b/yarn.lock
index 52a508235d..2e6f814cf5 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2248,7 +2248,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.16.0, @babel/helper-module-imports@npm:^7.18.6":
+"@babel/helper-module-imports@npm:^7.0.0, @babel/helper-module-imports@npm:^7.12.13, @babel/helper-module-imports@npm:^7.16.0, @babel/helper-module-imports@npm:^7.16.7, @babel/helper-module-imports@npm:^7.18.6":
version: 7.18.6
resolution: "@babel/helper-module-imports@npm:7.18.6"
dependencies:
@@ -2730,7 +2730,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.18.6, @babel/plugin-syntax-jsx@npm:^7.7.2":
+"@babel/plugin-syntax-jsx@npm:^7.0.0, @babel/plugin-syntax-jsx@npm:^7.17.12, @babel/plugin-syntax-jsx@npm:^7.18.6, @babel/plugin-syntax-jsx@npm:^7.7.2":
version: 7.18.6
resolution: "@babel/plugin-syntax-jsx@npm:7.18.6"
dependencies:
@@ -3472,7 +3472,7 @@ __metadata:
languageName: node
linkType: hard
-"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
+"@babel/runtime@npm:^7.0.0, @babel/runtime@npm:^7.1.2, @babel/runtime@npm:^7.10.1, @babel/runtime@npm:^7.12.1, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.6, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.6, @babel/runtime@npm:^7.2.0, @babel/runtime@npm:^7.20.1, @babel/runtime@npm:^7.20.13, @babel/runtime@npm:^7.20.7, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.3.1, @babel/runtime@npm:^7.4.4, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.6.0, @babel/runtime@npm:^7.7.6, @babel/runtime@npm:^7.8.3, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2":
version: 7.21.0
resolution: "@babel/runtime@npm:7.21.0"
dependencies:
@@ -9627,9 +9627,13 @@ __metadata:
resolution: "@backstage/theme@workspace:packages/theme"
dependencies:
"@backstage/cli": "workspace:^"
- "@material-ui/core": ^4.12.2
+ "@emotion/react": ^11.10.5
+ "@emotion/styled": ^11.10.5
+ "@mui/material": ^5.12.2
"@types/react": ^16.13.1 || ^17.0.0
peerDependencies:
+ "@material-ui/core": ^4.12.2
+ "@types/react": ^16.13.1 || ^17.0.0
react: ^16.13.1 || ^17.0.0
react-dom: ^16.13.1 || ^17.0.0
languageName: unknown
@@ -10157,6 +10161,41 @@ __metadata:
languageName: node
linkType: hard
+"@emotion/babel-plugin@npm:^11.10.5":
+ version: 11.10.5
+ resolution: "@emotion/babel-plugin@npm:11.10.5"
+ dependencies:
+ "@babel/helper-module-imports": ^7.16.7
+ "@babel/plugin-syntax-jsx": ^7.17.12
+ "@babel/runtime": ^7.18.3
+ "@emotion/hash": ^0.9.0
+ "@emotion/memoize": ^0.8.0
+ "@emotion/serialize": ^1.1.1
+ babel-plugin-macros: ^3.1.0
+ convert-source-map: ^1.5.0
+ escape-string-regexp: ^4.0.0
+ find-root: ^1.1.0
+ source-map: ^0.5.7
+ stylis: 4.1.3
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ checksum: e3353499c76c4422d6e900c0dfab73607056d9da86161a3f27c3459c193c4908050c5d252c68fcde231e13f02a9d8e0dc07d260317ae0e5206841e331cc4caae
+ languageName: node
+ linkType: hard
+
+"@emotion/cache@npm:^11.10.5, @emotion/cache@npm:^11.10.7":
+ version: 11.10.7
+ resolution: "@emotion/cache@npm:11.10.7"
+ dependencies:
+ "@emotion/memoize": ^0.8.0
+ "@emotion/sheet": ^1.2.1
+ "@emotion/utils": ^1.2.0
+ "@emotion/weak-memoize": ^0.3.0
+ stylis: 4.1.3
+ checksum: 6b1efed2dffc93dac419409d91f6d57a200d858ec5ffa4b7c30080fdbd93db431ff86bb779c5b8830b8373f3c5dd754d9beb386604ed2667c7d55608ff653dfc
+ languageName: node
+ linkType: hard
+
"@emotion/hash@npm:^0.8.0":
version: 0.8.0
resolution: "@emotion/hash@npm:0.8.0"
@@ -10164,19 +10203,93 @@ __metadata:
languageName: node
linkType: hard
-"@emotion/is-prop-valid@npm:^1.1.0":
- version: 1.1.2
- resolution: "@emotion/is-prop-valid@npm:1.1.2"
- dependencies:
- "@emotion/memoize": ^0.7.4
- checksum: 58b1f2d429a589f8f5bc2c33a8732cbb7bbcb17131a103511ef9a94ac754d7eeb53d627f947da480cd977f9d419fd92e244991680292f3287204159652745707
+"@emotion/hash@npm:^0.9.0":
+ version: 0.9.0
+ resolution: "@emotion/hash@npm:0.9.0"
+ checksum: b63428f7c8186607acdca5d003700cecf0ded519d0b5c5cc3b3154eafcad6ff433f8361bd2bac8882715b557e6f06945694aeb6ba8b25c6095d7a88570e2e0bb
languageName: node
linkType: hard
-"@emotion/memoize@npm:^0.7.4":
- version: 0.7.5
- resolution: "@emotion/memoize@npm:0.7.5"
- checksum: 83da8d4a7649a92c72f960817692bc6be13cc13e107b9f7e878d63766525ed4402881bfeb3cda61145c050281e7e260f114a0a2870515527346f2ef896b915b3
+"@emotion/is-prop-valid@npm:^1.1.0, @emotion/is-prop-valid@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "@emotion/is-prop-valid@npm:1.2.0"
+ dependencies:
+ "@emotion/memoize": ^0.8.0
+ checksum: cc7a19850a4c5b24f1514665289442c8c641709e6f7711067ad550e05df331da0692a16148e85eda6f47e31b3261b64d74c5e25194d053223be16231f969d633
+ languageName: node
+ linkType: hard
+
+"@emotion/memoize@npm:^0.8.0":
+ version: 0.8.0
+ resolution: "@emotion/memoize@npm:0.8.0"
+ checksum: c87bb110b829edd8e1c13b90a6bc37cebc39af29c7599a1e66a48e06f9bec43e8e53495ba86278cc52e7589549492c8dfdc81d19f4fdec0cee6ba13d2ad2c928
+ languageName: node
+ linkType: hard
+
+"@emotion/react@npm:^11.10.5":
+ version: 11.10.5
+ resolution: "@emotion/react@npm:11.10.5"
+ dependencies:
+ "@babel/runtime": ^7.18.3
+ "@emotion/babel-plugin": ^11.10.5
+ "@emotion/cache": ^11.10.5
+ "@emotion/serialize": ^1.1.1
+ "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0
+ "@emotion/utils": ^1.2.0
+ "@emotion/weak-memoize": ^0.3.0
+ hoist-non-react-statics: ^3.3.1
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ react: ">=16.8.0"
+ peerDependenciesMeta:
+ "@babel/core":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: 32b67b28e9b6d6c53b970072680697f04c2521441050bdeb19a1a7f0164af549b4dad39ff375eda1b6a3cf1cc86ba2c6fa55460ec040e6ebbca3e9ec58353cf7
+ languageName: node
+ linkType: hard
+
+"@emotion/serialize@npm:^1.1.1":
+ version: 1.1.1
+ resolution: "@emotion/serialize@npm:1.1.1"
+ dependencies:
+ "@emotion/hash": ^0.9.0
+ "@emotion/memoize": ^0.8.0
+ "@emotion/unitless": ^0.8.0
+ "@emotion/utils": ^1.2.0
+ csstype: ^3.0.2
+ checksum: 24cfd5b16e6f2335c032ca33804a876e0442aaf8f9c94d269d23735ebd194fb1ed142542dd92191a3e6ef8bad5bd560dfc5aaf363a1b70954726dbd4dd93085c
+ languageName: node
+ linkType: hard
+
+"@emotion/sheet@npm:^1.2.1":
+ version: 1.2.1
+ resolution: "@emotion/sheet@npm:1.2.1"
+ checksum: ce78763588ea522438156344d9f592203e2da582d8d67b32e1b0b98eaba26994c6c270f8c7ad46442fc9c0a9f048685d819cd73ca87e544520fd06f0e24a1562
+ languageName: node
+ linkType: hard
+
+"@emotion/styled@npm:^11.10.5":
+ version: 11.10.5
+ resolution: "@emotion/styled@npm:11.10.5"
+ dependencies:
+ "@babel/runtime": ^7.18.3
+ "@emotion/babel-plugin": ^11.10.5
+ "@emotion/is-prop-valid": ^1.2.0
+ "@emotion/serialize": ^1.1.1
+ "@emotion/use-insertion-effect-with-fallbacks": ^1.0.0
+ "@emotion/utils": ^1.2.0
+ peerDependencies:
+ "@babel/core": ^7.0.0
+ "@emotion/react": ^11.0.0-rc.0
+ react: ">=16.8.0"
+ peerDependenciesMeta:
+ "@babel/core":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: 1cec5f6aeb227a7255141031e8594f38ad83902413472aae0a46c27e5f9769c01e23c1ad39adee408d8a2168a697464314d1a0c4f50b31a5d25ea506b2d7bbc8
languageName: node
linkType: hard
@@ -10194,6 +10307,36 @@ __metadata:
languageName: node
linkType: hard
+"@emotion/unitless@npm:^0.8.0":
+ version: 0.8.0
+ resolution: "@emotion/unitless@npm:0.8.0"
+ checksum: 176141117ed23c0eb6e53a054a69c63e17ae532ec4210907a20b2208f91771821835f1c63dd2ec63e30e22fcc984026d7f933773ee6526dd038e0850919fae7a
+ languageName: node
+ linkType: hard
+
+"@emotion/use-insertion-effect-with-fallbacks@npm:^1.0.0":
+ version: 1.0.0
+ resolution: "@emotion/use-insertion-effect-with-fallbacks@npm:1.0.0"
+ peerDependencies:
+ react: ">=16.8.0"
+ checksum: 4f06a3b48258c832aa8022a262572061a31ff078d377e9164cccc99951309d70f4466e774fe704461b2f8715007a82ed625a54a5c7a127c89017d3ce3187d4f1
+ languageName: node
+ linkType: hard
+
+"@emotion/utils@npm:^1.2.0":
+ version: 1.2.0
+ resolution: "@emotion/utils@npm:1.2.0"
+ checksum: 55457a49ddd4db6a014ea0454dc09eaa23eedfb837095c8ff90470cb26a303f7ceb5fcc1e2190ef64683e64cfd33d3ba3ca3109cd87d12bc9e379e4195c9a4dd
+ languageName: node
+ linkType: hard
+
+"@emotion/weak-memoize@npm:^0.3.0":
+ version: 0.3.0
+ resolution: "@emotion/weak-memoize@npm:0.3.0"
+ checksum: f43ef4c8b7de70d9fa5eb3105921724651e4188e895beb71f0c5919dc899a7b8743e1fdd99d38b9092dd5722c7be2312ebb47fbdad0c4e38bea58f6df5885cc0
+ languageName: node
+ linkType: hard
+
"@esbuild-kit/cjs-loader@npm:^2.4.1":
version: 2.4.2
resolution: "@esbuild-kit/cjs-loader@npm:2.4.2"
@@ -12734,6 +12877,162 @@ __metadata:
languageName: node
linkType: hard
+"@mui/base@npm:5.0.0-alpha.127":
+ version: 5.0.0-alpha.127
+ resolution: "@mui/base@npm:5.0.0-alpha.127"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@emotion/is-prop-valid": ^1.2.0
+ "@mui/types": ^7.2.4
+ "@mui/utils": ^5.12.0
+ "@popperjs/core": ^2.11.7
+ clsx: ^1.2.1
+ prop-types: ^15.8.1
+ react-is: ^18.2.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
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 330baeef1fdaa513707f295e07a3436af24d0831a18109ed877f76b86cf1f392309833d33a2c7ca250db79fdf53f5e88c2618f876f50dbbbf9323bbf08e367e7
+ languageName: node
+ linkType: hard
+
+"@mui/core-downloads-tracker@npm:^5.12.2":
+ version: 5.12.2
+ resolution: "@mui/core-downloads-tracker@npm:5.12.2"
+ checksum: d748bdc56df6fdfe6712550a94263cf094c53ddcb70f6a8f633caf23927edf5ac88b1f888429d895fe2a5045b27eb7aa9826ccee5b917e31973667d604ed87fe
+ languageName: node
+ linkType: hard
+
+"@mui/material@npm:^5.12.2":
+ version: 5.12.2
+ resolution: "@mui/material@npm:5.12.2"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@mui/base": 5.0.0-alpha.127
+ "@mui/core-downloads-tracker": ^5.12.2
+ "@mui/system": ^5.12.1
+ "@mui/types": ^7.2.4
+ "@mui/utils": ^5.12.0
+ "@types/react-transition-group": ^4.4.5
+ clsx: ^1.2.1
+ csstype: ^3.1.2
+ prop-types: ^15.8.1
+ react-is: ^18.2.0
+ react-transition-group: ^4.4.5
+ peerDependencies:
+ "@emotion/react": ^11.5.0
+ "@emotion/styled": ^11.3.0
+ "@types/react": ^17.0.0 || ^18.0.0
+ react: ^17.0.0 || ^18.0.0
+ react-dom: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: a3464dfbcc496164967e134d6f1d40e060ee02fc2ddb5fcf648ca85580efdbd5eff5aab6a73486d0a7f329f7299127b52501a13993bb131cbd4e310c7f2e633f
+ languageName: node
+ linkType: hard
+
+"@mui/private-theming@npm:^5.12.0":
+ version: 5.12.0
+ resolution: "@mui/private-theming@npm:5.12.0"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@mui/utils": ^5.12.0
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@types/react": ^17.0.0 || ^18.0.0
+ react: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 761bc7a57e1643c2c4c327886882fa5efc7bacae1c6fffe6be4197f49d337261c916a883d96996445efcdedc0672251725c1e5b264b6250d6c9527fd0cafcc62
+ languageName: node
+ linkType: hard
+
+"@mui/styled-engine@npm:^5.12.0":
+ version: 5.12.0
+ resolution: "@mui/styled-engine@npm:5.12.0"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@emotion/cache": ^11.10.7
+ csstype: ^3.1.2
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@emotion/react": ^11.4.1
+ "@emotion/styled": ^11.3.0
+ react: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ checksum: 4a415473cf62aa05012f667dd2e9b1dc2fb175be5b0c4d0b8df541e2dac3d7db410e920e0d5910c8e2b8996a4fb51f74d79483e2878a9b5c0d334498f5537d74
+ languageName: node
+ linkType: hard
+
+"@mui/system@npm:^5.12.1":
+ version: 5.12.1
+ resolution: "@mui/system@npm:5.12.1"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@mui/private-theming": ^5.12.0
+ "@mui/styled-engine": ^5.12.0
+ "@mui/types": ^7.2.4
+ "@mui/utils": ^5.12.0
+ clsx: ^1.2.1
+ csstype: ^3.1.2
+ prop-types: ^15.8.1
+ peerDependencies:
+ "@emotion/react": ^11.5.0
+ "@emotion/styled": ^11.3.0
+ "@types/react": ^17.0.0 || ^18.0.0
+ react: ^17.0.0 || ^18.0.0
+ peerDependenciesMeta:
+ "@emotion/react":
+ optional: true
+ "@emotion/styled":
+ optional: true
+ "@types/react":
+ optional: true
+ checksum: b951959bf5e5af581319354c044f441d97849ff120cfec111d2ed5e7fa05efd63721acff96f48093b8e2bdeb5ccbe35c48613fb925be2b58c596447d10dbed3e
+ languageName: node
+ linkType: hard
+
+"@mui/types@npm:^7.2.4":
+ version: 7.2.4
+ resolution: "@mui/types@npm:7.2.4"
+ peerDependencies:
+ "@types/react": "*"
+ peerDependenciesMeta:
+ "@types/react":
+ optional: true
+ checksum: 16bea0547492193a22fd1794382f314698a114f6c673825314c66b56766c3a9d305992cc495684722b7be16a1ecf7e6e48a79caa64f90c439b530e8c02611a61
+ languageName: node
+ linkType: hard
+
+"@mui/utils@npm:^5.12.0":
+ version: 5.12.0
+ resolution: "@mui/utils@npm:5.12.0"
+ dependencies:
+ "@babel/runtime": ^7.21.0
+ "@types/prop-types": ^15.7.5
+ "@types/react-is": ^16.7.1 || ^17.0.0
+ prop-types: ^15.8.1
+ react-is: ^18.2.0
+ peerDependencies:
+ react: ^17.0.0 || ^18.0.0
+ checksum: 87b2c7468803b083f50af28d7c215c45291e73fef16570848b596d0f1cde1fc613c20e8951f431217b31451de254744abd50eda5013dedec4982420b5bf1c6b6
+ languageName: node
+ linkType: hard
+
"@n1ru4l/push-pull-async-iterable-iterator@npm:^3.1.0":
version: 3.1.0
resolution: "@n1ru4l/push-pull-async-iterable-iterator@npm:3.1.0"
@@ -13645,6 +13944,13 @@ __metadata:
languageName: node
linkType: hard
+"@popperjs/core@npm:^2.11.7":
+ version: 2.11.7
+ resolution: "@popperjs/core@npm:2.11.7"
+ checksum: 5b6553747899683452a1d28898c1b39173a4efd780e74360bfcda8eb42f1c5e819602769c81a10920fc68c881d07fb40429604517d499567eac079cfa6470f19
+ languageName: node
+ linkType: hard
+
"@protobufjs/aspromise@npm:^1.1.1, @protobufjs/aspromise@npm:^1.1.2":
version: 1.1.2
resolution: "@protobufjs/aspromise@npm:1.1.2"
@@ -16489,7 +16795,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.3":
+"@types/prop-types@npm:*, @types/prop-types@npm:^15.0.0, @types/prop-types@npm:^15.7.3, @types/prop-types@npm:^15.7.5":
version: 15.7.5
resolution: "@types/prop-types@npm:15.7.5"
checksum: 5b43b8b15415e1f298243165f1d44390403bb2bd42e662bca3b5b5633fdd39c938e91b7fce3a9483699db0f7a715d08cef220c121f723a634972fdf596aec980
@@ -16555,6 +16861,15 @@ __metadata:
languageName: node
linkType: hard
+"@types/react-is@npm:^16.7.1 || ^17.0.0":
+ version: 17.0.3
+ resolution: "@types/react-is@npm:17.0.3"
+ dependencies:
+ "@types/react": "*"
+ checksum: 6abb7c47d54f012272650df8a962a28bd82f219291e5ef8b4dfa7fe0bb98ae243b060bf9fbe8ceff6213141794855a006db194b490b00ffd15842ae19d0ce1f0
+ languageName: node
+ linkType: hard
+
"@types/react-redux@npm:^7.1.16":
version: 7.1.19
resolution: "@types/react-redux@npm:7.1.19"
@@ -16603,12 +16918,12 @@ __metadata:
languageName: node
linkType: hard
-"@types/react-transition-group@npm:^4.2.0":
- version: 4.2.4
- resolution: "@types/react-transition-group@npm:4.2.4"
+"@types/react-transition-group@npm:^4.2.0, @types/react-transition-group@npm:^4.4.5":
+ version: 4.4.5
+ resolution: "@types/react-transition-group@npm:4.4.5"
dependencies:
"@types/react": "*"
- checksum: a8abb3ad3c6e0575c630b591503a78ae3a94e21d1285905a49c36168e5d3de68b0886e2c6d75b751e30f2dc6e4245351cde30e4b3ff2649aec345f2088961e2c
+ checksum: 265f1c74061556708ffe8d15559e35c60d6c11478c9950d3735575d2c116ca69f461d85effa06d73a613eb8b73c84fd32682feb57cf7c5f9e4284021dbca25b0
languageName: node
linkType: hard
@@ -18665,6 +18980,17 @@ __metadata:
languageName: node
linkType: hard
+"babel-plugin-macros@npm:^3.1.0":
+ version: 3.1.0
+ resolution: "babel-plugin-macros@npm:3.1.0"
+ dependencies:
+ "@babel/runtime": ^7.12.5
+ cosmiconfig: ^7.0.0
+ resolve: ^1.19.0
+ checksum: 765de4abebd3e4688ebdfbff8571ddc8cd8061f839bb6c3e550b0344a4027b04c60491f843296ce3f3379fb356cc873d57a9ee6694262547eb822c14a25be9a6
+ languageName: node
+ linkType: hard
+
"babel-plugin-polyfill-corejs2@npm:^0.3.1":
version: 0.3.1
resolution: "babel-plugin-polyfill-corejs2@npm:0.3.1"
@@ -20120,7 +20446,7 @@ __metadata:
languageName: node
linkType: hard
-"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.1":
+"clsx@npm:^1.0.2, clsx@npm:^1.0.4, clsx@npm:^1.1.1, clsx@npm:^1.2.1":
version: 1.2.1
resolution: "clsx@npm:1.2.1"
checksum: 30befca8019b2eb7dbad38cff6266cf543091dae2825c856a62a8ccf2c3ab9c2907c4d12b288b73101196767f66812365400a227581484a05f968b0307cfaf12
@@ -20703,12 +21029,10 @@ __metadata:
languageName: node
linkType: hard
-"convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0":
- version: 1.7.0
- resolution: "convert-source-map@npm:1.7.0"
- dependencies:
- safe-buffer: ~5.1.1
- checksum: bcd2e3ea7d37f96b85a6e362c8a89402ccc73757256e3ee53aa2c22fe915adb854c66b1f81111be815a3a6a6ce3c58e8001858e883c9d5b4fe08a853fa865967
+"convert-source-map@npm:^1.5.0, convert-source-map@npm:^1.6.0, convert-source-map@npm:^1.7.0":
+ version: 1.9.0
+ resolution: "convert-source-map@npm:1.9.0"
+ checksum: dc55a1f28ddd0e9485ef13565f8f756b342f9a46c4ae18b843fe3c30c675d058d6a4823eff86d472f187b176f0adf51ea7b69ea38be34be4a63cbbf91b0593c8
languageName: node
linkType: hard
@@ -21328,10 +21652,10 @@ __metadata:
languageName: node
linkType: hard
-"csstype@npm:^3.0.2, csstype@npm:^3.0.6":
- version: 3.0.7
- resolution: "csstype@npm:3.0.7"
- checksum: 2f30c993be570c6d0de334b979a718370ee9bca9569c90340f13e05e542146c55b22e87372b858c061f9f8ded494da7a4715957882f9356cf9993ba11ab6f09c
+"csstype@npm:^3.0.2, csstype@npm:^3.0.6, csstype@npm:^3.1.2":
+ version: 3.0.9
+ resolution: "csstype@npm:3.0.9"
+ checksum: 199f9af7e673f9f188525c3102a329d637ff46c52f6385a4427ff5cb17adcb736189150170a7af7c5701d18d7704bdad130273f4aa7e44c6c4f9967e6115dc93
languageName: node
linkType: hard
@@ -25963,7 +26287,7 @@ __metadata:
languageName: node
linkType: hard
-"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.2.1, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.2":
+"hoist-non-react-statics@npm:^3.0.0, hoist-non-react-statics@npm:^3.2.1, hoist-non-react-statics@npm:^3.3.0, hoist-non-react-statics@npm:^3.3.1, hoist-non-react-statics@npm:^3.3.2":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
@@ -26502,15 +26826,6 @@ __metadata:
languageName: node
linkType: hard
-"indefinite-observable@npm:^2.0.1":
- version: 2.0.1
- resolution: "indefinite-observable@npm:2.0.1"
- dependencies:
- symbol-observable: 1.2.0
- checksum: b4305c999b7596901f8798e569b8faa030361dfb77f8b720e229558a29f544826f7e8987c55cc2a84c37ff2723594a965b96a40a6c71daae92b918f3eb393077
- languageName: node
- linkType: hard
-
"indent-string@npm:^4.0.0":
version: 4.0.0
resolution: "indent-string@npm:4.0.0"
@@ -28844,76 +29159,76 @@ __metadata:
linkType: hard
"jss-plugin-camel-case@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-camel-case@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-camel-case@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
hyphenate-style-name: ^1.0.3
- jss: 10.6.0
- checksum: 75c23826deef63c3603cfb47331d1eaf9feeafd097bd115a076f2ee9fb696855d3f18b3f41455a046120fddf0ea11985259c1b8b8a37b3556f4de1a1c83affd5
+ jss: 10.9.2
+ checksum: 5fa617b23ce9718244691c59ace6a0d1271dbcb4430ce3e13b851ee1879c1db8ecab7e941c33802bea763a0f0e2b609d004b8a975b2063f213cdd639cdd384d2
languageName: node
linkType: hard
"jss-plugin-default-unit@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-default-unit@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-default-unit@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
- jss: 10.6.0
- checksum: 7ae36fadf4f206a16e49c40806ef92ba1f0e60395488ab8ad4df96796b408013b38ea5ed975155ecd7833a42a96c8d5cb1e90aef011279816633e60f807ec330
+ jss: 10.9.2
+ checksum: 48d8d836d36dd15513d98de11fba6be373ac29e6fd5702eb2edd143c815fb9e2f9969b2af6b1b964e9b8a052828690887042f6bcb34836836d5c359e52702d0f
languageName: node
linkType: hard
"jss-plugin-global@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-global@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-global@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
- jss: 10.6.0
- checksum: 7aab58408c77071c571dd2c2132edad8d40b683513a8de534f0ec7f63926fd9d9fcf6bdda82103eb541452a723b992f061720f8e5cf2014acb7f6bbbde111f56
+ jss: 10.9.2
+ checksum: 9b29b0c1f169d5a1033890875df072d76364a902d0f6470f448544669a388612a9a4d51844fb2bcb6d25a1c43d67c1637f11a162c2cdd9f4b6b0a8f9c94f6090
languageName: node
linkType: hard
"jss-plugin-nested@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-nested@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-nested@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
- jss: 10.6.0
+ jss: 10.9.2
tiny-warning: ^1.0.2
- checksum: 38095127e8b5ddb0a33ccaf61a4d89dc1b0f78e6d06d079a47a14bca4aed4e885f1957d83f11c5da08b4249b2c629e8bc62b2996f1674ca1302575a7b2b11171
+ checksum: ee08df07f3d553931b48037674842a8314bbc7857cc954a52f962a516bfc4b2d4e9871578b06b8fa3981edf5a927cea00021fd368d4ce315870065b7647f7b57
languageName: node
linkType: hard
"jss-plugin-props-sort@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-props-sort@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-props-sort@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
- jss: 10.6.0
- checksum: 2917ff301e667f75efa15df865a860a50d4319d415d1169c213e66b464edc2b37b6f428be2d974ccdde7c8d61c50123f18e788143a96eacc2a1c42ad250ae375
+ jss: 10.9.2
+ checksum: 70bd181a458a6078f19ad4d7350570c78d26b9aabc25a1fbde673839edcc19825af7b636861b208a38aa17e551e68d0ea38599480716b4aec08e353bbe737222
languageName: node
linkType: hard
"jss-plugin-rule-value-function@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-rule-value-function@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-rule-value-function@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
- jss: 10.6.0
+ jss: 10.9.2
tiny-warning: ^1.0.2
- checksum: 709e1ce0afdc39a52cb78e371fef626f933e99992790b15771d85056176bdf69365d62cfed6ce95434752cc1a1e7e05a6f2548e4cd5999808d50a28174315be3
+ checksum: b1a03209d0249f13ea6de766d3ee14c1769cd1f67d8c543c7d1ce6178c32cf15507c021ecb3e3b7585a8a7a2425dddbe0bdae02f4135c4598725a4152bebfc99
languageName: node
linkType: hard
"jss-plugin-vendor-prefixer@npm:^10.5.1":
- version: 10.6.0
- resolution: "jss-plugin-vendor-prefixer@npm:10.6.0"
+ version: 10.9.2
+ resolution: "jss-plugin-vendor-prefixer@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
css-vendor: ^2.0.8
- jss: 10.6.0
- checksum: 9db048022ee2fb79a223a9f1be5976e131715057e3c0200cfcead9b9f8625023942534afa261e3c967cee6ad716bfd7d4a2f356556178f60f4eddcf83bcd8856
+ jss: 10.9.2
+ checksum: a5c352a500fea82e8a782a090cc9815f6331259f1a331158ed74ed77c750fb45750f5ae95f07d27922742830b45d4c3592cfaab194b3ba4a50591acbdeab04d8
languageName: node
linkType: hard
@@ -28937,16 +29252,15 @@ __metadata:
languageName: node
linkType: hard
-"jss@npm:10.6.0":
- version: 10.6.0
- resolution: "jss@npm:10.6.0"
+"jss@npm:10.9.2":
+ version: 10.9.2
+ resolution: "jss@npm:10.9.2"
dependencies:
"@babel/runtime": ^7.3.1
csstype: ^3.0.2
- indefinite-observable: ^2.0.1
is-in-browser: ^1.1.3
tiny-warning: ^1.0.2
- checksum: 529edd871ddf059beef55ee0f974ad8436fbcf050d6538e6d2d7edab53ce2c09983d2f863e42a1473dd0e42a0447e9912bce6706bb0e539226d92cdaad128d46
+ checksum: 7ae5cd2f8602bf197ec90251d774b9f10d55eb2db0854ac78dc7fb6983828c202e8eb0d5c8c59c73b2f64718ebd33d6063afa799d625a995986a22dc1cc27230
languageName: node
linkType: hard
@@ -35224,9 +35538,9 @@ __metadata:
languageName: node
linkType: hard
-"react-transition-group@npm:^4.0.0, react-transition-group@npm:^4.4.0":
- version: 4.4.1
- resolution: "react-transition-group@npm:4.4.1"
+"react-transition-group@npm:^4.0.0, react-transition-group@npm:^4.4.0, react-transition-group@npm:^4.4.5":
+ version: 4.4.5
+ resolution: "react-transition-group@npm:4.4.5"
dependencies:
"@babel/runtime": ^7.5.5
dom-helpers: ^5.0.1
@@ -35235,7 +35549,7 @@ __metadata:
peerDependencies:
react: ">=16.6.0"
react-dom: ">=16.6.0"
- checksum: 0bcd8af483709832e318dcef84c26ebddeb866bf4f58010286367ef0c1e7c5106e00cfc65688b9102414cb3d572c63909c2eb7ea972b4420fc70a78c10b6e8ad
+ checksum: 75602840106aa9c6545149d6d7ae1502fb7b7abadcce70a6954c4b64a438ff1cd16fc77a0a1e5197cdd72da398f39eb929ea06f9005c45b132ed34e056ebdeb1
languageName: node
linkType: hard
@@ -37229,6 +37543,13 @@ __metadata:
languageName: node
linkType: hard
+"source-map@npm:^0.5.7":
+ version: 0.5.7
+ resolution: "source-map@npm:0.5.7"
+ checksum: 5dc2043b93d2f194142c7f38f74a24670cd7a0063acdaf4bf01d2964b402257ae843c2a8fa822ad5b71013b5fcafa55af7421383da919752f22ff488bc553f4d
+ languageName: node
+ linkType: hard
+
"source-map@npm:^0.6.0, source-map@npm:^0.6.1, source-map@npm:~0.6.0, source-map@npm:~0.6.1":
version: 0.6.1
resolution: "source-map@npm:0.6.1"
@@ -38030,10 +38351,10 @@ __metadata:
languageName: node
linkType: hard
-"stylis@npm:^4.0.6":
- version: 4.0.7
- resolution: "stylis@npm:4.0.7"
- checksum: 4f9fdc4b131b54cdc5988aaf23e796fcf77927c9d2f3147f6b23b8f3a9568eb38ce91b338b9d1b50a50391da32969c34ff68ff971c453fc3a5af89941c60ab06
+"stylis@npm:4.1.3, stylis@npm:^4.0.6":
+ version: 4.1.3
+ resolution: "stylis@npm:4.1.3"
+ checksum: d04dbffcb9bf2c5ca8d8dc09534203c75df3bf711d33973ea22038a99cc475412a350b661ebd99cbc01daa50d7eedcf0d130d121800eb7318759a197023442a6
languageName: node
linkType: hard