ReactMigrationComponents
DateInput
Migration guide for DateInput to DateField from HeroUI v2 to v3
Refer to the v3 DateField documentation for complete API reference, styling guide, and advanced examples. This guide only focuses on migrating from HeroUI v2.
Structure Changes
In v2, DateInput was a single component with props:
import { DateInput } from "@heroui/react";
export default function App() {
return <DateInput label="Date" name="date" />;
}In v3, DateField requires compound components with DateInputGroup and a render prop for segments:
import { DateField, DateInputGroup, Label } from "@heroui/react";
export default function App() {
return (
<DateField className="w-[256px]" name="date">
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>
);
}Key Changes
1. Component Naming
v2: DateInput
v3: DateField
2. Component Structure
v2: Single component with props
v3: Compound components: DateField (root) + DateInputGroup with DateInputGroup.Input (render prop) and DateInputGroup.Segment; optionally DateInputGroup.Prefix and DateInputGroup.Suffix
3. Prop Changes
| v2 Prop | v3 Location | Notes |
|---|---|---|
label | - | Removed (use Label component) |
description | - | Removed (use Description component) |
errorMessage | - | Removed (use FieldError component) |
value, defaultValue, onChange | DateField | Same (React Aria) |
minValue, maxValue, granularity, placeholderValue | DateField | Same |
isRequired, isDisabled, isReadOnly, isInvalid, name | DateField | Same |
createCalendar, validationBehavior | DateField | Same |
variant | DateInputGroup | Simplified to primary | secondary only |
fullWidth | DateField or DateInputGroup | On root or group |
color | - | Removed (use Tailwind CSS) |
size | - | Removed (use Tailwind CSS) |
radius | - | Removed (use Tailwind CSS) |
labelPlacement | - | Removed (handle with layout) |
startContent | DateInputGroup.Prefix | Use Prefix child |
endContent | DateInputGroup.Suffix | Use Suffix child |
classNames | - | Use className on DateField and DateInputGroup parts |
groupProps | - | Removed (use className or DOM props on DateInputGroup) |
labelProps | - | Removed (use className on Label) |
fieldProps | - | Removed (use className on DateInputGroup) |
innerWrapperProps | - | Removed (use className on group/input parts) |
descriptionProps | - | Removed (use className on Description) |
errorMessageProps | - | Removed (use className on FieldError) |
inputRef | - | Removed (ref is handled by DateField / React Aria) |
Migration Examples
Basic
<DateInput label="Date" name="date" /><DateField className="w-[256px]" name="date">
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>With Description and Error
<DateInput
description="Select your birth date"
label="Birth date"
name="birthdate"
/>
<DateInput
errorMessage="Please enter a valid date"
isInvalid
label="Date"
name="date"
/>import { Description, FieldError, Label } from "@heroui/react";
<DateField className="w-[256px]" name="birthdate">
<Label>Birth date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
<Description>Select your birth date</Description>
</DateField>
<DateField className="w-[256px]" isInvalid name="date">
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
<FieldError>Please enter a valid date</FieldError>
</DateField>Required
<DateInput isRequired label="Date" name="date" /><DateField className="w-[256px]" isRequired name="date">
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>Controlled
import { parseDate } from "@internationalized/date";
import { useState } from "react";
const [value, setValue] = useState(null);
<DateInput
label="Date"
name="date"
value={value}
onChange={setValue}
/>import type { DateValue } from "@internationalized/date";
import { useState } from "react";
const [value, setValue] = useState<DateValue | null>(null);
<DateField
className="w-[256px]"
name="date"
value={value}
onChange={setValue}
>
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>Min/Max and Granularity
import { parseDate } from "@internationalized/date";
<DateInput
granularity="day"
label="Date"
maxValue={parseDate("2025-12-31")}
minValue={parseDate("2020-01-01")}
name="date"
/>import { parseDate } from "@internationalized/date";
<DateField
className="w-[256px]"
granularity="day"
maxValue={parseDate("2025-12-31")}
minValue={parseDate("2020-01-01")}
name="date"
>
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>Start/End Content
<DateInput
endContent={<CalendarIcon />}
label="Date"
name="date"
startContent={<CalendarIcon />}
/><DateField className="w-[256px]" name="date">
<Label>Date</Label>
<DateInputGroup>
<DateInputGroup.Prefix>
<CalendarIcon />
</DateInputGroup.Prefix>
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
<DateInputGroup.Suffix>
<CalendarIcon />
</DateInputGroup.Suffix>
</DateInputGroup>
</DateField>Variants
<DateInput label="Date" name="date" variant="bordered" />
<DateInput color="primary" label="Date" name="date" size="lg" /><DateField className="w-[256px]" name="date">
<Label>Date</Label>
<DateInputGroup variant="primary">
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>
<DateField className="w-[256px]" name="date">
<Label>Date</Label>
<DateInputGroup variant="secondary">
<DateInputGroup.Input>
{(segment) => <DateInputGroup.Segment segment={segment} />}
</DateInputGroup.Input>
</DateInputGroup>
</DateField>Component Anatomy
The v3 DateField follows this structure:
DateField (Root)
├── Label (optional)
├── DateInputGroup
│ ├── DateInputGroup.Prefix (optional)
│ ├── DateInputGroup.Input → (segment) => DateInputGroup.Segment
│ └── DateInputGroup.Suffix (optional)
├── Description (optional)
└── FieldError (optional)Summary
- Component Renamed:
DateInput→DateField - Component Structure: Must use compound components:
DateField(root) andDateInputGroupwithDateInputGroup.Input(render prop) andDateInputGroup.Segment - Label/Description/Error: Use separate components (
Label,Description,FieldError) - Date Props Unchanged:
value,defaultValue,onChange,minValue,maxValue,granularity,placeholderValue,isRequired,isDisabled,isInvalid,name,createCalendarstay onDateField - Variant on DateInputGroup: v3 supports only
variant="primary"andvariant="secondary"onDateInputGroup;color,size,radiusremoved — use Tailwind CSS - Start/End Content:
startContent/endContent→DateInputGroup.PrefixandDateInputGroup.Suffix - Label Placement Removed:
labelPlacementremoved — handle with layout - DOM/Class Props:
groupProps,labelProps,fieldProps,classNamesremoved — useclassName(and standard DOM props) on the relevant parts