apps/docs/content/docs/en/react/migration/(components)/dateinput.mdx
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>
);
}
v2: DateInput
v3: DateField
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
| 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) |
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <DateInput label="Date" name="date" />
</Tab>
<Tab value="v3">
tsx <DateField className="w-[256px]" name="date"> <Label>Date</Label> <DateInputGroup> <DateInputGroup.Input> {(segment) => <DateInputGroup.Segment segment={segment} />} </DateInputGroup.Input> </DateInputGroup> </DateField>
</Tab>
</Tabs>
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx <DateInput description="Select your birth date" label="Birth date" name="birthdate" />
<DateInput
errorMessage="Please enter a valid date"
isInvalid
label="Date"
name="date"
/>
```
<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>
```
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <DateInput isRequired label="Date" name="date" />
</Tab>
<Tab value="v3">
tsx <DateField className="w-[256px]" isRequired name="date"> <Label>Date</Label> <DateInputGroup> <DateInputGroup.Input> {(segment) => <DateInputGroup.Segment segment={segment} />} </DateInputGroup.Input> </DateInputGroup> </DateField>
</Tab>
</Tabs>
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx import { parseDate } from "@internationalized/date"; import { useState } from "react";
const [value, setValue] = useState(null);
<DateInput
label="Date"
name="date"
value={value}
onChange={setValue}
/>
```
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>
```
<Tabs items={["v2", "v3"]}> <Tab value="v2"> ```tsx import { parseDate } from "@internationalized/date";
<DateInput
granularity="day"
label="Date"
maxValue={parseDate("2025-12-31")}
minValue={parseDate("2020-01-01")}
name="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>
```
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <DateInput endContent={<CalendarIcon />} label="Date" name="date" startContent={<CalendarIcon />} />
</Tab>
<Tab value="v3">
tsx <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>
</Tab>
</Tabs>
<Tabs items={["v2", "v3"]}>
<Tab value="v2">
tsx <DateInput label="Date" name="date" variant="bordered" /> <DateInput color="primary" label="Date" name="date" size="lg" />
</Tab>
<Tab value="v3">
```tsx
<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>
```
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)
DateInput → DateFieldDateField (root) and DateInputGroup with DateInputGroup.Input (render prop) and DateInputGroup.SegmentLabel, Description, FieldError)value, defaultValue, onChange, minValue, maxValue, granularity, placeholderValue, isRequired, isDisabled, isInvalid, name, createCalendar stay on DateFieldvariant="primary" and variant="secondary" on DateInputGroup; color, size, radius removed — use Tailwind CSSstartContent/endContent → DateInputGroup.Prefix and DateInputGroup.SuffixlabelPlacement removed — handle with layoutgroupProps, labelProps, fieldProps, classNames removed — use className (and standard DOM props) on the relevant parts