Storybook for HTMLでレスポンシブUIを管理する

StorybookはすぐれたUIコンポーネント管理ツールですが、ReactやVueだとできるものがplain HTML用だと痒いところに手が届かない印象でした。でもやらないといけないということでまとめてみた。

要件

  • Responsive UIが確認できる
  • ソースコードをコピペで利用できるようにしたい

つまりaddonsをうまく利用して実現したい。(https://storybook.js.org/addons/
今回は addons-Viewport と mdxファイルが利用できる addons-Docs を利用しました。

ということで、目次

  1. 前提条件
  2. Storybook for Htmlのインストール
  3. SCSSを適用する設定
  4. Addonのインストール

前提条件

今回は既存プロジェクトを以下のように管理しており、そこにStorybookを同居させます。
既存プロジェクトのディレクトリ構造は以下の通りとします。
ECTテンプレート (http://ectjs.com/) を利用してHTML側もコンポーネント管理し、Storybook側では src/ect/_components 以下のコンポーネントを管理することになります。
また、スタイルについては、 MARKDOWN_HASH0f7bc6b0448cbca0959b2e11d9ee62f6MARKDOWNHASH をStorybook側でも読み込むようにします。
* 実際は webpackによるビルド環境ですが今回は省略しています。_

src
├── ect
│   ├── _components <-- ここのファイルをStorybookで管理
│   │  ├── _a.ect
│   │  ├── _b.ect
│   │  └── _c.ect
│   ├── _layout.ect
│   └── index.ect
├── js
│   └── main.js
└── scss
    ├── _components
    │  ├── _a.scss
    │  ├── _b.scss
    │  └── _c.scss
    └── main.scss <-- 上記a, b, cコンポーネとスタイルをimportしている

Storybook for HTML のインストール

https://storybook.js.org/docs/guides/guide-html/

以下を実行するだけで初期設定は完了です。

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

これでStorybookのベーシックUIが確認できます。

yarn storybook

Screen Shot 2020-03-30 at 9.04.45.png

この時点でのディレクトリ構造

.
├── .storybook
│   └── main.js
├── package.json
├── src
|   ├── ect
|   │   ├── _components
|   │   │   ├── _a.ect
|   │   │   ├── _b.ect
|   │   │   └── _c.ect
|   │   ├── _layout.ect
|   │   └── index.ect
|   ├── js
|   │   └── main.js
|   └── scss
|       ├── _components
|       │   ├── _a.scss
|       │   ├── _b.scss
|       │   └── _c.scss
|       └── main.scss
└── stories
    └── index.stories.js

SCSSを適用する設定

次に src/scss/main.scss をStorybook側で読み込む設定をします。

  1. node-sass, style-loader, css-loader , sass-loader パッケージのインストール
  2. .storybook/main.js にStorybook側のwebpack設定を追加
  3. .storybook/preview.js で対象のscssファイルをimport
yarn add -D node-sass style-loader css-loader sass-loader

.storybook/main.js

const path = require('path');

module.exports = {
  stories: ['../stories/**/*.stories.js'],

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

    return config;
  }
};

.storybook/preview.js

import '!style-loader!css-loader!sass-loader!../src/scss/main.scss';

Addonのインストール

Storybook Viewport Addon

https://github.com/storybookjs/storybook/tree/master/addons/viewport
モバイルデバイスごとのViewを確認できるaddonです。レスポンシブコンポーネントの確認にはとても便利です。

  1. @storybook/addon-viewport のインストール
  2. .storybook/main.js の更新
  3. .storybook/preview.js の更新

@storybook/addon-viewport のインストール

このaddonは @storybook/react に依存しているのでこちらもインストールします。

yarn add -D @storybook/addon-viewport @storybook/react

.storybook/main.js の更新

Addon定義を追加します。

const path = require('path');

module.exports = {
  stories: ['../stories/**/*.stories.js'],

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

    return config;
  },

  addons: [
    '@storybook/addon-viewport/register'
  ],
};

.storybook/preview.js の更新

viewport定義を追加します。

import { addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import '!style-loader!css-loader!sass-loader!../src/scss/main.scss';

addParameters({
  viewport: {
    viewports: INITIAL_VIEWPORTS,
  },
});

これでOKですが、ここで storybookを起動するとエラーになります。。これは次のaddonをついかすることで解消できます。

Screen Shot 2020-03-30 at 11.52.22.png

Storybook Docs Addon

https://github.com/storybookjs/storybook/tree/master/addons/docs
mdxファイルの利用を可能にするadonです。試行錯誤の結果これだと期待するアプトプットが出せました。

  1. @storybook/addon-docs のインストール
  2. .storybook/main.js の更新
  3. .storybook/preview.js の更新
  4. mdxコンポーネントファイルの作成

@storybook/addon-docs のインストール

yarn add -D @storybook/addon-docs

.storybook/main.js の更新

storiesプロパティでターゲットファイルを mdx にします。
今回は stories 以下のmdx拡張子ファイルを対象とします。
それから、addon定義も追加します。

const path = require('path');

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

    return config;
  },
  addons: [
    '@storybook/addon-viewport/register',
    '@storybook/addon-docs',
  ],
};

mdxコンポーネントファイルの作成

stories/ 配下にmdxファイルを作成します。今回は目次として index.stories.mdx , ボタンコンポーネントとして button.stories.mdx を作成します。

  • stories/index.stories.mdx
import { Meta } from '@storybook/addon-docs/blocks';

<Meta title="01_Getting started" />

# Getting started

Welcome to Our Design System!!
  • stories/button.stories.mdx

Storyタグ内のソースを元にコンポーネント表示、コピー用のソースが生成表示されます。

import { Meta, Story, Preview } from '@storybook/addon-docs/blocks';

<Meta title="02_Components/Button" />

# Button

Buttonコンポーネント

<Preview withSource="open">
    <Story name="Button">
        <button class="button button--primary">Sample Button</button>
    </Story>
</Preview>

.storybook/preview.js の更新

特に設定は不要ですが、左ペインのナビゲーションに連番でコンポーネントを並べたいので、options.storySort にソート設定を追加しました。

import { addParameters } from '@storybook/react';
import { INITIAL_VIEWPORTS } from '@storybook/addon-viewport';
import '!style-loader!css-loader!sass-loader!../src/scss/main.scss';

addParameters({
  viewport: {
    viewports: INITIAL_VIEWPORTS,
  },
  options: {
    storySort: (a, b) => {
      return a[1].kind === b[1].kind ? 0 : a[1].id.localeCompare(b[1].id, undefined, { numeric: true })
    }
  },
});

これで以下のように表示ができます。

Screen Shot 2020-03-30 at 13.12.26.png

●ポイント4.5倍●2段ベッドにもなるワイドキングサイズベッド Whentass ウェンタス 薄型軽量ポケットコイルマットレス付き スタンダード ワイドK200[L][00]

価格:103,565円
(2020/5/21 15:38時点)