使い方
Caroa UIの基本的な使い方
Server Components vs Client Components
Next.js App Routerでは、コンポーネントの種類に応じてインポート先を分けます。
Server Components
プレゼンテーショナルなコンポーネントは/serverからインポート:
import { Button, Card, Badge, Input } from '@caroainc/ui-components/server'
export default function Page() {
return (
<Card>
<Button>送信</Button>
</Card>
)
}Client Components
インタラクティブなコンポーネントは/clientからインポート:
'use client'
import { Dialog, Tabs, Select } from '@caroainc/ui-components/client'カラーバリアント
Caroa UIのカラーバリアントは以下のルールに従います:
| バリアント | 色 | 用途 |
|---|---|---|
base(デフォルト) | 黒 | 通常のUI要素 |
primary | オレンジ | CTA、重要なアクション |
destructive | 赤 | 削除、危険な操作 |
success | 緑 | 成功、完了 |
warning | 黄 | 警告、注意 |
<Button>通常</Button>
<Button variant="primary">重要</Button>
<Button variant="destructive">削除</Button>フォーム連携
react-hook-formと連携したフォームコンポーネント:
'use client'
import { useForm } from 'react-hook-form'
import { Form, FormField, FormItem, FormLabel, FormControl } from '@caroainc/ui-components/form'
import { Input, Button } from '@caroainc/ui-components/server'
export function MyForm() {
const form = useForm()
return (
<Form {...form}>
<form onSubmit={form.handleSubmit(console.log)}>
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>メール</FormLabel>
<FormControl>
<Input {...field} />
</FormControl>
</FormItem>
)}
/>
<Button type="submit">送信</Button>
</form>
</Form>
)
}data属性によるコンポーネント識別
DOM要素をレンダリングする各コンポーネント・サブコンポーネントに、2つのdata属性が付きます。
| 属性 | 値 | 用途 |
|---|---|---|
data-caroa-ui | 固定 | Caroa UIのコンポーネントであることの識別。CSSスコープやデバッグに使う |
data-slot | 部品名のケバブケース | どの部品かの識別。例: data-slot="button", data-slot="select-trigger" |
サブコンポーネントにもそれぞれ固有の data-slot が付きます(例: Cardは card / card-header / card-content)。E2EテストのセレクタやCSSでの限定的な上書きに利用できます。
ただし、ルートが自前のDOM要素を描画しないコンポーネントには、ルート名の属性は実DOMに現れません。Radixのコンテキストプロバイダをラップしている Select / Dialog / Popover / Tooltip / HoverCard 等のルートがこれに該当します。セレクタは select ではなく、実際に描画される select-trigger / select-content / dialog-content のようなサブコンポーネントのslot名で書いてください。
/* 例: Caroa UIのSelectトリガーだけに適用するスタイル */
[data-caroa-ui][data-slot='select-trigger'] {
min-width: 200px;
}注意: Toaster(Sonner)はサードパーティ実装がpropsをDOMへ透過しないため、この属性が実DOMに出力されません。