Skip to content

Commit

Permalink
feat(dark): enabled showing the dark theme if desired by the visitor
Browse files Browse the repository at this point in the history
  • Loading branch information
travi committed Oct 10, 2019
1 parent 421f327 commit c80c6a8
Show file tree
Hide file tree
Showing 7 changed files with 216 additions and 43 deletions.
17 changes: 12 additions & 5 deletions .storybook/config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,22 @@
import React from 'react';
import {useMediaQuery} from '@material-ui/core';
import {addDecorator, configure, getStorybook, setAddon} from '@storybook/react';
import {withInfo} from '@storybook/addon-info';
import createPercyAddon from '@percy-io/percy-storybook';
import {MuiThemeProvider} from '@material-ui/core/styles';
import createTheme from '../src/theme';

addDecorator(story => (
<MuiThemeProvider theme={createTheme()}>
{story()}
</MuiThemeProvider>
));
const Wrapper = ({story}) => {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');

return (
<MuiThemeProvider theme={createTheme(prefersDarkMode ? 'dark' : 'light')}>
{story()}
</MuiThemeProvider>
);
};

addDecorator(story => <Wrapper story={story} />);

function loadStories() {
const req = require.context('../src', true, /stories.js$/);
Expand Down
116 changes: 116 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@
"rollup-plugin-babel": "4.3.3",
"rollup-plugin-json": "4.0.0",
"rollup-plugin-node-resolve": "5.2.0",
"sinon": "^7.5.0",
"start-server-and-test": "^1.9.1"
},
"peerDependencies": {
Expand Down
5 changes: 4 additions & 1 deletion src/organisms/layout/presentational.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {bool, func, node, shape, string} from 'prop-types';
import {CssBaseline, withStyles} from '@material-ui/core';
import {ThemeProvider} from '@material-ui/styles';
import classNames from 'classnames';
import {useMediaQuery} from '../../../thirdparty-wrappers/material-ui';
import Header from '../../molecules/header';
import NavigationDrawer from '../../molecules/navigation';
import createTheme from '../../theme';
Expand Down Expand Up @@ -30,8 +31,10 @@ function styles(theme) {
}

export function Layout({children, navigationOpen, onNavigationDrawerToggle, classes}) {
const prefersDarkMode = useMediaQuery('(prefers-color-scheme: dark)');

return (
<ThemeProvider theme={createTheme()}>
<ThemeProvider theme={createTheme(prefersDarkMode ? 'dark' : 'light')}>
<CssBaseline />
<div css={{display: 'flex'}}>
<Header navigationOpen={navigationOpen} onNavigationDrawerToggle={onNavigationDrawerToggle} />
Expand Down
73 changes: 39 additions & 34 deletions src/theme.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
import {createMuiTheme} from '@material-ui/core';

// palette generated at http://mcg.mbitson.com/ from #c80000
export default function createTheme() {
export default function createTheme(colorScheme = 'light') {
return createMuiTheme({
typography: {
useNextVariants: true
},
palette: {
type: colorScheme,
primary: {
50: '#f8e0e0',
100: '#efb3b3',
200: '#e48080',
300: '#d94d4d',
400: '#d02626',
500: '#c80000',
600: '#c20000',
700: '#bb0000',
800: '#b40000',
900: '#a70000',
A100: '#ffd1d1',
A200: '#ff9e9e',
A400: '#ff6b6b',
A700: '#ff5252',
contrastDefaultColor: 'light',
contrastDarkColors: [
'50',
'100',
'200',
'A100',
'A200',
'A400',
'A700'
],
contrastLightColors: [
'300',
'400',
'500',
'600',
'700',
'800',
'900'
]
main: '#c80000'
// 50: '#f8e0e0',
// 100: '#efb3b3',
// 200: '#e48080',
// 300: '#d94d4d',
// 400: '#d02626',
// 500: '#c80000',
// 600: '#c20000',
// 700: '#bb0000',
// 800: '#b40000',
// 900: '#a70000',
// A100: '#ffd1d1',
// A200: '#ff9e9e',
// A400: '#ff6b6b',
// A700: '#ff5252',
// contrastDefaultColor: 'light',
// contrastDarkColors: [
// '50',
// '100',
// '200',
// 'A100',
// 'A200',
// 'A400',
// 'A700'
// ],
// contrastLightColors: [
// '300',
// '400',
// '500',
// '600',
// '700',
// '800',
// '900'
// ]
},
secondary: {
main: '#666'
}
}
});
Expand Down
42 changes: 39 additions & 3 deletions test/unit/organisms/layout/presentational-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,69 @@ import {CssBaseline} from '@material-ui/core';
import {shallow} from 'enzyme';
import {assert} from 'chai';
import any from '@travi/any';
import sinon from 'sinon';
import * as wrappedMaterial from '../../../../thirdparty-wrappers/material-ui';
import {Layout} from '../../../../src/organisms/layout/presentational';
import Header from '../../../../src/molecules/header';
import NavigationDrawer from '../../../../src/molecules/navigation';
import * as themeCreator from '../../../../src/theme';

suite('layout', () => {
let sandbox;
const Child = () => null;
Child.displayName = 'Child';

setup(() => {
sandbox = sinon.createSandbox();

sandbox.stub(themeCreator, 'default');
sandbox.stub(wrappedMaterial, 'useMediaQuery');
});

teardown(() => sandbox.restore());

test('that the layout includes the header and children', () => {
const navigationToggleHandler = () => undefined;
const navigationOpen = any.boolean();
const theme = any.simpleObject();
wrappedMaterial.useMediaQuery.returns(false);
themeCreator.default.withArgs('light').returns(theme);

const wrapper = shallow(
<Layout navigationOpen={navigationOpen} onNavigationDrawerToggle={navigationToggleHandler}>
<Child />
</Layout>
);
const header = wrapper.find(Header);
const navDrawer = wrapper.find(NavigationDrawer);
const themeProvider = wrapper.find('ThemeProvider');
const header = themeProvider.find(Header);
const navDrawer = themeProvider.find(NavigationDrawer);

assert.equal(themeProvider.prop('theme'), theme);

assert.isTrue(wrapper.find(CssBaseline).exists());
assert.isTrue(wrapper.find('Child').exists());
assert.isTrue(themeProvider.find('Child').exists());

assert.equal(header.prop('onNavigationDrawerToggle'), navigationToggleHandler);
assert.equal(header.prop('navigationOpen'), navigationOpen);

assert.equal(navDrawer.prop('onToggle'), navigationToggleHandler);
assert.equal(navDrawer.prop('open'), navigationOpen);
});

test('that dark mode is enabled when preferred', () => {
const navigationToggleHandler = () => undefined;
const navigationOpen = any.boolean();
const theme = any.simpleObject();
wrappedMaterial.useMediaQuery.withArgs('(prefers-color-scheme: dark)').returns(true);
themeCreator.default.withArgs('dark').returns(theme);

const wrapper = shallow(
<Layout navigationOpen={navigationOpen} onNavigationDrawerToggle={navigationToggleHandler}>
<Child />
</Layout>
);
const themeProvider = wrapper.find('ThemeProvider');

assert.equal(themeProvider.prop('theme'), theme);
});
});
5 changes: 5 additions & 0 deletions thirdparty-wrappers/material-ui.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import {useMediaQuery as materialUseMediaQuery} from '@material-ui/core';

export function useMediaQuery(...args) {
return materialUseMediaQuery(...args);
}

0 comments on commit c80c6a8

Please sign in to comment.