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-lts.

    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