> For AI agents: the complete documentation index is available at https://wallarm.github.io/design-system/llms.txt, the full documentation bundle is available at https://wallarm.github.io/design-system/llms-full.txt.

# DateInput

A date typed segment by segment, for a date the reader knows — pair it with `Calendar` when they need to see the month to choose. It takes React Aria date objects rather than a JavaScript `Date`, and segment order and hour cycle come from `DateFormatProvider` app-wide rather than per input.

[Source](https://github.com/wallarm/design-system/tree/main/packages/design-system/src/components/DateInput) · [Storybook](https://wallarm.github.io/design-system/storybook/?path=/docs/inputs-date-dateinput--overview)

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';

export const Basic = () => {
  return <DateInput />;
};
```

## Usage

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';
```

## Examples

### With icon

The calendar icon is decoration here, not a trigger — this field opens nothing. Reach for
`Calendar` when the icon should open a picker.

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const WithIcon = () => (
  <HStack gap={24}>
    <VStack gap={12}>
      <DateInput showIcon={false} />
    </VStack>
    <VStack gap={12}>
      <DateInput />
    </VStack>
  </HStack>
);
```

### States

Default, disabled and error side by side. `error` reddens the border and marks the field
invalid; the reason belongs in `FieldError`.

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const States = () => (
  <HStack gap={24}>
    <VStack gap={12}>
      <DateInput />
      <DateInput defaultValue={sampleDate} />
    </VStack>
    <VStack gap={12}>
      <DateInput disabled />
      <DateInput disabled defaultValue={sampleDate} />
    </VStack>
    <VStack gap={12}>
      <DateInput error />
      <DateInput error defaultValue={sampleDate} />
    </VStack>
  </HStack>
);
```

### Sizes

The same 36 / 32 / 24px scale as the other fields, so a date sits in a row of inputs without
breaking the line.

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const Sizes = () => (
  <HStack gap={24}>
    <VStack gap={16}>
      <VStack gap={4}>
        <DateInput size='default' />
      </VStack>
      <VStack gap={4}>
        <DateInput size='medium' />
      </VStack>
      <VStack gap={4}>
        <DateInput size='small' />
      </VStack>
    </VStack>
    <VStack gap={16}>
      <VStack gap={4}>
        <DateInput size='default' defaultValue={sampleDate} />
      </VStack>
      <VStack gap={4}>
        <DateInput size='medium' defaultValue={sampleDate} />
      </VStack>
      <VStack gap={4}>
        <DateInput size='small' defaultValue={sampleDate} />
      </VStack>
    </VStack>
  </HStack>
);
```

### Filled

A field holding a value, next to one holding a placeholder. The clear affordance only appears
once there is something to clear.

```tsx
import { DateFormatProvider } from '@wallarm-org/design-system/DateFormatProvider';
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { VStack } from '@wallarm-org/design-system/Stack';

export const Filled = () => (
  <VStack gap={16}>
    <VStack gap={4}>
      <DateInput defaultValue={sampleDate} />
    </VStack>
    <DateFormatProvider order='day-first' hourCycle={24}>
      <VStack gap={4}>
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
    <DateFormatProvider order='day-first' hourCycle={12}>
      <VStack gap={4}>
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
    <VStack gap={4}>
      <DateInput showIcon={false} defaultValue={sampleDate} />
    </VStack>
  </VStack>
);
```

### Granularity

`granularity` decides how many segments there are, from a day down to a second. Ask for the
smallest unit you will actually use — every extra segment is another thing to tab through.

```tsx
import { DateFormatProvider } from '@wallarm-org/design-system/DateFormatProvider';
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const Granularity = () => (
  <HStack gap={24}>
    <DateFormatProvider order='day-first' hourCycle={12}>
      <VStack gap={12}>
        <DateInput placeholder='day' granularity='day' />
        <DateInput placeholder='hour' granularity='hour' />
        <DateInput placeholder='minute' granularity='minute' />
        <DateInput placeholder='second' granularity='second' />
      </VStack>
    </DateFormatProvider>
    <DateFormatProvider order='day-first' hourCycle={24}>
      <VStack gap={12}>
        <DateInput placeholder='day' granularity='day' />
        <DateInput placeholder='hour' granularity='hour' />
        <DateInput placeholder='minute' granularity='minute' />
        <DateInput placeholder='second' granularity='second' />
      </VStack>
    </DateFormatProvider>
  </HStack>
);
```

### With field components

Inside `Field`, which supplies the label and description. The field does not read that
context, so check the labelling rather than assuming it wired itself.

```tsx
import { useState } from 'react';
import { CalendarDate, getLocalTimeZone, today } from '@wallarm-org/design-system';
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { Field, FieldAction, FieldDescription, FieldError, FieldLabel } from '@wallarm-org/design-system/Field';
import { VStack } from '@wallarm-org/design-system/Stack';

export const WithFieldComponents = () => {
  // With `granularity='day'` the runtime value is always a CalendarDate —
  // onChange gets cast on the way in so app state stays narrowly typed.
  const [value, setValue] = useState<CalendarDate | null>(null);
  const [errorValue, setErrorValue] = useState<CalendarDate | null>(today(getLocalTimeZone()));

  const handleSetNow = () => {
    setValue(today(getLocalTimeZone()));
  };

  return (
    <VStack gap={24}>
      <Field>
        <FieldLabel>
          Label
          <FieldAction onClick={handleSetNow}>Set now</FieldAction>
        </FieldLabel>
        <DateInput
          placeholder='Select a date'
          value={value}
          onChange={v => setValue(v as CalendarDate | null)}
        />
        <FieldDescription>This is an input description.</FieldDescription>
      </Field>

      <Field invalid>
        <FieldLabel>Label</FieldLabel>
        <DateInput
          error
          value={errorValue}
          onChange={v => setErrorValue(v as CalendarDate | null)}
        />
        <FieldError>An error message.</FieldError>
      </Field>
    </VStack>
  );
};
```

### Date order comparison

Day-first against month-first, each in its own scoped provider. This is an app-wide decision,
not a per-field one — the comparison exists to show what the provider changes.

```tsx
import { DateFormatProvider } from '@wallarm-org/design-system/DateFormatProvider';
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const DateOrderComparison = () => (
  <HStack gap={32}>
    <DateFormatProvider order='day-first' hourCycle={24}>
      <VStack gap={12}>
        <DateInput />
        <DateInput defaultValue={sampleDate} />
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
    <DateFormatProvider order='month-first' hourCycle={24}>
      <VStack gap={12}>
        <DateInput />
        <DateInput defaultValue={sampleDate} />
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
  </HStack>
);
```

### Hour cycle by context

12-hour against 24-hour, again from the provider. There is no per-input escape hatch, which
is deliberate: a form mixing both would be unreadable.

```tsx
import { DateFormatProvider } from '@wallarm-org/design-system/DateFormatProvider';
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const HourCycleByContext = () => (
  <HStack gap={32}>
    <DateFormatProvider order='day-first' hourCycle={12}>
      <VStack gap={12}>
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
        <DateInput granularity='second' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
    <DateFormatProvider order='day-first' hourCycle={24}>
      <VStack gap={12}>
        <DateInput granularity='minute' defaultValue={sampleDateTime} />
        <DateInput granularity='second' defaultValue={sampleDateTime} />
      </VStack>
    </DateFormatProvider>
  </HStack>
);
```

### Read only

`readOnly` keeps the value legible and removes every edit affordance. Different from
disabled, which says the control exists but is unavailable.

```tsx
import { DateInput } from '@wallarm-org/design-system/DateInput';
import { HStack, VStack } from '@wallarm-org/design-system/Stack';

export const ReadOnly = () => (
  <HStack gap={24}>
    <VStack gap={12}>
      <DateInput readOnly defaultValue={sampleDate} data-testid='date-input-read-only' />
    </VStack>
    <VStack gap={12}>
      <DateInput
        readOnly
        granularity='minute'
        defaultValue={sampleDateTime}
        data-testid='date-input-read-only-datetime'
      />
    </VStack>
  </HStack>
);
```

## Props

| Prop             | Type                             | Default   | Description                                                                  |
| ---------------- | -------------------------------- | --------- | ---------------------------------------------------------------------------- |
| showIcon         | `boolean \| undefined`           | `true`    | Whether to show the leading icon. Default: true.                             |
| error            | `boolean \| undefined`           | `false`   | Whether the input has an error state. Sets `aria-invalid` and error styling. |
| disabled         | `boolean \| undefined`           | `false`   | Whether the input is disabled. Prevents user interaction.                    |
| readOnly         | `boolean \| undefined`           | `false`   | Whether the input is read-only. Segments are focusable but not editable.     |
| placeholder      | `string \| undefined`            |           | Placeholder shown when no value is selected.                                 |
| size             | `TemporalInputSize \| undefined` | `default` | Visual size. Default: 'default' (36px).                                      |
| title            | `string \| undefined`            |           |                                                                              |
| defaultChecked   | `boolean \| undefined`           |           |                                                                              |
| autoFocus        | `boolean \| undefined`           |           |                                                                              |
| id               | `string \| undefined`            |           |                                                                              |
| tabIndex         | `number \| undefined`            |           |                                                                              |
| rel              | `string \| undefined`            |           |                                                                              |
| data-testid      | `string \| undefined`            |           |                                                                              |
| value            | `DateValue \| null \| undefined` |           |                                                                              |
| defaultValue     | `DateValue \| null \| undefined` |           |                                                                              |
| onChange         | `complex`                        |           |                                                                              |
| minValue         | `DateValue \| undefined`         |           |                                                                              |
| maxValue         | `DateValue \| undefined`         |           |                                                                              |
| placeholderValue | `DateValue \| undefined`         |           |                                                                              |
| name             | `string \| undefined`            |           |                                                                              |
| isRequired       | `boolean \| undefined`           |           | Marks the field as required in assistive tech and HTML form validation.      |
| granularity      | `"day" \| undefined`             | `day`     |                                                                              |
| showTimeDropdown | `undefined`                      |           |                                                                              |
| timeStep         | `undefined`                      | `30`      |                                                                              |
