LoginSignup
2

More than 1 year has passed since last update.

はじめに

phx_live_storybookを試すことを楽しんでみます。

Elixirの作者José Valimさん、Phoenixの作者Chris McCordさんの両御大がフィードバックをくれているそうです。

What is phx_live_storybook ?

御両所も注目のphx_live_storybookとは、そもそも一体何でしょうか。

説明を読んでみます。

PhxLiveStorybook provides a storybook-like UI interface for your Phoenix LiveView components.

JSの世界に、Storybookというものが存在するそうです。

Storybook is a frontend workshop for building UI components and pages in isolation. Thousands of teams use it for UI development, testing, and documentation. It’s open source and free.

Storybookをよく知っている方はこの時点でピンとこられたこととおもいます。
私はこの世界を知らないので文章の説明だけでは、私はわかりませんでした。
それでとりあえずわからないものは触ってみるということで触ってみました。
そのことを書いておきます。

あとでわかることですが、自分で作成したUI componentをいろいろと試すことができるようです。

デモ

phx_live_storybook
作者の方がデモサイトを立ち上げてくださっています。
こちらを触ってみるのが一番わかりやすいとおもいます。

使用したElixirとErlang、Phoenixのバージョン

  • Phoenix v1.6.13
  • elixir 1.14.0-otp-2
  • erlang 25.0.3

おことわり

Phoenix 1.7(未リリース)と組み合わせるほうがよさそうです。
理由は後述します。

とりあえず今日時点で動かした手順を書いておきます。

mix phx.new

mix phx.new hello_storybook
cd hello_storybook
mix setup

依存Hexを追加

mix.exs
  defp deps do
    {:phoenix_live_view, "~> 0.18.1"}, # change
    {:phoenix_live_dashboard, "~> 0.6", override: true}, # change

    ...
    {:phx_live_storybook, "~> 0.4.0"}, # add
    {:tailwind, "~> 0.1", runtime: Mix.env() == :dev}, # add
    {:heroicons, "~> 0.5.0"} # add
  end

phx_live_storybook 0.4.0は、phoenix_live_view 0.18以上が必要です。
それで、mix phx.newでもともと書かれていた、phoenix_live_viewphoenix_live_dashboardの指定を変更しています。

tailwindはのちほどの手順でmix phx.gen.storybookということを行うのですが、そのときにTailwindの設定を書き換えるように指示されるのでインストールしました。
Tailwindは、

の手順に従って設定を進めてください。

heroiconsは、mix phx.gen.storybookにてIconコンポーネントのサンプルが作られます。そのサンプルが依存するのでここでインストールしています。

mix deps.get

phoenix_live_viewphoenix_live_dashboardの指定を変更しないと以下のエラーでコケます。

Resolving Hex dependencies...

Failed to use "phoenix_live_view" (version 0.17.12) because
  phoenix_live_dashboard (version 0.6.5) requires ~> 0.17.7
  phx_live_storybook (versions 0.4.0 and 0.4.1) requires ~> 0.18
  mix.lock specifies 0.17.12

** (Mix) Hex dependency resolution failed, change the version requirements of your dependencies or unlock them (by using mix deps.update or mix deps.unlock). If you are unable to resolve the conflicts you can try overriding with {:dependency, "~> 1.0", override: true}

mix phx.gen.storybook

mix phx.gen.storybookというインストールコマンドが使えるようになるので、実行します。
以下のファイルが作られます。

  • assets/css/storybook.css
  • assets/js/storybook.js
  • lib/hello_storybook_web/storybook.ex
  • storybook/components/icon.story.exs
  • storybook/my_page.story.exs

またインストールの途中で手動で実行すべき作業が示されます。
その通りに手動で変更をします。

* manual setup instructions:
  Add the following to your router.ex:

    use HelloStorybookWeb, :router
    import PhxLiveStorybook.Router

    scope "/" do
      storybook_assets()
    end

    scope "/", HelloStorybookWeb do
      pipe_through(:browser)
      live_storybook "/storybook", backend_module: HelloStorybookWeb.Storybook
    end


[Y to continue] [Yn] Y
* manual setup instructions:
  Add js/storybook.js as a new entry point to your esbuild args in config/config.exs:

    config :esbuild,
    default: [
      args:
        ~w(js/app.js js/storybook.js --bundle --target=es2017 --outdir=../priv/static/assets ...),
      ...
    ]


[Y to continue] [Yn] Y
* manual setup instructions:
  Add a new Tailwind build profile for css/storybook.css in config/config.exs:

    config :tailwind,
      ...
      default: [
        ...
      ],
      storybook: [
        args: ~w(
          --config=tailwind.config.js
          --input=css/storybook.css
          --output=../priv/static/assets/storybook.css
        ),
        cd: Path.expand("../assets", __DIR__)
      ]


[Y to continue] [Yn] Y
* manual setup instructions:
  Add a new endpoint watcher for your new Tailwind build profile in config/dev.exs:

    config :hello_storybook_web, HelloStorybookWeb.Endpoint,
      ...
      watchers: [
        ...
        storybook_tailwind: {Tailwind, :install_and_run, [:storybook, ~w(--watch)]}
      ]


[Y to continue] [Yn] Y
* manual setup instructions:
  Add a new live_reload pattern to your endpoint in config/dev.exs:

    config :hello_storybook_web, HelloStorybookWeb.Endpoint,
      live_reload: [
        patterns: [
          ...
          ~r"storybook/.*(exs)$"
        ]
      ]


[Y to continue] [Yn] Y
You are all set! 🚀

mix phx.server

mix phx.server

立ち上がりません。エラー内容は、

== Compilation error in file lib/hello_storybook_web/views/layout_view.ex ==
** (CompileError) lib/hello_storybook_web/templates/layout/live.html.heex:4: undefined function live_flash/2 (expected HelloStorybookWeb.LayoutView to define such a function or for it to be imported, but none are available)

Phoenix 1.7(未リリース)と組み合わせるほうがよさそうです」の理由です。
mix.exsのバージョン指定を変えたことで、Phoenix.Component.live_flash/2が使えなくなっています。

ドキュメントは

スクリーンショット 2022-10-01 7.47.07.png

と書いてあります。
Phoenix 1.7を待ったほうがよさそうです。
Phoenix.Flashモジュールは探しましたが見当たりません。

とりあえず先へ進みたい :fire::fire::fire:

phx_live_storybookを楽しむという目的にとっては、大勢には影響がなさそうな箇所なので、lib/hello_storybook_web/templates/layout/live.html.heexからPhoenix.Component.live_flash/2の呼び出しを消しちゃいます。

lib/hello_storybook_web/templates/layout/live.html.heex
 <main class="container">
   <p class="alert alert-info" role="alert"
     phx-click="lv:clear-flash"
-    phx-value-key="info"><%= live_flash(@flash, :info) %></p>
+    phx-value-key="info"></p>
 
   <p class="alert alert-danger" role="alert"
     phx-click="lv:clear-flash"
-    phx-value-key="error"><%= live_flash(@flash, :error) %></p>
+    phx-value-key="error"></p>

再度 mix phx.server

今度は立ち上がりました :fire::fire::fire:

Visit: http://localhost:4000/storybook

2 componentsのサンプルがあります。

スクリーンショット 2022-10-01 7.07.21.png

スクリーンショット 2022-10-01 7.07.31.png

自作コンポーネントを追加してみたい :rocket:

まず自作のコンポーネントを作ります。

lib/hello_storybook_web/components/button.ex
defmodule HelloStorybookWeb.Components.Button do
  use HelloStorybookWeb, :component

  attr :label, :string, required: true, doc: "Button label"
  attr :theme, :atom

  def button(assigns) do
    assigns
    |> assign_new(:theme, fn -> :not_set end)
    |> assign_new(:label, fn -> "" end)
    |> assign_new(:"bg-color", fn -> "bg-indigo-600" end)
    |> assign_new(:"hover-bg-color", fn -> "hover:bg-indigo-700" end)
    |> assign_new(:"text-color", fn -> "text-white" end)
    |> render()
  end

  defp render(assigns) do
    ~H"""
    <button phx-click="boom" type="button" theme={@theme} class={"inline-flex items-center px-2.5 py-1.5 border border-transparent text-xs font-medium rounded shadow-sm #{assigns[:"text-color"]} #{assigns[:"bg-color"]} #{assigns[:"hover-bg-color"]} focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"}>
      <%= @label %>
    </button>
    """
  end
end

https://github.com/phenixdigital/phx_live_storybook_sample/blob/8178df34662b28bf0496b11b953b1a7145e5278f/lib/phx_live_storybook_sample/components/buttons/button.ex
を参考にしました。
(モジュール名を一部変えただけのコピペです)

続いて、storybookに表示されるようにします。

storybook/components/button.story.exs
defmodule Storybook.Components.Button do
  alias HelloStorybookWeb.Components.Button

  use PhxLiveStorybook.Story, :component

  def function, do: &Button.button/1
  def description, do: "A simple button. If you click, I'll log a message!"

  def variations do
    [
      %Variation{
        id: :default,
        description: "Default button",
        attributes: %{
          label: "Boom!"
        }
      },
      %Variation{
        id: :custom_colors,
        description: "A button with custom colors",
        attributes: %{
          :label => "A button",
          :"bg-color" => "bg-green-600",
          :"hover-bg-color" => "bg-green-700"
        }
      }
    ]
  end
end

これもhttps://github.com/phenixdigital/phx_live_storybook_sample/blob/8178df34662b28bf0496b11b953b1a7145e5278f/storybook/components/buttons/button.story.exs
を参考にしました。
(モジュール名を一部変えただけのコピペです)

この2つのファイルを用意すると、storybookにメニューが追加されます。

スクリーンショット 2022-10-01 7.16.27.png

:tada::tada::tada:

おわりに

phx_live_storybookを試すことを楽しんでみました。

私は、Phoenixのアプリケーションでcomponentをちゃんと作ったことがあまりありませんし、JSのStorybookのことは今日はじめて知りました。
わからないことが複数重なっているので、私にはその有り難みがまだよくわかっていません。
ただ、それは私がものを知らないだけです。

冒頭に紹介した通り、José Valimさん、Chris McCordさんの両御大がフィードバックをされているそうで、今後お世話になる機会はたくさん増えそうです。

phx_live_storybookが一人だけPhoenix 1.7+の世界を先取りしている感じが良いです :fire::fire::fire:

注目のHexです。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2