diff --git a/.changeset/cool-starfishes-love.md b/.changeset/cool-starfishes-love.md new file mode 100644 index 0000000000..63e387c364 --- /dev/null +++ b/.changeset/cool-starfishes-love.md @@ -0,0 +1,5 @@ +--- +'@backstage/theme': patch +--- + +Overwrite `PaletteOptions` & `ThemeOptions` type to allow use of `createTheme` from `@backstage/theme` as well as `@material-ui/core/styles` with the same type. Also replaced the default `CSSBaseline` with v4 instead of v5 for better backwards compatibility for now. diff --git a/packages/theme/api-report.md b/packages/theme/api-report.md index fe05ca6b4e..d29ad937cf 100644 --- a/packages/theme/api-report.md +++ b/packages/theme/api-report.md @@ -10,7 +10,8 @@ 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 { Theme as Theme_2 } from '@material-ui/core/styles'; +import { Theme as Theme_3 } 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'; @@ -86,7 +87,7 @@ export type BackstagePaletteOptions = PaletteOptions & BackstagePaletteAdditions; // @public @deprecated -export interface BackstageTheme extends Theme_2 { +export interface BackstageTheme extends Theme_3 { // (undocumented) getPageTheme: (selector: PageThemeSelector) => PageTheme; // (undocumented) @@ -172,13 +173,13 @@ export function createBaseThemeOptions( }; // @public @deprecated -export function createTheme(options: SimpleThemeOptions): Theme_2; +export function createTheme(options: SimpleThemeOptions): Theme_3; // @public @deprecated export function createThemeOptions(options: SimpleThemeOptions): ThemeOptions_3; // @public @deprecated -export function createThemeOverrides(theme: Theme_2): Overrides; +export function createThemeOverrides(theme: Theme_3): Overrides; // @public export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme; @@ -187,7 +188,7 @@ export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme; export function createUnifiedThemeFromV4(options: ThemeOptions_2): UnifiedTheme; // @public @deprecated -export const darkTheme: Theme_2; +export const darkTheme: Theme_3; // @public export const defaultComponentThemes: ThemeOptions['components']; @@ -202,7 +203,7 @@ export function genPageTheme(props: { }): PageTheme; // @public @deprecated -export const lightTheme: Theme_2; +export const lightTheme: Theme_3; // @public export type PageTheme = { @@ -380,6 +381,12 @@ export type SimpleThemeOptions = { htmlFontSize?: number; }; +// @public +export type SupportedThemes = Theme_2 | Theme; + +// @public +export type SupportedVersions = 'v4' | 'v5'; + // @public export const themes: { light: UnifiedTheme; @@ -398,7 +405,7 @@ export function transformV5ComponentThemesToV4( // @public export interface UnifiedTheme { // (undocumented) - getTheme(version: string): unknown | undefined; + getTheme(version: SupportedVersions): SupportedThemes | undefined; } // @public diff --git a/packages/theme/src/unified/UnifiedTheme.tsx b/packages/theme/src/unified/UnifiedTheme.tsx index 0c5f80357a..6bf05350b4 100644 --- a/packages/theme/src/unified/UnifiedTheme.tsx +++ b/packages/theme/src/unified/UnifiedTheme.tsx @@ -20,21 +20,22 @@ import { 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, + DeprecatedThemeOptions, Theme as Mui5Theme, - createTheme as createV5Theme, + PaletteOptions as PaletteOptionsV5, ThemeOptions as ThemeOptionsV5, + adaptV4Theme, + createTheme as createV5Theme, } from '@mui/material/styles'; -import { transformV5ComponentThemesToV4 } from './overrides'; +import { createBaseThemeOptions } from '../base/createBaseThemeOptions'; import { PageTheme } from '../base/types'; import { defaultComponentThemes } from '../v5'; -import { createBaseThemeOptions } from '../base/createBaseThemeOptions'; -import { UnifiedTheme } from './types'; +import { transformV5ComponentThemesToV4 } from './overrides'; +import { SupportedThemes, SupportedVersions, UnifiedTheme } from './types'; export class UnifiedThemeHolder implements UnifiedTheme { - #themes = new Map(); + #themes = new Map(); constructor(v4?: Mui4Theme, v5?: Mui5Theme) { this.#themes = new Map(); @@ -46,7 +47,7 @@ export class UnifiedThemeHolder implements UnifiedTheme { } } - getTheme(version: string): unknown | undefined { + getTheme(version: SupportedVersions): SupportedThemes | undefined { return this.#themes.get(version); } } @@ -75,12 +76,6 @@ export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme { 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); @@ -95,7 +90,7 @@ export function createUnifiedTheme(options: UnifiedThemeOptions): UnifiedTheme { export function createUnifiedThemeFromV4( options: ThemeOptionsV4, ): UnifiedTheme { - const v5Theme = adaptV4Theme(options as any); + const v5Theme = adaptV4Theme(options as DeprecatedThemeOptions); 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 index 613f89d5e0..ba28c505f9 100644 --- a/packages/theme/src/unified/UnifiedThemeProvider.tsx +++ b/packages/theme/src/unified/UnifiedThemeProvider.tsx @@ -16,16 +16,18 @@ import React, { ReactNode } from 'react'; import './MuiClassNameSetup'; +import { CssBaseline } from '@material-ui/core'; import { ThemeProvider, StylesProvider, createGenerateClassName, + Theme as Mui4Theme, } from '@material-ui/core/styles'; import { StyledEngineProvider, ThemeProvider as Mui5Provider, + Theme as Mui5Theme, } from '@mui/material/styles'; -import CSSBaseline from '@mui/material/CssBaseline'; import { UnifiedTheme } from './types'; /** @@ -57,12 +59,12 @@ export function UnifiedThemeProvider( ): JSX.Element { const { children, theme, noCssBaseline = false } = props; - const v4Theme = theme.getTheme('v4'); - const v5Theme = theme.getTheme('v5'); + const v4Theme = theme.getTheme('v4') as Mui4Theme; + const v5Theme = theme.getTheme('v5') as Mui5Theme; let cssBaseline: JSX.Element | undefined = undefined; if (!noCssBaseline) { - cssBaseline = ; + cssBaseline = ; } let result = ( diff --git a/packages/theme/src/unified/index.ts b/packages/theme/src/unified/index.ts index f5c805d3ed..747662e195 100644 --- a/packages/theme/src/unified/index.ts +++ b/packages/theme/src/unified/index.ts @@ -20,4 +20,4 @@ export type { UnifiedThemeOptions } from './UnifiedTheme'; export { themes } from './themes'; export { UnifiedThemeProvider } from './UnifiedThemeProvider'; export type { UnifiedThemeProviderProps } from './UnifiedThemeProvider'; -export type { UnifiedTheme } from './types'; +export type { UnifiedTheme, SupportedThemes, SupportedVersions } from './types'; diff --git a/packages/theme/src/unified/types.ts b/packages/theme/src/unified/types.ts index f090a99b83..2dfea6d9b7 100644 --- a/packages/theme/src/unified/types.ts +++ b/packages/theme/src/unified/types.ts @@ -14,6 +14,25 @@ * limitations under the License. */ +import { Theme as Mui4Theme } from '@material-ui/core/styles'; +import { Theme as Mui5Theme } from '@mui/material/styles'; + +/** + * Supported Material UI Versions + * + * Currently: 'v4' and 'v5'. + * + * @public + */ +export type SupportedVersions = 'v4' | 'v5'; + +/** + * Supported Material UI Theme Types for `SupportedVersions` + * + * @public + */ +export type SupportedThemes = Mui4Theme | Mui5Theme; + /** * A container of one theme for multiple different MUI versions. * @@ -22,5 +41,5 @@ * @public */ export interface UnifiedTheme { - getTheme(version: string): unknown | undefined; + getTheme(version: SupportedVersions): SupportedThemes | undefined; } diff --git a/packages/theme/src/v4/types.ts b/packages/theme/src/v4/types.ts index d059bc2d71..48f394447d 100644 --- a/packages/theme/src/v4/types.ts +++ b/packages/theme/src/v4/types.ts @@ -93,8 +93,12 @@ export type SimpleThemeOptions = { declare module '@material-ui/core/styles/createPalette' { interface Palette extends BackstagePaletteAdditions {} + + interface PaletteOptions extends Partial {} } declare module '@material-ui/core/styles/createTheme' { interface Theme extends BackstageThemeAdditions {} + + interface ThemeOptions extends Partial {} } diff --git a/packages/theme/src/v5/defaultComponentThemes.ts b/packages/theme/src/v5/defaultComponentThemes.ts index 14656b007d..e312ef9017 100644 --- a/packages/theme/src/v5/defaultComponentThemes.ts +++ b/packages/theme/src/v5/defaultComponentThemes.ts @@ -240,4 +240,9 @@ export const defaultComponentThemes: ThemeOptions['components'] = { }, }, }, + MuiLink: { + defaultProps: { + underline: 'hover', + }, + }, }; diff --git a/packages/theme/src/v5/types.ts b/packages/theme/src/v5/types.ts index ab74129b95..0d6d46cef9 100644 --- a/packages/theme/src/v5/types.ts +++ b/packages/theme/src/v5/types.ts @@ -22,10 +22,14 @@ import { declare module '@mui/material/styles' { interface Palette extends BackstagePaletteAdditions {} + + interface PaletteOptions extends Partial {} } declare module '@mui/material/styles' { interface Theme extends BackstageThemeAdditions {} + + interface ThemeOptions extends Partial {} } declare module '@mui/private-theming/defaultTheme' {