@storybook/preact 7.0.0-alpha.45 → 7.0.0-alpha.47

Sign up to get free protection for your applications and to get access to all the features.
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{b as t}from"./chunk-VVPUC5MQ.mjs";import s from"global";var{window:n}=s;n&&(n.STORYBOOK_ENV="preact");import{start as a}from"@storybook/core-client";var i="preact",r=a(t),y=(o,p)=>r.clientApi.storiesOf(o,p).addParameters({framework:i}),c=(...o)=>r.configure(i,...o),f=r.forceReRender,l=r.clientApi.raw;module?.hot?.decline();export{c as configure,f as forceReRender,l as raw,y as storiesOf};
1
+ import{b as t}from"./chunk-VVPUC5MQ.mjs";import i from"global";var{window:n}=i;n&&(n.STORYBOOK_ENV="preact");import{start as a}from"@storybook/core-client";var p="preact",r=a(t),m=(o,s)=>r.clientApi.storiesOf(o,s).addParameters({framework:p}),c=(...o)=>r.configure(p,...o),f=r.forceReRender,l=r.clientApi.raw;module?.hot?.decline();export{c as configure,f as forceReRender,l as raw,m as storiesOf};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@storybook/preact",
3
- "version": "7.0.0-alpha.45",
3
+ "version": "7.0.0-alpha.47",
4
4
  "description": "Storybook Preact renderer",
5
5
  "keywords": [
6
6
  "storybook"
@@ -41,6 +41,7 @@
41
41
  "types": "dist/index.d.ts",
42
42
  "files": [
43
43
  "dist/**/*",
44
+ "template/**/*",
44
45
  "README.md",
45
46
  "*.js",
46
47
  "*.d.ts"
@@ -50,10 +51,10 @@
50
51
  "prep": "../../../scripts/prepare/bundle.ts"
51
52
  },
52
53
  "dependencies": {
53
- "@storybook/addons": "7.0.0-alpha.45",
54
- "@storybook/core-client": "7.0.0-alpha.45",
55
- "@storybook/store": "7.0.0-alpha.45",
56
- "@storybook/types": "7.0.0-alpha.45",
54
+ "@storybook/addons": "7.0.0-alpha.47",
55
+ "@storybook/core-client": "7.0.0-alpha.47",
56
+ "@storybook/store": "7.0.0-alpha.47",
57
+ "@storybook/types": "7.0.0-alpha.47",
57
58
  "global": "^4.4.0",
58
59
  "react": "16.14.0",
59
60
  "react-dom": "16.14.0",
@@ -79,5 +80,5 @@
79
80
  ],
80
81
  "platform": "browser"
81
82
  },
82
- "gitHead": "3ef14366115c56c1d45c0359ff681cc47ed50532"
83
+ "gitHead": "1c706a4a778831e012343c905f86225fa71491a7"
83
84
  }
@@ -0,0 +1,7 @@
1
+ {
2
+ "rules": {
3
+ "import/extensions": "off",
4
+ "react/react-in-jsx-scope": "off",
5
+ "import/no-extraneous-dependencies": "off"
6
+ }
7
+ }
@@ -0,0 +1,49 @@
1
+ import PropTypes from 'prop-types';
2
+ import './button.css';
3
+
4
+ /**
5
+ * Primary UI component for user interaction
6
+ */
7
+ export const Button = ({ primary, backgroundColor, size, label, ...props }) => {
8
+ const mode = primary ? 'storybook-button--primary' : 'storybook-button--secondary';
9
+ return (
10
+ <button
11
+ type="button"
12
+ className={['storybook-button', `storybook-button--${size}`, mode].join(' ')}
13
+ style={backgroundColor && { backgroundColor }}
14
+ {...props}
15
+ >
16
+ {label}
17
+ </button>
18
+ );
19
+ };
20
+
21
+ Button.propTypes = {
22
+ /**
23
+ * Is this the principal call to action on the page?
24
+ */
25
+ primary: PropTypes.bool,
26
+ /**
27
+ * What background color to use
28
+ */
29
+ backgroundColor: PropTypes.string,
30
+ /**
31
+ * How large should the button be?
32
+ */
33
+ size: PropTypes.oneOf(['small', 'medium', 'large']),
34
+ /**
35
+ * Button contents
36
+ */
37
+ label: PropTypes.string.isRequired,
38
+ /**
39
+ * Optional click handler
40
+ */
41
+ onClick: PropTypes.func,
42
+ };
43
+
44
+ Button.defaultProps = {
45
+ backgroundColor: null,
46
+ primary: false,
47
+ size: 'medium',
48
+ onClick: undefined,
49
+ };
@@ -0,0 +1,40 @@
1
+ import { Button } from './Button';
2
+
3
+ // More on default export: https://storybook.js.org/docs/preact/writing-stories/introduction#default-export
4
+ export default {
5
+ title: 'Example/Button',
6
+ component: Button,
7
+ // More on argTypes: https://storybook.js.org/docs/preact/api/argtypes
8
+ argTypes: {
9
+ backgroundColor: { control: 'color' },
10
+ onClick: { action: 'onClick' },
11
+ },
12
+ };
13
+
14
+ // More on component templates: https://storybook.js.org/docs/preact/writing-stories/introduction#using-args
15
+ export const Primary = {
16
+ args: {
17
+ primary: true,
18
+ label: 'Button',
19
+ },
20
+ };
21
+
22
+ export const Secondary = {
23
+ args: {
24
+ label: 'Button',
25
+ },
26
+ };
27
+
28
+ export const Large = {
29
+ args: {
30
+ size: 'large',
31
+ label: 'Button',
32
+ },
33
+ };
34
+
35
+ export const Small = {
36
+ args: {
37
+ size: 'small',
38
+ label: 'Button',
39
+ },
40
+ };
@@ -0,0 +1,58 @@
1
+ import PropTypes from 'prop-types';
2
+
3
+ import { Button } from './Button';
4
+ import './header.css';
5
+
6
+ export const Header = ({ user, onLogin, onLogout, onCreateAccount }) => (
7
+ <header>
8
+ <div className="wrapper">
9
+ <div>
10
+ <svg width="32" height="32" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg">
11
+ <g fill="none" fillRule="evenodd">
12
+ <path
13
+ d="M10 0h12a10 10 0 0110 10v12a10 10 0 01-10 10H10A10 10 0 010 22V10A10 10 0 0110 0z"
14
+ fill="#FFF"
15
+ />
16
+ <path
17
+ d="M5.3 10.6l10.4 6v11.1l-10.4-6v-11zm11.4-6.2l9.7 5.5-9.7 5.6V4.4z"
18
+ fill="#555AB9"
19
+ />
20
+ <path
21
+ d="M27.2 10.6v11.2l-10.5 6V16.5l10.5-6zM15.7 4.4v11L6 10l9.7-5.5z"
22
+ fill="#91BAF8"
23
+ />
24
+ </g>
25
+ </svg>
26
+ <h1>Acme</h1>
27
+ </div>
28
+ <div>
29
+ {user ? (
30
+ <>
31
+ <span className="welcome">
32
+ Welcome, <b>{user.name}</b>!
33
+ </span>
34
+ <Button size="small" onClick={onLogout} label="Log out" />
35
+ </>
36
+ ) : (
37
+ <>
38
+ <Button size="small" onClick={onLogin} label="Log in" />
39
+ <Button primary size="small" onClick={onCreateAccount} label="Sign up" />
40
+ </>
41
+ )}
42
+ </div>
43
+ </div>
44
+ </header>
45
+ );
46
+
47
+ Header.propTypes = {
48
+ user: PropTypes.shape({
49
+ name: PropTypes.string.isRequired,
50
+ }),
51
+ onLogin: PropTypes.func.isRequired,
52
+ onLogout: PropTypes.func.isRequired,
53
+ onCreateAccount: PropTypes.func.isRequired,
54
+ };
55
+
56
+ Header.defaultProps = {
57
+ user: null,
58
+ };
@@ -0,0 +1,25 @@
1
+ import { Header } from './Header';
2
+
3
+ export default {
4
+ title: 'Example/Header',
5
+ component: Header,
6
+ parameters: {
7
+ // More on Story layout: https://storybook.js.org/docs/preact/configure/story-layout
8
+ layout: 'fullscreen',
9
+ },
10
+ argTypes: {
11
+ onLogin: { action: 'onLogin' },
12
+ onLogout: { action: 'onLogout' },
13
+ onCreateAccount: { action: 'onCreateAccount' },
14
+ },
15
+ };
16
+
17
+ export const LoggedIn = {
18
+ args: {
19
+ user: {
20
+ name: 'Jane Doe',
21
+ },
22
+ },
23
+ };
24
+
25
+ export const LoggedOut = {};
@@ -0,0 +1,68 @@
1
+ import { useState } from 'preact/hooks';
2
+ import { Header } from './Header';
3
+ import './page.css';
4
+
5
+ export const Page = () => {
6
+ const [user, setUser] = useState();
7
+
8
+ return (
9
+ <article>
10
+ <Header
11
+ user={user}
12
+ onLogin={() => setUser({ name: 'Jane Doe' })}
13
+ onLogout={() => setUser(undefined)}
14
+ onCreateAccount={() => setUser({ name: 'Jane Doe' })}
15
+ />
16
+
17
+ <section>
18
+ <h2>Pages in Storybook</h2>
19
+ <p>
20
+ We recommend building UIs with a{' '}
21
+ <a href="https://componentdriven.org" target="_blank" rel="noopener noreferrer">
22
+ <strong>component-driven</strong>
23
+ </a>{' '}
24
+ process starting with atomic components and ending with pages.
25
+ </p>
26
+ <p>
27
+ Render pages with mock data. This makes it easy to build and review page states without
28
+ needing to navigate to them in your app. Here are some handy patterns for managing page
29
+ data in Storybook:
30
+ </p>
31
+ <ul>
32
+ <li>
33
+ Use a higher-level connected component. Storybook helps you compose such data from the
34
+ "args" of child component stories
35
+ </li>
36
+ <li>
37
+ Assemble data in the page component from your services. You can mock these services out
38
+ using Storybook.
39
+ </li>
40
+ </ul>
41
+ <p>
42
+ Get a guided tutorial on component-driven development at{' '}
43
+ <a href="https://storybook.js.org/tutorials/" target="_blank" rel="noopener noreferrer">
44
+ Storybook tutorials
45
+ </a>
46
+ . Read more in the{' '}
47
+ <a href="https://storybook.js.org/docs" target="_blank" rel="noopener noreferrer">
48
+ docs
49
+ </a>
50
+ .
51
+ </p>
52
+ <div className="tip-wrapper">
53
+ <span className="tip">Tip</span> Adjust the width of the canvas with the{' '}
54
+ <svg width="10" height="10" viewBox="0 0 12 12" xmlns="http://www.w3.org/2000/svg">
55
+ <g fill="none" fillRule="evenodd">
56
+ <path
57
+ d="M1.5 5.2h4.8c.3 0 .5.2.5.4v5.1c-.1.2-.3.3-.4.3H1.4a.5.5 0 01-.5-.4V5.7c0-.3.2-.5.5-.5zm0-2.1h6.9c.3 0 .5.2.5.4v7a.5.5 0 01-1 0V4H1.5a.5.5 0 010-1zm0-2.1h9c.3 0 .5.2.5.4v9.1a.5.5 0 01-1 0V2H1.5a.5.5 0 010-1zm4.3 5.2H2V10h3.8V6.2z"
58
+ id="a"
59
+ fill="#999"
60
+ />
61
+ </g>
62
+ </svg>
63
+ Viewports addon in the toolbar
64
+ </div>
65
+ </section>
66
+ </article>
67
+ );
68
+ };
@@ -0,0 +1,25 @@
1
+ import { within, userEvent } from '@storybook/testing-library';
2
+
3
+ import { Page } from './Page';
4
+
5
+ export default {
6
+ title: 'Example/Page',
7
+ component: Page,
8
+ parameters: {
9
+ // More on Story layout: https://storybook.js.org/docs/preact/configure/story-layout
10
+ layout: 'fullscreen',
11
+ },
12
+ };
13
+
14
+ export const LoggedOut = {};
15
+
16
+ // More on interaction testing: https://storybook.js.org/docs/preact/writing-tests/interaction-testing
17
+ export const LoggedIn = {
18
+ play: async ({ canvasElement }) => {
19
+ const canvas = within(canvasElement);
20
+ const loginButton = await canvas.getByRole('button', {
21
+ name: /Log in/i,
22
+ });
23
+ await userEvent.click(loginButton);
24
+ },
25
+ };
@@ -0,0 +1,14 @@
1
+ /* eslint-disable react/react-in-jsx-scope */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import PropTypes from 'prop-types';
4
+
5
+ export const Button = ({ onClick, label }) => (
6
+ <button type="button" onClick={onClick}>
7
+ {label}
8
+ </button>
9
+ );
10
+
11
+ Button.propTypes = {
12
+ onClick: PropTypes.func.isRequired,
13
+ label: PropTypes.node.isRequired,
14
+ };
@@ -0,0 +1,38 @@
1
+ /* eslint-disable react/react-in-jsx-scope */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import PropTypes from 'prop-types';
4
+ import { useState } from 'preact/hooks';
5
+
6
+ export const Form = ({ onSuccess }) => {
7
+ const [value, setValue] = useState('');
8
+ const [complete, setComplete] = useState(false);
9
+
10
+ function onSubmit(event) {
11
+ event.preventDefault();
12
+ onSuccess(value);
13
+
14
+ setTimeout(() => setComplete(true), 500);
15
+ setTimeout(() => setComplete(false), 1500);
16
+ }
17
+
18
+ return (
19
+ <form id="interaction-test-form" onSubmit={onSubmit}>
20
+ <label>
21
+ Enter Value
22
+ <input
23
+ type="text"
24
+ data-testid="value"
25
+ value={value}
26
+ required
27
+ onChange={(event) => setValue(event.target.value)}
28
+ />
29
+ </label>
30
+ <button type="submit">Submit</button>
31
+ {complete && <p>Completed!!</p>}
32
+ </form>
33
+ );
34
+ };
35
+
36
+ Form.propTypes = {
37
+ onSuccess: PropTypes.func.isRequired,
38
+ };
@@ -0,0 +1,10 @@
1
+ /* eslint-disable react/react-in-jsx-scope */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import PropTypes from 'prop-types';
4
+
5
+ // eslint-disable-next-line react/no-danger
6
+ export const Html = ({ content }) => <div dangerouslySetInnerHTML={{ __html: content }} />;
7
+
8
+ Html.propTypes = {
9
+ content: PropTypes.string.isRequired,
10
+ };
@@ -0,0 +1,21 @@
1
+ /* eslint-disable react/react-in-jsx-scope */
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import PropTypes from 'prop-types';
4
+
5
+ export const Pre = ({ style, object, text }) => (
6
+ <pre style={style} data-testid="pre">
7
+ {object ? JSON.stringify(object, null, 2) : text}
8
+ </pre>
9
+ );
10
+
11
+ Pre.propTypes = {
12
+ style: PropTypes.shape({}),
13
+ object: PropTypes.shape({}),
14
+ text: PropTypes.string,
15
+ };
16
+
17
+ Pre.defaultProps = {
18
+ style: {},
19
+ object: null,
20
+ text: '',
21
+ };
@@ -0,0 +1,9 @@
1
+ import globalThis from 'global';
2
+
3
+ import { Button } from './Button.jsx';
4
+ import { Pre } from './Pre.jsx';
5
+ import { Form } from './Form.jsx';
6
+ import { Html } from './Html.jsx';
7
+
8
+ globalThis.Components = { Button, Pre, Form, Html };
9
+ globalThis.storybookRenderer = 'preact';
@@ -0,0 +1,50 @@
1
+ import React from 'react';
2
+ // eslint-disable-next-line import/no-extraneous-dependencies
3
+ import PropTypes from 'prop-types';
4
+
5
+ export const ReactFunctionalComponent = ({ label }) => {
6
+ const [clicks, setValue] = React.useState(0);
7
+ return (
8
+ <div
9
+ tabIndex={0}
10
+ onClick={() => setValue(clicks + 1)}
11
+ style={{ cursor: 'pointer' }}
12
+ onKeyDown={() => undefined}
13
+ role="button"
14
+ >
15
+ <div style={{ color: 'red' }}>{label}</div>
16
+ <div>Clicked {clicks} times.</div>
17
+ </div>
18
+ );
19
+ };
20
+
21
+ ReactFunctionalComponent.propTypes = {
22
+ label: PropTypes.string.isRequired,
23
+ };
24
+
25
+ export class ReactClassComponent extends React.Component {
26
+ state = {
27
+ clicks: 0,
28
+ };
29
+
30
+ render() {
31
+ const { label } = this.props;
32
+ const { clicks } = this.state;
33
+ return (
34
+ <div
35
+ tabIndex={0}
36
+ onClick={() => this.setState({ clicks: clicks + 1 })}
37
+ onKeyDown={() => undefined}
38
+ style={{ cursor: 'pointer' }}
39
+ role="button"
40
+ >
41
+ <div style={{ color: 'green' }}>{label}</div>
42
+ <div>Clicked {clicks} times.</div>
43
+ </div>
44
+ );
45
+ }
46
+ }
47
+
48
+ ReactClassComponent.propTypes = {
49
+ label: PropTypes.string.isRequired,
50
+ };
@@ -0,0 +1,15 @@
1
+ /* eslint-disable react/react-in-jsx-scope */
2
+ import { ReactFunctionalComponent, ReactClassComponent } from './React';
3
+
4
+ export default {
5
+ component: ReactFunctionalComponent,
6
+ };
7
+
8
+ export const ReactComponentDemo = () => (
9
+ <div>
10
+ <h1>React component demo</h1>
11
+ <ReactFunctionalComponent label="This is a React functional component rendered by Preact" />
12
+ <hr />
13
+ <ReactClassComponent label="This is a React class component rendered by Preact" />
14
+ </div>
15
+ );