DatePicker
日付選択コンポーネント。入力欄への直接入力とカレンダー選択の両方に対応。
インポート
import { DatePicker } from '@caroainc/ui-components/client'個別サブパス:
import { DatePicker } from '@caroainc/ui-components/date-picker'注意:
DatePickerはiconNamepropで実行時にアイコンを選べる設計のため、内部で全アイコンを参照する動的解決を経由します。このサブパスを使ってもlucide-reactの全アイコンがバンドルに含まれるため、バンドルサイズ削減効果はありません(他コンポーネントのサブパスとは異なります)。他の依存を絞る目的では有効です。
基本的な使い方
日付を選択するシンプルなパターンです。
const [date, setDate] = useState<Date | undefined>()
<DatePicker value={date} onChange={setDate} />カレンダーのみ(即時選択)
closeOnSelect を指定すると、日付をクリックした瞬間に確定してポップオーバーが閉じます。
カレンダー下部の日付入力欄・クリア/決定ボタンが非表示になり、シンプルなカレンダーのみの表示になります
(トリガー側の入力欄は非表示にはならず、確定した日付がそのまま反映されます)。
const [date, setDate] = useState<Date | undefined>()
<DatePicker
value={date}
onChange={setDate}
closeOnSelect
/>サイズ
3つのサイズが用意されています。
<DatePicker size="sm" value={date} onChange={setDate} />
<DatePicker size="default" value={date} onChange={setDate} />
<DatePicker size="lg" value={date} onChange={setDate} />曜日表示
showDayOfWeek を指定すると、曜日も表示されます。
<DatePicker value={date} onChange={setDate} showDayOfWeek />
// → 2026/01/21(火)カスタムアイコン
iconName でカレンダーアイコンを変更できます。デフォルトは Calendar です。
<DatePicker value={date} onChange={setDate} iconName="CalendarDays" />アイコン非表示
showIcon={false} でアイコンを非表示にできます。
<DatePicker value={date} onChange={setDate} showIcon={false} />プレースホルダー
<DatePicker
value={date}
onChange={setDate}
placeholder="期日を設定"
/>無効状態
<DatePicker
value={date}
onChange={setDate}
disabled
/>選択可能な日付の範囲を制限
minDate / maxDate で選択可能な日付範囲を制限できます。範囲外の日付はカレンダー上で無効化され、
トリガー入力欄への手入力も範囲外の場合は確定されません(フォーカスが外れても反映されず、
入力自体は残ります)。より複雑な条件は disabledDates(react-day-pickerのMatcher)で指定できます。
const today = new Date()
today.setHours(0, 0, 0, 0)
const maxDate = new Date(today)
maxDate.setDate(maxDate.getDate() + 30)
<DatePicker
value={date}
onChange={setDate}
minDate={today}
maxDate={maxDate}
/>
// 特定の曜日だけ無効化したい場合はdisabledDatesを使う
<DatePicker
value={date}
onChange={setDate}
disabledDates={{ dayOfWeek: [0, 6] }} // 土日を無効化
/>実際の使用例
フォーム内での使用
import { Field, FieldLabel } from '@caroainc/ui-components/client'
import { DatePicker } from '@caroainc/ui-components/client'
function TaskForm() {
const [dueDate, setDueDate] = useState<Date | undefined>()
return (
<Field>
<FieldLabel>期日</FieldLabel>
<DatePicker
value={dueDate}
onChange={setDueDate}
placeholder="期日を選択"
/>
</Field>
)
}react-hook-formとの連携
id / name / ref / aria-invalid / aria-describedby などの標準的なinput属性はトリガー入力欄まで透過されるため、
Controller 経由でreact-hook-formと組み合わせられます(onChangeはDate型を返すためregister()の直接展開ではなくControllerを使用してください)。
import { useForm, Controller } from 'react-hook-form'
import { DatePicker, Field, FieldLabel } from '@caroainc/ui-components/client'
interface ReservationFormValues {
visitDate: Date | undefined
}
function ReservationForm() {
const { control, handleSubmit, formState } = useForm<ReservationFormValues>({
defaultValues: { visitDate: undefined },
})
return (
<form onSubmit={handleSubmit((values) => console.log(values))}>
<Field>
<FieldLabel>来店日</FieldLabel>
<Controller
control={control}
name="visitDate"
rules={{ required: '来店日を選択してください' }}
render={({ field, fieldState }) => (
<DatePicker
id="visit-date"
name={field.name}
ref={field.ref}
value={field.value}
onChange={field.onChange}
onBlur={field.onBlur}
aria-invalid={fieldState.invalid}
aria-describedby={fieldState.error ? 'visit-date-error' : undefined}
/>
)}
/>
{formState.errors.visitDate && (
<p id="visit-date-error">{formState.errors.visitDate.message}</p>
)}
</Field>
</form>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
value | Date | - | 選択された日付 |
onChange* | (date: Date | undefined) => void | - | 日付が変更された時のコールバック |
placeholder | string | 'yyyy/MM/dd' | プレースホルダーテキスト |
iconName | IconName | 'Calendar' | トリガーに表示するアイコン |
showIcon | boolean | true | アイコンを表示するか |
size | 'sm' | 'default' | 'lg' | 'default' | トリガーボタンのサイズ |
disabled | boolean | false | 無効状態 |
closeOnSelect | boolean | false | 日付クリックで即座に確定する。trueの場合、カレンダーのみ表示になり、クリックで即座にonChangeが呼ばれてポップオーバーが閉じる |
showDayOfWeek | boolean | false | 曜日を表示する(例: 2026/01/21(火)) |
minDate | Date | - | 選択可能な最小日付。これより前の日付はカレンダー上で無効化され、手入力でも確定されない |
maxDate | Date | - | 選択可能な最大日付。これより後の日付はカレンダー上で無効化され、手入力でも確定されない |
disabledDates | Matcher | Matcher[] | - | 追加で無効化する日付の条件(react-day-pickerのMatcher)。カレンダーUI側にのみ適用され、手入力のバリデーション対象はminDate/maxDateのみ |
captionLayout | 'label' | 'buttons' | 'dropdown' | 'dropdown-months' | 'dropdown-years' | 'label' | カレンダーのキャプション(月・年移動UI)表示形式。Calendarへそのまま透過される |
className | string | - | 追加のクラス名 |
id / name / required / aria-invalid / aria-describedby / onBlur など、上記に無い標準のinput属性は
トリガー入力欄(input[type=text])へそのまま透過されます(value / onChange / defaultValue / placeholder /
disabled / type は独自の意味を持つため除外されます)。
注意事項
- 入力欄に直接日付を入力できます(
yyyy/MM/ddまたはyyyy-MM-dd形式) - フォーカスが外れた時に入力値が確定されます(
minDate/maxDateの範囲外は確定されず、入力値はそのまま残ります) - 時刻が必要な場合は、DatePickerとTimePickerを組み合わせて使用してください
refを渡すとトリガー入力欄(HTMLInputElement)が取得できます