From df5cac08a259c16566c218821e027a7bf704fff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B8egh?= Date: Thu, 23 Feb 2023 09:06:49 +0100 Subject: [PATCH] fix(DatePicker): make focus handling on input work on second click --- .../components/date-picker/DatePickerInput.js | 25 +++-- .../date-picker/__tests__/DatePicker.test.tsx | 100 +++++++++++++++++- .../__snapshots__/DatePicker.test.tsx.snap | 18 ---- 3 files changed, 113 insertions(+), 30 deletions(-) diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js b/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js index d2145aae02f..065f4432f88 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js +++ b/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js @@ -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) } @@ -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': @@ -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 @@ -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) => { diff --git a/packages/dnb-eufemia/src/components/date-picker/__tests__/DatePicker.test.tsx b/packages/dnb-eufemia/src/components/date-picker/__tests__/DatePicker.test.tsx index 7e847abf406..c9797ff010e 100644 --- a/packages/dnb-eufemia/src/components/date-picker/__tests__/DatePicker.test.tsx +++ b/packages/dnb-eufemia/src/components/date-picker/__tests__/DatePicker.test.tsx @@ -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 @@ -1006,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( { expect(legendElem.instance().classList).toContain('dnb-sr-only') }) + it('has to select all only on first focus', () => { + render( + + ) + + 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( + + ) + + 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( + + ) + + 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(