Inputs

Input DateTime

Date and time input with segmented editing, a hidden field for native forms, and optional calendar selection.

Overview

InputDatetime composes Input Group and, for date / datetime modes, Popover and Calendar. The visible value is split into focusable segments (one per date/time field in your format). A hidden <input> mirrors the composed string for native form posts. Use onValueChange when a full Date is committed: all segments are valid, then Enter, blur after completion, or a calendar pick.

In date and datetime modes, the trailing button opens a Calendar popover for day selection; time mode has no calendar.

Key bindings

KeyBehavior
⌫Deletes the last digit in the focused segment. If the segment is empty, focus moves to the previous segment.
⌦Clears the focused segment. The next digit typed replaces the whole segment (same as focusing fresh).
←/→Move focus to the previous or next segment (at ends of the field, the key has no effect).
↵Commits the current composed string: if every segment is filled and the value parses for the format, onValueChange runs with the resulting Date. Works from a segment or from the surrounding control.
⇥Moves through segments and the calendar button (in date / datetime modes) in focus order.
blurLeaving a segment commits the same way as ↵ (when the value is complete and valid).

Custom props

PropTypeDescription
mode'date' | 'time' | 'datetime'Defaults to 'datetime'. Narrows which field tokens from format are editable (date parts, time parts, or both).
formatstringPattern for editable segments (y, M, d, H, m, s runs, as in date-fns) and static text between them (e.g. yyyy/MM/dd - HH:mm). If omitted, defaults are yyyy/MM/dd (date), HH:mm (time), and yyyy/MM/dd HH:mm (datetime).
valueDate | string | nullControlled value: a Date or an ISO-like or formatted string parseable with format.
onValueChange(date: Date | null) => voidFires when a committed, valid Date is available (see Overview and Key bindings).
size'xs' | 'sm' | 'default' | 'lg'Optional. Input Group size: shell height, segment padding/text, and calendar control scale together. This is not the HTML size attribute (that prop is not forwarded to the hidden input).

Install

Configure your registry in components.json:

{
  "registries": {
    "@uxio": "https://ui.uxio.dev/r/styles/{style}/{name}.json"
  }
}

Then run:

npx shadcn@latest add @uxio/input-datetime

This pulls input-group, calendar, and popover as registry dependencies. The correct variant (Base UI or Radix) follows your components.json style.

Usage

Controlled datetime

import * as React from "react"

import { InputDatetime } from "@/components/ui/input-datetime"

export function ScheduledAtField() {
  const [value, setValue] = React.useState<Date | null>(null)

  return <InputDatetime mode="datetime" value={value ?? undefined} onValueChange={setValue} />
}

Date-only with custom format

import * as React from "react"

import { InputDatetime } from "@/components/ui/input-datetime"

export function BirthDateField() {
  const [value, setValue] = React.useState<Date | null>(null)

  return (
    <InputDatetime
      mode="date"
      format="dd/MM/yyyy"
      value={value ?? undefined}
      onValueChange={setValue}
    />
  )
}

Time-only

import * as React from "react"

import { InputDatetime } from "@/components/ui/input-datetime"

export function TimeField() {
  const [value, setValue] = React.useState<Date | null>(null)

  return (
    <InputDatetime mode="time" format="HH:mm" value={value ?? undefined} onValueChange={setValue} />
  )
}

Examples

Date mode (mode="date")

00000000

Committed (onValueChange): —

Hidden string (onChange): —

Time mode (mode="time")

0000

Committed time: Fill HH:mm or pick a day in the calendar (reference date).

Datetime mode (mode="datetime")

000000000000

Controlled value: —

Size variants

Use size so the field aligns with InputGroup and Input dimensions. Segment padding and text scale with the group.

xs

000000000000

sm

000000000000

default

000000000000

lg

000000000000