# DatePicker

**📖 Live documentation:** https://cds.coinbase.com/components/other/DatePicker/

Date Picker allows our global users to input past, present, future and important dates into our interface in a simple and intuitive manner. Date Picker offers both manual and calendar entry options - accommodating both internationalization and accessibility needs while being adaptable across screen platforms.

## Import

```tsx
import { DatePicker } from '@coinbase/cds-web/dates/DatePicker'
```

## Examples

DatePicker combines [DateInput](/components/other/DateInput/) with [Calendar](/components/other/Calendar/) for date selection.

### Basics

A basic DatePicker with the minimum props necessary for correct UX.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Birthdate"
      openCalendarAccessibilityLabel="Open calendar"
      closeCalendarAccessibilityLabel="Close calendar"
      nextArrowAccessibilityLabel="Next month"
      previousArrowAccessibilityLabel="Previous month"
      helperTextErrorIconAccessibilityLabel="Error"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

#### Validation

##### Invalid dates

Always provide the `invalidDateError` prop for when users type an impossible date like 99/99/2000.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

##### Minimum and maximum dates

Make sure to provide the `disabledDateError` prop when providing `minDate`, `maxDate`, or `disabledDates` props. Navigation to dates before the `minDate` and after the `maxDate` is disabled.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  const today = new Date(new Date().setHours(0, 0, 0, 0));
  const lastMonth15th = new Date(today.getFullYear(), today.getMonth() - 1, 15);
  const nextMonth15th = new Date(today.getFullYear(), today.getMonth() + 1, 15);

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      minDate={lastMonth15th}
      maxDate={nextMonth15th}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
      disabledDateError="Date unavailable"
    />
  );
}
```

##### Disabled dates

The `disabledDates` prop is an array of Dates and Date tuples for date ranges. A number is created for every individual date within a tuple range, so do not abuse this with massive ranges.

Make sure to provide the `disabledDateError` prop when providing `minDate`, `maxDate`, or `disabledDates` props.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  const today = new Date(new Date().setHours(0, 0, 0, 0));
  const oneWeekAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);
  const twoDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 2);
  const oneWeekLater = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);

  const disabledDates = [[oneWeekAgo, twoDaysAgo], oneWeekLater];

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      disabledDates={disabledDates}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
      disabledDateError="Date unavailable"
    />
  );
}
```

##### Required field

Make sure to provide the `requiredError` prop when setting the `required` prop to true. The `requiredError` will be displayed if a user blurs the input, without a date selected, after having typed into it.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <DatePicker
      required
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
      requiredError="This field is required"
    />
  );
}
```

##### Custom validation

The DatePicker handles common error states internally, and calls `onErrorDate` when the validity / error state changes.

You can use the `DateInputValidationError` class to create custom error states.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  useEffect(() => {
    setError(new DateInputValidationError('custom', 'Hello world!'));
  }, []);

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

### Accessibility

Always provide the accessibility label props and all necessary error props. See the Accessibility section under the Guidelines tab at the top of the page for more info.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <DatePicker
      required
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      disabledDates={[new Date()]}
      label="Birthdate"
      accessibilityLabel="Birthdate"
      openCalendarAccessibilityLabel="Open calendar to select birthdate"
      closeCalendarAccessibilityLabel="Close calendar"
      nextArrowAccessibilityLabel="Next month"
      previousArrowAccessibilityLabel="Previous month"
      highlightedDateAccessibilityHint="Highlighted"
      helperTextErrorIconAccessibilityLabel="Error"
      invalidDateError="Please enter a valid date"
      disabledDateError="Date unavailable"
      requiredError="This field is required"
    />
  );
}
```

### Localization

The date format is automatically adjusted to the `LocaleContext`. Check `LocaleProvider` usage below.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <LocaleProvider locale="es-ES">
      <DatePicker
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Birthdate"
        invalidDateError="Please enter a valid date"
      />
    </LocaleProvider>
  );
}
```

### Styling

DatePicker supports the same styling functionality as [DateInput](/components/other/DateInput/) and [Calendar](/components/other/Calendar/).

#### Compact

Use the `compact` prop for a smaller input size.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <VStack gap={3}>
      <DatePicker
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Default size"
        invalidDateError="Please enter a valid date"
      />
      <DatePicker
        compact
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Compact size"
        invalidDateError="Please enter a valid date"
      />
    </VStack>
  );
}
```

#### Disabled

```jsx live
function Example() {
  const [date, setDate] = useState(new Date());
  const [error, setError] = useState(null);

  return (
    <DatePicker
      disabled
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Disabled picker"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

#### Helper text

Use the `helperText` prop to provide additional context below the input.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      label="Start date"
      helperText="Select when you'd like to begin"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

#### Label

You can pass a ReactNode to `labelNode` to render a custom label. If you want to include a tooltip, ensure the touch target is at least 24x24 for accessibility compliance.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <VStack gap={2}>
      <DatePicker
        accessibilityLabel="Birthdate"
        openCalendarAccessibilityLabel="Open birthdate calendar"
        closeCalendarAccessibilityLabel="Close calendar"
        date={date}
        error={error}
        helperTextErrorIconAccessibilityLabel="Error"
        id="birthdate-tooltip"
        invalidDateError="Please enter a valid date"
        labelNode={
          <HStack alignItems="center">
            <InputLabel htmlFor="birthdate-tooltip">Birthdate</InputLabel>
            {/* Add padding to ensure 24x24 tooltip tap target for a11y compliance */}
            <Tooltip content="This will be visible to other users.">
              <Icon active color="fg" name="info" padding={0.75} size="xs" tabIndex={0} />
            </Tooltip>
          </HStack>
        }
        nextArrowAccessibilityLabel="Next month"
        onChangeDate={setDate}
        onErrorDate={setError}
        previousArrowAccessibilityLabel="Previous month"
      />
      <DatePicker
        required
        accessibilityLabel="Event date"
        date={date}
        error={error}
        invalidDateError="Please enter a valid date"
        labelNode={
          <InputLabel>
            <HStack alignItems="center" gap={0.5}>
              Event date
              <Text color="fgNegative" font="label1">
                *
              </Text>
            </HStack>
          </InputLabel>
        }
        onChangeDate={setDate}
        onErrorDate={setError}
        requiredError="This field is required"
      />
    </VStack>
  );
}
```

##### Label Variant

Use the `labelVariant` prop to position the label inside the input.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  return (
    <VStack gap={3}>
      <DatePicker
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Default label"
        invalidDateError="Please enter a valid date"
      />
      <DatePicker
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Inside label"
        labelVariant="inside"
        invalidDateError="Please enter a valid date"
      />
      <DatePicker
        compact
        date={date}
        error={error}
        onChangeDate={setDate}
        onErrorDate={setError}
        label="Compact inside label"
        labelVariant="inside"
        invalidDateError="Please enter a valid date"
      />
      <DatePicker
        accessibilityLabel="Event date"
        date={date}
        error={error}
        id="event-date-inside"
        invalidDateError="Please enter a valid date"
        labelVariant="inside"
        labelNode={
          <InputLabel htmlFor="event-date-inside" paddingY={0}>
            <HStack alignItems="center" gap={1}>
              Event date
              <Text color="fgMuted" font="legal">
                (optional)
              </Text>
            </HStack>
          </InputLabel>
        }
        onChangeDate={setDate}
        onErrorDate={setError}
      />
    </VStack>
  );
}
```

#### Seeding the date

Defaults to today when undefined.

The `seedDate` prop is used to generate the Calendar month when there is no selected date value.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  const seedDate = new Date('11/16/1991');

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      seedDate={seedDate}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

#### Highlighted dates

The `highlightedDates` prop is an array of Dates and Date tuples for date ranges. A number is created for every individual date within a tuple range, so do not abuse this with massive ranges.

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  const today = new Date(new Date().setHours(0, 0, 0, 0));
  const oneWeekAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 7);
  const twoDaysAgo = new Date(today.getFullYear(), today.getMonth(), today.getDate() - 2);
  const oneWeekLater = new Date(today.getFullYear(), today.getMonth(), today.getDate() + 7);

  const highlightedDates = [[oneWeekAgo, twoDaysAgo], oneWeekLater];

  return (
    <DatePicker
      date={date}
      error={error}
      onChangeDate={setDate}
      onErrorDate={setError}
      highlightedDates={highlightedDates}
      label="Birthdate"
      invalidDateError="Please enter a valid date"
    />
  );
}
```

### Composed Examples

#### Date range selector

This is a complex example using many different props. We use multiple DatePickers together to allow a user to select a date range.

We enforce that the time between the start date and end date must be at least 5 days but less than 14 days long, that the end date comes after the start date, and that all days are within the current month. We use the `onChange` prop to automatically suggest an end date of 1 week after the start date, or the last of the month - whichever is sooner. We also explicitly disable 1 week at the beginning of the month.

```jsx live
function Example() {
  const [startDate, setStartDate] = useState(null);
  const [startError, setStartError] = useState(null);
  const [endDate, setEndDate] = useState(null);
  const [endError, setEndError] = useState(null);

  const today = new Date(new Date().setHours(0, 0, 0, 0));
  const firstDayThisMonth = new Date(today.getFullYear(), today.getMonth(), 1);
  const seventhDayThisMonth = new Date(today.getFullYear(), today.getMonth(), 7);
  const lastDayThisMonth = new Date(today.getFullYear(), today.getMonth() + 1, 0);

  const disabledDates = [[firstDayThisMonth, seventhDayThisMonth]];

  const updateEndDate = (endDate, startDate) => {
    setEndDate(endDate);
    setEndError(null);
    if (!endDate) return;
    // The time from startDate to endDate must be at least 5 days and less than 14 days
    const endDateMin = new Date(
      startDate.getFullYear(),
      startDate.getMonth(),
      startDate.getDate() + 4,
    );
    const endDateMax = new Date(
      startDate.getFullYear(),
      startDate.getMonth(),
      startDate.getDate() + 13,
    );

    let errorMessage;
    if (endDate < startDate) errorMessage = 'Must come after start date';
    else if (endDate < endDateMin) errorMessage = 'Must select at least 5 days';
    else if (endDate > endDateMax) errorMessage = 'Cannot select more than 14 days';

    if (errorMessage) setEndError(new DateInputValidationError('custom', errorMessage));
  };

  const handleChangeDateStart = (date) => {
    setStartDate(date);
    if (!date) return;
    // Suggest an end date based on the new start date
    const suggestedEndDate = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 7);
    const newEndDate = new Date(Math.min(suggestedEndDate.getTime(), lastDayThisMonth.getTime()));
    updateEndDate(newEndDate, date);
  };

  const handleChangeDateEnd = (date) => {
    if (startDate) updateEndDate(date, startDate);
  };

  return (
    <Box gap={2} flexDirection={{ base: 'column', tablet: 'column', desktop: 'row' }}>
      <DatePicker
        required
        date={startDate}
        disabledDateError="Date unavailable"
        disabledDates={disabledDates}
        error={startError}
        highlightedDates={startDate && endDate ? [[startDate, endDate]] : undefined}
        invalidDateError="Please enter a valid date"
        label="Start date"
        maxDate={lastDayThisMonth}
        minDate={firstDayThisMonth}
        onChangeDate={handleChangeDateStart}
        onErrorDate={setStartError}
        requiredError="This field is required"
        style={{ width: '100%' }}
      />
      <DatePicker
        required
        date={endDate}
        disabled={!startDate}
        disabledDateError="Date unavailable"
        disabledDates={startDate ? [...disabledDates, startDate] : disabledDates}
        error={endError}
        highlightedDates={
          startDate && endDate && startDate < endDate
            ? [[startDate, endDate]]
            : startDate
              ? [startDate]
              : undefined
        }
        invalidDateError="Please enter a valid date"
        label="End date"
        maxDate={lastDayThisMonth}
        minDate={firstDayThisMonth}
        onChangeDate={handleChangeDateEnd}
        onErrorDate={setEndError}
        requiredError="This field is required"
        variant={endError ? 'negative' : undefined}
        style={{ width: '100%' }}
      />
    </Box>
  );
}
```

### Event Lifecycle

- Selecting a date with the Calendar:

  `onOpen -> onConfirm -> onChangeDate -> onErrorDate -> onClose`

- Closing the Calendar without selecting a date:

  `onOpen -> onCancel -> onClose`

- Typing a date in a blank DateInput:

  `onChange -> onChange -> ... -> onChangeDate -> onErrorDate`

- Typing a date in a DateInput that already had a date:

  `onChange -> onChangeDate -> onChange -> onChange -> ... -> onChangeDate -> onErrorDate`

```jsx live
function Example() {
  const [date, setDate] = useState(null);
  const [error, setError] = useState(null);

  const handleChangeDate = (date) => {
    console.log('onChangeDate', date);
    setDate(date);
  };

  const handleErrorDate = (error) => {
    console.log('onErrorDate', error);
    setError(error);
  };

  return (
    <DatePicker
      required
      date={date}
      invalidDateError="Please enter a valid date"
      label="Birthdate"
      onChange={(event) => console.log('onChange', event)}
      onChangeDate={handleChangeDate}
      onConfirm={() => console.log('onConfirm')}
      onCancel={() => console.log('onCancel')}
      onErrorDate={handleErrorDate}
      onOpen={() => console.log('onOpen')}
      onClose={() => console.log('onClose')}
    />
  );
}
```

## Props

| Prop | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `date` | `Date \| null` | Yes | `-` | Control the date value of the DatePicker. |
| `error` | `DateInputValidationError \| null` | Yes | `-` | Control the error value of the DatePicker. Control the error value of the DateInput. |
| `onChangeDate` | `(selectedDate: Date \| null) => void` | Yes | `-` | Callback function fired when the date changes, e.g. when a valid date is selected or unselected. |
| `onErrorDate` | `((error: DateInputValidationError \| null) => void) & ((error: DateInputValidationError \| null) => void)` | Yes | `-` | Callback function fired when validation finds an error, e.g. required input fields and impossible or disabled dates. Will always be called after onChangeDate. |
| `align` | `center \| start \| end \| justify` | No | `start` | Text Align Input |
| `alignContent` | `ResponsiveProp<center \| normal \| start \| end \| flex-start \| flex-end \| stretch \| baseline \| first baseline \| last baseline \| space-between \| space-around \| space-evenly>` | No | `-` | - |
| `alignItems` | `ResponsiveProp<center \| normal \| start \| end \| flex-start \| flex-end \| self-start \| self-end \| stretch \| baseline \| first baseline \| last baseline>` | No | `-` | - |
| `alignSelf` | `ResponsiveProp<center \| normal \| auto \| start \| end \| flex-start \| flex-end \| self-start \| self-end \| stretch \| baseline \| first baseline \| last baseline>` | No | `-` | - |
| `as` | `input` | No | `-` | The underlying element or component the polymorphic component will render.  Changing as also changes the inherited native props (e.g. href for as=a) and the expected ref type. |
| `aspectRatio` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<AspectRatio \| undefined>` | No | `-` | - |
| `background` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent \| ResponsiveValue<Color \| undefined>` | No | `-` | - |
| `borderBottomLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000 \| ResponsiveValue<BorderRadius \| undefined>` | No | `-` | - |
| `borderBottomRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000 \| ResponsiveValue<BorderRadius \| undefined>` | No | `-` | - |
| `borderBottomWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| ResponsiveValue<BorderWidth \| undefined>` | No | `-` | - |
| `borderColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent \| ResponsiveValue<Color \| undefined>` | No | `-` | - |
| `borderEndWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| ResponsiveValue<BorderWidth \| undefined>` | No | `-` | - |
| `borderRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000 \| ResponsiveValue<BorderRadius \| undefined>` | No | `200` | Leverage one of the borderRadius styles we offer to round the corners of the input. |
| `borderStartWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| ResponsiveValue<BorderWidth \| undefined>` | No | `-` | - |
| `borderTopLeftRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000 \| ResponsiveValue<BorderRadius \| undefined>` | No | `-` | - |
| `borderTopRightRadius` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| 600 \| 700 \| 800 \| 900 \| 1000 \| ResponsiveValue<BorderRadius \| undefined>` | No | `-` | - |
| `borderTopWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| ResponsiveValue<BorderWidth \| undefined>` | No | `-` | - |
| `borderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500 \| ResponsiveValue<BorderWidth \| undefined>` | No | `-` | - |
| `bordered` | `boolean` | No | `true` | Add a border around all sides of the box. Adds border to input. When set to false, focus border styling is disabled by default. |
| `borderedBottom` | `boolean` | No | `-` | Add a border to the bottom side of the box. |
| `borderedEnd` | `boolean` | No | `-` | Add a border to the trailing side of the box. |
| `borderedHorizontal` | `boolean` | No | `-` | Add a border to the leading and trailing sides of the box. |
| `borderedStart` | `boolean` | No | `-` | Add a border to the leading side of the box. |
| `borderedTop` | `boolean` | No | `-` | Add a border to the top side of the box. |
| `borderedVertical` | `boolean` | No | `-` | Add a border to the top and bottom sides of the box. |
| `bottom` | `ResponsiveProp<Bottom<string \| number>>` | No | `-` | - |
| `calendarClassName` | `string` | No | `-` | Custom class name to apply to the Calendar container. |
| `calendarIconButtonAccessibilityLabel` | `string` | No | `-` | Accessibility label describing the calendar IconButton, which opens the calendar when pressed. |
| `calendarStyle` | `CSSProperties` | No | `-` | Custom style to apply to the Calendar container. |
| `classNames` | `{ dateInput?: string; calendar?: string \| undefined; calendarHeader?: string \| undefined; calendarTitle?: string \| undefined; calendarNavigation?: string \| undefined; calendarContent?: string \| undefined; calendarDay?: string \| undefined; } \| undefined` | No | `-` | Custom class names for the DateInput and Calendar subcomponents. |
| `closeCalendarAccessibilityLabel` | `string` | No | `'Close calendar'` | Accessibility label for the calendar IconButton when the popover is open (closes the calendar when pressed). |
| `color` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent \| ResponsiveValue<Color \| undefined>` | No | `-` | - |
| `columnGap` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `compact` | `boolean` | No | `false false` | Decreases the padding within the input element Enables compact variation |
| `containerSpacing` | `string` | No | `-` | Custom container spacing if needed. This will add to the existing spacing |
| `dangerouslySetBackground` | `string` | No | `-` | - |
| `dateInputClassName` | `string` | No | `-` | Custom class name to apply to the DateInput. |
| `dateInputStyle` | `CSSProperties` | No | `-` | Custom style to apply to the DateInput. |
| `defaultOpen` | `boolean` | No | `-` | Control the default open state of the Calendar popover. |
| `disabled` | `boolean` | No | `false` | Disables user interaction. Toggles input interactability and opacity |
| `disabledDateError` | `string` | No | `'Date unavailable'` | Tooltip content shown when hovering or focusing a disabled date, including dates before the minDate or after the maxDate. |
| `disabledDates` | `(Date \| [Date, Date])[]` | No | `-` | Array of disabled dates, and date tuples for date ranges. Make sure to set disabledDateError as well. A number is created for every individual date within a tuple range, so do not abuse this with massive ranges. |
| `display` | `ResponsiveProp<grid \| revert \| none \| block \| inline \| inline-block \| flex \| inline-flex \| inline-grid \| contents \| flow-root \| list-item>` | No | `-` | - |
| `elevation` | `0 \| 1 \| 2 \| ResponsiveValue<Elevation \| undefined>` | No | `-` | - |
| `enableColorSurge` | `boolean` | No | `-` | Enable Color Surge motion |
| `end` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Adds content to the end of the inner input. Refer to diagram for location of endNode in InputStack component |
| `flexBasis` | `ResponsiveProp<FlexBasis<string \| number>>` | No | `-` | - |
| `flexDirection` | `ResponsiveProp<column \| row \| row-reverse \| column-reverse>` | No | `-` | - |
| `flexGrow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| ResponsiveValue<FlexGrow \| undefined>` | No | `-` | - |
| `flexShrink` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| ResponsiveValue<FlexShrink \| undefined>` | No | `-` | - |
| `flexWrap` | `ResponsiveProp<nowrap \| wrap \| wrap-reverse>` | No | `-` | - |
| `focusedBorderWidth` | `0 \| 100 \| 200 \| 300 \| 400 \| 500` | No | `-` | Additional border width when focused. Set this when bordered={false} to opt into a focus border style. |
| `font` | `ResponsiveProp<FontFamily \| inherit>` | No | `-` | - |
| `fontFamily` | `ResponsiveProp<FontFamily \| inherit>` | No | `-` | - |
| `fontSize` | `ResponsiveProp<FontSize \| inherit>` | No | `-` | - |
| `fontWeight` | `ResponsiveProp<FontWeight \| inherit>` | No | `-` | - |
| `gap` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `grid` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none \| ResponsiveValue<Grid \| undefined>` | No | `-` | - |
| `gridArea` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridArea \| undefined>` | No | `-` | - |
| `gridAutoColumns` | `ResponsiveProp<GridAutoColumns<string \| number>>` | No | `-` | - |
| `gridAutoFlow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| column \| dense \| row \| ResponsiveValue<GridAutoFlow \| undefined>` | No | `-` | - |
| `gridAutoRows` | `ResponsiveProp<GridAutoRows<string \| number>>` | No | `-` | - |
| `gridColumn` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridColumn \| undefined>` | No | `-` | - |
| `gridColumnEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridColumnEnd \| undefined>` | No | `-` | - |
| `gridColumnStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridColumnStart \| undefined>` | No | `-` | - |
| `gridRow` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridRow \| undefined>` | No | `-` | - |
| `gridRowEnd` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridRowEnd \| undefined>` | No | `-` | - |
| `gridRowStart` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<GridRowStart \| undefined>` | No | `-` | - |
| `gridTemplate` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none \| ResponsiveValue<GridTemplate \| undefined>` | No | `-` | - |
| `gridTemplateAreas` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none \| ResponsiveValue<GridTemplateAreas \| undefined>` | No | `-` | - |
| `gridTemplateColumns` | `ResponsiveProp<GridTemplateColumns<string \| number>>` | No | `-` | - |
| `gridTemplateRows` | `ResponsiveProp<GridTemplateRows<string \| number>>` | No | `-` | - |
| `height` | `ResponsiveProp<Height<string \| number>>` | No | `-` | Height of input |
| `helperText` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | For cases where label is not enough information to describe what the text input is for. Can also be used for showing positive/negative messages |
| `helperTextErrorIconAccessibilityLabel` | `string` | No | `'error'` | Accessibility label for helper text error icon when variant=negative |
| `highlightedDateAccessibilityHint` | `string` | No | `'Highlighted'` | Accessibility hint announced for highlighted dates. Applied to all highlighted dates. |
| `highlightedDates` | `(Date \| [Date, Date])[]` | No | `-` | Array of highlighted dates, and date tuples for date ranges. A number is created for every individual date within a tuple range, so do not abuse this with massive ranges. |
| `inputBackground` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `'bg'` | Background color of the input. |
| `invalidDateError` | `string` | No | `'Please enter a valid date'` | Error text to display when an impossible date is selected, e.g. 99/99/2000. This should always be defined for accessibility. Also displays when a date is selected that is more than 100 years before the minDate, or more than 100 years after the maxDate. |
| `justifyContent` | `ResponsiveProp<left \| right \| center \| normal \| start \| end \| flex-start \| flex-end \| stretch \| space-between \| space-around \| space-evenly>` | No | `-` | - |
| `key` | `Key \| null` | No | `-` | - |
| `label` | `string` | No | `-` | Short messageArea indicating purpose of input |
| `labelColor` | `currentColor \| fg \| fgMuted \| fgInverse \| fgPrimary \| fgWarning \| fgPositive \| fgNegative \| bg \| bgAlternate \| bgInverse \| bgOverlay \| bgElevation1 \| bgElevation2 \| bgPrimary \| bgPrimaryWash \| bgSecondary \| bgTertiary \| bgSecondaryWash \| bgNegative \| bgNegativeWash \| bgPositive \| bgPositiveWash \| bgWarning \| bgWarningWash \| bgLine \| bgLineHeavy \| bgLineInverse \| bgLinePrimary \| bgLinePrimarySubtle \| accentSubtleRed \| accentBoldRed \| accentSubtleGreen \| accentBoldGreen \| accentSubtleBlue \| accentBoldBlue \| accentSubtlePurple \| accentBoldPurple \| accentSubtleYellow \| accentBoldYellow \| accentSubtleGray \| accentBoldGray \| transparent` | No | `-` | Color token for the field label. |
| `labelFont` | `display1 \| display2 \| display3 \| title1 \| title2 \| title3 \| title4 \| headline \| body \| label1 \| label2 \| caption \| legal` | No | `-` | Typography token for the field label. |
| `labelNode` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | React node to render label. Takes precedence over label. |
| `labelVariant` | `inside \| outside` | No | `'outside'` | The variant of the label. Only used when compact is not true. |
| `left` | `ResponsiveProp<Left<string \| number>>` | No | `-` | - |
| `lineHeight` | `ResponsiveProp<LineHeight \| inherit>` | No | `-` | - |
| `margin` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginBottom` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginEnd` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginStart` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginTop` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginX` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `marginY` | `ResponsiveProp<0 \| -1 \| -5 \| -10 \| -0.25 \| -0.5 \| -0.75 \| -1.5 \| -2 \| -3 \| -4 \| -6 \| -7 \| -8 \| -9>` | No | `-` | - |
| `maxDate` | `Date` | No | `-` | Maximum date allowed to be selected, inclusive. Dates after the maxDate are disabled. All navigation to months after the maxDate is disabled. |
| `maxHeight` | `ResponsiveProp<MaxHeight<string \| number>>` | No | `-` | - |
| `maxWidth` | `ResponsiveProp<MaxWidth<string \| number>>` | No | `-` | - |
| `minDate` | `Date` | No | `-` | Minimum date allowed to be selected, inclusive. Dates before the minDate are disabled. All navigation to months before the minDate is disabled. |
| `minHeight` | `ResponsiveProp<MinHeight<string \| number>>` | No | `-` | - |
| `minWidth` | `ResponsiveProp<MinWidth<string \| number>>` | No | `-` | - |
| `nextArrowAccessibilityLabel` | `string` | No | `'Go to next month'` | Accessibility label describing the Calendar next month arrow. |
| `onCancel` | `(() => void)` | No | `-` | Callback function fired when the user closes the picker without selecting a date. Interacting with the DateInput does not fire this callback. Will always be called before onClose. |
| `onChange` | `FormEventHandler<HTMLDivElement>` | No | `-` | - |
| `onClose` | `(() => void)` | No | `-` | Callback function fired when the picker is closed. Will always be called after onCancel, onConfirm, and onChangeDate. |
| `onConfirm` | `(() => void)` | No | `-` | Callback function fired when the user selects a date using the picker. Interacting with the DateInput does not fire this callback. Will always be called before onClose. |
| `onOpen` | `(() => void)` | No | `-` | Callback function fired when the picker is opened. |
| `opacity` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| ResponsiveValue<Opacity \| undefined>` | No | `-` | - |
| `openCalendarAccessibilityLabel` | `string` | No | `'Open calendar'` | Accessibility label for the calendar IconButton when the popover is closed (opens the calendar when pressed). |
| `overflow` | `ResponsiveProp<hidden \| auto \| visible \| clip \| scroll>` | No | `-` | - |
| `padding` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingBottom` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingEnd` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingStart` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingTop` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingX` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `paddingY` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `pin` | `top \| bottom \| left \| right \| all` | No | `-` | Direction in which to absolutely pin the box. |
| `placeholder` | `string` | No | `-` | Placeholder text displayed inside of the input. Will be replaced if there is a value. |
| `position` | `ResponsiveProp<fixed \| static \| relative \| absolute \| sticky>` | No | `-` | - |
| `previousArrowAccessibilityLabel` | `string` | No | `'Go to previous month'` | Accessibility label describing the Calendar previous month arrow. |
| `readOnly` | `boolean` | No | `-` | When true, the value cannot be edited but the control may remain focusable (unlike disabled). |
| `ref` | `null \| RefObject<HTMLButtonElement \| null> \| (instance: HTMLButtonElement \| null) => void \| (() => VoidOrUndefinedOnly)` | No | `-` | Allows getting a ref to the component instance. Once the component unmounts, React will set ref.current to null (or call the ref with null if you passed a callback ref). |
| `required` | `boolean` | No | `-` | If required, the requiredError will be displayed if a user blurs the input, without a date selected, after having typed into it. |
| `requiredError` | `string` | No | `'This field is required'` | Error text to display when required is true and a user blurs the input without a date selected, after having typed into it. |
| `restoreFocusOnUnmount` | `boolean` | No | `true` | If true, the focus trap will restore focus to the previously focused element when it unmounts.  WARNING: If you disable this, you need to ensure that focus is restored properly so it doesnt end up on the body |
| `right` | `ResponsiveProp<Right<string \| number>>` | No | `-` | - |
| `rowGap` | `0 \| 1 \| 5 \| 10 \| 0.25 \| 0.5 \| 0.75 \| 1.5 \| 2 \| 3 \| 4 \| 6 \| 7 \| 8 \| 9 \| ResponsiveValue<Space \| undefined>` | No | `-` | - |
| `seedDate` | `Date` | No | `-` | Date used to generate the Calendar month when there is no value for the selectedDate prop, defaults to today. |
| `showOverlay` | `boolean` | No | `-` | Display an overlay over all content below the Popover menu |
| `start` | `null \| string \| number \| bigint \| false \| true \| ReactElement<unknown, string \| JSXElementConstructor<any>> \| Iterable<ReactNode> \| ReactPortal \| Promise<AwaitedReactNode>` | No | `-` | Adds content to the start of the inner input. Refer to diagram for location of startNode in InputStack component |
| `styles` | `{ dateInput?: CSSProperties; calendar?: CSSProperties \| undefined; calendarHeader?: CSSProperties \| undefined; calendarTitle?: CSSProperties \| undefined; calendarNavigation?: CSSProperties \| undefined; calendarContent?: CSSProperties \| undefined; calendarDay?: CSSProperties \| undefined; } \| undefined` | No | `-` | Custom styles for the DateInput and Calendar subcomponents. |
| `suffix` | `string` | No | `-` | Adds suffix text to the end of input |
| `testID` | `string` | No | `-` | Used to locate this element in unit and end-to-end tests. Under the hood, testID translates to data-testid on Web. On Mobile, testID stays the same - testID |
| `testIDMap` | `{ start?: string; end?: string \| undefined; label?: string \| undefined; helperText?: string \| undefined; } \| undefined` | No | `-` | Add ability to test individual parts of the input |
| `textAlign` | `ResponsiveProp<center \| start \| end \| justify>` | No | `-` | - |
| `textDecoration` | `ResponsiveProp<none \| underline \| overline \| line-through \| underline overline \| underline double>` | No | `-` | - |
| `textTransform` | `ResponsiveProp<capitalize \| lowercase \| none \| uppercase>` | No | `-` | - |
| `top` | `ResponsiveProp<Top<string \| number>>` | No | `-` | - |
| `transform` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| none \| ResponsiveValue<Transform \| undefined>` | No | `-` | - |
| `type` | `button \| reset \| submit` | No | `-` | - |
| `userSelect` | `ResponsiveProp<text \| none \| auto \| all>` | No | `-` | - |
| `variant` | `primary \| secondary \| positive \| negative \| foregroundMuted \| foreground` | No | `foregroundMuted` | Determines the sentiment of the input. Because we allow startContent and endContent to be custom ReactNode, the content placed inside these slots will not change colors according to the variant. You will have to add that yourself |
| `visibility` | `ResponsiveProp<hidden \| visible>` | No | `-` | - |
| `width` | `ResponsiveProp<Width<string \| number>>` | No | `100%` | Width of input as a percentage string. |
| `zIndex` | `-moz-initial \| inherit \| initial \| revert \| revert-layer \| unset \| auto \| ResponsiveValue<ZIndex \| undefined>` | No | `-` | - |


