4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

はじめに

前回、とりあえず Phoenix のトップ画面にコンポーネントを配置してみました

しかし、それだと実用的ではないので mix phx.gen.live で生成した画面に組み込んでみます

基本となるプロジェクトの準備

プロジェクトの作成

新しいプロジェクトを作成し、ディレクトリー配下に移動します

mix archive.install hex phx_new
mix phx.new salad_ui_sample
cd salad_ui_sample

データベースの用意

今回はデータベースを使用するため、 Docker で起動します(ローカルで起動している場合などはそのまま使って問題ありません)

"docker-compose.yml" をカレントディレクトリーに以下の内容で作成します

POSTGRES_USER などの値は作成したプロジェクトの設定に従っています

---

services:
  db:
    container_name: postgres
    image: postgres:15.7-bullseye
    ports:
      - "5432:5432"
    volumes:
      - postgres:/var/lib/postgresql/data
    environment:
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres
      - POSTGRES_DB=salad_ui_sample_dev

volumes:
  postgres:

PostgreSQL  のコンテナを起動します

--detach でコンテナを裏で起動したままにしています

docker compose up --detach

依存モジュールをインストールし、データベースを作成します

mix setup

画面の生成

以下のコマンドでユーザー一覧、ユーザー詳細、ユーザー作成/更新などの画面を一括生成します

mix phx.gen.live Accounts User users name:string age:integer

"lib/salad_ui_sample_web/router.ex" に各画面のルートを追記します

...
  scope "/", SaladUiSampleWeb do
    pipe_through :browser

    get "/", PageController, :home

+   live "/users", UserLive.Index, :index
+   live "/users/new", UserLive.Index, :new
+   live "/users/:id/edit", UserLive.Index, :edit
+
+   live "/users/:id", UserLive.Show, :show
+   live "/users/:id/show/edit", UserLive.Show, :edit
  end
...

ユーザーテーブルをデータベース上に作成します

mix ecto.migrate

ベースとなる画面の確認

Phoenix を起動します

mix phx.server

http://localhost:4000/users にアクセスすると、ユーザー一覧画面が確認できます

スクリーンショット 2024-07-13 11.20.45.png

ユーザーを一人作成してみましょう

スクリーンショット 2024-07-13 11.20.54.png

スクリーンショット 2024-07-13 11.21.53.png

SaladUI の導入

プロジェクトに SaladUI を導入します

前回の手順とほぼ同じです

SaladUI モジュールの追加

{:salad_ui, "~> 0.5"} を "mix.exs" 内の依存モジュールに追加します

...
  defp deps do
    [
      {:phoenix, "~> 1.7.14"},
      {:phoenix_html, "~> 4.1"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      # TODO bump on release to {:phoenix_live_view, "~> 1.0.0"},
      {:phoenix_live_view, "~> 1.0.0-rc.1", override: true},
      ...
-     {:bandit, "~> 1.5"}
+     {:bandit, "~> 1.5"},
+     {:salad_ui, "~> 0.5"}
    ]
  end
...

依存モジュールをインストールします

mix deps.get

カスタムカラーの追加

shadcn/ui のテーマ提供ページを開きます

前回から少し画面が変わりました

スクリーンショット 2024-07-13 11.23.33.png

"Customize" のボタンをクリックして好きな色を選択します

スクリーンショット 2024-07-13 11.24.08.png

カスタムカラー用の CSS コードがモーダルで開くので、右上 "Copy" をクリックしてコードをクリップボードにコピーしておきます

スクリーンショット 2024-07-13 11.28.02.png

プロジェクト内の "assets/css/app.css" にコピーしたコードを追加します

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";

/* This file is for your main application CSS */

+@layer base {
+  :root {
+    --background: 0 0% 100%;
+    --foreground: 222.2 84% 4.9%;
+    --card: 0 0% 100%;
...
+   --border: 217.2 32.6% 17.5%;
+   --input: 217.2 32.6% 17.5%;
+   --ring: 224.3 76.3% 48%;
+ }
+}

"assets/tailwind.colors.json" を新規作成し、以下のコードを貼り付けます

{
  "accent": {
    "DEFAULT": "hsl(var(--accent))",
    "foreground": "hsl(var(--accent-foreground))"
  },
  "background": "hsl(var(--background))",
  "border": "hsl(var(--border))",
  "card": {
    "DEFAULT": "hsl(var(--card))",
    "foreground": "hsl(var(--card-foreground))"
  },
  "destructive": {
    "DEFAULT": "hsl(var(--destructive))",
    "foreground": "hsl(var(--destructive-foreground))"
  },
  "foreground": "hsl(var(--foreground))",
  "input": "hsl(var(--input))",
  "muted": {
    "DEFAULT": "hsl(var(--muted))",
    "foreground": "hsl(var(--muted-foreground))"
  },
  "popover": {
    "DEFAULT": "hsl(var(--popover))",
    "foreground": "hsl(var(--popover-foreground))"
  },
  "primary": {
    "DEFAULT": "hsl(var(--primary))",
    "foreground": "hsl(var(--primary-foreground))"
  },
  "ring": "hsl(var(--ring))",
  "secondary": {
    "DEFAULT": "hsl(var(--secondary))",
    "foreground": "hsl(var(--secondary-foreground))"
  }
}

TailwindCSS の設定

"assets/tailwind.config.js" を開いて編集します

...
module.exports = {
  content: [
    "./js/**/*.js",
+   "../deps/salad_ui/lib/**/*.ex",
    "../lib/salad_ui_sample_web.ex",
    "../lib/salad_ui_sample_web/**/*.*ex"
  ],
  theme: {
    extend: {
-     colors: {
-       brand: "#FD4F00",
-     }
+     colors: require("./tailwind.colors.json")
    },
  },
  plugins: [
    require("@tailwindcss/forms"),
+   require("@tailwindcss/typography"),
+   require("tailwindcss-animate"),
...

tailwindcss-animate の追加

TailwindCSS のアニメーション用プラグイン tailwindcss-animate を追加します

cd assets
yarn add -D tailwindcss-animate
cd ..

tails の設定

TailwindCSS の Elixir 用ユーティリティーである tails を設定します

"config/config.exs" に以下のコードを追加します

config :tails, colors_file: Path.join(File.cwd!(), "assets/tailwind.colors.json")

SaladUI コンポーネントの適用、追加

ベースとなる画面に SaladUI を組み込んでいきます

別名の設定

CoreComponents と共存させるため、使用する各コンポーネントに別名をつけておきます

"lib/salad_ui_sample_web.ex"

...
  defp html_helpers do
    quote do
      # HTML escaping functionality
      import Phoenix.HTML
      # Core UI components and translation
      import SaladUiSampleWeb.CoreComponents
      import SaladUiSampleWeb.Gettext

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

+     alias SaladUI.Button, as: SaladButton
+     alias SaladUI.Input, as: SaladInput
+     alias SaladUI.Tooltip, as: SaladTooltip

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

ボタンの変更

画面内のボタンに SaladButton の別名を付けるだけで変更可能です

選択したテーマの色が適用されます

"lib/salad_ui_sample_web/live/user_live/index.html.heex"

<.header>
  Listing Users
  <:actions>
    <.link patch={~p"/users/new"}>
-     <.button>New User</.button>
+     <SaladButton.button>New User</SaladButton.button>
    </.link>
  </:actions>
</.header>
...

スクリーンショット 2024-07-13 12.09.06.png

lib/salad_ui_sample_web/live/user_live/show.html.heex

<.header>
  User <%= @user.id %>
  <:subtitle>This is a user record from your database.</:subtitle>
  <:actions>
    <.link patch={~p"/users/#{@user}/show/edit"} phx-click={JS.push_focus()}>
-     <.button>Edit user</.button>
+     <SaladButton.button>Edit user</SaladButtonbutton>
    </.link>
  </:actions>
</.header>

スクリーンショット 2024-07-13 12.09.06.png

lib/salad_ui_sample_web/live/user_live/form_component.ex

...
        <:actions>
-         <.button phx-disable-with="Saving...">Save User</.button>
+         <SaladButton.button phx-disable-with="Saving...">Save User</SaladButton.button>
        </:actions>
...

スクリーンショット 2024-07-13 12.09.36.png

Input の変更

Input の場合、単純に入れ替えるだけではいけません

外観は SaladInput を付けただけですぐに変わりますが、値を変更したりするとエラーが出力されます

name 属性に user[name] のように <テーブル名>[<列名>] となるように値を設定しましょう

...
      <.simple_form
        for={@form}
        id="user-form"
        phx-target={@myself}
        phx-change="validate"
        phx-submit="save"
      >
-       <.input field={@form[:name]} type="text" label="Name" />
+       <SaladInput.input
+         field={@form[:name]}
+         type="text"
+         placeholder="Name"
+         name="user[name]"
+         id="user_name"
+       />
-       <.input field={@form[:age]} type="number" label="Age" />
+       <SaladInput.input
+         field={@form[:age]}
+         type="number"
+         placeholder="Age"
+         name="user[age]"
+         id="user_id"
+       />
        <:actions>
          <SaladButton.button phx-disable-with="Saving...">Save User</SaladButton.button>
        </:actions>
      </.simple_form>
...

スクリーンショット 2024-07-13 12.13.57.png

Tooltip を追加する

マウスオーバーでツールチップを表示させたい場合、 SaladTooltip.tooltip タグでマウスオーバーの対象を囲み、 SaladTooltip.tooltip_content 内にツールチップの内容を記載します

<.header>
  Listing Users
  <:actions>
-   <.link patch={~p"/users/new"}>
-     <SaladButton.button>New User</SaladButton.button>
-   </.link>
+   <SaladTooltip.tooltip>
+     <.link patch={~p"/users/new"}>
+       <SaladButton.button>New User</SaladButton.button>
+     </.link>
+     <SaladTooltip.tooltip_content>
+         <p>Open Modal.</p>
+     </SaladTooltip.tooltip_content>
+   </SaladTooltip.tooltip>
  </:actions>
</.header>

tooltip.gif

まとめ

SaladUI のコンポーネントに別名を付けることで CoreComponents と共存させました

外見だけなら別名を頭に付けるだけで既存のコンポーネントを変換可能ですが、特に入力が絡むようなものはそのままではエラーになるため、内部処理を理解して書き換えましょう

ちなみに、 Table は大掛かりな変更になりそうなので今回は対象外としました

4
0
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
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?