日付範囲ピッカーライブラリ比較
4つのアプローチで日付範囲を選択するUIを実装し、機能とスタイルを比較
共通の初期設定
各デモでは本日から7日後までを初期選択期間として設定しています。カレンダーから日付範囲を選択でき、選択結果がリアルタイムに表示されます。
{
"startDate": "2026-05-24",
"endDate": "2026-05-31",
"locale": "ja (日本語)"
}1. react-datepicker
最も人気のあるReact日付ピッカー — 豊富な機能と柔軟なカスタマイズ性
選択中:2026年5月24日 〜 2026年5月31日(7日間)
インラインカレンダー表示
5月 2026
6月 2026
特徴
- • ポップアップ・インライン両対応のカレンダー表示
- • 範囲選択・複数月表示・時刻選択に対応
- • ロケール設定で日本語表示が可能
- • 最小日・最大日の制限、除外日の設定が容易
インストール
npm install react-datepicker date-fns'use client';
import DatePicker from 'react-datepicker';
import 'react-datepicker/dist/react-datepicker.css';
import { useState } from 'react';
import { isAfter } from 'date-fns';
export function ReactDatePickerDemo() {
const [startDate, setStartDate] = useState<Date | null>(new Date());
const [endDate, setEndDate] = useState<Date | null>(
new Date(Date.now() + 7 * 24 * 60 * 60 * 1000)
);
return (
<div className="flex flex-col sm:flex-row gap-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">開始日</label>
<DatePicker
selected={startDate}
onChange={(date: Date | null) => {
setStartDate(date);
if (endDate && date && isAfter(date, endDate)) setEndDate(null);
}}
selectsStart
startDate={startDate}
endDate={endDate}
dateFormat="yyyy/MM/dd"
className="border border-gray-300 rounded px-3 py-2 text-sm"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">終了日</label>
<DatePicker
selected={endDate}
onChange={(date: Date | null) => setEndDate(date)}
selectsEnd
startDate={startDate}
endDate={endDate}
minDate={startDate ?? undefined}
dateFormat="yyyy/MM/dd"
className="border border-gray-300 rounded px-3 py-2 text-sm"
/>
</div>
</div>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、react-datepickerを使った日付範囲ピッカーを実装してください。
- 使用ライブラリ: react-datepicker、date-fns
- DatePicker コンポーネントで selectsStart/selectsEnd プロパティを使って開始日・終了日を個別に選択できること
- monthsShown={2} と selectsRange、inline プロパティでインラインの2ヶ月表示を実装すること
- locale="ja" で日本語表示し、dateFormat="yyyy/MM/dd" で書式化すること
- minDate プロパティで終了日に開始日以前を選択できないよう制限すること
- 選択された期間の日数をリアルタイムに計算して表示すること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
2. @daypicker/react(v10)
軽量でアクセシブルなカレンダー — WAI-ARIA対応でモダンな設計
選択中:2026年5月24日 〜 2026年5月31日(7日間)
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
| 日 | 月 | 火 | 水 | 木 | 金 | 土 |
|---|---|---|---|---|---|---|
特徴
- • WAI-ARIAガイドラインに準拠した高いアクセシビリティ
- • シングル・複数・範囲選択モードを標準サポート
- • CSSカスタムプロパティでスタイル変更が容易
- • date-fnsベースでロケール対応が充実(ロケールは同梱)
インストール
npm install @daypicker/react'use client';
import { DayPicker, type DateRange } from '@daypicker/react';
import '@daypicker/react/style.css';
import { useState } from 'react';
import { ja } from '@daypicker/react/locale';
export function ReactDayPickerDemo() {
const [range, setRange] = useState<DateRange | undefined>({
from: new Date(),
to: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000),
});
return (
<div>
<DayPicker
mode="range"
selected={range}
onSelect={setRange}
locale={ja}
numberOfMonths={2}
/>
{range?.from && range?.to && (
<p className="text-sm text-gray-600 mt-2">
選択期間: {range.from.toLocaleDateString('ja-JP')} 〜 {range.to.toLocaleDateString('ja-JP')}
</p>
)}
</div>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、@daypicker/react(v10)を使った日付範囲ピッカーを実装してください。
- 使用ライブラリ: @daypicker/react(v10)
- DayPicker コンポーネントで mode="range" と numberOfMonths={2} を使った2ヶ月表示の範囲選択を実装すること
- DateRange 型で選択中の from/to を管理すること
- locale={ja} で日本語表示すること(import { ja } from '@daypicker/react/locale')
- 「今週」「30日間」「90日間」「クリア」のプリセットボタンを実装すること
- 選択された期間の日数をリアルタイムに計算して表示すること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
3. Mantine DatePicker
Mantineと統合された日付ピッカー — 範囲選択・インライン表示・日本語対応が標準装備
インラインカレンダー表示
| Mo | Tu | We | Th | Fr | Sa | Su |
|---|---|---|---|---|---|---|
| Mo | Tu | We | Th | Fr | Sa | Su |
|---|---|---|---|---|---|---|
特徴
- •
type="range"で日付範囲選択、DateTimePickerで時刻選択にも対応 - • ポップアップ(DatePickerInput)とインライン(DatePicker)の両形式をサポート
- • locale="ja" と dayjs で日本語対応が容易
- • MantineをすでにDI採用しているプロジェクトなら追加ライブラリなしで使える
インストール
npm install @mantine/dates dayjs(@mantine/coreは別途必要)'use client';
import { useState } from 'react';
import { DatePickerInput, DatePicker } from '@mantine/dates';
import { MantineProvider } from '@mantine/core';
import '@mantine/core/styles.css';
import '@mantine/dates/styles.css';
import dayjs from 'dayjs';
export function MantineDatePickerDemo() {
const [range, setRange] = useState<[Date | null, Date | null]>([null, null]);
const presets = [
{ label: '今週', value: [dayjs().startOf('week').toDate(), dayjs().endOf('week').toDate()] as [Date, Date] },
{ label: '今月', value: [dayjs().startOf('month').toDate(), dayjs().endOf('month').toDate()] as [Date, Date] },
{ label: '先月', value: [dayjs().subtract(1, 'month').startOf('month').toDate(), dayjs().subtract(1, 'month').endOf('month').toDate()] as [Date, Date] },
];
return (
<MantineProvider>
<div className="flex flex-col gap-4">
<DatePickerInput
type="range"
label="日付範囲を選択"
placeholder="開始日 → 終了日"
value={range}
onChange={setRange}
locale="ja"
valueFormat="YYYY/MM/DD"
clearable
/>
<div className="flex gap-2">
{presets.map(preset => (
<button
key={preset.label}
onClick={() => setRange(preset.value)}
className="px-3 py-1 text-sm border rounded hover:bg-gray-50"
>
{preset.label}
</button>
))}
</div>
<DatePicker
type="range"
value={range}
onChange={setRange}
locale="ja"
numberOfColumns={2}
/>
</div>
</MantineProvider>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、Mantine DatePickerを使った日付範囲ピッカーを実装してください。
- 使用ライブラリ: @mantine/dates、@mantine/core、dayjs
- DatePickerInput コンポーネントで type="range" を使ったポップアップ日付範囲選択を実装すること
- DatePicker コンポーネントで type="range" と numberOfColumns={2} を使ったインライン2ヶ月表示を実装すること
- clearable プロパティでクリア機能を追加すること
- locale="ja" で日本語表示し、valueFormat="YYYY/MM/DD" で書式化すること
- dayjs を使って「今週」「今月」「先月」のプリセットボタンを実装すること
- MantineProvider でラップすること⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
4. カスタム実装(React + Tailwind CSS)
ライブラリ不要の完全カスタム実装 — ホバープレビューや2ヶ月表示を自作
2026年5月
2026年6月
選択期間:2026年5月24日 〜 2026年5月31日(7日間)
特徴
- • 外部ライブラリ不要で依存関係が最小限
- • ホバー時のプレビュー表示で直感的な範囲選択
- • プリセットボタン(今週・30日間など)を自由に追加可能
- • デザインの自由度が最も高い
インストール
npm install date-fns(日付計算用、カレンダーUIは自作)'use client';
import { useState } from 'react';
import { format, addMonths, subMonths, isSameDay, isAfter, isBefore } from 'date-fns';
import { ja } from 'date-fns/locale';
export function CustomDateRangePickerDemo() {
const [start, setStart] = useState<Date | null>(null);
const [end, setEnd] = useState<Date | null>(null);
const [hovered, setHovered] = useState<Date | null>(null);
const [viewMonth, setViewMonth] = useState(new Date());
const handleDayClick = (day: Date) => {
if (!start || (start && end)) {
setStart(day);
setEnd(null);
} else {
if (isAfter(day, start)) setEnd(day);
else { setEnd(start); setStart(day); }
}
};
const isInRange = (day: Date) => {
const rangeEnd = end ?? hovered;
if (!start || !rangeEnd) return false;
return isAfter(day, start) && isBefore(day, rangeEnd);
};
const daysInMonth = (year: number, month: number) =>
new Date(year, month + 1, 0).getDate();
const year = viewMonth.getFullYear();
const month = viewMonth.getMonth();
const firstDay = new Date(year, month, 1).getDay();
const days = daysInMonth(year, month);
return (
<div className="inline-block">
<div className="flex items-center justify-between mb-3">
<button onClick={() => setViewMonth(subMonths(viewMonth, 1))} className="px-2 py-1 text-sm">←</button>
<span className="font-semibold text-sm">{format(viewMonth, 'yyyy年M月', { locale: ja })}</span>
<button onClick={() => setViewMonth(addMonths(viewMonth, 1))} className="px-2 py-1 text-sm">→</button>
</div>
<div className="grid grid-cols-7 gap-1 text-center text-xs text-gray-500 mb-1">
{['日','月','火','水','木','金','土'].map(d => <span key={d}>{d}</span>)}
</div>
<div className="grid grid-cols-7 gap-1">
{Array.from({ length: firstDay }).map((_, i) => <span key={`e${i}`} />)}
{Array.from({ length: days }, (_, i) => {
const day = new Date(year, month, i + 1);
const isStart = start && isSameDay(day, start);
const isEnd = end && isSameDay(day, end);
const inRange = isInRange(day);
return (
<button
key={i}
onClick={() => handleDayClick(day)}
onMouseEnter={() => setHovered(day)}
onMouseLeave={() => setHovered(null)}
className={`text-sm py-1 rounded ${
isStart || isEnd ? 'bg-blue-600 text-white' : inRange ? 'bg-blue-100' : 'hover:bg-gray-100'
}`}
>
{i + 1}
</button>
);
})}
</div>
{start && (
<p className="text-xs text-gray-500 mt-2">
{format(start, 'yyyy/MM/dd')} {end ? `〜 ${format(end, 'yyyy/MM/dd')}` : '(終了日を選択)'}
</p>
)}
</div>
);
}🤖 AIプロンプトテンプレート
React + Tailwind CSSで、ライブラリ不要のカスタム日付範囲ピッカーを実装してください。 - 使用ライブラリ: date-fns(日付計算用)、React + Tailwind CSS(カレンダーUIは自作) - 2ヶ月分のカレンダーを横並びで表示し、開始日・終了日を順番にクリックして選択できること - onMouseEnter でホバー中の日付をプレビュー表示し、選択予定の範囲をハイライトすること - 選択中の範囲内の日付は bg-emerald-100、開始日・終了日は bg-emerald-600 でスタイリングすること - 「今週」「30日間」「クリア」のプリセットボタンと前月・翌月ナビゲーションを実装すること - 選択された期間の日数をリアルタイムに計算して表示すること
⚠️ このプロンプトはあくまでたたき台です。AIの回答はモデルやバージョン、会話の文脈によって毎回異なります。意図通りに動かない場合は、条件を追記・修正してお使いください。
ライブラリ比較表
| 項目 | react-datepicker | @daypicker/react(v10) | Mantine DatePicker | カスタム実装 |
|---|---|---|---|---|
| 日付範囲選択 | 内蔵 | 内蔵 | ✅ type="range" | 自作 |
| インライン表示 | 内蔵 | 内蔵 | ✅ DatePicker | 自作 |
| ポップアップ表示 | 内蔵 | 自作 | ✅ DatePickerInput | 自作 |
| プリセット選択 | 自作 | 自作 | ⚠️ 手動で実装 | 自作 |
| 時刻選択 | 内蔵 | なし | ✅ DateTimePicker | 自作 |
| 日本語対応 | locale="ja" | locale={ja} | ✅ locale="ja"(dayjs) | 自作 |
| クリア機能 | 自作 | 自作 | ✅ clearable prop | 自作 |
| バンドルサイズ | 中程度(~40KB) | 小さい(~10KB) | ⚠️ 中(Mantine全体で大) | 最小 |
| 学習コスト | 低 | 低〜中 | 低〜中 | 中〜高(要件次第) |
| おすすめ用途 | フォーム内の日付入力全般 | アクセシビリティ重視のアプリ | Mantine採用プロジェクト | 独自デザインが必要な場合 |
まとめ
react-datepicker — 最も手軽に日付範囲ピッカーを導入したい場合に最適。ポップアップ・インライン・時刻選択など豊富な機能が揃っている。
@daypicker/react(v10) — アクセシビリティを重視する場合におすすめ。WAI-ARIA準拠で、CSSカスタムプロパティによるスタイル変更も容易。
Mantine DatePicker — Mantineの統一デザインシステムに組み込まれた日付ピッカー。type="range" で日付範囲選択、DateTimePicker で時刻選択にも対応。すでにMantineを採用しているプロジェクトなら追加ライブラリなしで使える点が強み。
カスタム実装 — ブランドに合わせた独自デザインが必要な場合や、ホバープレビューなど細かいUX制御をしたい場合に最適。
日付範囲ピッカーは、開始日と終了日をカレンダーUIで選択するフォームコンポーネント。期間指定のインターフェースとして広く使われる。
ホテル・航空券予約・レポートの期間指定・タスクの開始〜終了日設定など、期間を選択する必要がある場面で使われる。
- •シングルカレンダー型
- •ダブルカレンダー型(2ヶ月表示)
- •インライン型(常時表示)
- •ポップオーバー型(クリックで表示)
- •プリセット選択付き型(今週・今月など)