Skip to content

Commit

Permalink
Fix keyboard interaction with canvas' DateIinput
Browse files Browse the repository at this point in the history
closes LS-2933
flag=none

test plan:
  - on a course setings page
  - set Participation to Course
  - tab into Start date input
  - press down arrow
  > expect the calendar to pop open
  - press more down and up arrows
  > expect the highlighted date to move accordingly
  - hit Enter
  > expect the calendar to close and the value to be set
  - hit Enter again (w/o navigation away)
  > expect the form to get submitted
  > expect the date to be what was set when the page reloads

  - go to the course pace plans page
  - click on Show Projections
  - tab to the start date input
  - start typing
  > expect the calendar to pop open
  > expect arrow keys to navigate around in the month
  - type Enter
  > expect the calendar to close and show the selected date
  - tab away
  > expect the date value to remain

Change-Id: I3b1359027af998be2f9cb986b8f680a8f93b936b
Reviewed-on: https://gerrit.instructure.com/c/canvas-lms/+/282802
Tested-by: Service Cloud Jenkins <[email protected]>
Reviewed-by: Robin Kuss <[email protected]>
QA-Review: Robin Kuss <[email protected]>
Product-Review: Ed Schiebel <[email protected]>
  • Loading branch information
eschiebel committed Jan 14, 2022
1 parent cc6d569 commit 2f2d4e3
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ import moment from 'moment'
import {render, fireEvent} from '@testing-library/react'
import CourseAvailabilityOptions from '../CourseAvailabilityOptions'

function pressKey(inputElem, keyOpts) {
fireEvent.keyDown(inputElem, keyOpts)
fireEvent.keyUp(inputElem, keyOpts)
}

function createFormField(wrapper, id, value) {
const field = document.createElement('input')
field.setAttribute('type', 'hidden')
Expand Down Expand Up @@ -238,7 +243,7 @@ describe('CourseAvailabilityOptions', () => {
const startDate = getByLabelText('Start')
const year = moment().year()
fireEvent.change(startDate, {target: {value: `Jan 1, ${year} 12:00am`}})
fireEvent.keyDown(startDate, {key: 'Enter'})
pressKey(startDate, {key: 'Enter'})
expect(document.getElementById('course_start_at').value).toBe(`${year}-01-01T00:00:00.000Z`)
})

Expand All @@ -249,7 +254,7 @@ describe('CourseAvailabilityOptions', () => {
const endDate = getByLabelText('End')
const year = moment().year()
fireEvent.change(endDate, {target: {value: `Feb 1, ${year} 12:00am`}})
fireEvent.keyDown(endDate, {key: 'Enter'})
pressKey(endDate, {key: 'Enter'})
expect(document.getElementById('course_conclude_at').value).toBe(`${year}-02-01T00:00:00.000Z`)
})

Expand Down
8 changes: 2 additions & 6 deletions ui/shared/datetime/react/components/DateInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -285,13 +285,9 @@ export default function CanvasDateInput({
}
}

function handleKeyDown(e: KeyboardEvent) {
function handleKey(e: KeyboardEvent) {
if (e.key === 'Enter') {
handleBlur()
} else if (e.key === 'ArrowDown' || e.keyCode === 40) {
modifySelectedMoment(1, 'day')
} else if (e.key === 'ArrowUp' || e.keyCode === 38) {
modifySelectedMoment(-1, 'day')
}
}

Expand Down Expand Up @@ -376,7 +372,7 @@ export default function CanvasDateInput({
value={inputValue}
onChange={handleChange}
onPaste={trackPasteEvent}
onKeyDown={handleKeyDown}
onKeyUp={handleKey}
isInline
placement={placement}
messages={messages.concat(internalMessages)}
Expand Down
15 changes: 10 additions & 5 deletions ui/shared/datetime/react/components/__tests__/DateInput.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,11 @@ function renderAndDirtyInput(inputValue, overrides = {}) {
return result
}

function pressKey(inputElem, keyOpts) {
fireEvent.keyDown(inputElem, keyOpts)
fireEvent.keyUp(inputElem, keyOpts)
}

const oldLocale = moment.locale()

beforeEach(() => {
Expand Down Expand Up @@ -118,28 +123,28 @@ describe('choosing a day on the calendar', () => {
it('selects the first of the month on ArrowDown if selectedDate is null', () => {
const {props, getInput} = renderInput()
fireEvent.click(getInput())
fireEvent.keyDown(getInput(), {key: 'ArrowDown', code: 40, keyCode: 40})
pressKey(getInput(), {key: 'ArrowDown', code: 40, keyCode: 40})
expect(props.onSelectedDateChange).toHaveBeenCalledWith(new Date('2020-05-01'))
})

it('selects the first of the month on up-arrow if selectedDate is null', () => {
const {props, getInput} = renderInput()
fireEvent.click(getInput())
fireEvent.keyDown(getInput(), {key: 'ArrowUp', code: 38, keyCode: 38})
pressKey(getInput(), {key: 'ArrowUp', code: 38, keyCode: 38})
expect(props.onSelectedDateChange).toHaveBeenCalledWith(new Date('2020-05-01'))
})

it('selects the next date on down-arrow', () => {
const {props, getInput} = renderInput({selectedDate: new Date()})
fireEvent.click(getInput())
fireEvent.keyDown(getInput(), {key: 'ArrowDown', code: 40, keyCode: 40})
pressKey(getInput(), {key: 'ArrowDown', code: 40, keyCode: 40})
expect(props.onSelectedDateChange).toHaveBeenCalledWith(new Date('2020-05-20'))
})

it('selects the previous date on up-arrow', () => {
const {props, getInput} = renderInput({selectedDate: new Date()})
fireEvent.click(getInput())
fireEvent.keyDown(getInput(), {key: 'ArrowUp', code: 38, keyCode: 38})
pressKey(getInput(), {key: 'ArrowUp', code: 38, keyCode: 38})
expect(props.onSelectedDateChange).toHaveBeenCalledWith(new Date('2020-05-18'))
})
})
Expand Down Expand Up @@ -173,7 +178,7 @@ describe('dirty input state', () => {
it('calls onSelectedDateChange with parsed date when Enter is pressed on the input', () => {
const {props, getInput} = renderAndDirtyInput('May 20')
const newDate = new Date('2020-05-20')
fireEvent.keyDown(getInput(), {key: 'Enter'})
pressKey(getInput(), {key: 'Enter'})
expect(props.onSelectedDateChange).toHaveBeenCalledWith(newDate)
})

Expand Down

0 comments on commit 2f2d4e3

Please sign in to comment.