mq-datetime-picker
v0.1.0
Published
Headless, platform-agnostic date/time picker for React and React Native
Downloads
86
Maintainers
Readme
mq-datetime-picker
A headless, platform-agnostic date/time picker library for React and React Native.
Features
- 🎯 Headless - No UI, you control 100% of the design
- 🌍 Universal - Works with React Web and React Native
- 📦 Zero dependencies - Only React as peer dependency
- 🔒 Type-safe - Written in TypeScript with full types
- ♿ Accessible - Built-in ARIA props via prop-getters
- 🌐 i18n - Internationalization via native Intl API
Installation
npm install mq-datetime-pickerAll Hooks
| Hook | Description |
|------|-------------|
| useDatePicker | Single date selection |
| useTimePicker | 12h/24h time selection |
| useDateRangePicker | Date range with hover preview |
| useDateTimePicker | Combined date + time |
| useYearPicker | Year from decade view |
| useMonthPicker | Month from year view |
| useWeekPicker | Select entire weeks |
| useMultiDatePicker | Multiple dates at once |
Quick Start
Date Picker
import { useDatePicker } from 'mq-datetime-picker';
function MyDatePicker() {
const {
calendar,
weekdays,
getDayProps,
goToPrevMonth,
goToNextMonth,
formattedDate,
} = useDatePicker({ locale: 'en-US' });
return (
<div>
<input value={formattedDate} readOnly />
<div className="calendar">
<button onClick={goToPrevMonth}>←</button>
<span>{calendar.monthName} {calendar.year}</span>
<button onClick={goToNextMonth}>→</button>
<div className="weekdays">
{weekdays.map(d => <span key={d.short}>{d.short}</span>)}
</div>
<div className="days">
{calendar.days.map(day => {
const props = getDayProps(day);
return (
<button
key={day.key}
onClick={props.onClick}
disabled={props.disabled}
className={props.isSelected ? 'selected' : ''}
>
{day.day}
</button>
);
})}
</div>
</div>
</div>
);
}Time Picker
import { useTimePicker } from 'mq-datetime-picker';
function MyTimePicker() {
const { hours, minutes, period, setHours, setMinutes, setPeriod } = useTimePicker({
format: '12h',
});
return (
<div>
<input value={hours} onChange={e => setHours(+e.target.value)} />
<span>:</span>
<input value={minutes} onChange={e => setMinutes(+e.target.value)} />
<button onClick={() => setPeriod(period === 'AM' ? 'PM' : 'AM')}>
{period}
</button>
</div>
);
}Date Range Picker
import { useDateRangePicker } from 'mq-datetime-picker';
function MyRangePicker() {
const { calendar, getDayProps, setHoveringDate, formattedRange } = useDateRangePicker();
return (
<div>
<input value={formattedRange} readOnly />
{calendar.days.map(day => {
const props = getDayProps(day);
return (
<button
key={day.key}
onClick={props.onClick}
onMouseEnter={() => setHoveringDate(day.date)}
onMouseLeave={() => setHoveringDate(null)}
className={`${props.isInRange ? 'in-range' : ''}`}
>
{day.day}
</button>
);
})}
</div>
);
}Year/Month/Week Pickers
import { useYearPicker, useMonthPicker, useWeekPicker } from 'mq-datetime-picker';
// Year Picker
const { selectedYear, years, selectYear } = useYearPicker();
// Month Picker
const { selectedMonth, months, selectMonth } = useMonthPicker();
// Week Picker
const { selectedWeek, weeks, selectWeek } = useWeekPicker();Multi-Date Picker
import { useMultiDatePicker } from 'mq-datetime-picker';
const { selectedDates, toggleDate, isSelected, formattedDates } = useMultiDatePicker({
maxSelections: 5,
});React Native
All hooks work with React Native - you just render native components:
import { useDatePicker } from 'mq-datetime-picker';
import { View, Text, Pressable } from 'react-native';
function MyDatePicker() {
const { calendar, getDayProps } = useDatePicker();
return (
<View>
{calendar.days.map(day => {
const props = getDayProps(day);
return (
<Pressable key={day.key} onPress={props.onClick} disabled={props.disabled}>
<Text>{day.day}</Text>
</Pressable>
);
})}
</View>
);
}Configuration
DatePickerConfig
useDatePicker({
defaultDate: { year: 2024, month: 12, day: 25 },
minDate: { year: 2024, month: 1, day: 1 },
maxDate: { year: 2025, month: 12, day: 31 },
disabledDates: [{ year: 2024, month: 12, day: 25 }],
locale: 'en-US',
weekStartsOn: 1, // Monday
});TimePickerConfig
useTimePicker({
defaultTime: { hours: 9, minutes: 30 },
minTime: { hours: 8, minutes: 0 },
maxTime: { hours: 18, minutes: 0 },
step: { hours: 1, minutes: 15 },
format: '12h', // or '24h'
});Design Freedom
Because this library is headless, you have complete control over the UI. The same hooks can create:
- Minimal flat calendars
- Modern pill-style time pickers
- Inline week selectors
- Compact mobile pickers
- Any custom design you can imagine
Just spread the prop-getters onto your elements for accessibility and behavior!
License
MIT
