Skip to Content
Dashflow Logo

DatePicker Component

A comprehensive guide to using the DatePicker component with examples, props, and best practices.


Overview

The DatePicker component provides a date selection interface with a calendar popup. It's commonly used for forms, scheduling, and any application that requires date input.

Basic Usage

import { DatePicker } from '@dashflowx/core'
export default function DatePickerExample() {
const [date, setDate] = useState<Date | undefined>(new Date());
return (
<DatePicker
mode="single"
date={date}
setDate={setDate}
/>
)
}

Preview:

December 2024
Calendar grid would be here

Props

PropTypeDefaultDescription
mode'default' | 'single' | 'multiple' | 'range''default'The selection mode for the date picker
dateDate | undefinedundefinedThe selected date value
setDatefunction-Callback function to update the selected date
classNamestring''Additional CSS classes for the container
initialFocusbooleanfalseWhether to focus the calendar initially

Examples

Basic Date Picker

const [date, setDate] = useState<Date | undefined>(new Date());
<DatePicker
mode="single"
date={date}
setDate={setDate}
/>

Preview:

December 2024
Calendar grid would be here

Date Range Picker

const [dateRange, setDateRange] = useState<DateRange | undefined>({
from: new Date(),
to: addDays(new Date(), 7)
});
<DatePicker
mode="range"
date={dateRange}
setDate={setDateRange}
/>

Preview:

December 2024
Calendar grid would be here

Multiple Date Selection

const [dates, setDates] = useState<Date[]>([]);
<DatePicker
mode="multiple"
date={dates}
setDate={setDates}
/>

Preview:

December 2024
Calendar grid would be here

Custom Styled Date Picker

<DatePicker
mode="single"
date={date}
setDate={setDate}
className="border-2 border-blue-500 rounded-xl"
/>

Preview:

December 2024
Calendar grid would be here

Date Picker with Initial Focus

<DatePicker
mode="single"
date={date}
setDate={setDate}
initialFocus={true}
/>

Preview:

December 2024
Calendar grid would be here

Common Use Cases

Form Date Input

const [formData, setFormData] = useState({
name: '',
email: '',
birthDate: undefined as Date | undefined
});
const handleDateChange = (date: Date | undefined) => {
setFormData(prev => ({
...prev,
birthDate: date
}));
};
<form className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Name</label>
<input
type="text"
value={formData.name}
onChange={(e) => setFormData(prev => ({ ...prev, name: e.target.value }))}
className="w-full border rounded px-3 py-2"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Birth Date</label>
<DatePicker
mode="single"
date={formData.birthDate}
setDate={handleDateChange}
/>
</div>
</form>

Event Scheduling

const [eventDate, setEventDate] = useState<Date | undefined>(new Date());
const [eventTime, setEventTime] = useState('09:00');
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Event Date</label>
<DatePicker
mode="single"
date={eventDate}
setDate={setEventDate}
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Event Time</label>
<input
type="time"
value={eventTime}
onChange={(e) => setEventTime(e.target.value)}
className="w-full border rounded px-3 py-2"
/>
</div>
</div>

Booking System

const [checkIn, setCheckIn] = useState<Date | undefined>(new Date());
const [checkOut, setCheckOut] = useState<Date | undefined>(addDays(new Date(), 1));
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Check-in Date</label>
<DatePicker
mode="single"
date={checkIn}
setDate={setCheckIn}
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Check-out Date</label>
<DatePicker
mode="single"
date={checkOut}
setDate={setCheckOut}
/>
</div>
</div>

Task Due Date

const [task, setTask] = useState({
title: '',
description: '',
dueDate: undefined as Date | undefined,
priority: 'medium'
});
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Task Title</label>
<input
type="text"
value={task.title}
onChange={(e) => setTask(prev => ({ ...prev, title: e.target.value }))}
className="w-full border rounded px-3 py-2"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Due Date</label>
<DatePicker
mode="single"
date={task.dueDate}
setDate={(date) => setTask(prev => ({ ...prev, dueDate: date }))}
/>
</div>
</div>

Appointment Booking

const [appointment, setAppointment] = useState({
patientName: '',
doctor: '',
date: undefined as Date | undefined,
time: '',
notes: ''
});
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Patient Name</label>
<input
type="text"
value={appointment.patientName}
onChange={(e) => setAppointment(prev => ({ ...prev, patientName: e.target.value }))}
className="w-full border rounded px-3 py-2"
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Doctor</label>
<select
value={appointment.doctor}
onChange={(e) => setAppointment(prev => ({ ...prev, doctor: e.target.value }))}
className="w-full border rounded px-3 py-2"
>
<option value="">Select Doctor</option>
<option value="dr-smith">Dr. Smith</option>
<option value="dr-jones">Dr. Jones</option>
</select>
</div>
</div>
<div>
<label className="block text-sm font-medium mb-2">Appointment Date</label>
<DatePicker
mode="single"
date={appointment.date}
setDate={(date) => setAppointment(prev => ({ ...prev, date }))}
/>
</div>
</div>

Best Practices

1. Clear Labels

Use clear and descriptive labels for date pickers.

// ✅ Good - Clear labels
<div>
<label className="block text-sm font-medium mb-2">Event Date</label>
<DatePicker mode="single" date={date} setDate={setDate} />
</div>
// ❌ Avoid - Unclear labels
<div>
<label>Date</label>
<DatePicker mode="single" date={date} setDate={setDate} />
</div>

2. Appropriate Date Ranges

Set appropriate date ranges for different contexts.

// ✅ Good - Appropriate date range
<DatePicker
mode="single"
date={date}
setDate={setDate}
disabled={(date) => date < new Date()}
/>
// ❌ Avoid - No date restrictions
<DatePicker
mode="single"
date={date}
setDate={setDate}
/>

3. Consistent Formatting

Use consistent date formatting across your application.

// ✅ Good - Consistent formatting
const formatDate = (date: Date) => {
return format(date, 'MMM dd, yyyy');
};
// ❌ Avoid - Inconsistent formatting
const formatDate = (date: Date) => {
return date.toLocaleDateString();
};

4. Accessible Implementation

Ensure date pickers are accessible to all users.

// ✅ Good - Accessible
<DatePicker
mode="single"
date={date}
setDate={setDate}
aria-label="Select event date"
/>

5. Error Handling

Handle date validation and errors gracefully.

// ✅ Good - Error handling
const [error, setError] = useState('');
const handleDateChange = (date: Date | undefined) => {
if (date && date < new Date()) {
setError('Date cannot be in the past');
return;
}
setError('');
setDate(date);
};

Customization

Custom Styling

You can customize the date picker appearance using CSS classes:

<DatePicker
mode="single"
date={date}
setDate={setDate}
className="border-2 border-purple-500 rounded-xl"
/>

Different Themes

Use different themes for different contexts:

// Light theme
<DatePicker
mode="single"
date={date}
setDate={setDate}
className="bg-white border-gray-200"
/>
// Dark theme
<DatePicker
mode="single"
date={date}
setDate={setDate}
className="bg-gray-900 border-gray-700 text-white"
/>

Size Variations

Use different sizes for different emphasis levels:

// Small date picker
<DatePicker
mode="single"
date={date}
setDate={setDate}
className="w-48"
/>
// Large date picker
<DatePicker
mode="single"
date={date}
setDate={setDate}
className="w-80"
/>

Advanced Usage

Date Validation

Implement date validation:

const [date, setDate] = useState<Date | undefined>();
const [error, setError] = useState('');
const validateDate = (date: Date | undefined) => {
if (!date) {
setError('Date is required');
return false;
}
if (date < new Date()) {
setError('Date cannot be in the past');
return false;
}
if (date > addYears(new Date(), 1)) {
setError('Date cannot be more than 1 year in the future');
return false;
}
setError('');
return true;
};
const handleDateChange = (newDate: Date | undefined) => {
if (validateDate(newDate)) {
setDate(newDate);
}
};

Date Range Validation

Implement date range validation:

const [dateRange, setDateRange] = useState<DateRange | undefined>();
const [error, setError] = useState('');
const validateDateRange = (range: DateRange | undefined) => {
if (!range?.from) {
setError('Start date is required');
return false;
}
if (!range?.to) {
setError('End date is required');
return false;
}
if (range.from >= range.to) {
setError('End date must be after start date');
return false;
}
const daysDiff = differenceInDays(range.to, range.from);
if (daysDiff > 30) {
setError('Date range cannot exceed 30 days');
return false;
}
setError('');
return true;
};

Custom Date Formatting

Implement custom date formatting:

const formatDate = (date: Date | undefined) => {
if (!date) return 'Select a date';
return format(date, 'EEEE, MMMM do, yyyy');
};
<DatePicker
mode="single"
date={date}
setDate={setDate}
formatDate={formatDate}
/>

Date Picker with Time

Combine date picker with time selection:

const [dateTime, setDateTime] = useState<Date | undefined>();
const handleDateTimeChange = (date: Date | undefined, time: string) => {
if (date && time) {
const [hours, minutes] = time.split(':');
const newDateTime = new Date(date);
newDateTime.setHours(parseInt(hours), parseInt(minutes));
setDateTime(newDateTime);
}
};
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Date</label>
<DatePicker
mode="single"
date={dateTime}
setDate={(date) => handleDateTimeChange(date, time)}
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">Time</label>
<input
type="time"
value={time}
onChange={(e) => handleDateTimeChange(dateTime, e.target.value)}
className="w-full border rounded px-3 py-2"
/>
</div>
</div>
  • Calendar: For calendar display
  • Popover: For popup content
  • Button: For trigger button
  • Input: For text input
  • Form: For form integration

API Reference

For the complete API reference and advanced usage patterns, see the DatePicker API documentation.

Edit this page on GitHub