Slide 1

Slide 1 text

BUILDING UI COMPONENTS WITH Storybook Benoît Burgener · @LeBenLeBen · Webmardi · November 5, 2019 · Liip, Lausanne

Slide 2

Slide 2 text

We used to design pages

Slide 3

Slide 3 text

But that didn’t scale

Slide 4

Slide 4 text

So we started building reusable components

Slide 5

Slide 5 text

More like “I have no idea how to use these” components

Slide 6

Slide 6 text

And so we started documenting them

Slide 7

Slide 7 text

× KSS 2011 ! × Hologram 2013 ! × Pattern Lab 2013 × Fabricator 2014 ! × Fractal 2015 × Styleguidist 2015 × …

Slide 8

Slide 8 text

/*doc --- title: Alert name: alert category: basics --- ```html_example
Hello
``` */ .alert { … }

Slide 9

Slide 9 text

--- notes: | These are notes written in `markdown` ---
My Component

Slide 10

Slide 10 text

{% extends "@page-layout" %}

{{ home.greeting }}, {{ name }}!

{% block content %} {% render '@button', { variant: 'primary' } %} {% endblock content %}

Slide 11

Slide 11 text

How about going even further?

Slide 12

Slide 12 text

No content

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

THINKING IN STORIES

Slide 16

Slide 16 text

StoriesOf API import React from 'react'; import { storiesOf } from '@storybook/react'; import Button from './Button'; storiesOf('Atoms|Button', module) .add('with text', () => Hello Button) .add('with some emoji', () => ( ! " # $ )); src/stories/button.stories.js

Slide 17

Slide 17 text

Component Story Format (CSF) import React from 'react'; import Button from './Button'; export default { component: Button, title: 'Atoms|Button', }; export const text = () => (Hello Button); export const emoji = () => ( ! " # $ ); src/stories/button.stories.js

Slide 18

Slide 18 text

CONFIGURING STORYBOOK

Slide 19

Slide 19 text

import { configure } from '@storybook/react'; // Load our global stylesheet into stories view import '@/assets/tailwind.css'; // Load stories configure( require.context('../src/stories', true, /\.stories\.(js|mdx)$/), module ); .storybook/config.js

Slide 20

Slide 20 text

ADDONS LET’S PIMP IT

Slide 21

Slide 21 text

import '@storybook/addon-knobs/register'; import '@storybook/addon-actions/register'; import '@storybook/addon-viewport/register'; import '@storybook/addon-backgrounds/register'; import '@storybook/addon-a11y/register'; .storybook/addons.js

Slide 22

Slide 22 text

ADDON KNOBS

Slide 23

Slide 23 text

import React from 'react'; import { withKnobs, text, boolean } from '@storybook/addon-knobs'; import Button from './Button'; export default { component: Button, title: 'Atoms|Button', decorators: [withKnobs] }; export const text = () => ( {text('Label', 'Hello Storybook')} );

Slide 24

Slide 24 text

No content

Slide 25

Slide 25 text

ADDON ACTIONS

Slide 26

Slide 26 text

import React from 'react'; import { action } from '@storybook/addon-actions'; import Button from './Button'; export default { component: Button, title: 'Atoms|Button', }; export const text = () => ( Hello button );

Slide 27

Slide 27 text

No content

Slide 28

Slide 28 text

ADDON VIEWPORT

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

ADDON BACKGROUNDS

Slide 31

Slide 31 text

No content

Slide 32

Slide 32 text

ADDON ACCESSIBILITY

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

× Knobs × Actions × Source × Notes × Viewport × Storyshots × Backgrounds × Accessibility × Console × Links And many more community addons…

Slide 35

Slide 35 text

PRESETS

Slide 36

Slide 36 text

module.exports = [ '@storybook/addon-docs/react/preset', ... ]; .storybook/presets.js

Slide 37

Slide 37 text

THEMING

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

No content

Slide 41

Slide 41 text

import { create } from '@storybook/theming'; export default create({ base: 'light', colorPrimary: '#00d5ff', colorSecondary: '#2625a5', textColor: '#2625a5', brandTitle: 'Webmardi', brandImage: require('./theme/webmardi.svg'), }); .storybook/theme.js

Slide 42

Slide 42 text

import theme from './theme'; addParameters({ options: { theme, }, }); .storybook/config.js

Slide 43

Slide 43 text

DOCS SINCE VERSION 5.2

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

No content

Slide 46

Slide 46 text

/** * Styled `a` or `button` element */ export default { props: { /** * The HTML tag used for the button. */ tag: { type: String, default: 'button', }, … }, … } src/components/Btn.vue

Slide 47

Slide 47 text

No content

Slide 48

Slide 48 text

No content

Slide 49

Slide 49 text

MDX stories import { Meta } from '@storybook/addon-docs/blocks'; # Webmardi Web Styleguide This project is based on [Tailwind CSS](https://tailwindcss.com/). For the sake of clarity, its classes are not documented here. You can find a dedicated documentation at [tailwindcss.com/docs](https://tailwindcss.com/docs). ## Usage The styleguide is available as a npm package, you can install it by running: ... src/stories/about.stories.mdx

Slide 50

Slide 50 text

import { Meta, Story, Preview } from '@storybook/addon-docs/blocks'; import { Checkbox } from './Checkbox'; # Checkbox With `MDX` we can define a story for `Checkbox` right in the middle of our markdown documentation.

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

import { Meta, ColorPalette, ColorItem } from '@storybook/addon-docs/blocks'; # Colors ... src/stories/colors.stories.mdx

Slide 53

Slide 53 text

No content

Slide 54

Slide 54 text

PUBLISHING

Slide 55

Slide 55 text

package.json { "scripts": { "storybook:build": "build-storybook -c .storybook -o build", "storybook:build:docs": "build-storybook -c .storybook -o build --docs", } } # Create a build npm run storybook:build # Preview the result npx http-server build

Slide 56

Slide 56 text

RECAP × Build components in isolation × Mock hard-to-reach use cases × Supercharge your workflow with addons × Match your project brand easily with theming × Generate a styleguide automatically

Slide 57

Slide 57 text

THANK YOU! × storybook.js.org × learnstorybook.com × github.com/storybookjs × twitter.com/storybookjs @LeBenLeBen