diff --git a/packages/mui-joy/src/styles/defaultTheme.test.js b/packages/mui-joy/src/styles/defaultTheme.test.js index 80e9c510728db0..c595c01b9c6b91 100644 --- a/packages/mui-joy/src/styles/defaultTheme.test.js +++ b/packages/mui-joy/src/styles/defaultTheme.test.js @@ -13,6 +13,7 @@ describe('defaultTheme', () => { 'components', 'colorSchemes', 'focus', + 'font', 'fontSize', 'fontFamily', 'fontWeight', diff --git a/packages/mui-joy/src/styles/extendTheme.test.js b/packages/mui-joy/src/styles/extendTheme.test.js index f40613de688895..078384e854e218 100644 --- a/packages/mui-joy/src/styles/extendTheme.test.js +++ b/packages/mui-joy/src/styles/extendTheme.test.js @@ -16,6 +16,7 @@ describe('extendTheme', () => { 'colorSchemes', 'defaultColorScheme', 'focus', + 'font', 'fontSize', 'fontFamily', 'fontWeight', @@ -51,6 +52,7 @@ describe('extendTheme', () => { 'radius', 'shadow', 'focus', + 'font', 'fontFamily', 'fontSize', 'fontWeight', @@ -156,7 +158,7 @@ describe('extendTheme', () => { describe('typography', () => { it('produce typography token by default', () => { const theme = extendTheme(); - expect(Object.keys(theme.vars.typography)).to.deep.equal([ + expect(Object.keys(theme.vars.font)).to.deep.equal([ 'h1', 'h2', 'h3', @@ -170,6 +172,28 @@ describe('extendTheme', () => { 'body-xs', ]); }); + + it('access font vars', () => { + const theme = extendTheme(); + expect( + theme.unstable_sx({ + font: 'h1', + }), + ).to.deep.equal({ + font: 'var(--joy-font-h1, var(--joy-fontWeight-xl, 700) var(--joy-fontSize-xl4, 2.25rem)/var(--joy-lineHeight-xs, 1.33334) var(--joy-fontFamily-display, "Inter", var(--joy-fontFamily-fallback, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol")))', + }); + }); + + it('use provided value if no font', () => { + const theme = extendTheme(); + expect( + theme.unstable_sx({ + font: 'var(--custom-font)', + }), + ).to.deep.equal({ + font: 'var(--custom-font)', + }); + }); }); describe('theme.unstable_sx', () => { diff --git a/packages/mui-joy/src/styles/extendTheme.ts b/packages/mui-joy/src/styles/extendTheme.ts index 4bff671510dbf0..34052c61f99992 100644 --- a/packages/mui-joy/src/styles/extendTheme.ts +++ b/packages/mui-joy/src/styles/extendTheme.ts @@ -385,6 +385,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme { light: lightColorSystem, dark: darkColorSystem, }, + font: {}, fontSize, fontFamily, fontWeight, @@ -606,7 +607,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme { cssVarPrefix, getCssVar, spacing: getSpacingVal(spacing), - typography: prepareTypographyVars(mergedScales.typography), + font: { ...prepareTypographyVars(mergedScales.typography), ...mergedScales.font }, } as unknown as Theme & { attribute: string; colorSchemeSelector: string }; // Need type casting due to module augmentation inside the repo theme = cssContainerQueries(theme); diff --git a/packages/mui-joy/src/styles/shouldSkipGeneratingVar.ts b/packages/mui-joy/src/styles/shouldSkipGeneratingVar.ts index 1fed284abc8bc4..d61b8f695cc5b8 100644 --- a/packages/mui-joy/src/styles/shouldSkipGeneratingVar.ts +++ b/packages/mui-joy/src/styles/shouldSkipGeneratingVar.ts @@ -1,6 +1,6 @@ export default function shouldSkipGeneratingVar(keys: string[]) { return ( - !!keys[0].match(/^(variants|breakpoints)$/) || + !!keys[0].match(/^(typography|variants|breakpoints)$/) || !!keys[0].match(/sxConfig$/) || // ends with sxConfig (keys[0] === 'palette' && !!keys[1]?.match(/^(mode)$/)) || (keys[0] === 'focus' && keys[1] !== 'thickness') diff --git a/packages/mui-joy/src/styles/types/theme.ts b/packages/mui-joy/src/styles/types/theme.ts index 520ff6501472ce..708d88953fa501 100644 --- a/packages/mui-joy/src/styles/types/theme.ts +++ b/packages/mui-joy/src/styles/types/theme.ts @@ -85,7 +85,7 @@ interface ColorSystemVars extends Omit { palette: Omit; } export interface ThemeVars extends ThemeScales, ColorSystemVars { - typography: ExtractTypographyTokens; + font: ExtractTypographyTokens; } export interface ThemeCssVarOverrides {} diff --git a/packages/mui-material/src/styles/experimental_extendTheme.d.ts b/packages/mui-material/src/styles/experimental_extendTheme.d.ts index 4ff6b7853ade8b..b82af5287cf4aa 100644 --- a/packages/mui-material/src/styles/experimental_extendTheme.d.ts +++ b/packages/mui-material/src/styles/experimental_extendTheme.d.ts @@ -322,6 +322,7 @@ export interface CssVarsThemeOptions extends Omit; palette: Omit< ColorSystem['palette'], | 'colorScheme' @@ -337,7 +338,6 @@ export interface ThemeVars { shape: Theme['shape']; spacing: string; zIndex: ZIndex; - typography: ExtractTypographyTokens; } type Split = K extends string | number diff --git a/packages/mui-material/src/styles/experimental_extendTheme.js b/packages/mui-material/src/styles/experimental_extendTheme.js index e2130a125f993f..8dea1c19f7ef61 100644 --- a/packages/mui-material/src/styles/experimental_extendTheme.js +++ b/packages/mui-material/src/styles/experimental_extendTheme.js @@ -139,7 +139,7 @@ export default function extendTheme(options = {}, ...args) { overlays: colorSchemesInput.dark?.overlays || defaultDarkOverlays, }, }, - typography: prepareTypographyVars(muiTheme.typography), + font: { ...prepareTypographyVars(muiTheme.typography), ...muiTheme.font }, spacing: getSpacingVal(input.spacing), }; @@ -437,7 +437,6 @@ export default function extendTheme(options = {}, ...args) { theme.getColorSchemeSelector = (colorScheme) => `[${theme.attribute}="${colorScheme}"] &`; theme.spacing = theme.generateSpacing(); theme.shouldSkipGeneratingVar = shouldSkipGeneratingVar; - theme.typography = muiTheme.typography; theme.unstable_sxConfig = { ...defaultSxConfig, ...input?.unstable_sxConfig, diff --git a/packages/mui-material/src/styles/experimental_extendTheme.test.js b/packages/mui-material/src/styles/experimental_extendTheme.test.js index b758bc4edd0f98..601dc385562a73 100644 --- a/packages/mui-material/src/styles/experimental_extendTheme.test.js +++ b/packages/mui-material/src/styles/experimental_extendTheme.test.js @@ -411,7 +411,7 @@ describe('experimental_extendTheme', () => { describe('typography', () => { it('produce typography token by default', () => { const theme = extendTheme(); - expect(Object.keys(theme.vars.typography)).to.deep.equal([ + expect(Object.keys(theme.vars.font)).to.deep.equal([ 'h1', 'h2', 'h3', @@ -428,6 +428,28 @@ describe('experimental_extendTheme', () => { 'inherit', ]); }); + + it('access font vars', () => { + const theme = extendTheme(); + expect( + theme.unstable_sx({ + font: 'h1', + }), + ).to.deep.equal({ + font: 'var(--mui-font-h1, 300 6rem/1.167 "Roboto", "Helvetica", "Arial", sans-serif)', + }); + }); + + it('use provided value if no font', () => { + const theme = extendTheme(); + expect( + theme.unstable_sx({ + font: 'var(--custom-font)', + }), + ).to.deep.equal({ + font: 'var(--custom-font)', + }); + }); }); describe('container queries', () => { diff --git a/packages/mui-material/src/styles/shouldSkipGeneratingVar.ts b/packages/mui-material/src/styles/shouldSkipGeneratingVar.ts index 60d3ea937ab57b..0146d320943c88 100644 --- a/packages/mui-material/src/styles/shouldSkipGeneratingVar.ts +++ b/packages/mui-material/src/styles/shouldSkipGeneratingVar.ts @@ -1,6 +1,6 @@ export default function shouldSkipGeneratingVar(keys: string[]) { return ( - !!keys[0].match(/(cssVarPrefix|mixins|breakpoints|direction|transitions)/) || + !!keys[0].match(/(cssVarPrefix|typography|mixins|breakpoints|direction|transitions)/) || !!keys[0].match(/sxConfig$/) || // ends with sxConfig (keys[0] === 'palette' && !!keys[1]?.match(/(mode|contrastThreshold|tonalOffset)/)) ); diff --git a/packages/mui-system/src/cssVars/prepareTypographyVars.test.ts b/packages/mui-system/src/cssVars/prepareTypographyVars.test.ts index 81b05d1d00aae3..903d8277d96358 100644 --- a/packages/mui-system/src/cssVars/prepareTypographyVars.test.ts +++ b/packages/mui-system/src/cssVars/prepareTypographyVars.test.ts @@ -1,11 +1,11 @@ import { expect } from 'chai'; import { createTheme } from '@mui/material/styles'; -import prepareTypographyTokens from './prepareTypographyVars'; +import prepareTypographyVars from './prepareTypographyVars'; describe('prepareTypographyVars', () => { it('should prepare typography vars', () => { const theme = createTheme(); - expect(prepareTypographyTokens(theme.typography)).to.deep.equal({ + expect(prepareTypographyVars(theme.typography)).to.deep.equal({ body1: '400 1rem/1.5 "Roboto", "Helvetica", "Arial", sans-serif', body2: '400 0.875rem/1.43 "Roboto", "Helvetica", "Arial", sans-serif', button: '500 0.875rem/1.75 "Roboto", "Helvetica", "Arial", sans-serif', diff --git a/packages/mui-system/src/cssVars/prepareTypographyVars.ts b/packages/mui-system/src/cssVars/prepareTypographyVars.ts index a7ecc4f336c3a1..7ecf484af71ef1 100644 --- a/packages/mui-system/src/cssVars/prepareTypographyVars.ts +++ b/packages/mui-system/src/cssVars/prepareTypographyVars.ts @@ -4,7 +4,7 @@ type RecordPropertyNames = { export type ExtractTypographyTokens = { [K in RecordPropertyNames]: string }; -export default function prepareTypographyTokens>(typography: T) { +export default function prepareTypographyVars>(typography: T) { const vars: Record = {}; const entries = Object.entries(typography); entries.forEach((entry) => { diff --git a/packages/mui-system/src/styleFunctionSx/defaultSxConfig.js b/packages/mui-system/src/styleFunctionSx/defaultSxConfig.js index 52452b7b32f857..67453970ab264e 100644 --- a/packages/mui-system/src/styleFunctionSx/defaultSxConfig.js +++ b/packages/mui-system/src/styleFunctionSx/defaultSxConfig.js @@ -290,6 +290,9 @@ const defaultSxConfig = { boxSizing: {}, // typography + font: { + themeKey: 'font', + }, fontFamily: { themeKey: 'typography', },