Help us understand the problem. What is going on with this article?

storybook for htmlを使って簡単にコンポーネントのカタログを作成する

対象読者

  • React.js,Vue.jsを使っていないプロジェクトでstorybookを導入したいけどやり方がわからない人
  • マークアップ言語 + JavaScriptちょっとわかる人
  • storybookの勉強はしたいけど、React.js,Vue.jsの勉強まではやりたくない人

成果物

URL

https://miwa-storybook-html.netlify.com/

GitHub

現在作成中です。

https://github.com/miwashutaro0611/html-storybook

対応環境

言語

  • HTML
  • SCSS

cssで行いたい場合、「既存のscssファイルの読み込み」の部分などのscsscssに変えたり、「storybook上でscssファイルが読み込まれるように設定」の部分を飛ばすなどで対応することができると思います。(未検証)

バージョン

  • node: v12.16.1
  • @storybook/html: "^5.3.18"
  • node-sass: "^4.13.1"

セットアップ

参考: Storybook for HTML

自動セットアップ

$ npx -p @storybook/cli sb init --type html

ゼロから作成する場合

ゼロから設定を行う方法を見る

1. package.json作成。必要なパッケージのインストール

$ npm init
$ npm i -D @storybook/html babel-loader @babel/core

パッケージ一覧

2. npm scriptの追加

package.json
{
    "scripts": {
      "storybook": "start-storybook"
    }
}

3. .storybook/main.jsの作成

$ mkdir .storybook
$ touch .storybook/main.js

.storybook/main.jsに記載する内容

module.exports = {
    stories: ['../src/**/*.stories.[tj]s'],
};

上記にように記載した場合、以下のような感じで読み込みが行われる

├── .storybook
│   └── main.js
└── src 
    ├── index.stories.js # 対象ファイル
    └── components # 対象ディレクトリ
        └── index.stories.js # 対象ファイル

4. ストーリーファイルの作成

export default { title: 'Button' }

export const withText = () => '<button class="btn">Hello World</button>' // HTMLで書く場合

export const withEmoji = () => {
  const button = document.createElement('button') // button要素作成
  button.innerText = '😀 😎 👍 💯' // button要素のテキスト
  return button
};

storybook上でscssファイルが読み込まれるように設定

参考: Custom Webpack Config

必要なパッケージのインストール

$ npm i -D style-loader css-loader sass-loader

パッケージ一覧

.storybook/main.jsにscss読み込み設定を記載

const { resolve } = require('path')

module.exports = {
  webpackFinal: async(config, {configType}) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader'
      ],
      include: resolve(__dirname, '../'),
    })
    return config
  }
}

storybookに読み込みを行うコンポーネントを作成

.htmlを使ってHTMLの記載を行いたい場合

├── _index.scss # スタイル用ファイル
├── index.html # テンプレート用ファイル
└── index.stories.js # storybook用ファイル

_index.scss

.c-title {
  font-size: 40px;
  span {
      font-size: 60px;
  }
}

index.html

<p class='c-text'>Hello <span>World!!</span></p>

index.stories.js

import Templete from './index.html'
import './_index.scss'

export default {
  title: 'Heading',
}

export const HeadingTem = () =>  {
  return Templete
}

テンプレート内に入れる

├── _index.scss # スタイル用ファイル
├── index.js # テンプレート用ファイル
└── index.stories.js # storybook用ファイル

_index.scss

.c-title {
  font-size: 40px;
  span {
      font-size: 60px;
  }
}

index.js

export const Template = () => {
  return `
    <p class='c-text'>Hello <span>World!!</span></p>
  `
}

index.stories.js

import Templete from './index.js'
import './_index.scss'

export default {
  title: 'Heading',
}

export const HeadingTem = () =>  {
  return Templete
}

既存のscssファイルの読み込み

参考: Default Config

  • reset.cssなどの読み込み
  • 上記のようなコンポーネントごとにscssファイルを記載したくない時
  • プロジェクトのscssをそのまま使いたい時

の時に.storybook/preview.jsに読み込みを行うことで既存のscssファイルを読み込むこともできる。

.storybook/preview.jsにscss読み込み設定を記載

import '../scss/style.scss' // 読み込みを行いたいscssファイル

アドオン一覧

アドオン参考リンク

スクリーンショット 2020-04-05 3.35.50.png

※2020年4月5日時点

今回使ったアドオン一覧

@pickra/copy-code-block

HTMLのソースコードを表示・コピーすることができるアドオン

インストール

$ npm i @pickra/copy-code-block

使い方

コンポーネントファイル

import copyCodeBlock from '@pickra/copy-code-block'
import Templete from './index.html'

export const TempleteCode = () =>  {
  return (Templete + copyCodeBlock(Templete)) // テンプレートの内容 + コードブロックを表示
}

@storybook/addon-knobs

テンプレート内のテキストや状態を動的に変更を行うことができるアドオン

インストール

$ npm i @storybook/addon-knobs

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-knobs/register']
}

コンポーネントファイル

import { withKnobs, text } from '@storybook/addon-knobs'

export default {
  decorators: [withKnobs]
}

export const Template = () => {
  const tmpText = text('Text', 'Hello World!!')
  return `
    <p class='c-text'>${tmpText}</p>
  `
}

@storybook/addon-a11y

コンポーエント内のアクセシビリティをチェックするアドオン

インストール

$ npm i @storybook/addon-a11y

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-a11y/register']
}

ファイル全体に適応させたい場合、.storybook/preview.jsに以下を記載

import { addDecorator } from '@storybook/html'
import { withA11y } from '@storybook/addon-a11y'

addDecorator(withA11y)

@storybook/addon-storysource

ストーリーのソースを表示するアドオン

インストール

$ npm i @storybook/addon-storysource

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-storysource'],
};

@storybook/addon-notes

テキストやマークダウン形式でストーリーの説明部などを追加することができるアドオン

インストール

$ npm i @storybook/addon-notes

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-notes/register'],
};

コンポーネントファイル

import README from './README.md' // コンポーネントと同じ階層にファイルを配置

export default {
  title: 'Heading',
  parameters: {
    notes: { README }
  }
}

@storybook/addon-viewport

インストール

$ npm i @storybook/addon-viewport

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-viewport/register']
}

サイズをカスタマイズしたい場合
既存だと「iphone5」などのサイズがないので、.storybook/preview.jsをカスタマイズして、任意のサイズでの表示されるようにする。

import { addParameters } from '@storybook/html'

const customViewports = {
  iPhone5: {
    name: 'iPhone5',
    styles: {
      width: '320px',
      height: '568px',
    },
  },
  iPhone6: {
    name: 'iPhone6,7,8',
    styles: {
      width: '375px',
      height: '667px',
    },
  },
  iPhoneX: {
    name: 'iPhoneX',
    styles: {
      width: '375px',
      height: '812px',
    },
  },
  iPhoneXsMax: {
    name: 'iPhoneXsMax',
    styles: {
      width: '414px',
      height: '896px',
    },
  },
}

addParameters({
  viewport: { viewports: customViewports }
})

@storybook/addon-docs

ストーリーをドキュメント形式で表示してくれるアドオン 

インストール

$ npm i @storybook/addon-docs

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-docs'],
};

@storybook/addon-backgrounds

storybookの背景色を変更することができるアドオン

インストール

$ npm i @storybook/addon-backgrounds

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['@storybook/addon-backgrounds/register']
};

.storybook/preview.jsに以下を記載

import { addParameters } from '@storybook/html'

addParameters({
  backgrounds: [
    { name: 'white', value: '#fff', default: true }, // デフォルトの色を設定したい場合、「default: true」を記載。
    { name: 'black', value: '#333' },
    { name: 'facebook', value: '#3b5998' },
    { name: 'twitter', value: '#00aced' },
  ]
})

storybook-dark-mode/register

storybookのテーマカラーをダークモード・ライトモードで切り替えを行うことができるアドオン

インストール

$ npm i storybook-dark-mode

使い方

.storybook/main.jsに以下を記載

module.exports = {
  addons: ['storybook-dark-mode/register']
};

.storybook/preview.jsに以下を記載

import { addParameters } from '@storybook/html'

addParameters({
  darkMode: {
    dark: { ...themes.dark, appBg: 'black' },
    light: { ...themes.normal, appBg: 'white' }
  }
})

20200309233915.png

画像のようなエラーが出た場合、@storybook/themingのインストールを行う。

$ npm i @storybook/theming

.storybook/preview.jsに「themes」を記載

import { addParameters } from '@storybook/html'
import { themes } from '@storybook/theming' // これを追記

addParameters({
  darkMode: {
    dark: { ...themes.dark, appBg: 'black' },
    light: { ...themes.normal, appBg: 'white' }
  }
})

アドオンを読みこんだ後の設定ファイルの中身

.storybook/main.js

const { resolve } = require('path')

module.exports = {
  stories: ['../components/**/*.stories.js'],
  addons: [
    '@storybook/addon-knobs/register',
    '@storybook/addon-a11y/register',
    '@storybook/addon-storysource/register',
    '@storybook/addon-notes/register',
    '@storybook/addon-viewport/register',
    '@storybook/addon-docs',
    '@storybook/addon-backgrounds/register',
    'storybook-dark-mode/register'
  ],
  webpackFinal: async(config, {configType}) => {
    config.module.rules.push({
      test: /\.scss$/,
      use: [
        'style-loader',
        'css-loader',
        'sass-loader'
      ],
      include: resolve(__dirname, '../'),
    })
    return config
  }
}

.storybook/preview.js

import { configure, addParameters, addDecorator } from '@storybook/html'
import { withA11y } from '@storybook/addon-a11y'
import { themes } from '@storybook/theming'

import '../scss/style.scss'

addDecorator(withA11y)

const customViewports = {
  iPhone5: {
    name: 'iPhone5',
    styles: {
      width: '320px',
      height: '568px',
    },
  },
  iPhone6: {
    name: 'iPhone6,7,8',
    styles: {
      width: '375px',
      height: '667px',
    },
  },
  iPhoneX: {
    name: 'iPhoneX',
    styles: {
      width: '375px',
      height: '812px',
    },
  },
  iPhoneXsMax: {
    name: 'iPhoneXsMax',
    styles: {
      width: '414px',
      height: '896px',
    },
  },
}

addParameters({
  viewport: { viewports: customViewports },
  backgrounds: [
    { name: 'white', value: '#fff', default: true },
    { name: 'black', value: '#333' },
    { name: 'facebook', value: '#3b5998' },
    { name: 'twitter', value: '#00aced' },
  ],
  darkMode: {
    dark: { ...themes.dark, appBg: 'black' },
    light: { ...themes.normal, appBg: 'white' }
  }
})
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした