Skip to content

Commit b8085fc

Browse files
First component for new package: Collapsible (codesandbox#3269)
* start * setup packages * update packages * add missing dep * try to fix build * readd test files * no duplication * fix jest * fix ts * ts * add np * small fixes * remove some ts-irgnore * fix rbg colors * fixed yarn * remove unsed deps * re add ts * load stories based on new storybook format as well * export theme from root * merge design language and vscode theme at top * add new globals? * move decorators to .storybook * Add collipsible * move theme out + use sidebar colors for globals? * bring back old globals too * add breakpoints to design language * change sidebar.foreground! to match design!! * add a polyfill layer * add todo to polyfil * just checking if chromatic works * oops need a build first * add comments on theme file * not sure why i made 2 files Co-authored-by: Sara Vieira <hey@iamsaravieira.com>
1 parent baf5d21 commit b8085fc

File tree

12 files changed

+221
-40
lines changed

12 files changed

+221
-40
lines changed

packages/common/src/components/Preference/PreferenceNumber.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
import React, { ChangeEvent, FunctionComponent, ComponentProps } from 'react';
1+
import React, { ChangeEvent, FunctionComponent } from 'react';
22

33
import { Input } from './elements';
44

55
type Props = {
66
setValue: (value: number) => void;
77
step?: number;
88
value: number;
9-
} & Pick<ComponentProps<typeof Input>, 'style'>;
9+
style?: React.CSSProperties;
10+
};
1011

1112
export const PreferenceNumber: FunctionComponent<Props> = ({
1213
setValue,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './theme';

packages/common/src/design-language/theme.ts

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ const theme = {
1212
// transition speeds in ms
1313
speeds: [0, '75ms', '100ms', '150ms', '200ms', '300ms', '500ms'],
1414

15+
// mobile first
16+
breakpoints: ['576px', '768px', '992px'],
17+
1518
radii: {
1619
small: 2,
1720
medium: 4,

packages/common/src/themes/codesandbox-black.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -206,9 +206,8 @@ const colors = {
206206
},
207207
sideBar: {
208208
background: tokens.grays[700],
209-
hoverBackground: tokens.green,
210209
border: tokens.grays[500],
211-
foreground: tokens.grays[300],
210+
foreground: tokens.grays[200],
212211
},
213212
sideBarSectionHeader: {
214213
background: tokens.grays[700],

packages/components/.storybook/config.tsx

+18-36
Original file line numberDiff line numberDiff line change
@@ -4,43 +4,39 @@ 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 { ThemeDecorator } from '../src/stories/decorators';
7+
import { ThemeDecorator } from './decorators';
88
import { createGlobalStyle } from 'styled-components';
99
import global from '@codesandbox/common/lib/global.css';
10+
import theme from './theme';
1011

1112
const viewports = {
1213
mobile: {
1314
name: 'Mobile',
14-
styles: {
15-
width: '375px',
16-
height: '667px',
17-
},
15+
styles: { width: '375px', height: '667px' },
1816
},
1917
tablet: {
2018
name: 'Tablet',
21-
styles: {
22-
width: '768px',
23-
height: '1024px',
24-
},
19+
styles: { width: '768px', height: '1024px' },
2520
},
2621
laptop: {
2722
name: 'Laptop',
28-
styles: {
29-
width: '1366px',
30-
height: '768px',
31-
},
23+
styles: { width: '1366px', height: '768px' },
3224
},
3325
desktop: {
3426
name: 'Desktop',
35-
styles: {
36-
width: '1920px',
37-
height: '1080px',
38-
},
27+
styles: { width: '1920px', height: '1080px' },
3928
},
4029
};
4130

31+
// new globals based on theme?
32+
// using sidebar as the styles for body for now 🤷
4233
const GlobalStyle = createGlobalStyle`
43-
${global}
34+
${global};
35+
body {
36+
font-family: 'Inter', sans-serif;
37+
background-color: ${theme.colors.sideBar.background};
38+
color: ${theme.colors.sideBar.foreground};
39+
}
4440
`;
4541

4642
export const withGlobal = cb => (
@@ -54,24 +50,10 @@ addDecorator(withA11y);
5450
addDecorator(withKnobs);
5551
addDecorator(withGlobal);
5652
addDecorator(ThemeDecorator);
57-
addParameters({
58-
viewport: {
59-
viewports,
60-
},
61-
});
53+
addParameters({ viewport: { viewports } });
6254

6355
// Option defaults.
64-
addParameters({
65-
options: {
66-
theme: themes.dark,
67-
},
68-
});
69-
70-
// automatically import all files ending in *.stories.tsx
71-
const req = require.context('../src', true, /.stories.tsx$/);
72-
73-
const loadStories = () => {
74-
req.keys().forEach(req);
75-
};
56+
addParameters({ options: { theme: themes.dark } });
7657

77-
configure(loadStories, module);
58+
// automatically import all files ending in *.stories.js
59+
configure(require.context('../src', true, /\.stories\.tsx$/), module);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import React from 'react';
2+
import theme from '../theme';
3+
import { ThemeProvider } from 'styled-components';
4+
5+
export const ThemeDecorator = (fn: () => JSX.Element) => (
6+
<ThemeProvider theme={theme}>{fn()}</ThemeProvider>
7+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './ThemeDecorator';
+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/**
2+
* There are 3 layers to our component styles.
3+
*
4+
* design language - spacing, fontsizes, radii, etc.
5+
* vscode theme - color tokens
6+
* polyfill - color tokens missing from vscode
7+
*/
8+
9+
import dot from 'dot-object';
10+
import deepmerge from 'deepmerge';
11+
12+
// Layer 1
13+
import designLanguage from '@codesandbox/common/lib/design-language';
14+
15+
// Layer 2
16+
// black is the default, it would be helpful to use storybook-addon-themes
17+
// to test our components across multiple themes
18+
import vsCodeTheme from '@codesandbox/common/lib/themes/codesandbox-black';
19+
20+
// Layer 3
21+
import polyfillTheme from '../src/utils/polyfill-theme';
22+
23+
// convert vscode colors to dot notation so that we can use them in tokens
24+
const vsCodeColors = dot.object({ ...vsCodeTheme.colors });
25+
26+
// Our interface does not map 1-1 with vscode.
27+
// To add styles that remain themeable, we add
28+
// some polyfills to the theme tokens.
29+
const polyfilledVSCodeColors = polyfillTheme(vsCodeColors);
30+
31+
// merge the design language and vscode theme
32+
const theme = deepmerge(designLanguage, { colors: polyfilledVSCodeColors });
33+
34+
export default theme;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
import { Collapsible } from '.';
3+
4+
export default {
5+
title: 'components/Collapsible',
6+
component: Collapsible,
7+
};
8+
9+
// replace the text inside with Text variants when available
10+
export const Basic = () => (
11+
<Collapsible title="Files">
12+
The move from Cerebral
13+
<br />
14+
This is a static template with no bundling
15+
</Collapsible>
16+
);
17+
18+
export const DefaultOpen = () => (
19+
<Collapsible title="Files" defaultOpen>
20+
The move from Cerebral
21+
<br />
22+
This is a static template with no bundling
23+
</Collapsible>
24+
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import React from 'react';
2+
import styled from 'styled-components';
3+
import css from '@styled-system/css';
4+
5+
export const Header = styled.div(
6+
css({
7+
display: 'flex',
8+
alignItems: 'center',
9+
height: '32px',
10+
paddingX: 3,
11+
borderBottom: '1px solid',
12+
// Note: sideBarSectionHeader exists but we dont use it because it is rarely implemented
13+
// in themes, so intentionally ignoring the declaration and using sidebar colors makes sense.
14+
borderColor: 'sideBar.border',
15+
cursor: 'pointer',
16+
':hover': {
17+
backgroundColor: 'sideBar.hoverBackground',
18+
svg: {
19+
// TODO: this should come from somewhere else - text muted maybe?
20+
color: 'grays.300',
21+
},
22+
},
23+
})
24+
);
25+
26+
// temporary: replace with <Text variant="strong">
27+
export const Title = styled.div(
28+
css({
29+
fontSize: 3,
30+
fontWeight: 'semibold',
31+
})
32+
);
33+
34+
// temporary: replace with <Icon name="triangle/toggle">
35+
export const Icon = styled.svg<{
36+
open?: boolean;
37+
}>(props =>
38+
css({
39+
marginRight: 2,
40+
transform: props.open ? 'rotate(0)' : 'rotate(-90deg)',
41+
color: 'grays.400',
42+
})
43+
);
44+
45+
export const Body = styled.div(
46+
css({
47+
borderBottom: '1px solid',
48+
borderColor: 'sideBar.border',
49+
paddingTop: 4,
50+
paddingBottom: 8,
51+
})
52+
);
53+
54+
const ToggleIcon = props => (
55+
<Icon
56+
width="9"
57+
height="6"
58+
viewBox="0 0 9 6"
59+
xmlns="http://www.w3.org/2000/svg"
60+
{...props}
61+
>
62+
<path
63+
d="M4.50009 6L-5.24537e-07 1.26364e-06L9 4.76837e-07L4.50009 6Z"
64+
fill="currentcolor"
65+
/>
66+
</Icon>
67+
);
68+
69+
interface ICollapsibleProps {
70+
defaultOpen?: boolean;
71+
title: string;
72+
}
73+
74+
export const Collapsible: React.FC<ICollapsibleProps> = ({
75+
defaultOpen,
76+
title,
77+
children,
78+
...props
79+
}) => {
80+
const [open, setOpen] = React.useState(defaultOpen || false);
81+
const toggle = () => setOpen(!open);
82+
83+
return (
84+
<section {...props}>
85+
<Header onClick={toggle}>
86+
<ToggleIcon open={open} />
87+
<Title>{title}</Title>
88+
</Header>
89+
{open ? <Body>{children}</Body> : null}
90+
</section>
91+
);
92+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Our interface does not map 1-1 with vscode
3+
* To add styles that remain themeable, we add
4+
* some _polyfills_ to the theme tokens.
5+
* These are mapped to existing variables from the vscode theme
6+
* that always exists - editor, sidebar.
7+
*/
8+
9+
import deepmerge from 'deepmerge';
10+
11+
// TODO: For themes that we officially support, we have the option
12+
// to modify the theme and add our custom keys
13+
// which we can use when the polyfill is a bad alternate.
14+
// In that case, we should check if it exists before overriding it
15+
const polyfillTheme = vsCodeTheme =>
16+
deepmerge(vsCodeTheme, {
17+
sideBar: {
18+
hoverBackground: vsCodeTheme.sideBar.border,
19+
},
20+
});
21+
22+
export default polyfillTheme;

yarn.lock

+15
Original file line numberDiff line numberDiff line change
@@ -20332,6 +20332,21 @@ meow@^5.0.0:
2033220332
trim-newlines "^2.0.0"
2033320333
yargs-parser "^10.0.0"
2033420334

20335+
meow@^5.0.0:
20336+
version "5.0.0"
20337+
resolved "https://registry.yarnpkg.com/meow/-/meow-5.0.0.tgz#dfc73d63a9afc714a5e371760eb5c88b91078aa4"
20338+
integrity sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==
20339+
dependencies:
20340+
camelcase-keys "^4.0.0"
20341+
decamelize-keys "^1.0.0"
20342+
loud-rejection "^1.0.0"
20343+
minimist-options "^3.0.1"
20344+
normalize-package-data "^2.3.4"
20345+
read-pkg-up "^3.0.0"
20346+
redent "^2.0.0"
20347+
trim-newlines "^2.0.0"
20348+
yargs-parser "^10.0.0"
20349+
2033520350
merge-anything@^2.2.4:
2033620351
version "2.4.0"
2033720352
resolved "https://registry.yarnpkg.com/merge-anything/-/merge-anything-2.4.0.tgz#86959caf02bb8969d1ae5e1b652862bc5fe54e44"

0 commit comments

Comments
 (0)