Pro--% off in--d : --h : --m : --s
HeroUI
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 Propv3 LocationNotes
label-Removed (use Label component)
description-Removed (use Description component)
errorMessage-Removed (use FieldError component)
value, defaultValue, onChangeDateFieldSame (React Aria)
minValue, maxValue, granularity, placeholderValueDateFieldSame
isRequired, isDisabled, isReadOnly, isInvalid, nameDateFieldSame
createCalendar, validationBehaviorDateFieldSame
variantDateInputGroupSimplified to primary | secondary only
fullWidthDateField or DateInputGroupOn root or group
color-Removed (use Tailwind CSS)
size-Removed (use Tailwind CSS)
radius-Removed (use Tailwind CSS)
labelPlacement-Removed (handle with layout)
startContentDateInputGroup.PrefixUse Prefix child
endContentDateInputGroup.SuffixUse 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

  1. Component Renamed: DateInputDateField
  2. Component Structure: Must use compound components: DateField (root) and DateInputGroup with DateInputGroup.Input (render prop) and DateInputGroup.Segment
  3. Label/Description/Error: Use separate components (Label, Description, FieldError)
  4. Date Props Unchanged: value, defaultValue, onChange, minValue, maxValue, granularity, placeholderValue, isRequired, isDisabled, isInvalid, name, createCalendar stay on DateField
  5. Variant on DateInputGroup: v3 supports only variant="primary" and variant="secondary" on DateInputGroup; color, size, radius removed — use Tailwind CSS
  6. Start/End Content: startContent/endContentDateInputGroup.Prefix and DateInputGroup.Suffix
  7. Label Placement Removed: labelPlacement removed — handle with layout
  8. DOM/Class Props: groupProps, labelProps, fieldProps, classNames removed — use className (and standard DOM props) on the relevant parts

On this page