Skip to content

Commit

Permalink
[zero] Export extendTheme for creating a zero-runtime theme (#40897)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp authored Feb 13, 2024
1 parent 2d43ad1 commit f33e247
Show file tree
Hide file tree
Showing 19 changed files with 728 additions and 300 deletions.
87 changes: 76 additions & 11 deletions apps/zero-runtime-next-app/next.config.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,89 @@
/* eslint-env node */
// eslint-ignore-next-line import/no-unresolved
const { withZeroPlugin } = require('@mui/zero-next-plugin');
const { experimental_extendTheme: extendTheme } = require('@mui/material/styles');
const { extendTheme } = require('@mui/zero-runtime');

/**
* @typedef {import('@mui/zero-next-plugin').ZeroPluginConfig} ZeroPluginConfig
*/

const theme = extendTheme({
cssVarPrefix: 'app',
components: {
MuiBadge: {
defaultProps: {
color: 'error',
'max-width': '1100px',
'border-radius': '12px',
'font-mono': `ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono', 'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono', 'Courier New', monospace`,
colorSchemes: {
light: {
'foreground-rgb': '0, 0, 0',
'background-start-rgb': '214, 219, 220',
'background-end-rgb': '255, 255, 255',
'primary-glow': `conic-gradient(
from 180deg at 50% 50%,
#16abff33 0deg,
#0885ff33 55deg,
#54d6ff33 120deg,
#0071ff33 160deg,
transparent 360deg
)`,
'secondary-glow': `radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0))`,
title: {
'start-rbg': '239, 245, 249',
'end-rgb': '228, 232, 233',
border: `conic-gradient(
#00000080,
#00000040,
#00000030,
#00000020,
#00000010,
#00000010,
#00000080
)`,
},
callout: {
rgb: '238, 240, 241',
'border-rgb': '172, 175, 176',
},
card: {
rgb: '180, 185, 188',
'border-rgb': '131, 134, 135',
},
},
dark: {
'foreground-rgb': '255, 255, 255',
'background-start-rgb': '0, 0, 0',
'background-end-rgb': '0, 0, 0',
'primary-glow': `radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0))`,
'secondary-glow': `linear-gradient(
to bottom right,
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0.3)
)`,
title: {
'start-rbg': '2, 13, 46',
'end-rgb': '2, 5, 19',
border: `conic-gradient(
#ffffff80,
#ffffff40,
#ffffff30,
#ffffff20,
#ffffff10,
#ffffff10,
#ffffff80
)`,
},
callout: {
rgb: '20, 20, 20',
'border-rgb': '108, 108, 108',
},
card: {
rgb: '100, 100, 100',
'border-rgb': '200, 200, 200',
},
},
},
});
theme.getColorSchemeSelector = (targetColorScheme) =>
`[data-mui-color-scheme="${targetColorScheme}"] &`;

/**
* @typedef {import('@mui/zero-next-plugin').ZeroPluginConfig} ZeroPluginConfig
*/
// { [theme.getColorSchemeSelector('dark')]: { color: 'black' } }

/**
* @type {ZeroPluginConfig}
Expand Down
72 changes: 0 additions & 72 deletions apps/zero-runtime-next-app/src/app/globals.css
Original file line number Diff line number Diff line change
@@ -1,75 +1,3 @@
:root {
--max-width: 1100px;
--border-radius: 12px;
--font-mono: ui-monospace, Menlo, Monaco, 'Cascadia Mono', 'Segoe UI Mono', 'Roboto Mono',
'Oxygen Mono', 'Ubuntu Monospace', 'Source Code Pro', 'Fira Mono', 'Droid Sans Mono',
'Courier New', monospace;

--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;

--primary-glow: conic-gradient(
from 180deg at 50% 50%,
#16abff33 0deg,
#0885ff33 55deg,
#54d6ff33 120deg,
#0071ff33 160deg,
transparent 360deg
);
--secondary-glow: radial-gradient(rgba(255, 255, 255, 1), rgba(255, 255, 255, 0));

--tile-start-rgb: 239, 245, 249;
--tile-end-rgb: 228, 232, 233;
--tile-border: conic-gradient(
#00000080,
#00000040,
#00000030,
#00000020,
#00000010,
#00000010,
#00000080
);

--callout-rgb: 238, 240, 241;
--callout-border-rgb: 172, 175, 176;
--card-rgb: 180, 185, 188;
--card-border-rgb: 131, 134, 135;
}

@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;

--primary-glow: radial-gradient(rgba(1, 65, 255, 0.4), rgba(1, 65, 255, 0));
--secondary-glow: linear-gradient(
to bottom right,
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0),
rgba(1, 65, 255, 0.3)
);

--tile-start-rgb: 2, 13, 46;
--tile-end-rgb: 2, 5, 19;
--tile-border: conic-gradient(
#ffffff80,
#ffffff40,
#ffffff30,
#ffffff20,
#ffffff10,
#ffffff10,
#ffffff80
);

--callout-rgb: 20, 20, 20;
--callout-border-rgb: 108, 108, 108;
--card-rgb: 100, 100, 100;
--card-border-rgb: 200, 200, 200;
}
}

* {
box-sizing: border-box;
padding: 0;
Expand Down
28 changes: 20 additions & 8 deletions apps/zero-runtime-next-app/src/app/page.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,32 @@
import Image from 'next/image';
import { styled } from '@mui/zero-runtime';
import Badge from '@mui/material/Badge';
import { styled, css } from '@mui/zero-runtime';
import styles from './page.module.css';

const Main = styled.main({
color: 'rgb(var(--foreground-rgb))',
const visuallyHidden = css({
border: 0,
clip: 'rect(0 0 0 0)',
height: '1px',
margin: -1,
overflow: 'hidden',
padding: 0,
position: 'absolute',
whiteSpace: 'nowrap',
width: '1px',
});

const Main = styled.main(({ theme }) => ({
color: theme.vars['foreground-rgb'],
background: `linear-gradient(to bottom, transparent, rgb(var(--background-end-rgb))) rgb(var(--background-start-rgb))`,
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
alignItems: 'center',
padding: '6rem',
minHeight: '100vh',
});
...theme.applyStyles('dark', {
color: 'yellow',
}),
}));

const Description = styled.div({
display: 'inherit',
Expand Down Expand Up @@ -78,9 +92,7 @@ const Description = styled.div({
export default function Home() {
return (
<Main>
<Badge variant="dot">
<div>Hey</div>
</Badge>
<div className={visuallyHidden}>I am invisible</div>
<Description>
<p>
Get started by editing&nbsp;
Expand Down
38 changes: 29 additions & 9 deletions apps/zero-runtime-next-app/src/augment.d.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
import type { Theme } from '@mui/material/styles';
import type {} from '@mui/material/themeCssVarsAugmentation';
import '@mui/zero-runtime/theme';
import type { ExtendTheme } from '@mui/zero-runtime';

declare module '@mui/zero-runtime/theme' {
export interface ThemeArgs {
theme: Omit<Theme, 'applyStyles'> & {
applyStyles: (
colorScheme: 'light' | 'dark',
styles: Record<string, any>,
) => Record<string, any>;
interface ThemeTokens {
'max-width': string;
'border-radius': string;
'font-mono': string;
'foreground-rgb': string;
'background-start-rgb': string;
'background-end-rgb': string;
'primary-glow': string;
'secondary-glow': string;
title: {
'start-rgb': string;
'end-rgb': string;
border: string;
};
callout: {
rgb: string;
'border-rgb': string;
};
card: {
rgb: string;
'border-rgb': string;
};
}

interface ThemeArgs {
theme: ExtendTheme<{
colorScheme: 'light' | 'dark';
tokens: ThemeTokens;
}>;
}
}
29 changes: 21 additions & 8 deletions packages/mui-system/src/cssVars/prepareCssVars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,24 @@ import { deepmerge } from '@mui/utils';
import cssVarsParser from './cssVarsParser';

export interface DefaultCssVarsTheme {
colorSchemes: Record<string, any>;
colorSchemes?: Record<string, any>;
defaultColorScheme?: string;
}

function prepareCssVars<T extends DefaultCssVarsTheme, ThemeVars extends Record<string, any>>(
function prepareCssVars<
T extends DefaultCssVarsTheme,
ThemeVars extends Record<string, any>,
Selector = any,
>(
theme: T,
parserConfig?: {
prefix?: string;
shouldSkipGeneratingVar?: (objectPathKeys: Array<string>, value: string | number) => boolean;
getSelector?: (colorScheme: string | undefined, css: Record<string, any>) => Selector;
},
) {
// @ts-ignore - ignore components do not exist
const { colorSchemes = {}, components, ...otherTheme } = theme;
const { colorSchemes = {}, components, defaultColorScheme = 'light', ...otherTheme } = theme;
const {
vars: rootVars,
css: rootCss,
Expand All @@ -23,26 +29,33 @@ function prepareCssVars<T extends DefaultCssVarsTheme, ThemeVars extends Record<

const colorSchemesMap: Record<string, { css: Record<string, string | number>; vars: ThemeVars }> =
{};
const { light, ...otherColorSchemes } = colorSchemes;
const { [defaultColorScheme]: light, ...otherColorSchemes } = colorSchemes;
Object.entries(otherColorSchemes || {}).forEach(([key, scheme]) => {
const { vars, css, varsWithDefaults } = cssVarsParser<ThemeVars>(scheme, parserConfig);
themeVars = deepmerge(themeVars, varsWithDefaults);
colorSchemesMap[key] = { css, vars };
});
if (light) {
// light color scheme vars should be merged last to set as default
// default color scheme vars should be merged last to set as default
const { css, vars, varsWithDefaults } = cssVarsParser<ThemeVars>(light, parserConfig);
themeVars = deepmerge(themeVars, varsWithDefaults);
colorSchemesMap.light = { css, vars };
colorSchemesMap[defaultColorScheme] = { css, vars };
}

const generateCssVars = (colorScheme?: string) => {
if (!colorScheme) {
return { css: { ...rootCss }, vars: rootVars };
const css = { ...rootCss };
return {
css,
vars: rootVars,
selector: parserConfig?.getSelector?.(colorScheme, css) || ':root',
};
}
const css = { ...colorSchemesMap[colorScheme].css };
return {
css: { ...colorSchemesMap[colorScheme].css },
css,
vars: colorSchemesMap[colorScheme].vars,
selector: parserConfig?.getSelector?.(colorScheme, css) || ':root',
};
};

Expand Down
Loading

0 comments on commit f33e247

Please sign in to comment.