Package Exports
- @anasyd/react-native-modern-date-picker
- @anasyd/react-native-modern-date-picker/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@anasyd/react-native-modern-date-picker) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
@anasyd/react-native-modern-date-picker
Modern, fully-featured date and time picker for React Native & Expo with scroll-wheel time selection, age restrictions, time ranges, and custom theming.
Install
npm install @anasyd/react-native-modern-date-pickerOptional blur libs if you want a blur backdrop:
# Expo
npm install expo-blur
# Bare RN
npm install @react-native-community/blurChangelog
See CHANGELOG.md for release notes.
Quick Start
import ModernDatePicker from "@anasyd/react-native-modern-date-picker";
<ModernDatePicker
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
/>;Features
- ๐ Date Picker - Month view calendar with year/month selection
- โฐ Time Picker - iOS-style scroll wheels for hours, minutes, and AM/PM
- ๐ Multiple Modes - Date, time, or datetime combined
- ๐ค Age Restrictions -
minAgeandmaxAgeprops (e.g., 18+ only) - โฑ๏ธ Time Ranges -
minTimeandmaxTimefor business hours, etc. - ๐ฑ Haptic Feedback - Smart haptic feedback on iOS/Android
- ๐จ Full Theming - Semantic color tokens, palette system, dark/light presets
- ๐ Internationalization - Locale support for dates and first day of week
- ๐งช TypeScript - Full type safety
- โก Lightweight - No heavy dependencies
Picker Modes
Date Mode
Traditional calendar picker for selecting dates.
<ModernDatePicker
mode="date"
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
minDate={new Date(2020, 0, 1)}
maxDate={new Date()}
/>Time Mode
Scrollable time picker with hour/minute wheels. Supports 12/24 hour formats.
<ModernDatePicker
mode="time"
is24Hour={false}
minuteInterval={15}
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
minTime={{ hour: 9, minute: 0 }} // 9:00 AM
maxTime={{ hour: 17, minute: 0 }} // 5:00 PM
/>DateTime Mode
Combined date and time selection. Pick date first, then switch to time.
<ModernDatePicker
mode="datetime"
is24Hour={false}
minuteInterval={15}
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
/>Date & Time Constraints
Age Restrictions
Use minAge and maxAge to restrict birth date selection:
// Only allow ages 18-65
<ModernDatePicker
mode="date"
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
minAge={18} // Must be at least 18 years old
maxAge={65} // Cannot be older than 65
/>Date Range
Use minDate and maxDate for custom date ranges:
<ModernDatePicker
mode="date"
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
minDate={new Date(2020, 0, 1)}
maxDate={new Date()} // Today
/>Time Range
Use minTime and maxTime to restrict time selection (e.g., business hours):
<ModernDatePicker
mode="time"
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
minTime={{ hour: 9, minute: 0 }} // 9:00 AM
maxTime={{ hour: 17, minute: 30 }} // 5:30 PM
/>Invalid times are visually disabled (crossed out with low opacity) and cannot be selected.
Theming
You can theme in two ways:
A) App-wide (recommended): ThemeProvider + createTheme
import {
ThemeProvider,
createTheme,
} from "@anasyd/react-native-modern-date-picker";
const theme = createTheme({
preset: "light", // "light" | "dark"
palette: {
primary: "#ffffff", // surfaces/background
secondary: "#000000", // text/icons
accent: "#2563eb", // selection highlight
},
// optional fine tuning:
// overrides: { colors: { divider: "#eaeaea" }, radii: { md: 14 } }
});
<ThemeProvider value={theme}>
<ModernDatePicker
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
/>
</ThemeProvider>;B) One-off: pass a theme input on the component
Useful for quick demos or if you don't want a provider.
<ModernDatePicker
open={open}
onClose={() => setOpen(false)}
value={value}
onChange={setValue}
theme={{
preset: "dark",
palette: {
primary: "#1f2937",
secondary: "#ffffff",
accent: "#f59e0b",
},
}}
/>Palette to Semantic Token Mapping
When you define a theme with createTheme({ preset, palette }), the palette colors map to semantic tokens:
| Palette Property | Maps To Semantic Token | Purpose |
|---|---|---|
primary |
background, surface, header |
Surfaces and backgrounds |
secondary |
foreground, mutedForeground |
Text and icon colors |
accent |
accent, onAccent |
Selection highlights and their text |
Semantic color tokens
| Token | Purpose |
|---|---|
background |
Main sheet background |
surface |
Calendar body surface |
header |
Header surface |
foreground |
Primary text color on surfaces |
mutedForeground |
Subdued text |
border |
Border color |
divider |
Hairline dividers |
accent |
Selection chip background |
onAccent |
Text on top of accent |
disabledForeground |
Disabled text |
createTheme({ preset, palette, overrides }) computes these tokens for you and auto-contrasts text (WCAG-ish 4.5) to avoid unreadable combos.
Backdrop
Custom Blur Backdrop (Expo)
import { BlurView } from "expo-blur";
import { Animated, StyleSheet, Platform } from "react-native";
<ModernDatePicker
open={open}
onClose={onClose}
renderBackdrop={(opacity) => (
<Animated.View style={[StyleSheet.absoluteFill, { opacity }]}>
<BlurView
intensity={12}
tint="dark"
experimentalBlurMethod={
Platform.OS === "android" ? "dimezisBlurView" : undefined
}
style={StyleSheet.absoluteFill}
/>
</Animated.View>
)}
/>;Custom Blur Backdrop (Bare RN)
import { BlurView } from "@react-native-community/blur";
import { Animated, StyleSheet } from "react-native";
<ModernDatePicker
open={open}
onClose={onClose}
renderBackdrop={(opacity) => (
<Animated.View style={[StyleSheet.absoluteFill, { opacity }]}>
<BlurView
blurType="dark"
blurAmount={12}
style={StyleSheet.absoluteFill}
/>
</Animated.View>
)}
/>;Backdrop Props
renderBackdrop(opacity)โ custom backdrop node.showDefaultBackdrop(defaulttrue) โ toggle built-in dim.backdropColor(default#000) โ dim overlay color.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
open |
boolean |
โ | Show/hide the picker. |
onClose |
() => void |
โ | Called when the picker requests to close. |
value |
Date | null |
โ | Selected date (controlled). |
defaultValue |
Date |
โ | Default date (uncontrolled). |
onChange |
(date: Date) => void |
โ | Fired on selection. |
| Date Constraints | |||
minDate |
Date |
โ | Minimum selectable date. |
maxDate |
Date |
โ | Maximum selectable date. |
minAge |
number |
โ | Minimum age in years (e.g., 18 for adults only). |
maxAge |
number |
โ | Maximum age in years (e.g., 65). |
| Time Constraints | |||
minTime |
{ hour: number; minute: number } |
โ | Minimum time (e.g., { hour: 9, minute: 0 } for 9:00 AM). |
maxTime |
{ hour: number; minute: number } |
โ | Maximum time (e.g., { hour: 17, minute: 0 } for 5:00 PM). |
| Picker Mode | |||
mode |
'date' | 'time' | 'datetime' |
'date' |
Picker mode: date only, time only, or both. |
is24Hour |
boolean |
true |
Use 24-hour format for time picker. |
minuteInterval |
1|2|3|4|5|6|10|12|15|20|30 |
1 |
Minute interval for time picker. |
| Theming | |||
theme |
Theme | CreateThemeInput |
โ | Provide a full theme or palette input. Uses provider/default. |
| Localization | |||
locale |
string |
platform | Locale (e.g., "en-US"). |
firstDayOfWeek |
0โฆ6 |
0 |
0=Sun, 1=Mon, โฆ |
| Other | |||
testID |
string |
โ | Test identifier. |
style |
StyleProp<ViewStyle> |
โ | Container style. |
animationSpeed |
number |
220 |
Show/hide animation speed (ms). |
renderBackdrop |
(opacity: Animated.Value) => React.ReactNode |
โ | Custom backdrop. |
showDefaultBackdrop |
boolean |
true |
Show built-in dim overlay. |
backdropColor |
string |
#000 |
Color for built-in dim overlay. |
Haptic Feedback
The picker automatically provides haptic feedback on:
- Year scroll interactions (medium intensity)
- Time picker scroll selections (light intensity)
- AM/PM scroll changes (light intensity)
Platform Support
iOS:
- Uses Expo Haptics if available with proper intensity levels
- Falls back to native iOS HapticFeedback
- Last resort: Minimal vibration (5ms)
Android:
- Uses
react-native-haptic-feedbackif available for native haptic effects - Falls back to native Android haptic feedback
- Last resort: Minimal vibration (3ms)
Optional Enhanced Haptics
For the best haptic experience, you can optionally install:
npm install react-native-haptic-feedback
# For React Native 0.60+, run:
cd ios && pod installThis provides native haptic effects like impactLight, impactMedium, and impactHeavy on both platforms.
Key Features:
- โ Smart triggering: Only on actual value changes, not every scroll event
- โ Proper haptics: Uses native haptic APIs, not loud vibration
- โ Graceful fallbacks: Works on all devices with appropriate intensity
- โ No spam: Prevents excessive haptic feedback during scrolling
Exports
import ModernDatePicker, {
createTheme,
extendTheme,
ThemeProvider,
useTheme,
} from "@anasyd/react-native-modern-date-picker";createTheme(input)โ builds a WCAG-safe theme frompreset+palette(+ optionaloverrides).extendTheme(base, overrides)โ convenient theme layering (e.g., tweak accent for a section).ThemeProvider/useTheme()โ share theme via context (global or nested).ModernDatePickerโ the component.
License
MIT