268 lines
7.2 KiB
JavaScript
Raw Normal View History

2021-05-25 13:25:54 -04:00
import global from 'global';
import React, { Fragment, useEffect } from 'react';
import isChromatic from 'chromatic/isChromatic';
import {
Global,
ThemeProvider,
themes,
createReset,
convert,
styled,
useTheme,
} from '@storybook/theming';
2020-12-14 13:39:17 +01:00
import { Symbols } from '@storybook/components';
import addHeadWarning from './head-warning';
2021-05-25 13:25:54 -04:00
const { document } = global;
2018-10-14 17:39:35 +02:00
if (process.env.NODE_ENV === 'development') {
if (!process.env.DOTENV_DEVELOPMENT_DISPLAY_WARNING) {
2018-12-29 19:50:44 +01:00
addHeadWarning('dotenv-env', 'Dotenv development file not loaded');
2018-10-14 17:39:35 +02:00
}
if (!process.env.STORYBOOK_DISPLAY_WARNING) {
2018-12-29 19:50:44 +01:00
addHeadWarning('env-glob', 'Global storybook env var not loaded');
2018-10-14 17:39:35 +02:00
}
if (process.env.DISPLAY_WARNING) {
2018-12-29 19:50:44 +01:00
addHeadWarning('env-extra', 'Global non-storybook env var loaded');
2018-10-14 17:39:35 +02:00
}
}
2018-12-29 19:50:44 +01:00
addHeadWarning('preview-head-not-loaded', 'Preview head not loaded');
addHeadWarning('dotenv-file-not-loaded', 'Dotenv file not loaded');
2017-12-27 10:39:31 +01:00
const ThemeBlock = styled.div(
{
position: 'absolute',
top: 0,
left: 0,
right: '50vw',
width: '50vw',
height: '100vh',
bottom: 0,
overflow: 'auto',
padding: 10,
},
({ theme }) => ({
background: theme.background.app,
color: theme.color.defaultText,
}),
({ side }) =>
side === 'left'
? {
left: 0,
right: '50vw',
}
: {
right: 0,
left: '50vw',
}
);
2017-11-27 13:48:46 +11:00
const ThemeStack = styled.div(
{
position: 'relative',
minHeight: 'calc(50vh - 15px)',
},
({ theme }) => ({
background: theme.background.app,
color: theme.color.defaultText,
})
);
const PlayFnNotice = styled.div(
{
position: 'absolute',
bottom: '1rem',
right: '1rem',
border: '1px solid #ccc',
borderRadius: '5px',
padding: '1rem',
fontSize: '12px',
'> *': {
display: 'block',
},
},
({ theme }) => ({
background: theme.background.app,
color: theme.color.defaultText,
})
);
const ThemedSetRoot = () => {
const theme = useTheme();
2020-03-01 15:14:52 +08:00
useEffect(() => {
document.body.style.background = theme.background.app;
document.body.style.color = theme.defaultText;
return () => {
//
};
});
2020-03-01 15:14:52 +08:00
return null;
};
export const decorators = [
(StoryFn, { globals, parameters, playFunction }) => {
2022-08-18 10:26:36 +02:00
const defaultTheme = isChromatic() && !playFunction ? 'stacked' : 'light';
const theme = globals.theme || parameters.theme || defaultTheme;
switch (theme) {
case 'side-by-side': {
return (
<Fragment>
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<ThemeProvider theme={convert(themes.light)}>
<Global styles={createReset} />
</ThemeProvider>
<ThemeProvider theme={convert(themes.light)}>
<ThemeBlock side="left" data-side="left">
<StoryFn />
</ThemeBlock>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeBlock side="right" data-side="right">
<StoryFn />
</ThemeBlock>
</ThemeProvider>
</Fragment>
);
}
case 'stacked': {
return (
<Fragment>
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<ThemeProvider theme={convert(themes.light)}>
<Global styles={createReset} />
</ThemeProvider>
<ThemeProvider theme={convert(themes.light)}>
<ThemeStack side="left" data-side="left">
<StoryFn />
</ThemeStack>
</ThemeProvider>
<ThemeProvider theme={convert(themes.dark)}>
<ThemeStack side="right" data-side="right">
<StoryFn />
</ThemeStack>
</ThemeProvider>
</Fragment>
);
}
default: {
return (
<ThemeProvider theme={convert(themes[theme])}>
2020-12-14 13:39:17 +01:00
<Symbols icons={['folder', 'component', 'document', 'bookmarkhollow']} />
<Global styles={createReset} />
<ThemedSetRoot />
2022-08-18 10:26:36 +02:00
{!parameters.theme && isChromatic() && playFunction && (
<PlayFnNotice>
<span>Detected play function.</span>
<span>Rendering in a single theme</span>
</PlayFnNotice>
)}
<StoryFn />
</ThemeProvider>
);
}
}
},
];
export const parameters = {
exportedParameter: 'exportedParameter',
actions: { argTypesRegex: '^on.*' },
options: {
storySort: (a, b) =>
a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true }),
},
docs: {
theme: themes.light,
},
controls: {
presetColors: [
{ color: '#ff4785', title: 'Coral' },
{ color: '#1EA7FD', title: 'Ocean' },
{ color: 'rgb(252, 82, 31)', title: 'Orange' },
{ color: 'RGBA(255, 174, 0, 0.5)', title: 'Gold' },
{ color: 'hsl(101, 52%, 49%)', title: 'Green' },
{ color: 'HSLA(179,65%,53%,0.5)', title: 'Seafoam' },
{ color: '#6F2CAC', title: 'Purple' },
{ color: '#2A0481', title: 'Ultraviolet' },
{ color: 'black' },
{ color: '#333', title: 'Darkest' },
{ color: '#444', title: 'Darker' },
{ color: '#666', title: 'Dark' },
{ color: '#999', title: 'Mediumdark' },
{ color: '#ddd', title: 'Medium' },
{ color: '#EEE', title: 'Mediumlight' },
{ color: '#F3F3F3', title: 'Light' },
{ color: '#F8F8F8', title: 'Lighter' },
{ color: '#FFFFFF', title: 'Lightest' },
'#fe4a49',
'#FED766',
'rgba(0, 159, 183, 1)',
'HSLA(240,11%,91%,0.5)',
'slategray',
],
},
};
export const globals = {
foo: 'fooValue',
};
export const globalTypes = {
foo: { defaultValue: 'fooDefaultValue' },
bar: { defaultValue: 'barDefaultValue' },
theme: {
name: 'Theme',
description: 'Global theme for components',
toolbar: {
2020-03-01 15:14:52 +08:00
icon: 'circlehollow',
title: 'Theme',
2020-03-01 15:14:52 +08:00
items: [
{ value: 'light', icon: 'circlehollow', title: 'light' },
{ value: 'dark', icon: 'circle', title: 'dark' },
{ value: 'side-by-side', icon: 'sidebar', title: 'side by side' },
{ value: 'stacked', icon: 'bottombar', title: 'stacked' },
2020-03-01 15:14:52 +08:00
],
},
},
locale: {
name: 'Locale',
description: 'Internationalization locale',
toolbar: {
2020-03-01 15:14:52 +08:00
icon: 'globe',
shortcuts: {
next: {
label: 'Go to next language',
keys: ['L'],
},
previous: {
label: 'Go to previous language',
keys: ['K'],
},
reset: {
label: 'Reset language',
keys: ['meta', 'shift', 'L'],
},
},
2020-03-01 15:14:52 +08:00
items: [
{ title: 'Reset locale', type: 'reset' },
2020-03-01 15:14:52 +08:00
{ value: 'en', right: '🇺🇸', title: 'English' },
{ value: 'es', right: '🇪🇸', title: 'Español' },
{ value: 'zh', right: '🇨🇳', title: '中文' },
{ value: 'kr', right: '🇰🇷', title: '한국어' },
],
},
},
};
2020-10-08 14:00:35 +08:00
export const loaders = [async () => ({ globalValue: 1 })];
export const argTypes = { color: { control: 'color' } };
export const args = { color: 'red' };