# DateField **Category**: react **URL**: https://www.heroui.com/docs/react/components/date-field **Source**: https://raw.githubusercontent.com/heroui-inc/heroui/refs/heads/v3/apps/docs/content/docs/react/components/(date-and-time)/date-field.mdx > Date input field with labels, descriptions, and validation built on React Aria DateField *** ## Import ```tsx import { DateField } from '@heroui/react'; ``` ### Usage ```tsx "use client"; import {DateField, Label} from "@heroui/react"; export function Basic() { return ( {(segment) => } ); } ``` ### Anatomy ```tsx import {DateField, Label, Description, FieldError} from '@heroui/react'; export default () => ( ) ``` > **DateField** combines label, date input, description, and error into a single accessible component. ### With Description ```tsx "use client"; import {DateField, Description, Label} from "@heroui/react"; export function WithDescription() { return (
{(segment) => } Enter your date of birth {(segment) => } Enter a date for your appointment
); } ``` ### Required Field ```tsx "use client"; import {DateField, Description, Label} from "@heroui/react"; export function Required() { return (
{(segment) => } {(segment) => } Required field
); } ``` ### Validation Use `isInvalid` together with `FieldError` to surface validation messages. ```tsx "use client"; import {DateField, FieldError, Label} from "@heroui/react"; export function Invalid() { return (
{(segment) => } Please enter a valid date {(segment) => } Date must be in the future
); } ``` ### With Validation DateField supports validation with `minValue`, `maxValue`, and custom validation logic. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {DateField, Description, FieldError, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function WithValidation() { const [value, setValue] = useState(null); const todayDate = today(getLocalTimeZone()); const isInvalid = value !== null && value.compare(todayDate) < 0; return (
{(segment) => } {isInvalid ? ( Date must be today or in the future ) : ( Enter a date from today onwards )}
); } ``` ### Granularity ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {CircleQuestion} from "@gravity-ui/icons"; import {DateField, Label, ListBox, Select, Tooltip} from "@heroui/react"; import {parseDate, parseZonedDateTime} from "@internationalized/date"; import {useState} from "react"; export function Granularity() { const granularityOptions = [ {id: "day", label: "Day"}, {id: "hour", label: "Hour"}, {id: "minute", label: "Minute"}, {id: "second", label: "Second"}, ] as const; const [granularity, setGranularity] = useState<"day" | "hour" | "minute" | "second">("day"); // Determine appropriate default value based on granularity let defaultValue: DateValue; if (granularity === "day") { defaultValue = parseDate("2025-02-03"); } else { // hour, minute, second defaultValue = parseZonedDateTime("2025-02-03T08:45:00[America/Los_Angeles]"); } return (
{(segment) => }

Determines the smallest unit displayed in the date picker. By default, this is "day" for dates, and "minute" for times.

); } ``` ### Controlled Control the value to synchronize with other components or state management. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Button, DateField, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function Controlled() { const [value, setValue] = useState(null); return (
{(segment) => } Current value: {value ? value.toString() : "(empty)"}
); } ``` ### Disabled State ```tsx "use client"; import {DateField, Description, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; export function Disabled() { return (
{(segment) => } This date field is disabled {(segment) => } This date field is disabled
); } ``` ### With Icons Add prefix or suffix icons to enhance the date field. ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, Label} from "@heroui/react"; export function WithPrefixIcon() { return ( {(segment) => } ); } ``` ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, Label} from "@heroui/react"; export function WithSuffixIcon() { return ( {(segment) => } ); } ``` ```tsx "use client"; import {Calendar, ChevronDown} from "@gravity-ui/icons"; import {DateField, Description, Label} from "@heroui/react"; export function WithPrefixAndSuffix() { return ( {(segment) => } Enter a date ); } ``` ### Full Width ```tsx "use client"; import {Calendar, ChevronDown} from "@gravity-ui/icons"; import {DateField, Label} from "@heroui/react"; export function FullWidth() { return (
{(segment) => } {(segment) => }
); } ``` ### Variants The DateField.Group component supports two visual variants: - **`primary`** (default) - Standard styling with shadow, suitable for most use cases - **`secondary`** - Lower emphasis variant without shadow, suitable for use in Surface components ```tsx "use client"; import {DateField, Label} from "@heroui/react"; export function Variants() { return (
{(segment) => } {(segment) => }
); } ``` ### In Surface When used inside a [Surface](/docs/components/surface) component, use `variant="secondary"` on DateField.Group to apply the lower emphasis variant suitable for surface backgrounds. ```tsx "use client"; import {Calendar} from "@gravity-ui/icons"; import {DateField, Description, Label, Surface} from "@heroui/react"; export function OnSurface() { return ( {(segment) => } Enter a date {(segment) => } Enter a date for your appointment ); } ``` ### Form Example Complete form example with validation and submission handling. ```tsx "use client"; import type {DateValue} from "@internationalized/date"; import {Calendar} from "@gravity-ui/icons"; import {Button, DateField, Description, FieldError, Form, Label} from "@heroui/react"; import {getLocalTimeZone, today} from "@internationalized/date"; import {useState} from "react"; export function FormExample() { const [value, setValue] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const todayDate = today(getLocalTimeZone()); const isInvalid = value !== null && value.compare(todayDate) < 0; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!value || isInvalid) { return; } setIsSubmitting(true); // Simulate API call setTimeout(() => { console.log("Date submitted:", {date: value}); setValue(null); setIsSubmitting(false); }, 1500); }; return (
{(segment) => } {isInvalid ? ( Date must be today or in the future ) : ( Enter a date from today onwards )}
); } ``` ## Related Components - **DatePicker**: Composable date picker with date field trigger and calendar popover - **Calendar**: Interactive month grid for selecting dates - **Label**: Accessible label for form controls ### Custom Render Function ```tsx "use client"; import {DateField, Label} from "@heroui/react"; export function CustomRenderFunction() { return (
} >
}>
}> {(segment) => } ); } ``` ## Styling ### Passing Tailwind CSS classes ```tsx import {DateField, Label, Description} from '@heroui/react'; function CustomDateField() { return ( {(segment) => } Select a date for your appointment. ); } ``` ### Customizing the component classes DateField has minimal default styling. Override the `.date-field` class to customize the container styling. ```css @layer components { .date-field { @apply flex flex-col gap-1; &[data-invalid="true"], &[aria-invalid="true"] { [data-slot="description"] { @apply hidden; } } [data-slot="label"] { @apply w-fit; } [data-slot="description"] { @apply px-1; } } } ``` ### CSS Classes - `.date-field` – Root container with minimal styling (`flex flex-col gap-1`) > **Note:** Child components ([Label](/docs/components/label), [Description](/docs/components/description), [FieldError](/docs/components/field-error)) have their own CSS classes and styling. See their respective documentation for customization options. DateField.Group styling is documented below in the API Reference section. ### Interactive States DateField automatically manages these data attributes based on its state: - **Invalid**: `[data-invalid="true"]` or `[aria-invalid="true"]` - Automatically hides the description slot when invalid - **Required**: `[data-required="true"]` - Applied when `isRequired` is true - **Disabled**: `[data-disabled="true"]` - Applied when `isDisabled` is true - **Focus Within**: `[data-focus-within="true"]` - Applied when any child input is focused ## API Reference ### DateField Props DateField inherits all props from React Aria's [DateField](https://react-aria.adobe.com/DateField.md) component. #### Base Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `children` | `React.ReactNode \| (values: DateFieldRenderProps) => React.ReactNode` | - | Child components (Label, DateField.Group, etc.) or render function. | | `className` | `string \| (values: DateFieldRenderProps) => string` | - | CSS classes for styling, supports render props. | | `style` | `React.CSSProperties \| (values: DateFieldRenderProps) => React.CSSProperties` | - | Inline styles, supports render props. | | `fullWidth` | `boolean` | `false` | Whether the date field should take full width of its container | | `id` | `string` | - | The element's unique identifier. | | `render` | `DOMRenderFunction` | - | Overrides the default DOM element with a custom render function.| #### Value Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `value` | `DateValue \| null` | - | Current value (controlled). Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `defaultValue` | `DateValue \| null` | - | Default value (uncontrolled). Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `onChange` | `(value: DateValue \| null) => void` | - | Handler called when the value changes. | | `placeholderValue` | `DateValue \| null` | - | Placeholder date that influences the format of the placeholder. | #### Validation Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `isRequired` | `boolean` | `false` | Whether user input is required before form submission. | | `isInvalid` | `boolean` | - | Whether the value is invalid. | | `minValue` | `DateValue \| null` | - | The minimum allowed date that a user may select. Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `maxValue` | `DateValue \| null` | - | The maximum allowed date that a user may select. Uses [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) types. | | `isDateUnavailable` | `(date: DateValue) => boolean` | - | Callback that is called for each date. If it returns true, the date is unavailable. | | `validate` | `(value: DateValue) => ValidationError \| true \| null \| undefined` | - | Custom validation function. | | `validationBehavior` | `'native' \| 'aria'` | `'native'` | Whether to use native HTML form validation or ARIA attributes. | #### Format Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `granularity` | `Granularity` | - | Determines the smallest unit displayed. Defaults to `"day"` for dates, `"minute"` for times. | | `hourCycle` | `12 \| 24` | - | Whether to display time in 12 or 24 hour format. By default, determined by locale. | | `hideTimeZone` | `boolean` | `false` | Whether to hide the time zone abbreviation. | | `shouldForceLeadingZeros` | `boolean` | - | Whether to always show leading zeros in month, day, and hour fields. | #### State Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `isDisabled` | `boolean` | - | Whether the input is disabled. | | `isReadOnly` | `boolean` | - | Whether the input can be selected but not changed. | #### Form Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `name` | `string` | - | Name of the input element, for HTML form submission. Submits as ISO 8601 string. | | `autoFocus` | `boolean` | - | Whether the element should receive focus on render. | | `autoComplete` | `string` | - | Type of autocomplete functionality the input should provide. | #### Accessibility Props | Prop | Type | Default | Description | |------|------|---------|-------------| | `aria-label` | `string` | - | Accessibility label when no visible label is present. | | `aria-labelledby` | `string` | - | ID of elements that label this field. | | `aria-describedby` | `string` | - | ID of elements that describe this field. | | `aria-details` | `string` | - | ID of elements with additional details. | ### Composition Components DateField works with these separate components that should be imported and used directly: - **Label** - Field label component from `@heroui/react` - **DateField.Group** - Date input group component (documented below) - **DateField.Input** - Input component with segmented editing from `@heroui/react` - **DateField.InputContainer** - Scrollable container for grouping multiple inputs (e.g. start/end range inputs) with horizontal overflow - **DateField.Segment** - Individual date segment (year, month, day, etc.) - **DateField.Prefix** / **DateField.Suffix** - Prefix and suffix slots for the input group - **Description** - Helper text component from `@heroui/react` - **FieldError** - Validation error message from `@heroui/react` Each of these components has its own props API. Use them directly within DateField for composition: ```tsx import {parseDate} from '@internationalized/date'; import {DateField, Label, Description, FieldError} from '@heroui/react'; {(segment) => } Select a date from today onwards. Please select a valid date. ``` ### DateValue Types DateField uses types from [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/): - `CalendarDate` - Date without time or timezone - `CalendarDateTime` - Date with time but no timezone - `ZonedDateTime` - Date with time and timezone - `Time` - Time only Example: ```tsx import {parseDate, today, getLocalTimeZone} from '@internationalized/date'; // Parse from string const date = parseDate('2024-01-15'); // Today's date const todayDate = today(getLocalTimeZone()); // Use in DateField {/* ... */} ``` > **Note:** DateField uses the [`@internationalized/date`](https://react-aria.adobe.com/internationalized/date/) package for date manipulation, parsing, and type definitions. See the [Internationalized Date documentation](https://react-aria.adobe.com/internationalized/date/) for more information about available types and functions. ### DateFieldRenderProps When using render props with `className`, `style`, or `children`, these values are available: | Prop | Type | Description | |------|------|-------------| | `isDisabled` | `boolean` | Whether the field is disabled. | | `isInvalid` | `boolean` | Whether the field is currently invalid. | | `isReadOnly` | `boolean` | Whether the field is read-only. | | `isRequired` | `boolean` | Whether the field is required. | | `isFocused` | `boolean` | Whether the field is currently focused. | | `isFocusWithin` | `boolean` | Whether any child element is focused. | | `isFocusVisible` | `boolean` | Whether focus is visible (keyboard navigation). | ### DateField.Group Props DateField.Group accepts all props from React Aria's `Group` component plus the following: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `fullWidth` | `boolean` | `false` | Whether the date input group should take full width of its container | | `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the component. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. | ### DateField.Input Props DateField.Input accepts all props from React Aria's `DateInput` component plus the following: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `variant` | `"primary" \| "secondary"` | `"primary"` | Visual variant of the input. `primary` is the default style with shadow. `secondary` is a lower emphasis variant without shadow, suitable for use in surfaces. | The `DateField.Input` component accepts a render prop function that receives date segments. Each segment represents a part of the date (year, month, day, etc.). ### DateField.Segment Props DateField.Segment accepts all props from React Aria's `DateSegment` component: | Prop | Type | Default | Description | |------|------|---------|-------------| | `segment` | `DateSegment` | - | The date segment object from the DateField.Input render prop. | | `className` | `string` | - | Tailwind classes merged with the component styles. | ### DateField.InputContainer Props DateField.InputContainer accepts standard HTML `div` attributes: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display inside the scrollable container (typically multiple `DateField.Input` components). | ### DateField.Prefix Props DateField.Prefix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the prefix slot. | ### DateField.Suffix Props DateField.Suffix accepts standard HTML `div` attributes: | Prop | Type | Default | Description | |------|------|---------|-------------| | `className` | `string` | - | Tailwind classes merged with the component styles. | | `children` | `ReactNode` | - | Content to display in the suffix slot. | ## DateField.Group Styling ### Customizing the component classes The base classes power every instance. Override them once with `@layer components`. ```css @layer components { .date-input-group { @apply inline-flex h-9 items-center overflow-hidden rounded-field border bg-field text-sm text-field-foreground shadow-field outline-none; &:hover, &[data-hovered="true"] { @apply bg-field-hover; } &[data-focus-within="true"], &:focus-within { @apply status-focused-field; } &[data-invalid="true"] { @apply status-invalid-field; } &[data-disabled="true"], &[aria-disabled="true"] { @apply status-disabled; } } .date-input-group__input { @apply flex flex-1 items-center gap-px rounded-none border-0 bg-transparent px-3 py-2 shadow-none outline-none; } .date-input-group__segment { @apply inline-block rounded-md px-0.5 text-end tabular-nums outline-none; &:focus, &[data-focused="true"] { @apply bg-accent-soft text-accent-soft-foreground; } } .date-input-group__input-container { @apply flex flex-1 items-center; overflow-x: auto; overflow-y: clip; scrollbar-width: none; } .date-input-group__prefix, .date-input-group__suffix { @apply pointer-events-none shrink-0 text-field-placeholder flex items-center; } } ``` ### DateField.Group CSS Classes - `.date-input-group` – Root container styling - `.date-input-group__input` – Input wrapper styling - `.date-input-group__input-container` – Scrollable container for grouping multiple inputs - `.date-input-group__segment` – Individual date segment styling - `.date-input-group__prefix` – Prefix element styling - `.date-input-group__suffix` – Suffix element styling ### DateField.Group Interactive States - **Hover**: `:hover` or `[data-hovered="true"]` - **Focus Within**: `[data-focus-within="true"]` or `:focus-within` - **Invalid**: `[data-invalid="true"]` (also syncs with `aria-invalid`) - **Disabled**: `[data-disabled="true"]` or `[aria-disabled="true"]` - **Segment Focus**: `:focus` or `[data-focused="true"]` on segment elements - **Segment Placeholder**: `[data-placeholder="true"]` on segment elements