1.2.13 • Published 4 years ago

react-ada-keyboard-accessible-datepicker v1.2.13

Weekly downloads
2
License
ISC
Repository
github
Last release
4 years ago

React-ADA-Keyboard-Accessible-Datepicker

React-ADA-Keyboard-Accessible-Datepicker is an easy to implement date picker compliant with the standards set out by the Americans with Disabilities Act, including features such as full keyboard accessibility and aria labeling. The package builds upon the date picker developed by w3.org ( https://www.w3.org/TR/wai-aria-practices/examples/dialog-modal/datepicker-dialog.html ) and and adds several options for customization and easy React integrations.

alt text

Accessibility Features

React-ADA-Keyboard-Accessible-Datepicker includes several features to help make its use more accessible to all.

  • When a date is chosen, the accessible name of the “Choose Date” button is updated to include the selected date. So, when the dialog closes and focus returns to the “Choose Date” button, screen reader users hear confirmation of the selected date in the button name.
  • When the month or year of the calendar grid changes as users navigate the calendar or activate the buttons for next or previous month or year, a live region enables screen readers to announce the new month and year.
  • The calendar grid provides hotkeys for changing the year and month as well as support for normal grid navigation keys.
  • When the dialog opens and a date in the calendar grid receives focus, a live region enables screen readers to announce keyboard instructions for navigating the calendar grid. The instructions are also visible at the bottom of the dialog box.
  • A numbr of customization options including auto complete dates, date ranges, and more.

Installation

Use npm to install React-ADA-Keyboard-Accessible-Datepicker

npm install react-ada-keyboard-accessible-datepicker

Usage

import React from 'react';
import Datepicker from 'react-ada-keyboard-accessible-datepicker'

const DatePickerContainer = () =>{

    return(
        <div>
            <Datepicker  />
        </div>
    )
}

Keyboard Controls

Choose Date Button

KeyFunction
Space,Enter Open the date picker dialog. Move focus to selected date, i.e., the date displayed in the date input text field. If no date has been selected, places focus on the current date.

Date Picker Dialog

KeyFunction
ESCCloses the dialog and returns focus to the Choose Date button.
Tab Moves focus to next element in the dialog Tab sequence. Note that, as specified in the grid design pattern, only one button in the calendar grid is in the Tab sequence. * If focus is on the last button (i.e., OK), moves focus to the first button(i.e. Previous Year).

Date Picker Dialog: Month/Year Buttons

KeyFunction
Space,EnterChange the month and/or year displayed in the calendar grid.

Date Picker Dialog: Date Grid

KeyFunction
Space,Enter Select the date, close the dialog, and move focus to the Choose Date button. Update the value of the Date input with the selected date.* Update the accessible name of the Choose Date button to include the selected date.
Up ArrowMoves focus to the same day of the previous week.
Down ArrowMoves focus to the same day of the next week.
Right ArrowMoves focus to the next day.
Left ArrowMoves focus to the previous day.
HomeMoves focus to the first day (e.g Sunday) of the current week.
EndMoves focus to the last day (e.g. Saturday) of the current week.
Page UpChanges the grid of dates to the previous month.Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Shift + Page UpChanges the grid of dates to the previous Year.Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Page DownChanges the grid of dates to the next month.Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.
Shift + Page DownChanges the grid of dates to the next Year.Sets focus on the same day of the same week. If that day does not exist, then moves focus to the same day of the previous or next week.

Date Picker Dialog: OK and Cancel Buttons

KeyFunction
Space,EnterActivates the button: "Cancel": Closes the dialog, moves focus to Choose Date button, does not update date in date input.OK: Closes the dialog, moves focus to Choose Date button, updates date in date input.

Role, Property, State, and Tabindex Attributes

Chose Date Button

RoleAttributeElementUsage
aria-label="String"buttonThe initial value of accessible name is "Choose Date".When users select a date, the accessible name is updated to also include the selected date.

Date Picker Dialog

RoleAttributeElementUsage
dialogdivIdentifies the element as a dialog .
aria-modal="true"divIndicates the dialog is modal.
aria-labelledby="IDREF"divRefers to the heading containing the currently displayed month and year, which defines the accessible name for the dialog.
aria-live="polite"divIndicates the element that displays information about keyboard commands for navigating the grid should be automatically announced by screen readers.The script slightly delays display of the information so screen readers are more likely to read it after information related to change of focus.

Date Picker Dialog: Calendar Navigation Buttons

RoleAttributeElementUsage
aria-label="String"buttonDefines the accessible name of the button (e.g. Next Year).
aria-live="polite"h2When the month and/or year changes the content of the h2 element is updated.Indicates the h2 should be automatically announced by screen readers.

Date Picker Dialog: Date Grid

RoleAttributeElementUsage
gridtableIdentifies the table element as a grid widget.Since the grid role is applied to a table element, the row, colheader, and gridcell roles to be specified because they are implied by th, and tdtags.
aria-labelledby=IDREFtableDefines the accessible name for the grid using the h2 that shows the month and year of the dates displayed in the grid.
tabindex="0"buttonMakes the button focusable and includes it in the dialog Tab sequence.Set dynamically by the JavaScript when the element is to be included in the dialog Tab sequence.At any given time, only one button within the grid is in the dialog Tab sequence.This approach to managing focus is described in the section on roving tabindex.
tabindex="-1"buttonMakes the button focusable and excludes it from the dialog Tab sequence.Changed dynamically to 0 by the JavaScript when the button is to be included in the dialog Tab sequence.At any given time, only one button within the grid is in the dialog Tab sequence.*This approach to managing focus is described in the section on roving tabindex.
aria-selected="true"buttonIdentifies the button for the currently selected date, i.e., the date value present in the date input.Only set on the button representing the currently selected date, no other buttons have aria-selectedspecified.

Customization and Formatting

The date picker allows several levels of customization to acccomodate developers needs. Customizations are generally passed into the component as props. Additional levels of customization will be available in future releases.

themeColor Applies a selected color to the calendar button and calendar borders

const DatePickerContainer = () =>{

   return(
       <div>
           < Datepicker themeColor={"#B41C1C"} />
       </div>
   )
}

dateFormat Dates will be formatted to mm/dd/yyyy by default, but custom formats may be passed in as a string. The month field must be repressed by mm, the date by dd, and the year by yyyy. Fields may be separated by forward slashes, commas or spaces/ , . User input will be automatically formatted unless autoFormatting={false} is passed in as a prop.

const DatePickerContainer = () =>{

    return(
        <div>
            < Datepicker dateFormat={"yyyy,mm,dd"} />
        </div>
    )
}

minDate -Sets the earliest day that the user may choose by using the datepicker. All date cells before the minDate will be disabled. Combing the minDate prop with maxDate will create a date range. Users will not be able to naviagate to the dates outside of the range. minDate must be passed in with the “yyyy-mm-dd” format. To set the min date to the current date pass in minDate={“today”}

const DatePickerContainer = () =>{

  return(
      <div>
          < Datepicker
             minDate={"2019-12-25"} 
            # ----- OR -------
            minDate={"today"}
          />
      </div>
  )
}

maxDate Sets the latest date that the user may choose by using the date picker. All date cells after the maxDate will be disabled. Combining the maxDate with mandate will create a date range. Users will not be able to naviagate to the dates outside of the range. maxDate must be passed in with the “yyyy-mm-dd” format. To set the min date to the current date pass in maxDate={“today”}

const DatePickerContainer = () =>{

  return(
      <div>
          < Datepicker
             maxDate={"2017-10-12"} 
            # ----- OR -------
            maxDate={"today"}
          />
      </div>
  )
}

specifiedFocusDate You can specifiy which date that the datepicker will open to by passing in specifiedFocusDate={"yyyy-mm-dd"}

const DatePickerContainer = () =>{

  return(
      <div>
          < Datepicker
             specifiedFocusDate={"2019-10-15"}
          />
      </div>
  )
}

buttonInlineStyle Customized styling can be passed to the calendar button as a style object. Object keys follow JSX conventions. Alternatively, class names from your own stylesheet can be passed to the calendar button with the buttonClassNames prop.

const buttonInlineStyle = {"color": "orange", "marginLeft": "30px"} 

const DatePickerContainer = () =>{

    return(
        <div>
            < Datepicker
               buttonInlineStyle={buttonInlineStyle} 
            />
        </div>
    )
}

buttonClassNames One of more classes can be passed to the calendar button through the buttonClassNames prop as a string. Seperate the classes by a space Be sure to pass in names without a prepending period.

const DatePickerContainer = () =>{

  return(
      <div>
          < Datepicker
            buttonClassNames={"cssClass1 cssClass2 cssClass3"}
          />
      </div>
  )
}

customInputBox Save a custom input box as a variable and pass it in as a prob. Note, you will have ot provide your own ARIA labels.

const DatePickerContainer = () =>{

const customInputBox = <input id="Custom-Box" placeholder="this is a custom inputBox" style={{'backgroundColor': 'red'}}></input>

  return(
      <div>
          < Datepicker
              customInputBox={customInputBox}
          />
      </div>
  )
}

inputBoxLabel Pass in a string for a custom input box label, or pass in false to remove the default label.

const DatePickerContainer = () =>{

const customInputBox = <input id="Custom-Box" placeholder="this is a custom inputBox" style={{'backgroundColor': 'red'}}></input>

  return(
      <div>
          < Datepicker
            inputBoxLabel={"This is a custom label"}
            # OR
            inputBoxLabel={false}
          />
      </div>
  )
}

inputBoxClassNames One of more classes can be passed as strings to the input box through the inputBoxClassNames prop. Be sure to pass in names without a prepending period.

const DatePickerContainer = () =>{

   return(
       <div>
           < Datepicker
             inputBoxClassNames={"cssClass1 cssClass2 cssClass3"}
           />
       </div>
   )
}

Error Handling The datepicker comes with default internal error handling, but it is possible to passs in custom error messages through props. all of the following must be passed in as strings

invalidFormatError - This message will be displated when a user enters the date in an invaliud format

invalidMonthErrorMessage - This message will be displayed when a user enters a mm(month) value greater than 12

invalidDateErrorMessage - This message will be displayed when a user enters a dd(day) value greater than 31

pastMaxDateErrorMessage - This message will be displayted when there is a Maximum date prop passed into the datepicker and the user enters a date past that

minDateErrorMessage - This message will be displayted when there is a minimum date prop passed into the datepicker and the user enters a date before that

const DatePickerContainer = () =>{

   return(
       <div>
           < Datepicker
             invalidDateErrorMessage={" Month invalid, please check the month"}
           />
       </div>
   )
}

If you would prefer to handle error on your application level rather than internally through the datepicker, and alternative can be to pass in the errorHandlingCallback. and wrapping the datepicker in its own component with its own state. Set a field on the state called errorType. Write a function that will invoke this.setState and pass it into the errorHandlingCallback. An example can be seen below. Passing in errorHandlingCallback will disable the internally generated error messages.

For Class Based Components :

import React,{useState, Fragment, Component} from 'react';
import Datepicker from 'react-ada-keyboard-accessible-datepicker';
import './testStyle.css'

class ClassBasedCalContainer extends Component {
   constructor(props){
       super(props);
       this.state = {
           errorType: null
       }
       this.setStateCallBack = this.setStateCallBack.bind(this);
   }

   setStateCallBack(messageType){
       this.setState({errorType: messageType})
   }

render(){
   return(
       <div>
           <h1>CLASS BASED COMPONENT CONTAINER</h1>
           <h2>{`The State message is ${this.state.errorType}`}</h2>
           <Datepicker 
           
           errorHandlingCallback ={this.setStateCallBack}
           minDate={"today"} //eventually make this so it follows format
           maxDate={"2019-12-25"}

           />

       </div>
   )
}

}
}

For Functional Components:

const CalendarContainer = () =>{

    const [errorType, setErrorType] = useState(null)
   return(
       <div>
           <h1 >CALANDER CONTAINER APP</h1>
           <h2>{`The errorType is ${errorType}`}</h2>
     
           <Datepicker 
               specifiedFocusDate={"2019-10-15"}
               dateFormat ={"mm dd, yyyy"}
               minDate={"today"} 
               maxDate={"2019-12-25"}
               errorHandlingCallback ={setErrorType}
                           />
       </div>
   )
}

You can use the errorType const to write the logic for determining your errorType messages and errorHandling behavior.

inputBoxOnChange Callback that will be executed on input box change (under development)

inputBoxOnBlur Callback that will be executed on input box blur (under development)

autoFormat Auto formatting of user input can be turned off by passing in autoFormatting={false}. (under development)

History

v1.2.13

  • Improvements to error handling logic
  • Selecting date from calander now triggers an input event in the inputbox

v1.2.12

  • Improvements to autopcomplete functionality
  • Formatting error message only appears entire datepicker's blur
  • Errors in console for incorrect datadate format when passing in min and max date props

v1.2.9

  • Improved documentation readibility.

v1.2.3

  • Removed default "Cursor keys can navigate dates" message"
  • Calander height now changes to fit dates

v1.2.2

  • Added leading zeros into dateBoxInput string in roder to facilitate error handling and follow project formatting

v1.2.1

  • Fixes bug that causes DOM propagation on go to next year and go to previous year buttons.

v1.2.0

  • input box now calculates latest day of each month and throws error if entered date is beyond that
  • simplified autoformating that allows for easier revisions to input date
  • updated documentation with screenshots and keyboard controls

v1.1.4

  • custom iput boxs without ids are automatically assigned id of "id-textbox-1"
  • error messages nor use the htmlFor attribute and point ot inputBox
  • inputBox ariaDescribedby pointsx to the error message
  • updates to documentation
1.2.13

4 years ago

1.2.12

4 years ago

1.2.10

4 years ago

1.2.11

4 years ago

1.2.9

4 years ago

1.2.8

4 years ago

1.2.7

4 years ago

1.2.6

4 years ago

1.2.5

4 years ago

1.2.4

4 years ago

1.2.3

4 years ago

1.2.2

4 years ago

1.2.1

4 years ago

1.1.6

4 years ago

1.2.0

4 years ago

1.1.5

4 years ago

1.1.4

4 years ago

1.1.2

4 years ago

1.1.1

4 years ago

1.1.0

4 years ago

1.0.1

4 years ago

1.0.0

4 years ago