Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[system] Fix color-scheme implementation #34639

Merged
merged 33 commits into from Oct 11, 2022
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
88bd060
add resolved mode and add comments
siriwatknp Oct 6, 2022
b1fa4d8
remove unnecessary enableColorScheme
siriwatknp Oct 6, 2022
1964a6b
use palette.mode as color-scheme
siriwatknp Oct 6, 2022
b69e21b
add mode to palette in joy
siriwatknp Oct 6, 2022
d971b0b
remove enableColorScheme test (moved to regression)
siriwatknp Oct 6, 2022
119858c
fix joy dark mode
siriwatknp Oct 6, 2022
c1ae81a
remove omit
siriwatknp Oct 6, 2022
fd3268c
add initial setup from design system
siriwatknp Oct 6, 2022
317b915
revert to make code review easier
siriwatknp Oct 6, 2022
51fa80e
move enable color scheme to CssBaseline
siriwatknp Oct 6, 2022
a79c794
Add CssBaseline to Joy
siriwatknp Oct 6, 2022
b5da1b6
run proptypes
siriwatknp Oct 6, 2022
88b48f7
fix lint
siriwatknp Oct 6, 2022
23c27ee
fix backdrop color
siriwatknp Oct 7, 2022
bea2b11
fix Joy color scheme styles
siriwatknp Oct 7, 2022
784a5f6
add visual regression
siriwatknp Oct 7, 2022
4ae0ff0
fix color scheme styles generation
siriwatknp Oct 6, 2022
d7456f9
fix implementation
siriwatknp Oct 7, 2022
4187694
apply logic to ScopedCssBaseline
siriwatknp Oct 7, 2022
fb0a14b
update regression
siriwatknp Oct 7, 2022
65eaac9
fix mui CssBaseline
siriwatknp Oct 7, 2022
3c61b0b
fix logic and regression
siriwatknp Oct 7, 2022
269d647
fix naming
siriwatknp Oct 9, 2022
2b51a0c
flip the flag to disableColorScheme
siriwatknp Oct 9, 2022
49a4707
Add ScopedCssBaseline to Joy
siriwatknp Oct 9, 2022
c1822b3
Add JoyScopedBaseline regression
siriwatknp Oct 9, 2022
5bc8db9
add unit tests
siriwatknp Oct 9, 2022
44ac5cb
export GlobalStyles
siriwatknp Oct 9, 2022
89681bc
add CssBaseline doc
siriwatknp Oct 9, 2022
8fa3c77
fix tests
siriwatknp Oct 10, 2022
f4a7d86
Update packages/mui-joy/src/styles/defaultTheme.ts
siriwatknp Oct 10, 2022
de1ab16
content fix
siriwatknp Oct 10, 2022
1bfdb50
Merge branch 'system/fix-server-mode' of github.com:siriwatknp/materi…
siriwatknp Oct 10, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
84 changes: 84 additions & 0 deletions packages/mui-joy/src/CssBaseline/CssBaseline.tsx
@@ -0,0 +1,84 @@
import * as React from 'react';
import PropTypes from 'prop-types';
import { GlobalStyles } from '@mui/system';
import { Theme, DefaultColorScheme, ColorSystem } from '../styles/types';
import { CssBaselineProps } from './CssBaselineProps';

/**
* Kickstart an elegant, consistent, and simple baseline to build upon.
*/
function CssBaseline({ children, enableColorScheme = false }: CssBaselineProps) {
return (
<React.Fragment>
<GlobalStyles
styles={(theme: Theme) => {
const colorSchemeStyles: Record<string, any> = {};
if (enableColorScheme) {
// The CssBaseline is wrapped inside a CssVarsProvider
(
Object.entries(theme.colorSchemes) as Array<[DefaultColorScheme, ColorSystem]>
).forEach(([key, scheme]) => {
colorSchemeStyles[theme.getColorSchemeSelector(key).replace(/\s*&/, '')] = {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you clarify what is this doing?

theme.getColorSchemeSelector(key).replace(/\s*&/, '')

We have it in many places, maybe we should extract the logic?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

theme.getColorSchemeSelector(key) returns a string, [data-joy-color-scheme="$key"] &, with an & at the end so that developers can use it to write custom styles in styled or sx like this:

styled('div')(({ theme }) => ({
  [theme.getColorSchemeSelector('dark')]: { ... }
  // easier than writing
  // [`${theme.getColorSchemeSelector('dark')} &`]: { ... }
}))

However, the CssBaseline define the selector as global so the .replace(/\s*&/, '') is required to remove & at the end:

theme.getColorSchemeSelector(key).replace(/\s*&/, '') // '[data-joy-color-scheme="dark"]'

I think this case would be rare but I could provide the attribute from the theme to be used like:

[`[${theme.attribute}="dark"]`]: { ... }

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking again, I rather go with theme.getColorSchemeSelector(key).replace(/\s*&/, '') for now because I don't want to add a new property to the theme. Let's wait to see how the community would like to use the API.

colorScheme: scheme.palette?.mode,
};
});
}
return {
html: {
WebkitFontSmoothing: 'antialiased',
MozOsxFontSmoothing: 'grayscale',
// Change from `box-sizing: content-box` so that `width`
// is not affected by `padding` or `border`.
boxSizing: 'border-box',
// Fix font resize problem in iOS
WebkitTextSizeAdjust: '100%',
},
'*, *::before, *::after': {
boxSizing: 'inherit',
},
'strong, b': {
fontWeight: theme.vars.fontWeight.lg,
siriwatknp marked this conversation as resolved.
Show resolved Hide resolved
},
body: {
margin: 0, // Remove the margin in all browsers.
color: theme.vars.palette.text.primary,
...(theme.typography.body1 as any),
backgroundColor: theme.vars.palette.background.body,
'@media print': {
// Save printer ink.
backgroundColor: theme.vars.palette.common.white,
},
// Add support for document.body.requestFullScreen().
// Other elements, if background transparent, are not supported.
'&::backdrop': {
backgroundColor: theme.vars.palette.background.backdrop,
},
},
...colorSchemeStyles,
};
}}
/>
{children}
</React.Fragment>
);
}

CssBaseline.propTypes /* remove-proptypes */ = {
// ----------------------------- Warning --------------------------------
// | These PropTypes are generated from the TypeScript type definitions |
// | To update them edit TypeScript types and run "yarn proptypes" |
// ----------------------------------------------------------------------
/**
* You can wrap a node.
*/
children: PropTypes.node,
/**
* Enable `color-scheme` CSS property to use `theme.palette.mode`.
* For more details, check out https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme
* For browser support, check out https://caniuse.com/?search=color-scheme
* @default false
*/
enableColorScheme: PropTypes.bool,
} as any;

export default CssBaseline;
13 changes: 13 additions & 0 deletions packages/mui-joy/src/CssBaseline/CssBaselineProps.ts
@@ -0,0 +1,13 @@
export interface CssBaselineProps {
/**
* You can wrap a node.
*/
children?: React.ReactNode;
/**
* Enable `color-scheme` CSS property to use `theme.palette.mode`.
* For more details, check out https://developer.mozilla.org/en-US/docs/Web/CSS/color-scheme
* For browser support, check out https://caniuse.com/?search=color-scheme
* @default false
*/
enableColorScheme?: boolean;
}
2 changes: 2 additions & 0 deletions packages/mui-joy/src/CssBaseline/index.ts
@@ -0,0 +1,2 @@
export { default } from './CssBaseline';
export * from './CssBaselineProps';
3 changes: 3 additions & 0 deletions packages/mui-joy/src/index.ts
Expand Up @@ -52,6 +52,9 @@ export * from './ChipDelete';
export { default as Container } from './Container';
export * from './Container';

export { default as CssBaseline } from './CssBaseline';
export * from './CssBaseline';

export { default as Divider } from './Divider';
export * from './Divider';

Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/styles/CssVarsProvider.tsx
Expand Up @@ -4,6 +4,7 @@ import type { DefaultColorScheme, ExtendedColorScheme } from './types';

const shouldSkipGeneratingVar = (keys: string[]) =>
!!keys[0].match(/(typography|variants|breakpoints)/) ||
(keys[0] === 'palette' && !!keys[1]?.match(/^(mode)$/)) ||
(keys[0] === 'focus' && keys[1] !== 'thickness');

const { CssVarsProvider, useColorScheme, getInitColorSchemeScript } = createCssVarsProvider<
Expand Down
2 changes: 2 additions & 0 deletions packages/mui-joy/src/styles/extendTheme.ts
Expand Up @@ -142,6 +142,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme {

const lightColorSystem = {
palette: {
mode: 'light',
primary: {
...colors.blue,
...createLightModeVariantVariables('primary'),
Expand Down Expand Up @@ -243,6 +244,7 @@ export default function extendTheme(themeOptions?: CssVarsThemeOptions): Theme {
};
const darkColorSystem = {
palette: {
mode: 'dark',
primary: {
...colors.blue,
...createDarkModeVariantVariables('primary'),
Expand Down
1 change: 1 addition & 0 deletions packages/mui-joy/src/styles/types/colorSystem.ts
Expand Up @@ -135,6 +135,7 @@ export interface PaletteSuccess extends PaletteRange {}
export interface PaletteWarning extends PaletteRange {}

export interface Palette {
mode: 'light' | 'dark';
primary: PalettePrimary;
neutral: PaletteNeutral;
danger: PaletteDanger;
Expand Down
6 changes: 4 additions & 2 deletions packages/mui-joy/src/styles/types/theme.ts
Expand Up @@ -43,7 +43,6 @@ type NormalizeVars<T> = ConcatDeep<Split<T>>;

export interface RuntimeColorSystem extends Omit<ColorSystem, 'palette'> {
palette: ColorSystem['palette'] & {
mode: 'light' | 'dark';
colorScheme: DefaultColorScheme | ExtendedColorScheme;
};
}
Expand All @@ -59,7 +58,10 @@ export interface ThemeScales {
letterSpacing: LetterSpacing;
}

export interface ThemeVars extends ThemeScales, ColorSystem {}
interface ColorSystemVars extends Omit<ColorSystem, 'palette'> {
palette: Omit<ColorSystem['palette'], 'mode'>;
}
export interface ThemeVars extends ThemeScales, ColorSystemVars {}

export interface ThemeCssVarOverrides {}

Expand Down
12 changes: 11 additions & 1 deletion packages/mui-material/src/CssBaseline/CssBaseline.js
Expand Up @@ -11,7 +11,8 @@ export const html = (theme, enableColorScheme) => ({
boxSizing: 'border-box',
// Fix font resize problem in iOS
WebkitTextSizeAdjust: '100%',
...(enableColorScheme && { colorScheme: theme.palette.mode }),
// When used under CssVarsProvider, colorScheme should not be applied dynamically because it will generate the stylesheet twice for server-rendered applications.
...(enableColorScheme && !theme.vars && { colorScheme: theme.palette.mode }),
});

export const body = (theme) => ({
Expand All @@ -25,6 +26,14 @@ export const body = (theme) => ({
});

export const styles = (theme, enableColorScheme = false) => {
const colorSchemeStyles = {};
if (enableColorScheme && theme.colorSchemes) {
Object.entries(theme.colorSchemes).forEach(([key, scheme]) => {
colorSchemeStyles[theme.getColorSchemeSelector(key).replace(/\s*&/, '')] = {
colorScheme: scheme.palette?.mode,
};
});
}
let defaultStyles = {
html: html(theme, enableColorScheme),
'*, *::before, *::after': {
Expand All @@ -42,6 +51,7 @@ export const styles = (theme, enableColorScheme = false) => {
backgroundColor: (theme.vars || theme).palette.background.default,
},
},
...colorSchemeStyles,
};

const themeOverrides = theme.components?.MuiCssBaseline?.styleOverrides;
Expand Down
Expand Up @@ -22,6 +22,14 @@ const ScopedCssBaselineRoot = styled('div', {
slot: 'Root',
overridesResolver: (props, styles) => styles.root,
})(({ theme, ownerState }) => {
const colorSchemeStyles = {};
if (ownerState.enableColorScheme && theme.colorSchemes) {
Object.entries(theme.colorSchemes).forEach(([key, scheme]) => {
colorSchemeStyles[`&${theme.getColorSchemeSelector(key).replace(/\s*&/, '')}`] = {
colorScheme: scheme.palette?.mode,
};
});
}
return {
...html(theme, ownerState.enableColorScheme),
...body(theme),
Expand All @@ -31,6 +39,7 @@ const ScopedCssBaselineRoot = styled('div', {
'& strong, & b': {
fontWeight: theme.typography.fontWeightBold,
},
...colorSchemeStyles,
};
});

Expand Down
Expand Up @@ -193,7 +193,7 @@ export interface PaletteTooltip {

// The Palette should be sync with `../themeCssVarsAugmentation/index.d.ts`
export interface ColorSystemOptions {
palette?: Omit<PaletteOptions, 'mode'> & {
palette?: PaletteOptions & {
common?: Partial<PaletteCommonChannel>;
primary?: Partial<PaletteColorChannel>;
secondary?: Partial<PaletteColorChannel>;
Expand Down
5 changes: 0 additions & 5 deletions packages/mui-system/src/cssVars/createCssVarsProvider.d.ts
Expand Up @@ -39,11 +39,6 @@ export interface CssVarsProviderConfig<ColorScheme extends string> {
* @default false
*/
disableTransitionOnChange?: boolean;
/**
* Indicate to the browser which color scheme is used (light or dark) for rendering built-in UI
* @default true
*/
enableColorScheme?: boolean;
/**
* A function to determine if the key, value should be attached as CSS Variable
* `keys` is an array that represents the object path keys.
Expand Down