🚧 Glyx is pre-release software. APIs may change before v1.0. Get started →
Documentation
Form Components
Date & Time Pickers

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}`)
  }}
/>
PropTypeDefaultDescription
valueDate | string | nullnullAnything new Date() parses
onValueChange(d: Date) => voidFires when a day is clicked (popover closes)
disabledbooleanfalse
styleGlyxStyleTrigger 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 />
PropTypeDefaultDescription
valuestring | nullnullCanonical 24-hour 'HH:MM' regardless of display format
onValueChange(hhmm: string) => voidFires on every hour/minute/AM-PM click (popover stays open; backdrop dismisses)
use24HourbooleanfalseDisplay + columns: false2:05 PM with AM/PM cells, true14:05 with 0–23 hours
minuteStepnumber5Minute column granularity (1 for every minute)
disabledbooleanfalse

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} />
PropTypeDefaultDescription
valueDate | string | nullnull
onValueChange(d: Date) => voidFires on every date or time change
use24HourbooleanfalseTime display/columns format
minuteStepnumber5Minute column granularity
disabledbooleanfalse

See also

  • TextInput — free-text, password, numeric fields
  • Popover layer — the floating-layer mechanics these build on