Date Picker
Every date and time experience — single date, time, date+time combo, range — starts with a single DatePicker.Provider. The provider owns the value, draft, and open state. Fields, triggers, calendars, popovers, and modals all read from it as siblings; you compose only the pieces you need.
Draft mode controls whether selections are staged until the user presses OK or commit immediately. Surfaces pick a sensible default: DatePicker.Popover defaults to auto-save (draft={false}) and DatePicker.Modal defaults to staged (draft={true}). Both auto-render a Cancel / OK footer (via DatePicker.Actions) when draft is on, and hide it when it's off. Pass draft on the provider to force either behavior globally, or on the surface to override just that surface.
Full date picker (field + trigger + popover)
The common pattern: typed input, icon trigger, docked calendar in a popover with Cancel / OK.
import { useState } from 'react'; import { DateField } from 'react-native-molecules/components/DateField'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; import { IconButton } from 'react-native-molecules/components/IconButton'; import { TextInput } from 'react-native-molecules/components/TextInput'; export default function Example() { const [date, setDate] = useState<Date | null>(new Date()); return ( <DatePicker.Provider value={date} onChange={setDate}> <DateField> <TextInput.Right> <DatePicker.Trigger> <IconButton name="calendar" /> </DatePicker.Trigger> </TextInput.Right> </DateField> <DatePicker.Popover> <DatePicker.Calendar headerLayout="docked" /> </DatePicker.Popover> </DatePicker.Provider> ); }
Full date picker (field + trigger + modal)
Same composition, swap DatePicker.Popover for DatePicker.Modal when you want a focused overlay instead of a docked surface. The modal renders its own Cancel / OK actions.
import { useState } from 'react'; import { DateField } from 'react-native-molecules/components/DateField'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; import { IconButton } from 'react-native-molecules/components/IconButton'; import { TextInput } from 'react-native-molecules/components/TextInput'; export default function Example() { const [date, setDate] = useState<Date | null>(new Date()); return ( <DatePicker.Provider value={date} onChange={setDate}> <DateField> <TextInput.Right> <DatePicker.Trigger> <IconButton name="calendar" /> </DatePicker.Trigger> </TextInput.Right> </DateField> <DatePicker.Modal> <DatePicker.Calendar /> </DatePicker.Modal> </DatePicker.Provider> ); }
Button trigger with date label
No field — use any button as the trigger and show the selected date inline.
import { useState } from 'react'; import { Button } from 'react-native-molecules/components/Button'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; const formatLabel = (d: Date | null) => d ? d.toLocaleDateString(undefined, { dateStyle: 'medium' }) : 'Pick a date'; export default function Example() { const [date, setDate] = useState<Date | null>(null); return ( <DatePicker.Provider value={date} onChange={setDate}> <DatePicker.Trigger> <Button variant="outlined"> <Button.Text>{formatLabel(date)}</Button.Text> </Button> </DatePicker.Trigger> <DatePicker.Popover> <DatePicker.Calendar headerLayout="docked" /> </DatePicker.Popover> </DatePicker.Provider> ); }
Just the field (no overlay)
Typed-only — parse and validate what the user types, with no calendar surface.
import { useState } from 'react'; import { DateField } from 'react-native-molecules/components/DateField'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; export default function Example() { const [date, setDate] = useState<Date | null>(null); return ( <DatePicker.Provider value={date} onChange={setDate} draft={false}> <DateField /> </DatePicker.Provider> ); }
Just the calendar (standalone)
DatePicker.Calendar works without a provider — give it date and onChange directly.
import { useState } from 'react'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; export default function Example() { const [date, setDate] = useState<Date | null>(new Date()); return ( <DatePicker.Calendar mode="single" date={date} onChange={({ date }) => setDate(date ?? null)} /> ); }
Auto-close popover on selection
The popover defaults to draft={false}, so each calendar tap commits through the provider's onChange. Control open on the provider and close it from onChange to dismiss the popover the moment a date is picked.
import { useState } from 'react'; import { DateField } from 'react-native-molecules/components/DateField'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; import { IconButton } from 'react-native-molecules/components/IconButton'; import { TextInput } from 'react-native-molecules/components/TextInput'; export default function Example() { const [date, setDate] = useState<Date | null>(new Date()); const [open, setOpen] = useState(false); return ( <DatePicker.Provider value={date} onChange={next => { setDate(next); setOpen(false); }} open={open} onOpenChange={setOpen}> <DateField> <TextInput.Right> <DatePicker.Trigger> <IconButton name="calendar" /> </DatePicker.Trigger> </TextInput.Right> </DateField> <DatePicker.Popover> <DatePicker.Calendar headerLayout="docked" /> </DatePicker.Popover> </DatePicker.Provider> ); }
Date + time combos
Side-by-side date field + time field
One provider in mode="datetime" holds a single Date; each field edits its slice.
import { useState } from 'react'; import { View } from 'react-native'; import { DateField } from 'react-native-molecules/components/DateField'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; import { TimeField } from 'react-native-molecules/components/TimeField'; export default function Example() { const [value, setValue] = useState<Date | null>(new Date()); return ( <DatePicker.Provider mode="datetime" value={value} onChange={setValue} draft={false}> <View style={{ flexDirection: 'row', gap: 12 }}> <DateField style={{ flex: 1 }} /> <TimeField style={{ flex: 1 }} /> </View> </DatePicker.Provider> ); }
Date + time in a single popover
Calendar and clock side by side, shared draft, one OK to commit both.
import { useState } from 'react'; import { View } from 'react-native'; import { DatePicker } from 'react-native-molecules/components/DatePicker'; import { Icon } from 'react-native-molecules/components/Icon'; import { Text } from 'react-native-molecules/components/Text'; import { TimePicker } from 'react-native-molecules/components/TimePicker'; import { TouchableRipple } from 'react-native-molecules/components/TouchableRipple'; const formatLabel = (d: Date | null) => d ? d.toLocaleString(undefined, { dateStyle: 'medium', timeStyle: 'short' }) : 'Pick date & time'; export default function Example() { const [value, setValue] = useState<Date | null>(new Date()); return ( <DatePicker.Provider mode="datetime" value={value} onChange={setValue}> <DatePicker.Trigger> <TouchableRipple style={{ flexDirection: 'row', alignItems: 'center', gap: 8, paddingHorizontal: 16, paddingVertical: 10, borderRadius: 8, borderWidth: 1, borderColor: '#CAC4D0', alignSelf: 'flex-start', }} accessibilityRole="button"> <Text>{formatLabel(value)}</Text> <Icon name="chevron-down" size={18} /> </TouchableRipple> </DatePicker.Trigger> <DatePicker.Popover align="center"> <View style={{ flexDirection: 'row', gap: 16, padding: 12 }}> <DatePicker.Calendar headerLayout="docked" /> <TimePicker.Clock inputType="picker" /> </View> </DatePicker.Popover> </DatePicker.Provider> ); }
Component reference
DatePickerProvider
DatePickerProvider
Shared state container for every date / time component in its subtree.
Usage
Wrap fields, triggers, calendars, and overlays to share one value and open state.
Highlights
- Single source of truth for value, draft, and open state
- Modes: date, time, datetime, range
- Draft mode on by default — pair with DatePickerActions to commit
When to use it
- You render any combination of field, trigger, calendar, popover, or modal.
- You want one value shared across date and time inputs.
DatePickerTrigger
DatePickerTrigger
Headless trigger that toggles the overlay and registers the anchor ref.
Usage
Render as a default icon button, wrap any pressable, or pass asChild to slot a custom button.
Highlights
- Renders a default icon button when no children are provided
- Pass asChild to merge press handling onto a custom button
- Registers itself as the popover anchor
When to use it
- You want a button outside of a field to open the overlay.
- A field uses TextInput.Right to slot the trigger as an adornment.
DatePickerActions
DatePickerActions
Cancel / OK footer that commits the provider draft or reverts.
Usage
Mount inside a popover or modal when draft mode is on (the default).
Highlights
- Only renders when draft mode is on
- Calls provider commit / cancel so overlays close with the result
When to use it
- Selections should stage a draft until the user confirms.
- You want consistent Cancel / OK buttons across popover and modal surfaces.
DateField
DateField
Pure text input that reads / writes the provider date value with masking.
Usage
Mount inside a DatePickerProvider for typed date entry; optional alongside a trigger.
Highlights
- Parses and formats automatically using the provider date format
- Supports range mode via inputMode="start" | "end"
- No built-in trigger or overlay — compose those as siblings
When to use it
- The user should be able to type a date directly.
- You want typed entry paired with an optional calendar surface.
Inherits: TextInputProps
DateCalendar
DateCalendar
Calendar surface that works standalone or reads from the surrounding DatePickerProvider.
Usage
Mount inside a provider to share state, or pass date / onChange directly for standalone use.
Highlights
- Standalone or provider-driven
- Day, month, year views with keyboard navigation
- Range and multi-date selection supported
When to use it
- You want a shared calendar surface across modal, popover, and inline layouts.
- Range or multi-date selection belongs outside a field wrapper.
DatePicker.Calendar accepts headerLayout — "docked" uses the two-up month/year layout (default inside DatePicker.Popover), "inline" uses the stacked header.
DatePickerPopover
DatePickerPopover
Presentation shell for mounting date picker content in a popover.
Usage
Attach a calendar to a trigger without forcing modal UX.
Highlights
- Uses Popover positioning, anchored to the trigger registered with the provider
- Pure visual shell — draft / commit behavior comes from the provider
- Nested DateCalendar defaults to the docked month/year header layout
When to use it
- The screen should keep surrounding context visible while selecting a date.
- Desktop and tablet flows benefit from anchored overlays.
DatePickerModal
DatePickerModal
Modal shell for date picker content; reads from DatePickerProvider or falls back to its own props.
Usage
Wrap a calendar surface when the picker should open in a focused overlay.
Highlights
- Dual-mode: delegates to DatePickerProvider when present, otherwise owns state
- Built-in Cancel / OK and typed-entry toggle
When to use it
- The date selection UI should open in a focused overlay.
- You want the same trigger to swap between inline and modal presentations.