Skip to content
v2.5.0
English
Русский
Documentation

DateTimeField

DateTimeField is a compound component for combined date and time entry that coordinates typed input, optional calendar selection, and timestamp rules in one field.
date-time-field.tsx · 67 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,
Browser support
Newly available 2024
  • Chrome 125
  • Edge 125
  • Firefox 128
  • Safari 18
  • Safari on iOS 18
Bundle size
Tested in
32 tests

Summary

DateTimeField is a compound component for combined date and time entry that coordinates typed input, optional calendar selection, and timestamp rules in one field. It is the field-first timestamp layer when one stored value represents a specific scheduled instant.

Imports

import {
  DateTimeField,
  DateTimeFieldInput,
  DateTimeFieldCalendar,
  DateTimeFieldTriggerIconButton,
  type DateTimeFieldProps,
} from '@vega-ui/react';

Exported Types

  • DateTimeFieldProps
  • DateTimeFieldInputProps
  • DateTimeFieldCalendarProps
  • DateTimeFieldTriggerIconButtonProps

Minimal Composition

minimal-composition.tsx · 67 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,

Required Parts

  • DateTimeField: root state and timestamp-format owner
  • DateTimeFieldInput: typed date-time entry surface

Optional Parts

  • DateTimeFieldTriggerIconButton: calendar trigger affordance
  • DateTimeFieldCalendar: visual picker content, usually mounted in Popover

Composition Order

  1. DateTimeField
  2. DateTimeFieldInput
  3. Popover
  4. DateTimeFieldTriggerIconButton
  5. DateTimeFieldCalendar

Variants

  • Input-only versus input-plus-calendar composition
  • Minute-only versus second-level time formatting
  • Constraint-driven scheduling through min, max, disabledDates, and timeStep

Edge Cases

  • Timezone interpretation belongs to the consumer and should be documented at the feature level.
  • Partial timestamp editing is common and should not be treated as a final value too early.
  • Overlay behavior should be tested inside dialogs, drawers, and sheets.
  • Date validation and time validation should resolve into one timestamp policy, not two loosely connected checks.

Common Mistakes

  • Passing Date objects or display-format strings to min / max instead of ISO YYYY-MM-DDTHH:mm[:ss] strings.
  • Treating date and time validation as unrelated rules.
  • Leaving timezone meaning implicit in scheduling flows.
  • Using field-level overrides that make invalid or disabled state harder to read.

Examples

Basic

Basic: date and time with a calendar popover

One field for a date and a time. The calendar picks the day and keeps the typed time, or uses 00:00 while there is no complete time yet. dateSeparator, separator, and timeFormat here are the defaults, shown explicitly; defaultValue is a YYYY-MM-DDTHH:mm string.

en-US
ru-RU
ar-EG
he-IL
date-and-time-with-a-calendar-popover.tsx · 82 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,

Controlled/Stateful

Controlled/Stateful: meeting end follows the start

Both fields are controlled. The start is the min of the end field, so an end typed before the start is clamped to it, also when the start moves after the end was typed; the duration is computed from the two ISO values.

meeting-end-follows-the-start.tsx · 136 lines
import { useState } from 'react';
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,

Controlled/Stateful: snooze presets

Buttons set the controlled value from outside, and the input shows it in the field format. The presets read the current time in the click handler, never during render.

snooze-presets.tsx · 108 lines
import { useState } from 'react';
import {
  Button,
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,

Form/Integration

Form/Integration: submitting a local date-time

onChangeValue mirrors the value into a hidden input, so FormData holds 2026-07-15T09:30 instead of the typed text. It is a wall-clock time without an offset, so the submit handler adds the user's time zone. required and pattern block an empty or incomplete value.

submitting-a-local-date-time.tsx · 100 lines
import { FormEvent, useState } from 'react';
import {
  Button,
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,

Layout/Overlay

Layout/Overlay: rescheduling inside a sheet

The calendar popover opens above the sheet that contains the field. The sheet edits a draft that is reset from the saved value each time it opens, and the method='dialog' form saves it and closes the sheet.

rescheduling-inside-a-sheet.tsx · 121 lines
import { CSSProperties, useState } from 'react';
import { XIcon } from '@vega-ui/icons';
import {
  Button,
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,

Error

Error: required and incomplete timestamp

Native required and pattern make submit fire invalid while the field is empty or the date or time is incomplete. The handler picks the message from validity, error and aria-invalid mark the field, and typing clears the error.

required-and-incomplete-timestamp.tsx · 104 lines
import { FormEvent, useState } from 'react';
import {
  Button,
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,

Disabled

Disabled: locked execution time

disabled on the root disables the input and the calendar trigger, and the helper text explains why.

locked-execution-time.tsx · 73 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,

Edge

Edge: business hours window

min and max include the time: a complete value outside them is replaced by the nearest bound, so 01.07.2026, 08:30 becomes 01.07.2026, 09:00. Hours and minutes are clamped to their range, so 25:30 becomes 23:30.

business-hours-window.tsx · 88 lines
import { useState } from 'react';
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,

Edge: quarter-hour steps

timeStep sets how far ArrowUp and ArrowDown move the minutes under the caret, wrapping from 45 to 00 without changing the hour. On the hours the arrows still move by one, like a native datetime-local input with step. Typed minutes are kept as typed.

quarter-hour-steps.tsx · 73 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,

Edge: seconds precision

timeFormat='HH:mm:ss' adds a seconds segment; the value then has seconds too, and min and max can include them.

seconds-precision.tsx · 86 lines
import { useState } from 'react';
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,

Edge: weekdays only

disabledDates takes ISO days or a function and applies only to the calendar. A typed weekend is accepted, so the submit handler checks the same isWeekend rule on the date part and shows an error.

weekdays-only.tsx · 115 lines
import { FormEvent, useState } from 'react';
import {
  Button,
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,

Anatomy

Overview

DateTimeField is a compound component that coordinates typed date-time entry, optional calendar selection, and shared timestamp rules under one root.

Required Parts

DateTimeField

Required. Owns date parsing, time parsing, step rules, and combined timestamp state.

DateTimeFieldInput

Required. Provides the typed date-time input surface.

Optional Parts

DateTimeFieldTriggerIconButton

Optional trigger affordance for opening a calendar overlay.

DateTimeFieldCalendar

Optional visual date picker that stays synchronized with the field value.

Its children are the Calendar parts: CalendarHeader with CalendarPrevButton, CalendarViewButtonGroup (CalendarViewButton view='month' and view='year'), and CalendarNextButton, then CalendarContent with CalendarDays, CalendarMonths, and CalendarYears. The calendar takes locale and calendar from DateTimeField.

Composition Order

  1. DateTimeField
  2. DateTimeFieldInput
  3. Popover
  4. DateTimeFieldTriggerIconButton
  5. DateTimeFieldCalendar
  6. CalendarHeader and CalendarContent with the calendar views

Valid Composition Patterns

minimal-composition.tsx · 67 lines
import {
  CalendarContent,
  CalendarDay,
  CalendarDays,
  CalendarHeader,
  CalendarMonth,
  CalendarMonthLabel,
  CalendarMonths,
  CalendarNextButton,
  CalendarPrevButton,
  CalendarViewButton,
  CalendarViewButtonGroup,

Invalid Composition Patterns

Input outside DateTimeField

This breaks shared date-time parsing and synchronization.

Timestamp flow without explicit timezone rules

The field handles input, not product-level timezone policy.

Treating date and time validation as unrelated

The final product value is one timestamp, not two disconnected fields.