6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ElixirAdvent Calendar 2024

Day 11

Phoenix LiveView アプリケーションに MishkaChelekom の UI コンポーネントを導入する

Posted at

はじめに

Phoenix LiveView は Elixir の Web フレームワークです

JavaScript をほぼ書くことなく、 Elixir でフロントエンドもバックエンドも実装できます

MishkaChelekom は UI コンポーネントのジェネレーターです

UI コンポーネントを直接定義しているわけではなく、必要な UI コンポーネントを生成して Phoenix プロジェクト内に追加します

実装したアプリケーションはこちら

実行環境(前提条件)

Erlang と Elixir 、 Node.js をインストールしているものとします

各言語のバージョン

  • Erlang 27.2
  • Elixir 1.17.3
  • Node.js 22.12.0

macOS であれば miseasdf を使ってインストールするのがおすすめです

mise の場合

mise use -g erlang@27.2
mise use -g elixir@1.17.3
mise use -g node@22.12.0

asdf の場合

asdf plugin add erlang
asdf install erlang 27.2
asdf global erlang 27.2

asdf plugin add elixir
asdf install elixir 1.17.3
asdf global elixir 1.17.3

asdf plugin add nodejs
asdf install nodejs 22.12.0
asdf global nodejs 22.12.0

elixir のパッケージマネージャー Hex をインストールします

mix local.hex

Phoenix プロジェクトを生成するための phx_new をインストールします

mix archive.install hex phx_new

Phoenix プロジェクトの作成

Phoenix プロジェクトを作成します

今回は UI だけ見たいので DB 操作をしないため --no-ecto のオプションを付けています

mix phx.new phoenix_mishka_chelekom_sample --no-ecto

Fetch and install dependencies? [Yn] と質問されるので、そのまま Enter を押下(デフォルトの yes で回答)します

phoenix_mishka_chelekom_sample ディレクトリーが作成されるので、中に移動します

cd phoenix_mishka_chelekom_sample

Phoenix アプリケーションを起動します

mix phx.server

http://localhost:4000 にアクセスすると、以下のような画面が表示されます

スクリーンショット 2024-12-25 10.35.08.png

一旦、 Ctrl + C でアプリケーションを停止します

MishkaChelekom の導入

mix.exs を以下のように編集します

defmodule PhoenixBloomSample.MixProject do
...
  defp deps do
    [
...
-     {:bandit, "~> 1.5"}
-     {:bandit, "~> 1.5"},
+     {:mishka_chelekom, "~> 0.0.1", only: :dev}
    ]
  end
...
end

MishkaChelekom 自体はコードを生成するだけで実行環境には不要なため、 only: :dev を指定しています

これにより、リリースされるバイナリは必要最小限のものになります

MishkaChelekom をインストールします

mix deps.get

コンポーネントの導入

MishkaChelekom では以下のようなコマンドでコードを生成します

mix mishka.ui.gen.component <コンポーネント名>

公式ドキュメントからコンポーネントの種類、表示、動作、プロパティ、使用例などが確認できます

まだバージョン 0.0.1 であることもあるのか、コンポーネントのプロパティについてはドキュメントと実装が一致していません

1.0.0 リリースまでにはきっと整備されると思います

Rating コンポーネントを追加してみましょう

mix mishka.ui.gen.component rating

コマンドにより、 lib/phoenix_mishka_chelekom_sample_web/components/rating.ex が生成されます

コンポーネントを関数名だけで呼び出したいので、 lib/phoenix_mishka_chelekom_sample_web.ex を以下のように編集します

defmodule PhoenixMishkaChelekomSampleWeb do
  ...
  defp html_helpers do
    quote do
      # Translation
      use Gettext, backend: PhoenixMishkaChelekomSampleWeb.Gettext

      # HTML escaping functionality
      import Phoenix.HTML
      # Core UI components
      import PhoenixMishkaChelekomSampleWeb.CoreComponents
+     import PhoenixMishkaChelekomSampleWeb.Components.Rating

      # Shortcut for generating JS commands
      alias Phoenix.LiveView.JS

      # Routes generation with the ~p sigil
      unquote(verified_routes())
    end
  end
  ...
end

lib/phoenix_mishka_chelekom_sample_web/controllers/page_html/home.html.heex に Rating を追加します

...
    <h1 class="text-brand mt-10 flex items-center text-sm font-semibold leading-6">
      Phoenix Framework
      <small class="bg-brand/5 text-[0.8125rem] ml-3 rounded-full px-2 font-medium leading-6">
        v{Application.spec(:phoenix, :vsn)}
      </small>
    </h1>
    <.rating />
    <.rating select={3} />
    <.rating select={5} />
    <.rating interactive />
    <p class="text-[2rem] mt-4 font-semibold leading-10 tracking-tighter text-zinc-900 text-balance">
      Peace of mind from prototype to production.
    </p>
...

アプリケーションを起動します

mix phx.server

ブラウザで表示すると、以下のように Rating が表示されます

rating.gif

interactive を指定した場合はマウスオーバーで評価が変わっています

続けて Alert を追加してみます

極力コードを少なくするため、利用する予定のある色とスタイルのみを指定します

mix mishka.ui.gen.component alert --color info,error --variant default

lib/phoenix_mishka_chelekom_sample_web/components/alert.ex が生成されました

内容を確認すると、例えば色の指定は以下のように :error:danger:info だけが指定されています
:error:danger は同じ色を使っているので、片方しか指定しなくても両方ついてくるようです)

  defp color_variant("default", type) when type in [:error, :danger] do
    "bg-[#FFE6E6] text-[#E73B3B] border border-[#E73B3B] hover:[&>button]:text-[#F0756A]"
  end

  defp color_variant("default", :info) do
    "bg-[#E5F0FF] text-[#004FC4] border border-[#004FC4] hover:[&>button]:text-[#3680DB]"
  end

これにより、最終的に TailwindCSS が生成する CSS ファイルも小さくなり、その分フロントエンドが軽くなります

lib/phoenix_mishka_chelekom_sample_web/controllers/page_html/home.html.heex に Alert を追加します

defmodule PhoenixMishkaChelekomSampleWeb do
  ...
  defp html_helpers do
    quote do
      # Translation
      use Gettext, backend: PhoenixMishkaChelekomSampleWeb.Gettext

      # HTML escaping functionality
      import Phoenix.HTML
      # Core UI components
-     import PhoenixMishkaChelekomSampleWeb.CoreComponents
+     import PhoenixMishkaChelekomSampleWeb.CoreComponents, except: [flash_group: 1]
+     import PhoenixMishkaChelekomSampleWeb.Components.Alert
      import PhoenixMishkaChelekomSampleWeb.Components.Rating

      # Shortcut for generating JS commands
      alias Phoenix.LiveView.JS

      # Routes generation with the ~p sigil
      unquote(verified_routes())
    end
  end
  ...
end

Alert 内で flash_group を定義しているため、 CoreComponents からはインポートしないように指定しています

lib/phoenix_mishka_chelekom_sample_web/controllers/page_html/home.html.heex に Alert を追加します

...
    <h1 class="text-brand mt-10 flex items-center text-sm font-semibold leading-6">
      Phoenix Framework
      <small class="bg-brand/5 text-[0.8125rem] ml-3 rounded-full px-2 font-medium leading-6">
        v{Application.spec(:phoenix, :vsn)}
      </small>
    </h1>
    <.alert kind={:info}>Info</.alert>
    <.alert kind={:error}>Error</.alert>
    <.rating />
...

アプリケーションを起動すると、 Alert の表示が確認できます

スクリーンショット 2024-12-25 17.00.07.png

まとめてコンポーネントを作成する

以下のように実行すると、 Alert と Rating をまとめて読み込むためのモジュール MishkaComponents が生成されます

mix mishka.ui.gen.components alert,rating --import 

mishka.ui.gen.components <- 最後に s がついています

生成されたファイル lib/phoenix_mishka_chelekom_sample_web/components/mishka_components.ex の中身は以下のようになっています

defmodule PhoenixMishkaChelekomSampleWeb.Components.MishkaComponents do
  defmacro __using__(_) do
    quote do
      import PhoenixMishkaChelekomSampleWeb.Components.Alert,
        only: [flash: 1, flash_group: 1, alert: 1]

      import PhoenixMishkaChelekomSampleWeb.Components.Rating, only: [rating: 1]
    end
  end
end

MishkaComponents を使う場合、 lib/phoenix_mishka_chelekom_sample_web/controllers/page_html/home.html.heex は以下のように編集します

defmodule PhoenixMishkaChelekomSampleWeb do
  ...
  defp html_helpers do
    quote do
      # Translation
      use Gettext, backend: PhoenixMishkaChelekomSampleWeb.Gettext

      # HTML escaping functionality
      import Phoenix.HTML
      # Core UI components
-     import PhoenixMishkaChelekomSampleWeb.CoreComponents
+     import PhoenixMishkaChelekomSampleWeb.CoreComponents, except: [flash_group: 1]
+     use PhoenixMishkaChelekomSampleWeb.Components.MishkaComponents

      # Shortcut for generating JS commands
      alias Phoenix.LiveView.JS

      # Routes generation with the ~p sigil
      unquote(verified_routes())
    end
  end
  ...
end

use PhoenixMishkaChelekomSampleWeb.Components.MishkaComponents により、 MishkaComponents の中に記述されている各種コンポーネントの import を実施しています

ただし、 mix mishka.ui.gen.components を実行した場合、 Alert や Rating など個別のコンポーネントにオプションを指定できないため、コンポーネントの色やスタイルは全て生成されます

また、以下のコマンドを実行することで MishkaComponents で生成できる全てのコンポーネントを一括生成します

mix mishka.ui.gen.components --import --yes

まとめ

MishkaComponents はコンポーネントのジェネレーターという、他の UI ライブラリーとは毛色が違うものでした

コンポーネント自体の種類もオプションも豊富なので、 1.0.0 が出るのが楽しみですね

6
1
0

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
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?