From 7bc2cfc0673d542348c371fff4c735d5a58f7b07 Mon Sep 17 00:00:00 2001 From: Yann Braga Date: Wed, 26 Jan 2022 21:19:36 +0100 Subject: [PATCH] wip: add interactions to cli template --- examples/cra-ts-essentials/.storybook/main.js | 4 + .../cra-ts-essentials/.storybook/preview.js | 1 - .../stories/cli-templates/Button.stories.tsx | 41 ++++++++++ .../src/stories/cli-templates/Button.tsx | 48 ++++++++++++ .../stories/cli-templates/Header.stories.tsx | 24 ++++++ .../src/stories/cli-templates/Header.tsx | 53 +++++++++++++ .../stories/cli-templates/Page.stories.tsx | 24 ++++++ .../src/stories/cli-templates/Page.tsx | 74 +++++++++++++++++++ .../src/stories/cli-templates/button.css | 30 ++++++++ .../src/stories/cli-templates/header.css | 26 +++++++ .../src/stories/cli-templates/page.css | 69 +++++++++++++++++ 11 files changed, 393 insertions(+), 1 deletion(-) create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Button.stories.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Button.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Header.stories.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Header.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Page.stories.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/Page.tsx create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/button.css create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/header.css create mode 100644 examples/cra-ts-essentials/src/stories/cli-templates/page.css diff --git a/examples/cra-ts-essentials/.storybook/main.js b/examples/cra-ts-essentials/.storybook/main.js index 2ddcf7a8e5be..5df76a33bb17 100644 --- a/examples/cra-ts-essentials/.storybook/main.js +++ b/examples/cra-ts-essentials/.storybook/main.js @@ -11,6 +11,7 @@ module.exports = { viewport: false, }, }, + '@storybook/addon-interactions', ], logLevel: 'debug', webpackFinal: (config) => { @@ -25,5 +26,8 @@ module.exports = { core: { builder: 'webpack4', }, + features: { + interactionsDebugger: true + }, staticDirs: ['../public'], }; diff --git a/examples/cra-ts-essentials/.storybook/preview.js b/examples/cra-ts-essentials/.storybook/preview.js index 305c8eb0be14..6d714095bcb6 100644 --- a/examples/cra-ts-essentials/.storybook/preview.js +++ b/examples/cra-ts-essentials/.storybook/preview.js @@ -3,7 +3,6 @@ import React from 'react'; export const decorators = [ (StoryFn, { globals: { locale = 'en' } }) => ( <> -
{locale}
), diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/Button.stories.tsx b/examples/cra-ts-essentials/src/stories/cli-templates/Button.stories.tsx new file mode 100644 index 000000000000..a1fcbf23bef0 --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/Button.stories.tsx @@ -0,0 +1,41 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { Button } from './Button'; + +// More on default export: https://storybook.js.org/docs/react/writing-stories/introduction#default-export +export default { + title: 'CLI Template/Button', + component: Button, + // More on argTypes: https://storybook.js.org/docs/react/api/argtypes + argTypes: { + backgroundColor: { control: 'color' }, + }, +} as ComponentMeta; + +// More on component templates: https://storybook.js.org/docs/react/writing-stories/introduction#using-args +const Template: ComponentStory = (args) => + ); +}; diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/Header.stories.tsx b/examples/cra-ts-essentials/src/stories/cli-templates/Header.stories.tsx new file mode 100644 index 000000000000..ad92f7e3f1b8 --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/Header.stories.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; + +import { Header } from './Header'; + +export default { + title: 'CLI Template/Header', + component: Header, + parameters: { + layout: 'fullscreen', + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) =>
; + +export const LoggedIn = Template.bind({}); +LoggedIn.args = { + user: { + name: 'Jane Doe', + }, +}; + +export const LoggedOut = Template.bind({}); +LoggedOut.args = {}; diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/Header.tsx b/examples/cra-ts-essentials/src/stories/cli-templates/Header.tsx new file mode 100644 index 000000000000..a52c1617ff3a --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/Header.tsx @@ -0,0 +1,53 @@ +import React from 'react'; + +import { Button } from './Button'; +import './header.css'; + +type User = { + name: string; +}; + +interface HeaderProps { + user?: User; + isLoggedIn?: boolean; + onLogin: () => void; + onLogout: () => void; + onCreateAccount: () => void; +} + +export const Header = ({ user, isLoggedIn, onLogin, onLogout, onCreateAccount }: HeaderProps) => ( +
+
+
+ + + + + + + +

Acme

+
+
+ {user && Hello, {user.name}!} + {isLoggedIn ? ( +
+
+
+); diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/Page.stories.tsx b/examples/cra-ts-essentials/src/stories/cli-templates/Page.stories.tsx new file mode 100644 index 000000000000..fcc993628311 --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/Page.stories.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import { ComponentStory, ComponentMeta } from '@storybook/react'; +import { within, userEvent } from '@storybook/testing-library'; +import { Page } from './Page'; + +export default { + title: 'CLI Template/Page', + component: Page, + parameters: { + layout: 'fullscreen', + }, +} as ComponentMeta; + +const Template: ComponentStory = (args) => ; + +export const LoggedOut = Template.bind({}); + +export const LoggedIn = Template.bind({}); + +LoggedIn.play = async ({ canvasElement }: any) => { + const canvas = within(canvasElement); + const loginButton = await canvas.getByRole('button', { name: /Log in/i }); + await userEvent.click(loginButton); +}; diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/Page.tsx b/examples/cra-ts-essentials/src/stories/cli-templates/Page.tsx new file mode 100644 index 000000000000..c2d8c7c85d3d --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/Page.tsx @@ -0,0 +1,74 @@ +import React from 'react'; + +import { Header } from './Header'; +import './page.css'; + +type User = { + name: string; +}; + +export const Page: React.VFC = () => { + const [user, setUser] = React.useState(); + + return ( +
+
setUser({ name: 'Jane Doe' })} + onLogout={() => setUser(undefined)} + onCreateAccount={() => setUser({ name: 'Jane Doe' })} + /> + +
+

Pages in Storybook

+

+ We recommend building UIs with a{' '} + + component-driven + {' '} + process starting with atomic components and ending with pages. +

+

+ Render pages with mock data. This makes it easy to build and review page states without + needing to navigate to them in your app. Here are some handy patterns for managing page + data in Storybook: +

+
    +
  • + Use a higher-level connected component. Storybook helps you compose such data from the + "args" of child component stories +
  • +
  • + Assemble data in the page component from your services. You can mock these services out + using Storybook. +
  • +
+

+ Get a guided tutorial on component-driven development at{' '} + + Storybook tutorials + + . Read more in the{' '} + + docs + + . +

+
+ Tip Adjust the width of the canvas with the{' '} + + + + + + Viewports addon in the toolbar +
+
+
+ ); +}; diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/button.css b/examples/cra-ts-essentials/src/stories/cli-templates/button.css new file mode 100644 index 000000000000..dc91dc76370b --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/button.css @@ -0,0 +1,30 @@ +.storybook-button { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-weight: 700; + border: 0; + border-radius: 3em; + cursor: pointer; + display: inline-block; + line-height: 1; +} +.storybook-button--primary { + color: white; + background-color: #1ea7fd; +} +.storybook-button--secondary { + color: #333; + background-color: transparent; + box-shadow: rgba(0, 0, 0, 0.15) 0px 0px 0px 1px inset; +} +.storybook-button--small { + font-size: 12px; + padding: 10px 16px; +} +.storybook-button--medium { + font-size: 14px; + padding: 11px 20px; +} +.storybook-button--large { + font-size: 16px; + padding: 12px 24px; +} diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/header.css b/examples/cra-ts-essentials/src/stories/cli-templates/header.css new file mode 100644 index 000000000000..acadc9ec8c7f --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/header.css @@ -0,0 +1,26 @@ +.wrapper { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + padding: 15px 20px; + display: flex; + align-items: center; + justify-content: space-between; +} + +svg { + display: inline-block; + vertical-align: top; +} + +h1 { + font-weight: 900; + font-size: 20px; + line-height: 1; + margin: 6px 0 6px 10px; + display: inline-block; + vertical-align: top; +} + +button + button { + margin-left: 10px; +} diff --git a/examples/cra-ts-essentials/src/stories/cli-templates/page.css b/examples/cra-ts-essentials/src/stories/cli-templates/page.css new file mode 100644 index 000000000000..fbc32aea2e0f --- /dev/null +++ b/examples/cra-ts-essentials/src/stories/cli-templates/page.css @@ -0,0 +1,69 @@ +section { + font-family: 'Nunito Sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; + font-size: 14px; + line-height: 24px; + padding: 48px 20px; + margin: 0 auto; + max-width: 600px; + color: #333; +} + +section h2 { + font-weight: 900; + font-size: 32px; + line-height: 1; + margin: 0 0 4px; + display: inline-block; + vertical-align: top; +} + +section p { + margin: 1em 0; +} + +section a { + text-decoration: none; + color: #1ea7fd; +} + +section ul { + padding-left: 30px; + margin: 1em 0; +} + +section li { + margin-bottom: 8px; +} + +section .tip { + display: inline-block; + border-radius: 1em; + font-size: 11px; + line-height: 12px; + font-weight: 700; + background: #e7fdd8; + color: #66bf3c; + padding: 4px 12px; + margin-right: 10px; + vertical-align: top; +} + +section .tip-wrapper { + font-size: 13px; + line-height: 20px; + margin-top: 40px; + margin-bottom: 40px; +} + +section .tip-wrapper svg { + display: inline-block; + height: 12px; + width: 12px; + margin-right: 4px; + vertical-align: top; + margin-top: 3px; +} + +section .tip-wrapper svg path { + fill: #1ea7fd; +}