From 2062213180f578e81f9b7fba1e06a3b437d6a9f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B8egh?= Date: Mon, 8 Jan 2024 14:25:51 +0100 Subject: [PATCH] feat(DatePicker): add onFocus event (#3188) --- .../uilib/components/date-picker/events.mdx | 1 + .../components/date-picker/DatePicker.d.ts | 4 +++ .../src/components/date-picker/DatePicker.js | 1 - .../components/date-picker/DatePickerInput.js | 7 ++++ .../date-picker/__tests__/DatePicker.test.tsx | 35 +++++++++++++++++++ 5 files changed, 47 insertions(+), 1 deletion(-) diff --git a/packages/dnb-design-system-portal/src/docs/uilib/components/date-picker/events.mdx b/packages/dnb-design-system-portal/src/docs/uilib/components/date-picker/events.mdx index 7d53fbeaa59..c920f51e946 100644 --- a/packages/dnb-design-system-portal/src/docs/uilib/components/date-picker/events.mdx +++ b/packages/dnb-design-system-portal/src/docs/uilib/components/date-picker/events.mdx @@ -16,6 +16,7 @@ import { DatePickerDateFnsRangeIsWeekend } from 'Docs/uilib/components/date-pick | `on_show` | _(optional)_ will be called once date-picker is visible. | | `on_hide` | _(optional)_ will be called once date-picker is hidden. | | `on_days_render` | _(optional)_ will be called right before every new calendar view gets rendered. See the example above. | +| `onFocus` | _(optional)_ will be called once the input gets focus. | | `onBlur` | _(optional)_ will be called once the input lose focus. | ## Returned Object diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts b/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts index 9189daae741..bc512b67437 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts +++ b/packages/dnb-eufemia/src/components/date-picker/DatePicker.d.ts @@ -252,6 +252,10 @@ export interface DatePickerProps * Will be called once a user presses the reset button. */ on_reset?: (...args: any[]) => any; + /** + * Will be called once the input gets focus. + */ + onFocus?: (event: React.FocusEventHandler) => void; /** * Will be called once the input loses focus. */ diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js index 1aefe20b9e3..f40d6e65fd0 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePicker.js +++ b/packages/dnb-eufemia/src/components/date-picker/DatePicker.js @@ -673,7 +673,6 @@ export default class DatePicker extends React.PureComponent { locale={locale} {...attributes} submitAttributes={submitParams} - onFocus={this.showPicker} onSubmit={this.togglePicker} {...status_props} /> diff --git a/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js b/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js index e733012f689..0f4e72ce0ca 100644 --- a/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js +++ b/packages/dnb-eufemia/src/components/date-picker/DatePickerInput.js @@ -325,6 +325,13 @@ export default class DatePickerInput extends React.PureComponent { focusState: 'focus', _listenForPropChanges: false, }) + + if (this.props.onFocus) { + this.props.onFocus({ + ...event, + ...this.context.getReturnObject({ event }), + }) + } } onBlurHandler = (event) => { 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 bf5dc0d75cc..1bbef397b3e 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 @@ -1494,6 +1494,41 @@ describe('DatePicker component', () => { expect(thirdDateButton.children[2]).toHaveTextContent('24') }) + it('should fire fire event when input gets focus', async () => { + const onFocus = jest.fn() + render() + + const [firstInput, secondInput]: Array = Array.from( + document.querySelectorAll('.dnb-input__input') + ) + + await userEvent.click(firstInput) + + expect(onFocus).toHaveBeenCalledTimes(1) + expect(document.activeElement).toBe(firstInput) + + await userEvent.click(document.body) + + expect(document.activeElement).not.toBe(firstInput) + expect(onFocus).toHaveBeenCalledTimes(1) + expect(onFocus).toHaveBeenCalledWith( + expect.objectContaining({ target: firstInput, date: '2024-01-05' }) + ) + + await userEvent.click(secondInput) + + expect(onFocus).toHaveBeenCalledTimes(2) + expect(document.activeElement).toBe(secondInput) + + await userEvent.click(document.body) + + expect(document.activeElement).not.toBe(secondInput) + expect(onFocus).toHaveBeenCalledTimes(2) + expect(onFocus).toHaveBeenCalledWith( + expect.objectContaining({ target: secondInput, date: '2024-01-05' }) + ) + }) + it('should fire blur event when input loses focus', async () => { const onBlur = jest.fn() render()