Skip to content

Commit

Permalink
[system] Fix minor CssVars issues (#29747)
Browse files Browse the repository at this point in the history
  • Loading branch information
siriwatknp committed Nov 19, 2021
1 parent 2599528 commit 80c8795
Show file tree
Hide file tree
Showing 4 changed files with 190 additions and 13 deletions.
8 changes: 2 additions & 6 deletions packages/mui-system/src/cssVars/createCssVarsProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ export default function createCssVarsProvider(options) {
mergedTheme = {
...mergedTheme,
...colorSchemes[resolvedColorScheme],
colorSchemes,
vars: rootVars,
};

Expand All @@ -102,12 +103,7 @@ export default function createCssVarsProvider(options) {
basePrefix: designSystemPrefix,
shouldSkipGeneratingVar,
});
if (key === resolvedColorScheme) {
mergedTheme.vars = {
...mergedTheme.vars,
...vars,
};
}
mergedTheme.vars = deepmerge(mergedTheme.vars, vars);
const resolvedDefaultColorScheme = (() => {
if (typeof defaultColorScheme === 'string') {
return defaultColorScheme;
Expand Down
63 changes: 63 additions & 0 deletions packages/mui-system/src/cssVars/createCssVarsProvider.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,42 @@ describe('createCssVarsProvider', () => {
),
).not.toErrorDev(); // if `h1` is skipped, there will be no error.
});

it('vars are merged from all colorSchemes regardless of selected color scheme', () => {
const { CssVarsProvider } = createCssVarsProvider({
theme: {
colorSchemes: {
light: {
palette: {
primary: '#000',
},
},
dark: {
palette: {
grey: '#888',
},
},
},
},
defaultColorScheme: 'light',
});
const Consumer = () => {
const theme = useTheme();
return (
<div>
<div>{theme.vars.palette.primary || ''}</div>
<div>{theme.vars.palette.grey || ''}</div>
</div>
);
};
render(
<CssVarsProvider>
<Consumer />
</CssVarsProvider>,
);
expect(screen.getByText('var(--palette-primary)')).not.to.equal(null);
expect(screen.getByText('var(--palette-grey)')).not.to.equal(null);
});
});

describe('DOM', () => {
Expand Down Expand Up @@ -433,6 +469,33 @@ describe('createCssVarsProvider', () => {
expect(screen.getByTestId('swatch-bgcolor').textContent).to.equal('var(--palette-bgcolor)');
});

/**
* `colorSchemes` are useful for creating toggle UI.
* In some cases, developers might want to use the color defined in colorSchemes.
*/
it('All `colorSchemes` is available in theme', () => {
const { CssVarsProvider } = createCssVarsProvider({
theme: {
colorSchemes: {
light: {},
dark: {},
},
},
defaultColorScheme: 'light',
});
const Consumer = () => {
const theme = useTheme();
return <div>{Object.keys(theme.colorSchemes).join(', ')}</div>;
};
const { container } = render(
<CssVarsProvider theme={{ colorSchemes: { dim: {} } }}>
<Consumer />
</CssVarsProvider>,
);

expect(container.firstChild.textContent).to.equal('light, dark, dim');
});

it('able to override css variable prefix', () => {
const { CssVarsProvider } = createCssVarsProvider({
theme: {
Expand Down
118 changes: 118 additions & 0 deletions packages/mui-system/src/cssVars/getInitColorSchemeScript.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/* eslint-disable no-eval */
import { expect } from 'chai';
import { createRenderer } from 'test/utils';
import getInitColorSchemeScript, {
DEFAULT_ATTRIBUTE,
DEFAULT_MODE_STORAGE_KEY,
DEFAULT_COLOR_SCHEME_STORAGE_KEY,
} from './getInitColorSchemeScript';

describe('getInitColorSchemeScript', () => {
const { render } = createRenderer();
let originalMatchmedia;
let storage = {};
const createMatchMedia = (matches) => () => ({
matches,
addListener: () => {},
removeListener: () => {},
});

beforeEach(() => {
// Create mocks of localStorage getItem and setItem functions
Object.defineProperty(global, 'localStorage', {
value: {
getItem: (key) => storage[key],
},
configurable: true,
});

// clear the localstorage
storage = {};
document.body.removeAttribute(DEFAULT_ATTRIBUTE);
window.matchMedia = createMatchMedia(false);
});
afterEach(() => {
window.matchMedia = originalMatchmedia;
});

it('should set `light` color scheme to body', () => {
storage[DEFAULT_MODE_STORAGE_KEY] = 'light';
storage[`${DEFAULT_COLOR_SCHEME_STORAGE_KEY}-light`] = 'foo';

const { container } = render(getInitColorSchemeScript());
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('foo');
});

it('should set custom color scheme to body with custom attribute', () => {
storage['mui-foo-mode'] = 'light';
storage[`mui-bar-color-scheme-light`] = 'flash';

const { container } = render(
getInitColorSchemeScript({
modeStorageKey: 'mui-foo-mode',
colorSchemeStorageKey: 'mui-bar-color-scheme',
attribute: 'data-mui-baz-scheme',
}),
);
eval(container.firstChild.textContent);
expect(document.body.getAttribute('data-mui-baz-scheme')).to.equal('flash');
});

it('should set `dark` color scheme to body', () => {
storage[DEFAULT_MODE_STORAGE_KEY] = 'dark';
storage[`${DEFAULT_COLOR_SCHEME_STORAGE_KEY}-dark`] = 'bar';

const { container } = render(getInitColorSchemeScript());
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('bar');
});

it('should set dark color scheme to body, given prefers-color-scheme is `dark`', () => {
storage[DEFAULT_MODE_STORAGE_KEY] = 'system';
storage[`${DEFAULT_COLOR_SCHEME_STORAGE_KEY}-dark`] = 'dim';
window.matchMedia = createMatchMedia(true);

const { container } = render(getInitColorSchemeScript());
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('dim');
});

it('should set light color scheme to body, given prefers-color-scheme is NOT `dark`', () => {
storage[DEFAULT_MODE_STORAGE_KEY] = 'system';
storage[`${DEFAULT_COLOR_SCHEME_STORAGE_KEY}-light`] = 'bright';
window.matchMedia = createMatchMedia(false);

const { container } = render(getInitColorSchemeScript());
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('bright');
});

describe('[option: `enableSystem`]', () => {
it('should set dark color scheme to body, given `enableSystem` is true and prefers-color-scheme is `dark`', () => {
window.matchMedia = createMatchMedia(true);

const { container } = render(
getInitColorSchemeScript({
enableSystem: true,
defaultDarkColorScheme: 'trueDark',
}),
);
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('trueDark');
});

it('should set light color scheme to body, given `enableSystem` is true and prefers-color-scheme is NOT `dark`', () => {
window.matchMedia = createMatchMedia(false);

const { container } = render(
getInitColorSchemeScript({
enableSystem: true,
defaultLightColorScheme: 'yellow',
}),
);
eval(container.firstChild.textContent);
expect(document.body.getAttribute(DEFAULT_ATTRIBUTE)).to.equal('yellow');
});
});
});
14 changes: 7 additions & 7 deletions packages/mui-system/src/cssVars/getInitColorSchemeScript.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ export const DEFAULT_COLOR_SCHEME_STORAGE_KEY = 'mui-color-scheme';
export const DEFAULT_ATTRIBUTE = 'data-mui-color-scheme';

export default function getInitColorSchemeScript(options?: {
defaultMode?: 'light' | 'dark' | 'system';
enableSystem?: boolean;
defaultLightColorScheme?: string;
defaultDarkColorScheme?: string;
modeStorageKey?: string;
colorSchemeStorageKey?: string;
attribute?: string;
}) {
const {
defaultMode = 'light',
enableSystem,
defaultLightColorScheme = 'light',
defaultDarkColorScheme = 'dark',
modeStorageKey = DEFAULT_MODE_STORAGE_KEY,
Expand All @@ -27,20 +27,20 @@ export default function getInitColorSchemeScript(options?: {
__html: `(function() { try {
var mode = localStorage.getItem('${modeStorageKey}');
var colorScheme = '';
if (mode === 'system' || (!mode && ${defaultMode} === 'system')) {
if (mode === 'system' || (!mode && !!${enableSystem})) {
// handle system mode
var mql = window.matchMedia('(prefers-color-scheme: dark)');
if (mql.matches) {
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-dark') || ${defaultLightColorScheme};
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-dark') || '${defaultDarkColorScheme}';
} else {
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-light') || ${defaultDarkColorScheme};
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-light') || '${defaultLightColorScheme}';
}
}
if (mode === 'light') {
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-light') || ${defaultLightColorScheme};
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-light') || '${defaultLightColorScheme}';
}
if (mode === 'dark') {
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-dark') || ${defaultDarkColorScheme};
colorScheme = localStorage.getItem('${colorSchemeStorageKey}-dark') || '${defaultDarkColorScheme}';
}
if (colorScheme) {
document.body.setAttribute('${attribute}', colorScheme);
Expand Down

0 comments on commit 80c8795

Please sign in to comment.