Calendar
単一、範囲、複数選択に対応する日付グリッドです。月のスライド、範囲のプレビュー、タッチしやすいサイズの日付セルを備えています。
| Su | Mo | Tu | We | Th | Fr | Sa |
|---|---|---|---|---|---|---|
pnpm dlx shadcn@latest add https://hextaui.com/r/calendar.jsonコンポーネント、HextaUIのテーマトークン、依存するHextaUIコンポーネントを追加します。
まだ追加していない場合は、グローバルCSSにテーマトークンを追加してください。
依存関係をインストールします。
pnpm add react-day-picker @base-ui/react @tabler/icons-react class-variance-authority cn次のコードをコピーしてプロジェクトに貼り付けてください。
components/ui/calendar.tsx components/ui/button.tsx lib/motion.ts インポートパスは、お使いのプロジェクト構成に合わせて更新してください。
Calendar は react-day-picker の <DayPicker /> をラップしているため、DayPicker のすべての props が daypicker.dev に記載のとおりに動作します。HextaUI は、スタイリング、月の切り替えアニメーション、範囲のプレビュー、ハイドレーションに安全な today を追加します。
範囲
mode="range" では、最初のクリックの後に日付へホバーまたはフォーカスすると、次のクリックで選択される範囲がプレビューされます。numberOfMonths は月を横に並べて表示し、狭い画面では縦に積みます。
範囲の制限
min と max は範囲の日数を制限します。excludeDisabled を指定すると、無効な日を含む範囲は、含めずに最初からやり直しになります。
複数
mode="multiple" は個々の日付を切り替えます。max は選択できる数の上限を設定します。
月と年のドロップダウン
captionLayout="dropdown" はキャプションをネイティブの select に置き換えるため、スマートフォンでは標準のピッカーが使われます。年の範囲を限定するには startMonth と endMonth を設定します。
範囲を限定
移動は startMonth と endMonth で止まり、disabled はその範囲外の日を無効にします。useToday() は、サーバーレンダリング中も安全に使える今日の日付を返します。
制御された month
month と onMonthChange を渡すと、表示中の月を制御できます。ジャンプは移動の向きにスライドし、高さは 5 行と 6 行の週の間でイージングします。
週番号
showWeekNumber は週の列を追加します。ISOWeek は月曜始まりの ISO 週番号を使います。showOutsideDays={false} は他の月の日付を非表示にします。
固定された today
today を渡すと、ハイライトする日を固定できます。テストや別のタイムゾーンに使えます。animate={false} は月の切り替えアニメーションを無効にします。
シートの中
シート、ポップオーバー、ダイアログの内側では、カレンダーは独自の背景をなくし、面に溶け込みます。
右から左
react-day-picker/locale の locale と dir="rtl" を渡します。矢印、ナビゲーション、スライドの向きがすべて反転します。dir="rtl" の DirectionProvider の内側では、方向が自動的に取得されます。
日付にフォーカスしてから、これらのキーを使います。表示中の月を越えると、月が切り替わります。
| キー | アクション |
|---|---|
| ←→ | 前日または翌日。右から左のレイアウトでは逆になります。 |
| ↑↓ | 前週または翌週の同じ曜日。 |
| Shift←→ | 前月または翌月。 |
| Shift↑↓ | 前年または翌年。 |
| Page UpPage Down | 前月または翌月。 |
| ShiftPage UpPage Down | 前年または翌年。 |
| Home | 週の最初の日。 |
| End | 週の最後の日。 |
| EnterSpace | フォーカス中の日を選択します。 |
- 月はグリッドです。各日付は完全な日付ラベルを持つボタンで、選択された日付には
aria-selectedが設定されます。 - キーボードによる月の切り替えは、スライドをスキップしてフェードのみになるため、動くグリッドの下でフォーカスが移動することはありません。
- モーションの低減が有効な場合、月の切り替えはフェードになり、高さの変化は即座に行われます。
- タッチスクリーンでは、日付セルが 44px に拡大します。
<DayPicker /> のすべての props を受け付けます。以下のデフォルト値は、DayPicker のものと異なるか、HextaUI が追加したものです。
| プロパティ | 型 | デフォルト |
|---|---|---|
modemode がない場合、日付は選択できません。 | "single" | "multiple" | "range" | – |
selectedmode に合わせます。 | Date | Date[] | DateRange | – |
onSelect | (selected, triggerDate, modifiers, event) => void | – |
required最後の選択を解除できないようにします。 | boolean | – |
min範囲の最小日数、または multiple モードでの最小選択数。 | number | – |
max範囲の最大日数、または multiple モードでの最大選択数。 | number | – |
excludeDisabledrange モード。 | boolean | – |
disabled | Matcher | Matcher[] | – |
month制御された month。 | Date | – |
defaultMonth | Date | – |
onMonthChange | (month: Date) => void | – |
startMonth | Date | – |
endMonth | Date | – |
numberOfMonths | number | 1 |
captionLayout | "label" | "dropdown" | "dropdown-months" | "dropdown-years" | "label" |
navLayoutHextaUI のデフォルト。矢印はキャプションの両側に配置されます。 | "around" | "after" | "around" |
showOutsideDaysHextaUI のデフォルト。 | boolean | true |
animate月のスライドと高さのトランジション。HextaUI のデフォルト。 | boolean | true |
buttonVariant前へ・次へボタンの variant。 | Button variant | "ghost" |
showWeekNumber | boolean | false |
ISOWeek | boolean | false |
weekStartsOn | 0 | 1 | 2 | 3 | 4 | 5 | 6 | – |
fixedWeeks | boolean | false |
todayデフォルトはクライアントの今日で、日付変更時やハイドレーションをまたいで同期されます。 | Date | – |
timeZone | string | – |
locale | Partial<DayPickerLocale> | – |
dir | "ltr" | "rtl" | – |
footer | ReactNode | – |
| 属性 | 説明 |
|---|---|
data-slot="calendar" | CSS でカレンダーのルートを指定します。 |
--cell-size | 日付セルのサイズ。36px で、タッチスクリーンでは 44px です。 |
--cell-radius | 日付セルとボタンの角丸の半径。 |
data-slot="calendar-day" | 日付セル。data-selected、data-disabled、data-outside、data-today、data-hidden、data-focused を持ちます。 |
data-preview | 日付セルに付与されます: ホバー中の範囲プレビューの開始、中間、終了。 |
data-range-middle | 選択された範囲内の日付セルに付与されます。 |
各日付の内側のボタン。独自のものを components={{ DayButton }} に渡し、スタイルを維持するにはこのコンポーネントを再利用します。
| 属性 | 説明 |
|---|---|
data-slot="calendar-day-button" | CSS で日付ボタンを指定します。 |
data-day | 2026-10-03 のような ISO 形式の日付。 |
data-today | 今日に付与されます。範囲外の日は除きます。 |
data-selected-single | 範囲外で選択された日。 |
data-range-start | 範囲の最初の日。 |
data-range-middle | 範囲内の日。 |
data-range-end | 範囲の最後の日。 |
クライアントでは今日を Date で、サーバーレンダリング中は undefined を返すため、これを使って作った境界値がハイドレーションの不一致を起こすことはありません。日付が変わる時刻に更新されます。useToday のガイドを参照してください。
- Buttonすべてのバリアントとサイズのボタンです。読み込み、成功、エラーのフローを内蔵し、高速なリクエストではスピナーを省略します。
- Motionすべてのコンポーネントがアニメーションに使うイージングカーブ、継続時間、モーション軽減のチェックと、サイズのモーフィングやスライドするハイライト用のフックです。
- useToday日付が変わる時刻とタブに戻ったときに切り替わる今日の日付。ハイドレーションの不一致は起こりません。
- Checkboxチェックが描かれるように表示されるチェックボックスです。中間状態の親、グループ、ホバーを共有するラベルに対応します。
- Comboboxチップ、グループ、非同期の結果に対応した、絞り込み可能なセレクトです。入力に合わせてポップアップのサイズが変わります。
- Date picker押すとポップオーバーでカレンダーを開くボタンです。スマートフォンではボトムシートになり、単一の日付も範囲も選べます。