Skip to content

Commit

Permalink
fix(DatePicker): make focus handling on input work on second click (#…
Browse files Browse the repository at this point in the history
…2039)

* chore: refactor tests to TS

* fix(DatePicker): make focus handling on input work on second click
  • Loading branch information
tujoworker authored and joakbjerk committed Mar 27, 2023
1 parent 3f228a7 commit 0095003
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 34 deletions.
25 changes: 14 additions & 11 deletions packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,20 +301,20 @@ export default class DatePickerInput extends React.PureComponent {

await wait(1) // to get the correct position afterwards

const endPos = target.value.length
target.focus()
target.setSelectionRange(0, endPos)
selectAll(target)
} catch (e) {
warn(e)
}
}

selectStart = (target) => {
target.focus()
target.setSelectionRange(0, 0)
}

onFocusHandler = (event) => {
try {
const target = event.target
const endPos = target.value.length
target.focus()
target.setSelectionRange(0, endPos)
selectAll(event.target)
} catch (e) {
warn(e)
}
Expand All @@ -337,6 +337,10 @@ export default class DatePickerInput extends React.PureComponent {
const keyCode = keycode(event)
const target = event.target

if (target.selectionStart !== target.selectionEnd) {
this.selectStart(target)
}

// only to process key up and down press
switch (keyCode) {
case 'up':
Expand Down Expand Up @@ -522,7 +526,6 @@ export default class DatePickerInput extends React.PureComponent {
params = {
...params,
onKeyDown: this.onKeyDownHandler,
onMouseUp: selectInput,
onPaste: this.shortcutHandler,
onFocus: (e) => {
this.focusMode = mode
Expand Down Expand Up @@ -754,9 +757,9 @@ export default class DatePickerInput extends React.PureComponent {
}
}

const selectInput = (e) => {
e.target.focus()
e.target.select()
const selectAll = (target) => {
target.focus()
target.select()
}

const InputElement = (props) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ import {
getCalendar,
makeDayObject,
} from '../DatePickerCalc'
import { fireEvent, render } from '@testing-library/react'

beforeEach(() => {
document.body.innerHTML = ''
})

describe('DatePicker component', () => {
// for the integration tests
Expand All @@ -46,14 +51,14 @@ describe('DatePicker component', () => {
separatorRexExp: null,
}

const Comp = mount(<Component {...defaultProps} />)

// compare the snapshot
it('have to match snapshot', () => {
const Comp = mount(<Component {...defaultProps} />)
expect(toJson(Comp)).toMatchSnapshot()
})

it('has correct state at startup', () => {
const Comp = mount(<Component {...defaultProps} />)
expect(Comp.state().opened).toBe(false)
expect(Comp.state().hidden).toBe(true)
})
Expand All @@ -69,6 +74,7 @@ describe('DatePicker component', () => {
})

it('has correct state after "click" trigger', () => {
const Comp = mount(<Component {...defaultProps} />)
Comp.find('button.dnb-input__submit-button__button').simulate('click')
expect(Comp.state().opened).toBe(true)
expect(Comp.state().hidden).toBe(false)
Expand Down Expand Up @@ -179,8 +185,8 @@ describe('DatePicker component', () => {
).toContain('dnb-date-picker--opened')

expect(on_days_render).toHaveBeenCalledTimes(1)
expect(on_days_render.mock.calls[0][0].length).toBe(42)
expect(on_days_render.mock.calls[0][1]).toBe(0)
expect(on_days_render.mock.calls[0].at(0).length).toBe(42)
expect(on_days_render.mock.calls[0].at(1)).toBe(0)

const singleTd = Comp.find('td.dnb-date-picker__day').at(12)
const singleButton = singleTd.find('button')
Expand Down Expand Up @@ -228,12 +234,14 @@ describe('DatePicker component', () => {
})

it('has two calendar views', () => {
const Comp = mount(<Component {...defaultProps} />)
Comp.find('button.dnb-input__submit-button__button').simulate('click')
expect(Comp.find('.dnb-date-picker__views').exists()).toBe(true)
expect(Comp.find('.dnb-date-picker__calendar').length).toBe(2)
})

it('has a reacting start date input with valid value', () => {
const Comp = mount(<Component {...defaultProps} />)
const elem = Comp.find('input.dnb-date-picker__input--day').at(0)

// by default we have the start day
Expand Down Expand Up @@ -1003,7 +1011,7 @@ describe('DatePicker component', () => {
)
})

it('has to have a aria-describedby on first focus', async () => {
it('has to have a aria-describedby on first focus', () => {
const label = 'Input Label'
const Comp = mount(
<Component
Expand All @@ -1022,6 +1030,99 @@ describe('DatePicker component', () => {
expect(legendElem.instance().classList).toContain('dnb-sr-only')
})

it('has to select all only on first focus', () => {
render(
<Component
id="custom-id"
label="Input Label"
range
start_date={defaultProps.start_date}
/>
)

const inputElement = document.querySelector(
'input.dnb-input__input'
) as HTMLInputElement

fireEvent.focus(inputElement)

expect(inputElement.selectionStart).toBe(0)
expect(inputElement.selectionEnd).toBe(2)

fireEvent.keyDown(inputElement, {
key: 'A',
})

expect(inputElement.selectionStart).toBe(0)
expect(inputElement.selectionEnd).toBe(0)

fireEvent.mouseUp(inputElement)

expect(inputElement.selectionStart).toBe(0)
expect(inputElement.selectionEnd).toBe(0)

fireEvent.focus(inputElement)

expect(inputElement.selectionStart).toBe(0)
expect(inputElement.selectionEnd).toBe(2)
})

it('has to focus on date picker on opening', () => {
render(
<Component
id="custom-id"
label="Input Label"
show_input
range
start_date={defaultProps.start_date}
end_date={defaultProps.end_date}
/>
)

const element = document.querySelector('.dnb-date-picker')
const buttonElement = document.querySelector(
'button.dnb-input__submit-button__button'
)

expect(document.activeElement).toBe(document.body)

fireEvent.click(buttonElement)

expect(
element.classList.contains('dnb-date-picker--opened')
).toBeTruthy()

const tableElement = document.querySelector('table')

expect(document.activeElement).toBe(tableElement)
})

it('should not set focus when disable_autofocus is set', () => {
render(
<Component
id="custom-id"
label="Input Label"
show_input
disable_autofocus
start_date={defaultProps.start_date}
/>
)

const element = document.querySelector('.dnb-date-picker')
const buttonElement = document.querySelector(
'button.dnb-input__submit-button__button'
)

expect(document.activeElement).toBe(document.body)

fireEvent.click(buttonElement)

expect(document.activeElement).toBe(document.body)
expect(
element.classList.contains('dnb-date-picker--opened')
).toBeTruthy()
})

it('has to react on keydown events', async () => {
const Comp = mount(
<Component
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -574,7 +574,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="d"
size="2"
Expand Down Expand Up @@ -624,7 +623,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="d"
Expand All @@ -650,7 +648,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="2"
spellCheck={false}
Expand Down Expand Up @@ -711,7 +708,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="m"
size="2"
Expand Down Expand Up @@ -761,7 +757,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="m"
Expand All @@ -787,7 +782,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="2"
spellCheck={false}
Expand Down Expand Up @@ -850,7 +844,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="å"
size="4"
Expand Down Expand Up @@ -902,7 +895,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="å"
Expand All @@ -928,7 +920,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="4"
spellCheck={false}
Expand Down Expand Up @@ -988,7 +979,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="d"
size="2"
Expand Down Expand Up @@ -1038,7 +1028,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="d"
Expand All @@ -1064,7 +1053,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="2"
spellCheck={false}
Expand Down Expand Up @@ -1125,7 +1113,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="m"
size="2"
Expand Down Expand Up @@ -1175,7 +1162,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="m"
Expand All @@ -1201,7 +1187,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="2"
spellCheck={false}
Expand Down Expand Up @@ -1264,7 +1249,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
placeholderChar="å"
size="4"
Expand Down Expand Up @@ -1316,7 +1300,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
pipe={null}
placeholderChar="å"
Expand All @@ -1342,7 +1325,6 @@ exports[`DatePicker component have to match snapshot 1`] = `
onChange={[Function]}
onFocus={[Function]}
onKeyDown={[Function]}
onMouseUp={[Function]}
onPaste={[Function]}
size="4"
spellCheck={false}
Expand Down

0 comments on commit 0095003

Please sign in to comment.