The Basics

What it is

DateInput is a field where users enter a date. They can either type the date or select it in the popup calendar.

How it works

  • The user clicks or focuses on the DateInput, which makes it active.
  • A cursor appears in the input element, and a calendar pops up.
    • If the user tabs to the DateInput, the popup calendar doesn’t appear. This optimizes keyboard-based workflows (like data entry), which are disrupted by popups.
  • To enter a date, the user can:
    • Type the date.
    • Click the date in the calendar, using the arrows and dropdowns to navigate the available date range. This automatically closes the popup and fills the input with the selected date.
  • When finished, the user navigates away from the DateInput.

When to use

  • To ask users to enter a specific date, such as date of birth

When not to use

  • To ask users to enter a month and/or year, but not a specific day
  • To ask users to enter a date range

What to use instead

Select

Use Select to ask users to enter a month and/or year, but not a specific day.

DateRangeInput

Use DateRangeInput to pick a range of dates.

How to use

DateInput can be used as a standalone component, but it’s better when used with Form and FormField. Form provides a consistent, responsive layout, and FormField adds features like labels, error message handling, and hint text.

Limiting and disabling dates

By default, DateInput’s popup calendar opens to the current month and has a date range of +/- 5 years from today’s date. You can change this based on date availability. For example:

  • Open the popup calendar to a specific month and year when the next available appointment is 2 months from today.
  • Disable certain days when the clinic is closed on certain days of the week, or all appointments are fully booked.
  • Allow only dates in the past or in the future when users are entering birthdates (past) or booking procedures (future).
  • Set a range for the dates in the calendar when users are entering dates for reports on previous activity, like visit notes for the past 2 years.

Use labels and hint text to explain any disabled or restricted dates.

Opening the calendar (click vs. tab)

When users click the DateInput field, the popup calendar opens.

When users navigate to the field using the Tab key, however, the popup calendar does not open. This helps data entry staff and other heavy keyboard users enter data quickly, without interruption.

Keyboard shortcuts

DateInput supports these athenaOne date shortcuts:

  • t = today's date
  • t+[# of days] = a future date: # of days after today (e.g., t+5)
  • t-[# of days] = a past date: # of days before today (e.g., t-3)

Style

Design details

Required fields

Forge offers three display options to indicate required form fields. See Form for details.

Spacing and size

The height of this component and the vertical space around it vary according to the form layout (i.e., medium, compact, super-compact). See Form for details.

Placement and hierarchy

No additional information for this component.

Content

Use sentence case for label text (“Date of birth”, not “Date Of Birth”).

DateInput’s default placeholder text uses the standard date format for athenahealth apps: MM-DD-YYYY.

Demos

Use Within A Form Field Share

Standalone Share

Inline Share

Validation Share

Coding

Developer tips

DateInput is a thin wrapper around react-datepicker. The Forge package also includes the library date-fns, which contains useful utilities for manipulating JavaScript dates.

DateInput is rendered as an input[type="text"] to avoid the browser’s default date input UI.

Validation not built in

DateInput doesn’t include internal validation.

Disabled days do get a disabled style in the popup calendar; users can’t select them via click or keyboard navigation in the calendar. However, users can still type a disabled date in the text input field. You need to implement any validation for those dates yourself.

Disabling dates

There are 4 ways to mark disabled dates in DateInput:

  • Provide excludeDates an array of Date objects. All other dates are enabled.
  • Provide includeDates an array of Date objects. All other dates are disabled.
  • Provide filterDate a function. This function should accept a Date object argument and return a bool ({true} for enabled, {false} for disabled).
  • Use the minDate and/or maxDate props to set an upper or lower range.

Highlighting days

Like filterDate, the dayClassname prop can be given a function that takes a Date argument and returns custom class names for certain days in the calendar picker. You can use this to implement custom styling or behavior for a subset of days.

Starting date

By default, DateInput’s popup calendar opens to the current month. You can override this default behavior by providing a specific date to the openToDate prop. This opens the calendar to that date’s month. It doesn’t preselect or highlight that exact date. It also doesn’t change the time range shown in the calendar’s year dropdown. To change that time range, set minDate and maxDate.

Popup calendar and keyboard navigation

Although the DateInput input field is accessible as a standard text input, the keyboard functionality of the popup calendar is disabled by default. We made this decision to maintain standard arrow key behavior in the text input field.

To re-enable keyboard navigation in the calendar (and disable keyboard navigation in the text input), set the disabledKeyboardNavigation and preventOpenOnFocus props to {false}.

Required fields

Use the required prop to mark DateInput as required.

Forge offers three options to indicate required form fields. When using Form with this component, set Form’s requiredVariation prop. See Form for details.

Repository

Implementation links

DateInput directory in Bitbucket

Implementation details

It is strongly recommended to familiarize yourself with the Forge source code. While this documentation is a best effort to document the intent and usage of a component, sometimes some features only become clear when looking at the source code. Also, looking at Forge's source code may help identify and fix bugs in either your application or Forge itself.

Storybook files

Forge maintains at least one storybook file per component. While the primary audience for these files is typically the Forge team, these storybook files may cover usages of the component not covered by a demo. The storybook for the latest version of forge can be found at go/forge-storybook.

Testing library

Forge strongly encourages using testing-library to write tests for your application.

"The more your tests resemble the way your software is used, the more confidence they can give you."

If you're having trouble testing a Forge component using testing-library, it would be a good idea to see how Forge tests its own components. For the most part, Forge tries to use screen.getByRole as much as it can, as that API provides the best feedback on a11y compliance. Forge discourages the use of document.querySelector and screen.getByTestId as both APIs encourage using implementation details to test your component, and discourage adding roles to your component.

With that being said, many of Forge's components were not built with accessibility in mind. These components do break the recommendations listed above.

Import statements

In Nimbus applications

athenaOne serves the Forge bundle independently from your application's bundle. Importing Forge components directly from '@athena/forge' takes advantage of this feature.

import { DateInput } from '@athena/forge'

In standalone applications

Importing components using the exact path to the module takes advantage of webpack's tree shaking feature. Webpack will include only that module and its dependencies.

import DateInput from '@athena/forge/DateInput';

To use this import guidance, Typescript applications must use typescript >= 4.7.3, and should add this setting to their tsconfig.json file:

{
"compilerOptions": {
"moduleResolution": "Node16",
}
}

If this setting doesn't work for your application, use this import statement instead:

import DateInput from '@athena/forge/dist/DateInput';

Props