💝

daisyUI (+ tailwindcss) で Tauri 初期アプリをデコる

2024/07/20に公開

はじめに

daisyUI の Component って色々と種類があってワクワクしますよね。
というわけで、Tauri の初期アプリに daisyUI の Component を勉強がてら詰め込みまくってみました。
後から思えば、もっと色んな Component を詰め込めたし、Tauri で書く必要なかったし、そもそも tailwindcss も daisyUI も初心者だし。。
突っ込みどころが満載かと思いますがそれには目をつぶってご笑覧ください。

コードは https://github.com/1-arua/tauri-react-ts-daisyui-decoration で公開しています。

daisyUI の導入まで

bunx create-tauri-app
cd tauri-react-ts-daisyui
bun install
bun add --dev --exact @biomejs/biome
bunx @biomejs/biome init
bun install -D tailwindcss
bunx tailwindcss init
bun add -D daisyui@latest
bun add autoprefixer --dev

必要な設定はリポジトリを参照してください。
(daisyUI と autoprefixer は bun install じゃなくてよかったのか。。?)

Navigation bar とテーマスイッチャー

Navigation bar とテーマスイッチャーはそれぞれ navbartheme-controller のクラスを指定することで追加できます。

<div className="navbar bg-base-200">
        <div className="flex-1">
                <p className="btn btn-ghost text-xl">Tauri Starter App</p>
        </div>
        <div className="flex-none">
                <label className="swap swap-rotate">
                        <input type="checkbox" className="theme-controller" value="dim" />
                        <Sun className="swap-off" />
                        <Moon className="swap-on" />
                </label>
        </div>
</div>

Navigation bar は特に困らなかったのですが、テーマスイッチャーは思い通りにテーマが切り替わらず困りました。
theme-controller を指定した要素の value に切り替え先のテーマ名を指定しておく必要があるんですね。
しかも、使用するテーマは tailwindcss.config.js に記載しておく必要がある。

tailwindcss.config.js
daisyui: {
        themes: ["cupcake", "dim"],
}

とは言え、結構簡単にダークモード対応ができるのは嬉しいです。

Footer

Footer は footer 要素のクラスに footer を指定することで追加できます。

<footer className="footer bg-base-200 text-base-content p-10">
        <aside>
                <img src="/icon.png" alt="1_arua icon" width={50} />
                <p>こんにちは、ああるあです</p>
        </aside>
        <nav>
                <h6 className="footer-title">Author</h6>
                <a className="link link-hover" href="https://zenn.dev/1_arua">
                        About me
                </a>
        </nav>
        <nav>
                <h6 className="footer-title">favorites</h6>
                <a className="link link-hover" href="https://www.kaldi.co.jp/">
                        Coffee
                </a>
                <a className="link link-hover" href="https://www.sentaro.co.jp/">
                        Sweets
                </a>
        </nav>
</footer>

本来なら色々とリンクを用意するんでしょうけど、特に書くこともなかったので行きつけの店のサイトを貼りました。
おすすめです。

テキストボックス

input クラスや input-bordered モディファイアなどを利用することで追加できます。

<label className="input input-bordered flex items-center gap-2">
        <CircleUserRound />
        <input
                type="text"
                value={name}
                onChange={(e) => setName(e.currentTarget.value)}
                className="grow"
                placeholder="Your name"
        />
</label>
<label className="input input-bordered flex items-center gap-2">
        <BookLock />
        <input
                type="password"
                value={secretMsg}
                onChange={(e) => setSecretMsg(e.currentTarget.value)}
                className="grow"
                placeholder="Your secret meassage"
        />
</label>

daisyUI の力を借りているのはアイコンの設定だったり、テキストボックスの形です。
秘密のメッセージの方は入力内容にマスクがかかりますが、これは daisyUI の力ではなく html の力です[1]

Modal

Modal の作成はクラスに modal を指定することで追加できます。
よくあるモーダル外をクリックしたら閉じるやつは、modal を指定した要素内に modal-backdrop クラスを指定した要素を form を配置することで実現できます。

モーダルの作成
<dialog id="greeting_modal" className="modal">
        <div className="modal-box">
                <p className="py-4">{greetMsg}</p>
                <p className="py-4">{secretGreetMsg}</p>
        </div>
        <form method="dialog" className="modal-backdrop">
                <button type="submit">close</button>
        </form>
</dialog>
モーダルの呼び出し
onSubmit={(e) => {
    (
        document.getElementById("greeting_modal") as HTMLDialogElement
    )?.showModal();
}}

実現はできるのですが、modal-backdrop の内部実装はどうなっているんでしょうね。
勝手に内部実装は CSS をいい感じに書いてくれているものと思っていましたが、こればかりはさすがに CSS だけだと無理そうです。
とすると他のも JS の力を使ってたりするんでしょうか?

プルダウン

プルダウンの選択肢は select クラスで追加できます。

<p>
        You are a
        <select
                className="select border-1 border-gray-300 ml-2"
                value={visitorType}
                onChange={(e) => setVisitorType(e.target.value)}
        >
                {visitorTypes.map((vt) => (
                        <option key={vt.value} value={vt.value}>
                                {vt.label}
                        </option>
                ))}
        </select>
</p>

実は最初は Select と Dropdown は何が違うねんとなりました。ぜんぜん違うんですが。
Dropdown は Zenn だとヘッダーのアイコンのあたりがそうでしょうか。

一方で Select の方は単に選択して、それを form などで送りつけるといったところですかね。
MDN を見ると遥かにマシな解説が見れると思います。

まとめ

daisyUI、いいですね。
かなりの初心者の僕でも簡単にきれいな UI を作ることができて好きになりました。

一方で、tailwindcss への反論としてよく聞かれる「冗長なクラス」というのの片鱗が見えたような気もします。
border の太さの指定とか、色とか、サイズの指定とか。
大きなプロジェクトだと管理方法をちゃんと考えないと大変なことになりそうです。

また、Theme がカラーテーマとスタイル(要素の形)の2側面を内包しているのは気になります。
cupcake テーマの色は好きなんですが、スタイルが他と統一感ないのが。。
32種の Theme のうち、大半は角丸で、いくつかは角があって、いくつかは丸でってなんでこんなバラバラにしたんだろう。。

とは言え、そのあたりの気になる点を超える使い心地があるとは思います。
これからも常用しそう。

脚注
  1. https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/password ↩︎

Discussion