Skip to content

Commit a2ce3f9

Browse files
authored
Fix chromatic snaphots (codesandbox#3327)
* add config example * fix snapshots * fix select icon * update storybook * Revert "update storybook" This reverts commit f777309.
1 parent b47d00c commit a2ce3f9

File tree

10 files changed

+436
-19
lines changed

10 files changed

+436
-19
lines changed

packages/components/.storybook/addons.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@ import '@storybook/addon-knobs/register';
33
import '@storybook/addon-storysource/register';
44
import '@storybook/addon-viewport/register';
55
import '@storybook/addon-a11y/register';
6-
import 'storybook-addon-styled-component-theme/dist/register';
6+
import './storybook-addon-styled-component-theme/register.js';

packages/components/.storybook/config.tsx

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
import React from 'react';
2-
2+
import isChromatic from 'storybook-chromatic/isChromatic';
33
import { withKnobs } from '@storybook/addon-knobs';
44
import { withA11y } from '@storybook/addon-a11y';
55
import { addDecorator, addParameters, configure } from '@storybook/react';
66
import { themes } from '@storybook/theming';
7-
import { createGlobalStyle } from 'styled-components';
7+
import { createGlobalStyle, ThemeProvider } from 'styled-components';
88
// @ts-ignore
99
import global from '@codesandbox/common/lib/global.css';
1010
import { makeTheme, getThemes } from '../src/components/ThemeProvider';
11-
import { withThemesProvider } from 'storybook-addon-styled-component-theme';
11+
import { withThemesProvider } from './storybook-addon-styled-component-theme';
1212

1313
const viewports = {
1414
mobile: {
@@ -48,23 +48,34 @@ const GlobalStyle = createGlobalStyle`
4848
4949
}
5050
`;
51-
52-
export const withGlobal = (cb: any) => (
53-
<>
54-
<GlobalStyle />
55-
{cb()}
56-
</>
57-
);
58-
5951
const allThemes = getThemes();
6052
const vsCodeThemes = allThemes.map(b => makeTheme(b, b.name));
53+
6154
const blackCodesandbox = vsCodeThemes.find(
6255
theme => theme.name === 'CodeSandbox Black'
6356
);
57+
console.log(isChromatic());
58+
if (!isChromatic()) {
59+
const withGlobal = (cb: any) => (
60+
<>
61+
<GlobalStyle />
62+
{cb()}
63+
</>
64+
);
65+
66+
const rest = vsCodeThemes.filter(theme => theme.name !== 'CodeSandbox Black');
67+
addDecorator(withGlobal);
68+
addDecorator(withThemesProvider([blackCodesandbox, ...rest]));
69+
} else {
70+
const withGlobal = (cb: any) => (
71+
<ThemeProvider theme={makeTheme(blackCodesandbox, 'default')}>
72+
<GlobalStyle />
73+
{cb()}
74+
</ThemeProvider>
75+
);
6476

65-
const rest = vsCodeThemes.filter(theme => theme.name !== 'CodeSandbox Black');
66-
addDecorator(withGlobal);
67-
addDecorator(withThemesProvider([blackCodesandbox, ...rest]));
77+
addDecorator(withGlobal);
78+
}
6879
addDecorator(withA11y);
6980
addDecorator(withKnobs);
7081
addParameters({ viewport: { viewports } });
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-react",
5+
"@babel/preset-typescript"
6+
]
7+
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import { List } from 'immutable';
2+
import * as React from 'react';
3+
import {
4+
branch,
5+
compose,
6+
lifecycle,
7+
renderNothing,
8+
withHandlers,
9+
withState,
10+
} from 'recompose';
11+
import styled from 'styled-components';
12+
13+
const BaseComponent = ({ onSelectTheme, themes, theme }) => (
14+
<FlexRow>
15+
{themes
16+
.map((th, i) => (
17+
<Button
18+
selected={th === theme}
19+
key={i}
20+
onClick={() => onSelectTheme(th)}
21+
>
22+
{th.name}
23+
</Button>
24+
))
25+
.toArray()}
26+
<FillingDiv />
27+
<Border>|</Border>
28+
</FlexRow>
29+
);
30+
31+
export const Themes = compose(
32+
withState('theme', 'setTheme', null),
33+
withState('themes', 'setThemes', List()),
34+
withHandlers({
35+
onSelectTheme: ({ channel, setTheme }) => theme => {
36+
setTheme(theme);
37+
channel.emit('selectTheme', theme.name);
38+
},
39+
onReceiveThemes: ({ setTheme, setThemes, channel }) => newThemes => {
40+
const themes = List(newThemes);
41+
setThemes(List(themes));
42+
if (themes.count() > 0) {
43+
const theme = themes.first();
44+
setTheme(theme);
45+
channel.emit('selectTheme', theme.name);
46+
}
47+
},
48+
}),
49+
lifecycle({
50+
componentDidMount() {
51+
const { channel, onReceiveThemes } = this.props;
52+
channel.on('setThemes', onReceiveThemes);
53+
},
54+
componentWillUnmount() {
55+
const { channel, onReceiveThemes } = this.props;
56+
channel.removeListener('setThemes', onReceiveThemes);
57+
},
58+
}),
59+
branch(({ active }) => !active, renderNothing)
60+
)(BaseComponent);
61+
62+
const FlexRow = styled.div`
63+
margin-top: 16px;
64+
display: grid;
65+
grid-template-columns: repeat(auto-fill, 120px);
66+
grid-gap: 16px;
67+
position: relative !important;
68+
height: auto !important;
69+
`;
70+
71+
const FillingDiv = styled.div`
72+
flex: 1;
73+
`;
74+
75+
const Border = styled.div`
76+
font-size: 0;
77+
`;
78+
79+
const Button = styled.button`
80+
color: #fff;
81+
background-color: ${({ selected }) => (selected ? '#0971f1' : '#242424')};
82+
display: inline-block;
83+
cursor: pointer;
84+
height: 24px;
85+
width: 100%;
86+
font-size: 11px;
87+
border: none;
88+
border-radius: 2px;
89+
transition: all ease-in;
90+
transition-duration: 75ms;
91+
`;
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import addons from '@storybook/addons';
2+
import { List } from 'immutable';
3+
import * as React from 'react';
4+
import {
5+
branch,
6+
compose,
7+
lifecycle,
8+
mapProps,
9+
renderNothing,
10+
withHandlers,
11+
withState,
12+
} from 'recompose';
13+
import { ThemeProvider } from 'styled-components';
14+
15+
const BaseComponent = ({ theme, Provider, children }) => (
16+
<Provider theme={theme} children={children} />
17+
);
18+
19+
export const ThemesProvider = compose(
20+
mapProps(props => {
21+
const { CustomThemeProvider } = props;
22+
const Provider = CustomThemeProvider ? CustomThemeProvider : ThemeProvider;
23+
return { ...props, Provider };
24+
}),
25+
withState('theme', 'setTheme', null),
26+
withHandlers({
27+
onSelectTheme: ({ setTheme, themes }) => name => {
28+
const theme = themes.find(th => th.name === name);
29+
setTheme(theme);
30+
},
31+
}),
32+
lifecycle({
33+
componentDidMount() {
34+
const { onSelectTheme, themes } = this.props;
35+
const channel = addons.getChannel();
36+
channel.on('selectTheme', onSelectTheme);
37+
channel.emit('setThemes', themes);
38+
},
39+
componentWillUnmount() {
40+
const { onSelectTheme } = this.props;
41+
const channel = addons.getChannel();
42+
channel.removeListener('selectTheme', onSelectTheme);
43+
},
44+
}),
45+
branch(props => !props.theme, renderNothing)
46+
)(BaseComponent);
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export { ThemesProvider } from './ThemesProvider';
2+
export { Themes } from './Themes';
3+
export { withThemesProvider } from './withThemesProvider';
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import addons from '@storybook/addons';
2+
import React from 'react';
3+
import { Themes } from './Themes';
4+
5+
addons.register('storybook/themes', api => {
6+
// Also need to set a unique name to the panel.
7+
addons.addPanel('storybook/themes/panel', {
8+
title: 'Themes',
9+
render: ({ active }) => {
10+
return (
11+
<Themes
12+
key="storybook-theme-addon"
13+
channel={addons.getChannel()}
14+
api={api}
15+
active={active}
16+
/>
17+
);
18+
},
19+
});
20+
});
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { List } from 'immutable';
2+
import * as React from 'react';
3+
import { ThemesProvider } from './ThemesProvider';
4+
5+
export const withThemesProvider = (themes, CustomThemeProvider) => story => {
6+
return (
7+
<ThemesProvider
8+
themes={List(themes)}
9+
CustomThemeProvider={CustomThemeProvider}
10+
>
11+
{story()}
12+
</ThemesProvider>
13+
);
14+
};

packages/components/src/components/Select/index.tsx

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,12 @@ import { Text } from '../Text';
77
import { Element } from '../Element';
88

99
// Svg used for the icon
10-
const svg = () =>
11-
`"data:image/svg+xml,%3Csvg width='8' height='24' viewBox='0 0 8 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.00006 17L1 13L7 13L4.00006 17Z' fill='currentColor'/%3E%3Cpath d='M3.99994 7L7 11H1L3.99994 7Z' fill='currentColor'/%3E%3C/svg%3E%0A"`;
10+
const svg = color =>
11+
`"data:image/svg+xml,%3Csvg width='8' height='24' viewBox='0 0 8 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.00006 17L1 13L7 13L4.00006 17Z' fill='%23${
12+
color.split('#')[1]
13+
}'/%3E%3Cpath d='M3.99994 7L7 11H1L3.99994 7Z' fill='%23${
14+
color.split('#')[1]
15+
}'/%3E%3C/svg%3E%0A"`;
1216

1317
export const SelectComponent = styled.select<{ icon?: boolean }>(props =>
1418
css({
@@ -23,13 +27,15 @@ export const SelectComponent = styled.select<{ icon?: boolean }>(props =>
2327
borderColor: 'input.border',
2428
color: 'input.placeholderForeground',
2529
appearance: 'none',
26-
backgroundImage: `url(${svg})`,
30+
backgroundImage: `url(${svg(
31+
props.theme.colors.input.placeholderForeground
32+
)})`,
2733
backgroundPosition: 'calc(100% - 8px) center',
2834
backgroundRepeat: 'no-repeat',
2935

3036
':hover': {
31-
backgroundImage: `url(${svg})`,
3237
color: 'input.foreground',
38+
backgroundImage: `url(${svg(props.theme.colors.input.foreground)})`,
3339
},
3440
})
3541
);

0 commit comments

Comments
 (0)