daisyui
50以上のコンポーネントにセマンティックなクラス名を提供するTailwind CSSコンポーネントライブラリで、組み込みテーマ・ダークモード・カスタマイズ機能を備え、迅速なUI開発を実現します。
description の原文を見る
Tailwind CSS component library providing semantic class names for 50+ components with built-in themes, dark mode, and customization for rapid UI development.
SKILL.md 本文
DaisyUI コンポーネントライブラリ
概要
DaisyUI は最も人気のある Tailwind CSS コンポーネントライブラリで、50以上のコンポーネント向けセマンティッククラス名、組み込みテーマ、ダークモード、カスタマイズを提供します。フレームワーク非依存で本番環境対応です。
使用時期
- Tailwind CSS でUI構築する際にプリスタイルされたコンポーネントが必要
- ユーティリティのみの方法ではなくセマンティッククラス名(
btn、card)が必要 - 30以上のテーマとダークモードを備えた組み込みテーマシステムが必要
- React、Vue、Svelte、またはバニラ HTML 全体で一貫したデザインシステムが必要
- 既成コンポーネントでプロトタイプを素早く作成したい
- セマンティック HTML パターンに従ったアクセス可能なコンポーネントが必要
クイックスタート
インストール
npm install -D daisyui@latest
設定
tailwind.config.js に追加します:
module.exports = {
plugins: [require("daisyui")],
daisyui: {
themes: ["light", "dark", "cupcake"], // 特定のテーマを有効化
darkTheme: "dark", // デフォルトダークテーマ
base: true, // ベーススタイル
styled: true, // コンポーネントスタイル
utils: true, // ユーティリティクラス
},
}
基本的な使用方法
<!-- ボタンコンポーネント -->
<button class="btn btn-primary">Primary Button</button>
<!-- カードコンポーネント -->
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Card Title</h2>
<p>Card description goes here</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">Action</button>
</div>
</div>
</div>
<!-- モーダルコンポーネント -->
<dialog id="my_modal" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Modal Title</h3>
<p class="py-4">Modal content</p>
<div class="modal-action">
<button class="btn">Close</button>
</div>
</div>
</dialog>
コアコンポーネント
ボタン
<!-- バリアント -->
<button class="btn">Default</button>
<button class="btn btn-primary">Primary</button>
<button class="btn btn-secondary">Secondary</button>
<button class="btn btn-accent">Accent</button>
<button class="btn btn-ghost">Ghost</button>
<button class="btn btn-link">Link</button>
<!-- サイズ -->
<button class="btn btn-lg">Large</button>
<button class="btn btn-md">Medium</button>
<button class="btn btn-sm">Small</button>
<button class="btn btn-xs">Tiny</button>
<!-- 状態 -->
<button class="btn btn-active">Active</button>
<button class="btn btn-disabled">Disabled</button>
<button class="btn loading">Loading</button>
<!-- 形状 -->
<button class="btn btn-circle">C</button>
<button class="btn btn-square">S</button>
<button class="btn btn-wide">Wide</button>
<button class="btn btn-block">Block</button>
<!-- アウトライン -->
<button class="btn btn-outline btn-primary">Outline</button>
カード
<!-- 基本的なカード -->
<div class="card w-96 bg-base-100 shadow-xl">
<figure><img src="image.jpg" alt="Album"/></figure>
<div class="card-body">
<h2 class="card-title">Card Title</h2>
<p>Description text</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">Buy Now</button>
</div>
</div>
</div>
<!-- コンパクトカード -->
<div class="card card-compact w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Compact Card</h2>
<p>Reduced padding</p>
</div>
</div>
<!-- バッジ付きカード -->
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">
Title
<div class="badge badge-secondary">NEW</div>
</h2>
<p>Content</p>
</div>
</div>
<!-- 画像オーバーレイカード -->
<div class="card card-compact w-96 image-full bg-base-100 shadow-xl">
<figure><img src="image.jpg" alt="Album"/></figure>
<div class="card-body">
<h2 class="card-title">Overlay Text</h2>
<p>Text appears on top of image</p>
</div>
</div>
モーダル
<!-- モーダル構造 -->
<dialog id="my_modal_1" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Hello!</h3>
<p class="py-4">Press ESC key or click the button to close</p>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
<!-- JavaScript でモーダルを開く -->
<button onclick="my_modal_1.showModal()" class="btn">Open Modal</button>
<!-- バックドロップ付きモーダル -->
<dialog id="my_modal_2" class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Modal with backdrop</h3>
<p class="py-4">Click outside to close</p>
</div>
<form method="dialog" class="modal-backdrop">
<button>close</button>
</form>
</dialog>
<!-- レスポンシブモーダル -->
<dialog id="my_modal_3" class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<h3 class="font-bold text-lg">Responsive</h3>
<p class="py-4">Bottom on mobile, middle on desktop</p>
<div class="modal-action">
<button class="btn">Close</button>
</div>
</div>
</dialog>
フォーム
<!-- 入力フィールド -->
<input type="text" placeholder="Default" class="input input-bordered w-full max-w-xs" />
<input type="text" placeholder="Primary" class="input input-bordered input-primary w-full max-w-xs" />
<input type="text" placeholder="Disabled" class="input input-bordered w-full max-w-xs" disabled />
<!-- 入力サイズ -->
<input type="text" class="input input-bordered input-lg" />
<input type="text" class="input input-bordered input-md" />
<input type="text" class="input input-bordered input-sm" />
<input type="text" class="input input-bordered input-xs" />
<!-- テキストエリア -->
<textarea class="textarea textarea-bordered" placeholder="Bio"></textarea>
<!-- セレクト -->
<select class="select select-bordered w-full max-w-xs">
<option disabled selected>Pick one</option>
<option>Option 1</option>
<option>Option 2</option>
</select>
<!-- チェックボックス -->
<input type="checkbox" class="checkbox" />
<input type="checkbox" class="checkbox checkbox-primary" checked />
<input type="checkbox" class="checkbox checkbox-secondary" checked />
<!-- ラジオボタン -->
<input type="radio" name="radio-1" class="radio" checked />
<input type="radio" name="radio-1" class="radio radio-primary" />
<!-- トグル -->
<input type="checkbox" class="toggle" checked />
<input type="checkbox" class="toggle toggle-primary" checked />
<input type="checkbox" class="toggle toggle-secondary" checked />
<!-- 範囲スライダー -->
<input type="range" min="0" max="100" value="50" class="range range-primary" />
<!-- ファイル入力 -->
<input type="file" class="file-input file-input-bordered w-full max-w-xs" />
<!-- ラベル付きフォームコントロール -->
<div class="form-control w-full max-w-xs">
<label class="label">
<span class="label-text">Email</span>
</label>
<input type="text" placeholder="Type here" class="input input-bordered w-full max-w-xs" />
<label class="label">
<span class="label-text-alt">Helper text</span>
</label>
</div>
ナビゲーション
<!-- ナビゲーションバー -->
<div class="navbar bg-base-100">
<div class="flex-1">
<a class="btn btn-ghost text-xl">daisyUI</a>
</div>
<div class="flex-none">
<ul class="menu menu-horizontal px-1">
<li><a>Link</a></li>
<li>
<details>
<summary>Parent</summary>
<ul class="p-2 bg-base-100">
<li><a>Submenu 1</a></li>
<li><a>Submenu 2</a></li>
</ul>
</details>
</li>
</ul>
</div>
</div>
<!-- メニュー -->
<ul class="menu bg-base-200 w-56 rounded-box">
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
<li>
<details open>
<summary>Parent</summary>
<ul>
<li><a>Submenu 1</a></li>
<li><a>Submenu 2</a></li>
</ul>
</details>
</li>
</ul>
<!-- パンくずリスト -->
<div class="text-sm breadcrumbs">
<ul>
<li><a>Home</a></li>
<li><a>Documents</a></li>
<li>Add Document</li>
</ul>
</div>
<!-- タブ -->
<div class="tabs tabs-boxed">
<a class="tab">Tab 1</a>
<a class="tab tab-active">Tab 2</a>
<a class="tab">Tab 3</a>
</div>
<!-- ページネーション -->
<div class="join">
<button class="join-item btn">«</button>
<button class="join-item btn">Page 1</button>
<button class="join-item btn btn-active">2</button>
<button class="join-item btn">3</button>
<button class="join-item btn">»</button>
</div>
レイアウトコンポーネント
<!-- ドロワー(サイドバー) -->
<div class="drawer">
<input id="my-drawer" type="checkbox" class="drawer-toggle" />
<div class="drawer-content">
<label for="my-drawer" class="btn btn-primary drawer-button">Open drawer</label>
</div>
<div class="drawer-side">
<label for="my-drawer" class="drawer-overlay"></label>
<ul class="menu p-4 w-80 min-h-full bg-base-200 text-base-content">
<li><a>Sidebar Item 1</a></li>
<li><a>Sidebar Item 2</a></li>
</ul>
</div>
</div>
<!-- ヒーロー -->
<div class="hero min-h-screen bg-base-200">
<div class="hero-content text-center">
<div class="max-w-md">
<h1 class="text-5xl font-bold">Hello there</h1>
<p class="py-6">Provident cupiditate voluptatem et in.</p>
<button class="btn btn-primary">Get Started</button>
</div>
</div>
</div>
<!-- フッター -->
<footer class="footer p-10 bg-base-200 text-base-content">
<nav>
<h6 class="footer-title">Services</h6>
<a class="link link-hover">Branding</a>
<a class="link link-hover">Design</a>
</nav>
<nav>
<h6 class="footer-title">Company</h6>
<a class="link link-hover">About us</a>
<a class="link link-hover">Contact</a>
</nav>
</footer>
<!-- スタック(層状要素) -->
<div class="stack">
<div class="card shadow-md bg-primary text-primary-content">
<div class="card-body">A</div>
</div>
<div class="card shadow bg-primary text-primary-content">
<div class="card-body">B</div>
</div>
<div class="card shadow-sm bg-primary text-primary-content">
<div class="card-body">C</div>
</div>
</div>
<!-- ディバイダー -->
<div class="flex flex-col w-full">
<div class="divider">OR</div>
</div>
データ表示
<!-- テーブル -->
<div class="overflow-x-auto">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Job</th>
<th>Company</th>
</tr>
</thead>
<tbody>
<tr>
<td>Cy Ganderton</td>
<td>Quality Control Specialist</td>
<td>Littel, Schaden and Vandervort</td>
</tr>
<tr class="hover">
<td>Hart Hagerty</td>
<td>Desktop Support Technician</td>
<td>Zemlak, Daniel and Leannon</td>
</tr>
</tbody>
</table>
</div>
<!-- テーブルバリアント -->
<table class="table table-zebra"><!-- ストライプ行 --></table>
<table class="table table-pin-rows"><!-- ヘッダーピン留め --></table>
<table class="table table-pin-cols"><!-- 列ピン留め --></table>
<!-- バッジ -->
<div class="badge">default</div>
<div class="badge badge-primary">primary</div>
<div class="badge badge-secondary">secondary</div>
<div class="badge badge-accent">accent</div>
<div class="badge badge-ghost">ghost</div>
<div class="badge badge-outline">outline</div>
<!-- スタット -->
<div class="stats shadow">
<div class="stat">
<div class="stat-title">Total Page Views</div>
<div class="stat-value">89,400</div>
<div class="stat-desc">21% more than last month</div>
</div>
</div>
<!-- タイムライン -->
<ul class="timeline timeline-vertical">
<li>
<div class="timeline-start">1984</div>
<div class="timeline-middle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
</div>
<div class="timeline-end timeline-box">First Macintosh computer</div>
<hr/>
</li>
<li>
<hr/>
<div class="timeline-start">1998</div>
<div class="timeline-middle">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" class="w-5 h-5"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.857-9.809a.75.75 0 00-1.214-.882l-3.483 4.79-1.88-1.88a.75.75 0 10-1.06 1.061l2.5 2.5a.75.75 0 001.137-.089l4-5.5z" clip-rule="evenodd" /></svg>
</div>
<div class="timeline-end timeline-box">iMac</div>
<hr/>
</li>
</ul>
<!-- アバター -->
<div class="avatar">
<div class="w-24 rounded-full">
<img src="avatar.jpg" />
</div>
</div>
<!-- アバターグループ -->
<div class="avatar-group -space-x-6 rtl:space-x-reverse">
<div class="avatar">
<div class="w-12">
<img src="avatar1.jpg" />
</div>
</div>
<div class="avatar">
<div class="w-12">
<img src="avatar2.jpg" />
</div>
</div>
</div>
<!-- プログレスバー -->
<progress class="progress progress-primary w-56" value="70" max="100"></progress>
<!-- ラジアルプログレス -->
<div class="radial-progress" style="--value:70;">70%</div>
フィードバックコンポーネント
<!-- アラート -->
<div class="alert">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" class="stroke-info shrink-0 w-6 h-6"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"></path></svg>
<span>Info alert</span>
</div>
<div class="alert alert-success">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
<span>Success alert!</span>
</div>
<div class="alert alert-warning">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" /></svg>
<span>Warning alert!</span>
</div>
<div class="alert alert-error">
<svg xmlns="http://www.w3.org/2000/svg" class="stroke-current shrink-0 h-6 w-6" fill="none" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
<span>Error alert!</span>
</div>
<!-- トースト -->
<div class="toast">
<div class="alert alert-info">
<span>New message arrived.</span>
</div>
</div>
<!-- トースト位置 -->
<div class="toast toast-top toast-end">
<div class="alert alert-info">
<span>Top right</span>
</div>
</div>
<!-- ローディング -->
<span class="loading loading-spinner loading-xs"></span>
<span class="loading loading-spinner loading-sm"></span>
<span class="loading loading-spinner loading-md"></span>
<span class="loading loading-spinner loading-lg"></span>
<!-- ローディングバリアント -->
<span class="loading loading-dots"></span>
<span class="loading loading-ring"></span>
<span class="loading loading-ball"></span>
<span class="loading loading-bars"></span>
<span class="loading loading-infinity"></span>
<!-- ツールチップ -->
<div class="tooltip" data-tip="hello">
<button class="btn">Hover me</button>
</div>
<!-- ツールチップ位置 -->
<div class="tooltip tooltip-right" data-tip="Right">
<button class="btn">Right</button>
</div>
テーマシステム
組み込みテーマ
DaisyUI には 30以上のプリセットテーマが含まれています:
// tailwind.config.js
module.exports = {
daisyui: {
themes: [
"light", // デフォルトライトテーマ
"dark", // デフォルトダークテーマ
"cupcake", // ピンク/パステルテーマ
"bumblebee", // イエローテーマ
"emerald", // グリーンテーマ
"corporate", // プロフェッショナルブルー
"synthwave", // レトロネオン
"retro", // ビンテージブラウン
"cyberpunk", // ネオンイエロー/ピンク
"valentine", // ピンク/レッドロマンティック
"halloween", // オレンジ/パープルスプーキー
"garden", // グリーンネイチャー
"forest", // ダークグリーン
"aqua", // ブルーオーシャン
"lofi", // ローコントラスト
"pastel", // ソフトカラー
"fantasy", // パープル/ピンクファンタジー
"wireframe", // ミニマルブラック/ホワイト
"black", // ダークミニマル
"luxury", // ゴールド/ブラックエレガント
"dracula", // パープルダークテーマ
"cmyk", // プリントカラー
"autumn", // オレンジ/ブラウン
"business", // プロフェッショナルダーク
"acid", // ネオングリーン
"lemonade", // イエロー/グリーンフレッシュ
"night", // ディープブルーダーク
"coffee", // ブラウンコーヒーショップ
"winter", // ブルー/ホワイトコールド
"dim", // ローライトダーク
"nord", // ノルディックブルー/グレー
"sunset", // オレンジ/パープルグラデーション
],
},
}
テーマ切り替え
<!-- HTML 要素にテーマを設定 -->
<html data-theme="cupcake">
<!-- アプリケーション -->
</html>
<!-- JavaScript テーマスイッチャー -->
<script>
function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}
// 保存されたテーマを読み込み
const savedTheme = localStorage.getItem('theme') || 'light';
setTheme(savedTheme);
</script>
<!-- テーマスイッチャー UI -->
<select class="select select-bordered" onchange="setTheme(this.value)">
<option value="light">Light</option>
<option value="dark">Dark</option>
<option value="cupcake">Cupcake</option>
<option value="synthwave">Synthwave</option>
</select>
ダークモード
// システム設定に基づいた自動ダークモード
module.exports = {
daisyui: {
themes: ["light", "dark"],
darkTheme: "dark",
},
}
<!-- システム設定を検出 -->
<script>
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
document.documentElement.setAttribute('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
}
</script>
カスタムテーマ
// tailwind.config.js
module.exports = {
daisyui: {
themes: [
{
mytheme: {
"primary": "#a991f7",
"secondary": "#f6d860",
"accent": "#37cdbe",
"neutral": "#3d4451",
"base-100": "#ffffff",
"info": "#3abff8",
"success": "#36d399",
"warning": "#fbbd23",
"error": "#f87272",
},
},
],
},
}
既存テーマの拡張
module.exports = {
daisyui: {
themes: [
{
light: {
...require("daisyui/src/theming/themes")["light"],
primary: "#0000ff", // プライマリカラーをオーバーライド
".btn-twitter": { // カスタムコンポーネント
"background-color": "#1da1f2",
"border-color": "#1da1f2",
},
},
},
],
},
}
CSS 変数カスタマイズ
/* テーマ変数をオーバーライド */
[data-theme="mytheme"] {
--rounded-box: 1rem;
--rounded-btn: 0.5rem;
--rounded-badge: 1.9rem;
--animation-btn: 0.25s;
--animation-input: 0.2s;
--btn-text-case: uppercase;
--btn-focus-scale: 0.95;
--border-btn: 1px;
--tab-border: 1px;
--tab-radius: 0.5rem;
}
カラーシステム
セマンティックカラー
DaisyUI はテーマに適応するセマンティックカラー名を使用します:
<!-- 背景色 -->
<div class="bg-primary">Primary background</div>
<div class="bg-secondary">Secondary background</div>
<div class="bg-accent">Accent background</div>
<div class="bg-neutral">Neutral background</div>
<div class="bg-base-100">Base background (main)</div>
<div class="bg-base-200">Base background (lighter)</div>
<div class="bg-base-300">Base background (even lighter)</div>
<div class="bg-info">Info background</div>
<div class="bg-success">Success background</div>
<div class="bg-warning">Warning background</div>
<div class="bg-error">Error background</div>
<!-- テキスト色 -->
<p class="text-primary">Primary text</p>
<p class="text-primary-content">Text on primary background</p>
<p class="text-secondary">Secondary text</p>
<p class="text-secondary-content">Text on secondary background</p>
<p class="text-accent">Accent text</p>
<p class="text-accent-content">Text on accent background</p>
<p class="text-neutral">Neutral text</p>
<p class="text-neutral-content">Text on neutral background</p>
<p class="text-base-content">Base text color</p>
<!-- ボーダー色 -->
<div class="border border-primary">Primary border</div>
<div class="border border-secondary">Secondary border</div>
カラーユーティリティ
<!-- ガラス効果(フロストガラス) -->
<div class="glass">Glassmorphism effect</div>
<!-- ゴーストバリアント(透明) -->
<button class="btn btn-ghost">Ghost button</button>
<!-- アウトラインバリアント -->
<button class="btn btn-outline btn-primary">Outlined</button>
フレームワーク統合
React
import React from 'react';
// DaisyUI はプレーン HTML クラスで動作
function App() {
return (
<div className="card w-96 bg-base-100 shadow-xl">
<div className="card-body">
<h2 className="card-title">Card Title</h2>
<p>Card description</p>
<div className="card-actions justify-end">
<button className="btn btn-primary">Action</button>
</div>
</div>
</div>
);
}
// モーダルコンポーネント
function Modal({ children, id }) {
return (
<dialog id={id} className="modal">
<div className="modal-box">
{children}
<div className="modal-action">
<form method="dialog">
<button className="btn">Close</button>
</form>
</div>
</div>
</dialog>
);
}
// 使用法
function App() {
return (
<>
<button onClick={() => document.getElementById('my_modal').showModal()}
className="btn">
Open Modal
</button>
<Modal id="my_modal">
<h3 className="font-bold text-lg">Hello!</h3>
<p className="py-4">Modal content</p>
</Modal>
</>
);
}
Vue
<template>
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Card Title</h2>
<p>Card description</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">Action</button>
</div>
</div>
</div>
</template>
<!-- モーダルコンポーネント -->
<template>
<dialog ref="modal" class="modal">
<div class="modal-box">
<slot></slot>
<div class="modal-action">
<button @click="close" class="btn">Close</button>
</div>
</div>
</dialog>
</template>
<script setup>
import { ref } from 'vue';
const modal = ref(null);
function open() {
modal.value.showModal();
}
function close() {
modal.value.close();
}
defineExpose({ open, close });
</script>
Svelte
<script>
let modal;
function openModal() {
modal.showModal();
}
</script>
<button on:click={openModal} class="btn btn-primary">
Open Modal
</button>
<dialog bind:this={modal} class="modal">
<div class="modal-box">
<h3 class="font-bold text-lg">Hello!</h3>
<p class="py-4">Modal content</p>
<div class="modal-action">
<form method="dialog">
<button class="btn">Close</button>
</form>
</div>
</div>
</dialog>
<!-- カードコンポーネント -->
<div class="card w-96 bg-base-100 shadow-xl">
<div class="card-body">
<h2 class="card-title">Card Title</h2>
<p>Card description</p>
<div class="card-actions justify-end">
<button class="btn btn-primary">Action</button>
</div>
</div>
</div>
レスポンシブデザイン
レスポンシブユーティリティ
<!-- レスポンシブモディファイア(Tailwind ブレークポイント) -->
<button class="btn btn-sm md:btn-md lg:btn-lg">
Responsive size button
</button>
<div class="drawer drawer-mobile">
<input type="checkbox" class="drawer-toggle" />
<div class="drawer-content">
<!-- メインコンテンツ(デスクトップではサイドバーが常に表示) -->
</div>
<div class="drawer-side">
<!-- サイドバー -->
</div>
</div>
<!-- レスポンシブモーダル位置 -->
<dialog class="modal modal-bottom sm:modal-middle">
<div class="modal-box">
<p>Bottom on mobile, centered on desktop</p>
</div>
</dialog>
<!-- レスポンシブナビゲーションバー -->
<div class="navbar bg-base-100">
<div class="navbar-start">
<div class="dropdown">
<label tabindex="0" class="btn btn-ghost lg:hidden">
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h8m-8 6h16" /></svg>
</label>
<ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
</div>
</div>
<div class="navbar-center hidden lg:flex">
<ul class="menu menu-horizontal px-1">
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
</div>
</div>
モバイルファースト方式
<!-- モバイルではスタック、デスクトップではグリッド -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
<div class="card bg-base-100 shadow-xl">Card 1</div>
<div class="card bg-base-100 shadow-xl">Card 2</div>
<div class="card bg-base-100 shadow-xl">Card 3</div>
</div>
<!-- モバイルで非表示 -->
<div class="hidden md:block">Desktop only content</div>
<!-- モバイルのみで表示 -->
<div class="block md:hidden">Mobile only content</div>
高度な設定
完全な設定
// tailwind.config.js
module.exports = {
content: ["./src/**/*.{html,js,jsx,ts,tsx}"],
plugins: [require("daisyui")],
daisyui: {
themes: [
"light",
"dark",
{
mytheme: {
primary: "#570df8",
secondary: "#f000b8",
accent: "#37cdbe",
neutral: "#3d4451",
"base-100": "#ffffff",
info: "#3abff8",
success: "#36d399",
warning: "#fbbd23",
error: "#f87272",
},
},
],
darkTheme: "dark",
base: true,
styled: true,
utils: true,
prefix: "",
logs: true,
themeRoot: ":root",
},
}
設定オプション
- themes: テーマ名またはカスタムテーマオブジェクトの配列
- darkTheme: ダークモードで使用するテーマ(デフォルト: "dark")
- base: ベーススタイルを適用(デフォルト: true)
- styled: コンポーネントスタイルを適用(デフォルト: true)
- utils: ユーティリティクラスを適用(デフォルト: true)
- prefix: すべての daisyUI クラスのプレフィックス(デフォルト: "")
- logs: ビルド中にターミナルに情報を表示(デフォルト: true)
- themeRoot: テーマのルート要素(デフォルト: ":root")
ベーススタイルを無効化
// コンポーネントのみを使用、ベーススタイルは不使用
module.exports = {
daisyui: {
base: false, // HTML ベーススタイルを適用しない
styled: true,
utils: true,
},
}
クラスプレフィックス
// 競合を避けるためプレフィックスを追加
module.exports = {
daisyui: {
prefix: "daisy-",
},
}
<!-- daisy- プレフィックスを使用 -->
<button class="daisy-btn daisy-btn-primary">Button</button>
ベストプラクティス
コンポーネント組織
// 再利用可能なコンポーネントライブラリを作成
// components/Button.jsx
export function Button({ variant = 'primary', size = 'md', children, ...props }) {
return (
<button
className={`btn btn-${variant} btn-${size}`}
{...props}
>
{children}
</button>
);
}
// 使用法
<Button variant="primary" size="lg">Click me</Button>
テーマ管理
// utils/theme.js
export const THEMES = [
'light', 'dark', 'cupcake', 'bumblebee', 'emerald', 'corporate'
];
export function getTheme() {
return localStorage.getItem('theme') || 'light';
}
export function setTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme);
}
export function toggleDarkMode() {
const current = getTheme();
const next = current === 'light' ? 'dark' : 'light';
setTheme(next);
}
アクセシビリティ
<!-- セマンティック HTML を使用 -->
<button class="btn" aria-label="Close dialog">
<svg><!-- icon --></svg>
</button>
<!-- 適切なフォームラベル -->
<div class="form-control">
<label class="label" for="email-input">
<span class="label-text">Email</span>
</label>
<input
id="email-input"
type="email"
class="input input-bordered"
aria-describedby="email-help"
/>
<label class="label">
<span id="email-help" class="label-text-alt">We'll never share your email</span>
</label>
</div>
<!-- キーボードナビゲーション -->
<div role="tablist" class="tabs tabs-boxed">
<button role="tab" class="tab" aria-selected="true">Tab 1</button>
<button role="tab" class="tab" aria-selected="false">Tab 2</button>
</div>
パフォーマンス最適化
// 使用するテーマのみをインポート
module.exports = {
daisyui: {
themes: ["light", "dark"], // これら 2 つのテーマのみ
},
}
// またはカスタムテーマのみを使用
module.exports = {
daisyui: {
themes: [
{
light: { /* カスタムライト */ },
dark: { /* カスタムダーク */ },
},
],
},
}
Tailwind との組み合わせ
<!-- DaisyUI コンポーネント + Tailwind ユーティリティ -->
<button class="btn btn-primary rounded-full shadow-lg hover:shadow-xl transition-all">
Styled button
</button>
<!-- レイアウトには Tailwind を、コンポーネントには DaisyUI を使用 -->
<div class="container mx-auto px-4 py-8">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="card bg-base-100 shadow-xl">Card 1</div>
<div class="card bg-base-100 shadow-xl">Card 2</div>
<div class="card bg-base-100 shadow-xl">Card 3</div>
</div>
</div>
一般的なパターン
ローディング状態
function DataComponent() {
const [loading, setLoading] = useState(true);
if (loading) {
return (
<div className="flex justify-center items-center min-h-screen">
<span className="loading loading-spinner loading-lg"></span>
</div>
);
}
return <div>Data content</div>;
}
フォーム検証
function LoginForm() {
const [errors, setErrors] = useState({});
return (
<form className="space-y-4">
<div className="form-control">
<label className="label">
<span className="label-text">Email</span>
</label>
<input
type="email"
className={`input input-bordered ${errors.email ? 'input-error' : ''}`}
/>
{errors.email && (
<label className="label">
<span className="label-text-alt text-error">{errors.email}</span>
</label>
)}
</div>
<button type="submit" className="btn btn-primary btn-block">
Login
</button>
</form>
);
}
ドロップダウンメニュー
<div class="dropdown dropdown-end">
<label tabindex="0" class="btn btn-ghost">
Click
</label>
<ul tabindex="0" class="dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52">
<li><a>Item 1</a></li>
<li><a>Item 2</a></li>
</ul>
</div>
通知トースト
function showToast(message, type = 'info') {
const toast = document.createElement('div');
toast.className = 'toast toast-top toast-end';
toast.innerHTML = `
<div class="alert alert-${type}">
<span>${message}</span>
</div>
`;
document.body.appendChild(toast);
setTimeout(() => toast.remove(), 3000);
}
// 使用法
showToast('Operation successful!', 'success');
showToast('An error occurred', 'error');
トラブルシューティング
スタイルが適用されない
// DaisyUI が Tailwind プラグインにあることを確認
module.exports = {
plugins: [require("daisyui")],
}
// content パスがファイルを含むことを確認
module.exports = {
content: [
"./src/**/*.{html,js,jsx,ts,tsx}",
"./pages/**/*.{html,js,jsx,ts,tsx}",
],
}
テーマが変更されない
<!-- data-theme 属性が設定されていることを確認 -->
<html data-theme="dark">
<!-- JavaScript が実行されていることを確認 -->
<script>
console.log(document.documentElement.getAttribute('data-theme'));
</script>
モーダルが開かない
// ネイティブ dialog API を使用
const modal = document.getElementById('my_modal');
modal.showModal(); // モーダルを開く
modal.close(); // モーダルを閉じる
// またはチェックボックスで非dialog実装を使用
Tailwind との競合
// 競合を避けるためプレフィックスを使用
module.exports = {
daisyui: {
prefix: "d-",
},
}
リソース
- 公式ドキュメント: https://daisyui.com
- GitHub リポジトリ: https://github.com/saadeghi/daisyui
- コンポーネントエクスプローラー: https://daisyui.com/components/
- テーマジェネレータ: https://daisyui.com/theme-generator/
- コミュニティテーマ: https://github.com/saadeghi/daisyui/discussions
- NPM パッケージ: https://www.npmjs.com/package/daisyui
- Tailwind CSS ドキュメント: https://tailwindcss.com
マイグレーションガイド
プレーン Tailwind から
<!-- 前(Tailwind のみ) -->
<button class="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600">
Button
</button>
<!-- 後(DaisyUI) -->
<button class="btn btn-primary">
Button
</button>
Bootstrap から
<!-- Bootstrap -->
<button class="btn btn-primary">Button</button>
<div class="card">
<div class="card-body">Content</div>
</div>
<!-- DaisyUI(非常に似ています!) -->
<button class="btn btn-primary">Button</button>
<div class="card">
<div class="card-body">Content</div>
</div>
バージョン更新
# 現在のバージョンを確認
npm list daisyui
# 最新版に更新
npm install -D daisyui@latest
# 変更ログを確認
# https://github.com/saadeghi/daisyui/releases
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- bobmatnyc
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/bobmatnyc/claude-mpm-skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。