Skip to content

Commit a23a249

Browse files
committed
setup storybook
1 parent e15f0af commit a23a249

24 files changed

+10934
-3
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ pnpm-debug.log*
88
lerna-debug.log*
99

1010
node_modules
11-
dist
1211
dist-ssr
1312
*.local
1413

.storybook/main.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module.exports = {
2+
"stories": [
3+
"../src/**/*.stories.mdx",
4+
"../src/**/*.stories.@(js|jsx|ts|tsx)"
5+
],
6+
"addons": [
7+
"@storybook/addon-links",
8+
"@storybook/addon-essentials",
9+
"@storybook/addon-interactions"
10+
],
11+
"framework": "@storybook/react",
12+
"core": {
13+
"builder": "@storybook/builder-vite"
14+
},
15+
"features": {
16+
"storyStoreV7": true
17+
}
18+
}

.storybook/preview-head.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<script>
2+
window.global = window;
3+
</script>

.storybook/preview.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export const parameters = {
2+
actions: { argTypesRegex: "^on[A-Z].*" },
3+
controls: {
4+
matchers: {
5+
color: /(background|color)$/i,
6+
date: /Date$/,
7+
},
8+
},
9+
}

package.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,27 @@
55
"scripts": {
66
"dev": "vite",
77
"build": "vite build",
8-
"preview": "vite preview"
8+
"preview": "vite preview",
9+
"storybook": "start-storybook -p 6006",
10+
"build-storybook": "build-storybook"
911
},
1012
"dependencies": {
1113
"react": "^18.0.0",
1214
"react-dom": "^18.0.0"
1315
},
1416
"devDependencies": {
17+
"@babel/core": "^7.18.2",
18+
"@storybook/addon-actions": "^6.5.6",
19+
"@storybook/addon-essentials": "^6.5.6",
20+
"@storybook/addon-interactions": "^6.5.6",
21+
"@storybook/addon-links": "^6.5.6",
22+
"@storybook/builder-vite": "^0.1.35",
23+
"@storybook/react": "^6.5.6",
24+
"@storybook/testing-library": "^0.0.11",
1525
"@types/react": "^18.0.0",
1626
"@types/react-dom": "^18.0.0",
1727
"@vitejs/plugin-react": "^1.3.0",
28+
"babel-loader": "^8.2.5",
1829
"vite": "^2.9.9"
1930
}
20-
}
31+
}

src/stories/Button.jsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
import './button.css';
4+
5+
/**
6+
* Primary UI component for user interaction
7+
*/
8+
export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
9+
const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
10+
return (
11+
<button
12+
type="button"
13+
className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
14+
style={backgroundColor && { backgroundColor }}
15+
{...props}
16+
>
17+
{label}
18+
</button>
19+
);
20+
};
21+
22+
Button.propTypes = {
23+
/**
24+
* Is this the principal call to action on the page?
25+
*/
26+
primary: PropTypes.bool,
27+
/**
28+
* What background color to use
29+
*/
30+
backgroundColor: PropTypes.string,
31+
/**
32+
* How large should the button be?
33+
*/
34+
size: PropTypes.oneOf(['small', 'medium', 'large']),
35+
/**
36+
* Button contents
37+
*/
38+
label: PropTypes.string.isRequired,
39+
/**
40+
* Optional click handler
41+
*/
42+
onClick: PropTypes.func,
43+
};
44+
45+
Button.defaultProps = {
46+
backgroundColor: null,
47+
primary: false,
48+
size: 'medium',
49+
onClick: undefined,
50+
};

src/stories/Button.stories.jsx

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import React from 'react';
2+
3+
import { Button } from './Button';
4+
5+
// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export
6+
export default {
7+
title: 'Example/Button',
8+
component: Button,
9+
// More on argTypes: https://storybook.js.org/docs/react/api/argtypes
10+
argTypes: {
11+
backgroundColor: { control: 'color' },
12+
},
13+
};
14+
15+
// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args
16+
const Template = (args) => <Button {...args} />;
17+
18+
export const Primary = Template.bind({});
19+
// More on args: https://storybook.js.org/docs/react/writing-stories/args
20+
Primary.args = {
21+
primary: true,
22+
label: 'Button',
23+
};
24+
25+
export const Secondary = Template.bind({});
26+
Secondary.args = {
27+
label: 'Button',
28+
};
29+
30+
export const Large = Template.bind({});
31+
Large.args = {
32+
size: 'large',
33+
label: 'Button',
34+
};
35+
36+
export const Small = Template.bind({});
37+
Small.args = {
38+
size: 'small',
39+
label: 'Button',
40+
};

src/stories/Header.jsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
import { Button } from './Button';
5+
import './header.css';
6+
7+
export const Header = ({ user, onLogin, onLogout, onCreateAccount }) => (
8+
<header>
9+
<div className="wrapper">
10+
<div>
11+
<svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
12+
<g fill="none" fillRule="evenodd">
13+
<path
14+
d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
15+
fill="#FFF"
16+
/>
17+
<path
18+
d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
19+
fill="#555AB9"
20+
/>
21+
<path
22+
d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z"
23+
fill="#91BAF8"
24+
/>
25+
</g>
26+
</svg>
27+
<h1>Acme</h1>
28+
</div>
29+
<div>
30+
{user ? (
31+
<>
32+
<span className="welcome">
33+
Welcome, <b>{user.name}</b>!
34+
</span>
35+
<Button size="small" onClick={onLogout} label="Log out" />
36+
</>
37+
) : (
38+
<>
39+
<Button size="small" onClick={onLogin} label="Log in" />
40+
<Button primary size="small" onClick={onCreateAccount} label="Sign up" />
41+
</>
42+
)}
43+
</div>
44+
</div>
45+
</header>
46+
);
47+
48+
Header.propTypes = {
49+
user: PropTypes.shape({}),
50+
onLogin: PropTypes.func.isRequired,
51+
onLogout: PropTypes.func.isRequired,
52+
onCreateAccount: PropTypes.func.isRequired,
53+
};
54+
55+
Header.defaultProps = {
56+
user: null,
57+
};

src/stories/Header.stories.jsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import React from 'react';
2+
3+
import { Header } from './Header';
4+
5+
export default {
6+
title: 'Example/Header',
7+
component: Header,
8+
parameters: {
9+
// More on Story layout: https://storybook.js.org/docs/react/configure/story-layout
10+
layout: 'fullscreen',
11+
},
12+
};
13+
14+
const Template = (args) => <Header {...args} />;
15+
16+
export const LoggedIn = Template.bind({});
17+
LoggedIn.args = {
18+
user: {
19+
name: 'Jane Doe',
20+
},
21+
};
22+
23+
export const LoggedOut = Template.bind({});
24+
LoggedOut.args = {};

0 commit comments

Comments
 (0)