From d229ec212c3b1c6f01139cbbdf4a4403cee919c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20H=C3=B8egh?= Date: Wed, 8 Nov 2023 13:17:05 +0100 Subject: [PATCH] fix(Autocomplete): ensure correct value selection during data change (#2863) --- .../components/autocomplete/Autocomplete.js | 16 ++++- .../__tests__/Autocomplete.test.tsx | 65 +++++++++++++++++++ .../drawer-list/DrawerListHelpers.js | 5 +- 3 files changed, 83 insertions(+), 3 deletions(-) diff --git a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js index a55aed1e3a3..863b2be89e7 100644 --- a/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js +++ b/packages/dnb-eufemia/src/components/autocomplete/Autocomplete.js @@ -747,6 +747,12 @@ class AutocompleteInstance extends React.PureComponent { }) } + resetValue = () => { + this.context.drawerList.setState({ + _value: 're-evaluate', // ensure "state.selected_item = getCurrentIndex(...)" inside "prepareDerivedState" does run + }) + } + updateData = (rawData) => { // invalidate the local cache now, // because we get else the same after we show the new result @@ -763,7 +769,11 @@ class AutocompleteInstance extends React.PureComponent { if (parseFloat(itemIndex) > -1) { const newItem = rawData[itemIndex] const oldItem = this.context.drawerList.original_data[itemIndex] - if (newItem?.selected_key !== oldItem?.selected_key) { + if ( + typeof newItem?.selectedKey !== 'undefined' + ? newItem?.selectedKey !== oldItem?.selectedKey + : newItem?.selected_key !== oldItem?.selected_key + ) { this.resetSelectionItem() } } @@ -778,7 +788,7 @@ class AutocompleteInstance extends React.PureComponent { () => { const { typedInputValue } = this.state - if (typedInputValue && typedInputValue.length > 0) { + if (typedInputValue?.length > 0) { // run with side effects, to get preselection of active_item const filteredData = this.runFilterWithSideEffects(typedInputValue) @@ -786,6 +796,7 @@ class AutocompleteInstance extends React.PureComponent { this.showNoOptionsItem() } } else { + this.resetValue() this.resetActiveItem() if (this.context.drawerList.opened) { this.showAllItems() @@ -1008,6 +1019,7 @@ class AutocompleteInstance extends React.PureComponent { attributes, dataList: this.context.drawerList.data, updateData: this.updateData, + resetValue: this.resetValue, showAllItems: this.showAllItems, setVisible: this.setVisible, setHidden: this.setHidden, diff --git a/packages/dnb-eufemia/src/components/autocomplete/__tests__/Autocomplete.test.tsx b/packages/dnb-eufemia/src/components/autocomplete/__tests__/Autocomplete.test.tsx index 7fbec6d2793..6605f607cbc 100644 --- a/packages/dnb-eufemia/src/components/autocomplete/__tests__/Autocomplete.test.tsx +++ b/packages/dnb-eufemia/src/components/autocomplete/__tests__/Autocomplete.test.tsx @@ -2315,6 +2315,71 @@ describe('Autocomplete component', () => { 'dnb-autocomplete--default', ]) }) + + it('should set correct value in input', () => { + const data = [ + { + selectedKey: '+93', + selected_value: 'AF (+93)', + content: '+93 Afghanistan', + }, + { + selectedKey: '+47', + selected_value: 'NO (+47)', + content: '+47 Norge', + }, + { + selectedKey: '+46', + selected_value: 'SE (+46)', + content: '+46 Sverige', + }, + { + selectedKey: '+41', + selected_value: 'CH (+41)', + content: '+41 Sveits', + }, + ] + const MockComponent = () => { + const [value, setValue] = React.useState('+47') + + return ( + setValue(data.selectedKey)} + on_focus={({ updateData }) => updateData(data)} + search_numbers + no_animation + /> + ) + } + + render() + + const inputElement: HTMLInputElement = document.querySelector('input') + + expect(inputElement.value).toEqual('NO (+47)') + + // open + fireEvent.keyDown(inputElement, { + key: 'Enter', + keyCode: 13, + }) + + expect( + document.querySelectorAll('li.dnb-drawer-list__option')[0] + .textContent + ).toBe('+47 Norge') + + fireEvent.focus(inputElement) + fireEvent.change(inputElement, { target: { value: '+41' } }) + fireEvent.click( + document.querySelectorAll('li.dnb-drawer-list__option')[0] + ) + + expect(inputElement.value).toEqual('CH (+41)') + }) }) describe('Autocomplete markup', () => { diff --git a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js index 8362d620f3e..fabebce1941 100644 --- a/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js +++ b/packages/dnb-eufemia/src/fragments/drawer-list/DrawerListHelpers.js @@ -475,7 +475,10 @@ export const prepareDerivedState = (props, state) => { if (props.value === 'initval') { state.selected_item = null } else { - state.selected_item = getCurrentIndex(props.value, state.data) + state.selected_item = getCurrentIndex( + props.value, + state.original_data + ) } if (typeof props.on_state_update === 'function') {