Date & Time Pickers Stable WINMACLNX
Three picker components whose panels float in the root popover layer — they are never clipped by scroll containers, flip above the trigger near the window bottom, and dismiss on outside click. All cells have hover highlights.
Import
import { DatePicker, TimePicker, DateTimePicker } from '@glyx-dev/react'DatePicker
Calendar popover with month navigation. Clicking the header label zooms out
browser-style: days → month grid → 12-year grid — pick a year, then a
month, then a day. The ‹/› arrows step by month, year, or 12 years
depending on the current view.
const [due, setDue] = useState<string>('') // 'YYYY-MM-DD'
<DatePicker
value={due || null}
onValueChange={(d) => {
const y = d.getFullYear()
const m = String(d.getMonth() + 1).padStart(2, '0')
const day = String(d.getDate()).padStart(2, '0')
setDue(`${y}-${m}-${day}`)
}}
/>| Prop | Type | Default | Description |
|---|---|---|---|
value | Date | string | null | null | Anything new Date() parses |
onValueChange | (d: Date) => void | — | Fires when a day is clicked (popover closes) |
disabled | boolean | false | — |
style | GlyxStyle | — | Trigger container style (default width 240) |
Booking form
Two linked pickers — the check-out resets if it falls before a newly chosen check-in:
const [checkIn, setCheckIn] = useState<Date | null>(null)
const [checkOut, setCheckOut] = useState<Date | null>(null)
return (
<View style={{ gap: 24 }}>
<View>
<Text style={{ marginBottom: 8, fontWeight: '600' }}>Check-in date</Text>
<DatePicker
value={checkIn}
onValueChange={d => { setCheckIn(d); if (checkOut && d > checkOut) setCheckOut(null) }}
/>
</View>
{checkIn && (
<View>
<Text style={{ marginBottom: 8, fontWeight: '600' }}>Check-out date</Text>
<DatePicker value={checkOut} onValueChange={setCheckOut} />
</View>
)}
{checkIn && checkOut && (
<Text style={{ color: '#9999bb', fontSize: 14 }}>
{Math.round((checkOut.getTime() - checkIn.getTime()) / 86_400_000)} nights
</Text>
)}
</View>
)Inside a ScrollView
The calendar opens in the root overlay layer, so it is never clipped by a scroll ancestor and closes automatically on outside click:
<ScrollView>
<Text style={{ fontWeight: '600', marginBottom: 8 }}>Appointment date</Text>
<DatePicker value={apptDate} onValueChange={setApptDate} />
</ScrollView>TimePicker
Hour/minute columns; 12-hour mode adds AM/PM.
const [time, setTime] = useState<string>('') // always 'HH:MM' (24-hour)
<TimePicker value={time || null} onValueChange={setTime} />
<TimePicker value={time || null} onValueChange={setTime} use24Hour />| Prop | Type | Default | Description |
|---|---|---|---|
value | string | null | null | Canonical 24-hour 'HH:MM' regardless of display format |
onValueChange | (hhmm: string) => void | — | Fires on every hour/minute/AM-PM click (popover stays open; backdrop dismisses) |
use24Hour | boolean | false | Display + columns: false → 2:05 PM with AM/PM cells, true → 14:05 with 0–23 hours |
minuteStep | number | 5 | Minute column granularity (1 for every minute) |
disabled | boolean | false | — |
Storing the value as a 24-hour string keeps your data format independent of
how the user prefers to read it — toggle use24Hour freely without migrating
stored values.
DateTimePicker
Calendar and time columns side by side in one popover; emits a Date.
Selecting a day keeps the chosen time and vice versa.
const [when, setWhen] = useState<Date | null>(null)
<DateTimePicker value={when} onValueChange={setWhen} use24Hour minuteStep={15} />| Prop | Type | Default | Description |
|---|---|---|---|
value | Date | string | null | null | — |
onValueChange | (d: Date) => void | — | Fires on every date or time change |
use24Hour | boolean | false | Time display/columns format |
minuteStep | number | 5 | Minute column granularity |
disabled | boolean | false | — |
See also
- TextInput — free-text, password, numeric fields
- Popover layer — the floating-layer mechanics these build on