@atom_design/datepicker
v1.0.0
Published
A versatile React Native DatePicker component supporting date, time, datetime, and range selection with full accessibility.
Readme
@atom_design/datepicker
A powerful and flexible Date/Time/DateTime/Range Picker component for React Native. Built as part of the Atom Design System with full support for iOS and Android platforms.
✨ Features
- 📅 Single Date Selection - Standard date picker
- 🕒 Time Selection - Hour and minute picker
- 📆 DateTime Picker - Combined date and time (iOS native, Android fallback)
- 🔁 Date Range Selection - Start and end date flow
- 🎨 Customizable Styling - Colors, sizes, and custom styles
- ♿ Fully Accessible - Screen reader support with proper roles
- 📱 Platform Optimized - iOS inline picker, Android modal picker
- 🔒 Min/Max Date Support - Restrict selectable dates
- ⚠️ Error States - Visual validation feedback
- 🎯 TypeScript Support - Full type definitions included
📦 Installation
npm install @atom_design/datepickerOr with yarn:
yarn add @atom_design/datepickerPeer Dependencies
Make sure you have the required peer dependencies installed:
npm install @react-native-community/datetimepicker react-native-vector-icons prop-typesFor native setup:
- @react-native-community/datetimepicker: Follow the installation guide
- react-native-vector-icons: Follow the installation guide
📥 Import
import DatePicker from '@atom_design/datepicker';
// or
import { DatePicker } from '@atom_design/datepicker';🎯 Basic Usage
Single Date Picker
import React, { useState } from 'react';
import DatePicker from '@atom_design/datepicker';
function DateExample() {
const [date, setDate] = useState(null);
return (
<DatePicker
label="Birth Date"
placeholder="Select your birth date"
value={date}
onChange={setDate}
hint="MM/DD/YYYY"
/>
);
}Time Picker
import React, { useState } from 'react';
import DatePicker from '@atom_design/datepicker';
function TimeExample() {
const [time, setTime] = useState(null);
return (
<DatePicker
type="time"
label="Appointment Time"
placeholder="Select time"
value={time}
onChange={setTime}
/>
);
}DateTime Picker
import React, { useState } from 'react';
import DatePicker from '@atom_design/datepicker';
function DateTimeExample() {
const [datetime, setDatetime] = useState(null);
return (
<DatePicker
type="datetime"
label="Event Date & Time"
placeholder="Select date and time"
value={datetime}
onChange={setDatetime}
/>
);
}Date Range Picker
import React, { useState } from 'react';
import DatePicker from '@atom_design/datepicker';
function RangeExample() {
const [range, setRange] = useState({ start: null, end: null });
return (
<DatePicker
type="range"
label="Travel Dates"
placeholder="Select date range"
value={range}
onChange={setRange}
hint="Start date – End date"
/>
);
}📋 Props
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| type | 'date' \| 'time' \| 'datetime' \| 'range' | 'date' | Type of picker to display |
| label | string | - | Label text above the input |
| placeholder | string | 'Select date' | Placeholder text |
| value | Date \| string \| { start, end } | - | Current value |
| onChange | function | - | Callback when value changes |
| disabled | boolean | false | Disable the picker |
| error | boolean | false | Show error state styling |
| hint | string | - | Helper text below input |
| size | 'small' \| 'medium' \| 'large' | 'medium' | Size variant |
| minDate | Date \| string | - | Minimum selectable date |
| maxDate | Date \| string | - | Maximum selectable date |
| activeColor | string | '#d9232d' | Icon accent color |
| dateFormat | string | 'en-US' | Locale for date formatting |
| containerStyle | ViewStyle | - | Container style override |
| inputStyle | ViewStyle | - | Input container style |
| labelStyle | TextStyle | - | Label text style |
| testID | string | - | Test ID for testing |
| accessibilityLabel | string | - | Accessibility label |
🎨 Customization Examples
With Min/Max Dates
<DatePicker
label="Appointment Date"
value={date}
onChange={setDate}
minDate={new Date()} // Can't select past dates
maxDate={new Date(Date.now() + 30 * 24 * 60 * 60 * 1000)} // Next 30 days only
/>Custom Colors
<DatePicker
label="Event Date"
value={date}
onChange={setDate}
activeColor="#4CAF50"
/>Different Sizes
// Small
<DatePicker label="Small" value={date} onChange={setDate} size="small" />
// Large
<DatePicker label="Large" value={date} onChange={setDate} size="large" />Error State
<DatePicker
label="Required Date"
value={date}
onChange={setDate}
error={!date}
hint={!date ? "Please select a date" : ""}
/>Custom Date Format
<DatePicker
label="Date (UK Format)"
value={date}
onChange={setDate}
dateFormat="en-GB"
/>🧪 Test Screen Example
import React, { useState } from 'react';
import { View, Text, ScrollView, StyleSheet } from 'react-native';
import DatePicker from '@atom_design/datepicker';
const DatePickerTestScreen = () => {
// States for different picker types
const [singleDate, setSingleDate] = useState(null);
const [time, setTime] = useState(null);
const [datetime, setDatetime] = useState(null);
const [dateRange, setDateRange] = useState({ start: null, end: null });
// States for variations
const [minMaxDate, setMinMaxDate] = useState(null);
const [errorDate, setErrorDate] = useState(null);
// Calculate min/max dates
const today = new Date();
const nextMonth = new Date(today.getTime() + 30 * 24 * 60 * 60 * 1000);
return (
<ScrollView style={styles.container}>
<Text style={styles.header}>Atom Design - DatePicker</Text>
{/* Single Date Picker */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Single Date Picker</Text>
<DatePicker
label="Birth Date"
placeholder="Select your birth date"
value={singleDate}
onChange={setSingleDate}
hint="MM/DD/YYYY format"
/>
<Text style={styles.result}>
Selected: {singleDate ? singleDate.toLocaleDateString() : 'None'}
</Text>
</View>
{/* Time Picker */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Time Picker</Text>
<DatePicker
type="time"
label="Appointment Time"
placeholder="Select time"
value={time}
onChange={setTime}
/>
<Text style={styles.result}>
Selected: {time ? time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) : 'None'}
</Text>
</View>
{/* DateTime Picker */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>DateTime Picker</Text>
<Text style={styles.description}>
iOS: Native datetime picker | Android: Two-step flow
</Text>
<DatePicker
type="datetime"
label="Event Date & Time"
placeholder="Select date and time"
value={datetime}
onChange={setDatetime}
/>
<Text style={styles.result}>
Selected: {datetime ? datetime.toLocaleString() : 'None'}
</Text>
</View>
{/* Date Range Picker */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Date Range Picker</Text>
<Text style={styles.description}>Two-step selection: Start → End</Text>
<DatePicker
type="range"
label="Travel Dates"
placeholder="Select date range"
value={dateRange}
onChange={setDateRange}
hint="Select start and end dates"
/>
<Text style={styles.result}>
Start: {dateRange.start ? dateRange.start.toLocaleDateString() : 'Not set'}{'\n'}
End: {dateRange.end ? dateRange.end.toLocaleDateString() : 'Not set'}
</Text>
</View>
{/* Min/Max Date Restriction */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>With Min/Max Dates</Text>
<Text style={styles.description}>Restricted to next 30 days</Text>
<DatePicker
label="Booking Date"
placeholder="Select a date"
value={minMaxDate}
onChange={setMinMaxDate}
minDate={today}
maxDate={nextMonth}
hint="Only future dates within 30 days"
/>
</View>
{/* Size Variants */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Size Variants</Text>
<DatePicker
label="Small Size"
placeholder="Small picker"
value={null}
onChange={() => {}}
size="small"
/>
<View style={{ height: 12 }} />
<DatePicker
label="Medium Size (Default)"
placeholder="Medium picker"
value={null}
onChange={() => {}}
size="medium"
/>
<View style={{ height: 12 }} />
<DatePicker
label="Large Size"
placeholder="Large picker"
value={null}
onChange={() => {}}
size="large"
/>
</View>
{/* Error State */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Error State</Text>
<DatePicker
label="Required Date"
placeholder="This field is required"
value={errorDate}
onChange={setErrorDate}
error={!errorDate}
hint={!errorDate ? "Please select a date" : "Date selected"}
/>
</View>
{/* Disabled State */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Disabled State</Text>
<DatePicker
label="Unavailable Date"
placeholder="Cannot select"
value={new Date()}
onChange={() => {}}
disabled
hint="This picker is disabled"
/>
</View>
{/* Custom Color */}
<View style={styles.section}>
<Text style={styles.sectionTitle}>Custom Active Color</Text>
<DatePicker
label="Appointment Date"
placeholder="Select date"
value={null}
onChange={() => {}}
activeColor="#4CAF50"
/>
</View>
</ScrollView>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#F5F5F5',
},
header: {
fontSize: 24,
fontWeight: 'bold',
textAlign: 'center',
marginVertical: 20,
color: '#1A1A1A',
},
section: {
backgroundColor: '#FFFFFF',
marginHorizontal: 16,
marginBottom: 16,
padding: 16,
borderRadius: 12,
shadowColor: '#000',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.1,
shadowRadius: 4,
elevation: 3,
},
sectionTitle: {
fontSize: 18,
fontWeight: '600',
marginBottom: 12,
color: '#1A1A1A',
},
description: {
fontSize: 14,
color: '#666',
marginBottom: 12,
},
result: {
marginTop: 12,
fontSize: 14,
color: '#d9232d',
fontStyle: 'italic',
},
});
export default DatePickerTestScreen;🧠 Platform Behavior
iOS
- Date/Time: Opens native inline picker
- DateTime: Opens combined datetime picker
- Range: Two-step selection with native picker
Android
- Date/Time: Opens modal picker
- DateTime: Two-step flow (date picker → time picker), automatically combined
- Range: Two-step selection with modal picker
♿ Accessibility
The DatePicker component includes comprehensive accessibility support:
- Uses
accessibilityRole="button"for the input - Supports custom
accessibilityLabel - Provides
accessibilityHintwith usage instructions - Reports disabled state via
accessibilityState - Screen reader friendly value announcements
📝 TypeScript
Full TypeScript definitions are included:
import DatePicker, { DatePickerProps, DateRange } from '@atom_design/datepicker';
const MyComponent: React.FC = () => {
const [date, setDate] = useState<Date | null>(null);
const [range, setRange] = useState<DateRange>({ start: null, end: null });
return (
<>
<DatePicker
type="date"
label="Single Date"
value={date}
onChange={setDate}
/>
<DatePicker
type="range"
label="Date Range"
value={range}
onChange={setRange}
/>
</>
);
};📄 License
MIT © Atom Design
👤 Author
Atom Design Team
Part of the Atom Design System for React Native.
