Caroa UI

DatePicker

日付選択コンポーネント。入力欄への直接入力とカレンダー選択の両方に対応。

インポート

import { DatePicker } from '@caroainc/ui-components/client'

個別サブパス:

import { DatePicker } from '@caroainc/ui-components/date-picker'

注意: DatePickericonName propで実行時にアイコンを選べる設計のため、内部で全アイコンを参照する動的解決を経由します。このサブパスを使ってもlucide-reactの全アイコンがバンドルに含まれるため、バンドルサイズ削減効果はありません(他コンポーネントのサブパスとは異なります)。他の依存を絞る目的では有効です。


基本的な使い方

日付を選択するシンプルなパターンです。

Loading...
const [date, setDate] = useState<Date | undefined>()
 
<DatePicker value={date} onChange={setDate} />

カレンダーのみ(即時選択)

closeOnSelect を指定すると、日付をクリックした瞬間に確定してポップオーバーが閉じます。 カレンダー下部の日付入力欄・クリア/決定ボタンが非表示になり、シンプルなカレンダーのみの表示になります (トリガー側の入力欄は非表示にはならず、確定した日付がそのまま反映されます)。

Loading...
const [date, setDate] = useState<Date | undefined>()
 
<DatePicker
  value={date}
  onChange={setDate}
  closeOnSelect
/>

サイズ

3つのサイズが用意されています。

Loading...
<DatePicker size="sm" value={date} onChange={setDate} />
<DatePicker size="default" value={date} onChange={setDate} />
<DatePicker size="lg" value={date} onChange={setDate} />

曜日表示

showDayOfWeek を指定すると、曜日も表示されます。

Loading...
<DatePicker value={date} onChange={setDate} showDayOfWeek />
// → 2026/01/21(火)

カスタムアイコン

iconName でカレンダーアイコンを変更できます。デフォルトは Calendar です。

Loading...
<DatePicker value={date} onChange={setDate} iconName="CalendarDays" />

アイコン非表示

showIcon={false} でアイコンを非表示にできます。

Loading...
<DatePicker value={date} onChange={setDate} showIcon={false} />

プレースホルダー

Loading...
<DatePicker
  value={date}
  onChange={setDate}
  placeholder="期日を設定"
/>

無効状態

Loading...
<DatePicker
  value={date}
  onChange={setDate}
  disabled
/>

選択可能な日付の範囲を制限

minDate / maxDate で選択可能な日付範囲を制限できます。範囲外の日付はカレンダー上で無効化され、 トリガー入力欄への手入力も範囲外の場合は確定されません(フォーカスが外れても反映されず、 入力自体は残ります)。より複雑な条件は disabledDates(react-day-pickerのMatcher)で指定できます。

Loading...
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] }} // 土日を無効化
/>

実際の使用例

フォーム内での使用

Loading...
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を使用してください)。

Loading...
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

PropTypeDefaultDescription
valueDate-選択された日付
onChange*(date: Date | undefined) => void-日付が変更された時のコールバック
placeholderstring'yyyy/MM/dd'プレースホルダーテキスト
iconNameIconName'Calendar'トリガーに表示するアイコン
showIconbooleantrueアイコンを表示するか
size'sm' | 'default' | 'lg''default'トリガーボタンのサイズ
disabledbooleanfalse無効状態
closeOnSelectbooleanfalse日付クリックで即座に確定する。trueの場合、カレンダーのみ表示になり、クリックで即座にonChangeが呼ばれてポップオーバーが閉じる
showDayOfWeekbooleanfalse曜日を表示する(例: 2026/01/21(火))
minDateDate-選択可能な最小日付。これより前の日付はカレンダー上で無効化され、手入力でも確定されない
maxDateDate-選択可能な最大日付。これより後の日付はカレンダー上で無効化され、手入力でも確定されない
disabledDatesMatcher | Matcher[]-追加で無効化する日付の条件(react-day-pickerのMatcher)。カレンダーUI側にのみ適用され、手入力のバリデーション対象はminDate/maxDateのみ
captionLayout'label' | 'buttons' | 'dropdown' | 'dropdown-months' | 'dropdown-years''label'カレンダーのキャプション(月・年移動UI)表示形式。Calendarへそのまま透過される
classNamestring-追加のクラス名

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)が取得できます