The Basics

What it is

DateRangeInput is a combo component of two fields allowing users to enter a range of dates. They can either type the dates or select them in the popup calendar. If enabled, they can select one date while leaving the other blank allowing the user to define a selection of “Before X” or “After Y”. 

How it works

  • The user clicks or focuses on one of the two date inputs, which makes it active. 

  • A cursor appears in the input element, and a calendar pops up.

    • If the user tabs to the DateRangeInput, 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 to the next date input field or away if the second date input has been filled. 

When to use

  • To ask users to enter a specific date range, such as a stay of a visit

When not to use

  • To ask users to enter one specific day (see Forge DateInput

What to use instead

MultiField

Use MultiField for closely related data fields that are not dates.

DateInput

Use DateInput to ask users to enter one specific day.

How to use

DateRangeInput 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, DateRangeInput'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 that are not available. 
  • Allow only dates in the past or in the future, such as when users are entering birth dates (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. 
  • Require a date when at least one date must be selected such as a starting date of an illness 
  • Include null date when you are using date range as a filter and want to enable searching when dates were not entered. 
    • This option should not be used when DateRangeInput is being used as input only 

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

Opening the calendar (click vs. tab) 

When users click the date input 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 

DateRangeInput 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

Content

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

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

Demos

Required Date Range Share

Coding

Developer tips

Repository

Implementation links

DateRangeInput 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 accessability 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 { DateRangeInput } 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 DateRangeInput from '@athena/forge/DateRangeInput';

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 DateRangeInput from '@athena/forge/dist/DateRangeInput';

Props