From 189361f0c558124c3baa3526aec90dbe1c6b8884 Mon Sep 17 00:00:00 2001 From: Tobias Date: Wed, 17 Apr 2019 21:51:48 +0200 Subject: [PATCH] fix: fix better #dropdown key search support and example + add more tests due to the new key search feature --- .../uilib/components/dropdown/Examples.js | 10 ++--- .../src/components/dropdown/Dropdown.js | 37 +++++++++++++------ .../dropdown/__tests__/Dropdown.test.js | 30 +++++++++++++++ 3 files changed, 61 insertions(+), 16 deletions(-) diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/Examples.js b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/Examples.js index 501143eb341..6f5b3a2dce8 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/Examples.js +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/Examples.js @@ -30,25 +30,25 @@ class Example extends PureComponent { {` const scrollableData = [ { - selected_value: 'Find me by keypress', content: 'A' }, { content: 'B' }, { - selected_value: 'CC', + selected_value: '1134.56.78962', content: ['1134.56.78962', 'C'] }, { - selected_value: 'DD', + selected_value: '1534.96.48901', content: ['1534.96.48901', 'D'] }, { content: 'E' }, { - content: ['F', 'F', 'F', 'F', 'Find me by keypress'] + selected_value: 'Find me by keypress', + content: ['F', 'F', 'F', 'F'] }, { content: 'G' @@ -60,7 +60,7 @@ const scrollableData = [ render( ) diff --git a/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js b/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js index 5a6c34cec8d..9ff9973e29b 100644 --- a/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js +++ b/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js @@ -117,14 +117,21 @@ export default class Dropdown extends Component { } static parseOpened = state => /true|on/.test(String(state)) - static parseContentTitle = (dataItem, separator = '\n') => { + static parseContentTitle = ( + dataItem, + { separator = '\n', removeNumericOnlyValues = false } = {} + ) => { let ret = '' + const onlyNumericRegex = /[0-9.,-\s]+/ if (dataItem.content) { ret = Array.isArray(dataItem.content) ? dataItem.content .reduce((acc, cur) => { // remove only numbers - const found = cur && cur.match(/[0-9.,-\s]+/) + const found = + removeNumericOnlyValues && + cur && + cur.match(onlyNumericRegex) if (!(found && found[0].length === cur.length)) { acc.push(cur) } @@ -135,7 +142,10 @@ export default class Dropdown extends Component { } else if (typeof dataItem === 'string') { ret = dataItem } - if (dataItem.selected_value) { + if ( + dataItem.selected_value && + !onlyNumericRegex.test(dataItem.selected_value) + ) { ret = dataItem.selected_value + separator + ret } return ret @@ -259,7 +269,7 @@ export default class Dropdown extends Component { // this gives us the possibility to quickly search for an item // by simply pressing any alfabetic key findItemByValue(value) { - let index + let index = -1 try { // delete the cache @@ -273,8 +283,12 @@ export default class Dropdown extends Component { this.searchCache || this.state.data.reduce((acc, itemData, i) => { const str = String( - Dropdown.parseContentTitle(itemData, ' ') + Dropdown.parseContentTitle(itemData, { + removeNumericOnlyValues: true, + separator: ' ' + }) ).toLowerCase() + acc[str[0]] = acc[str[0]] || [] acc[str[0]].push({ i @@ -283,7 +297,7 @@ export default class Dropdown extends Component { }, {}) const found = this.searchCache[value] - index = (found && found[0] && found[0].i) || -1 + index = found && found[0] && found[0].i > -1 ? found[0].i : -1 // if ther eare several of the same type if (found && found.length > 1) { @@ -313,14 +327,15 @@ export default class Dropdown extends Component { `li.dnb-dropdown__option:nth-of-type(${active_item + 1})` ) const top = liElement.offsetTop - if (scrollTo) { - liElement.parentNode.scrollTop = top - liElement.parentNode.scrollTo({ + const { parentNode } = liElement + if (parentNode.scrollTo) { + parentNode.scrollTop = top + } + if (scrollTo && parentNode.scrollTo) { + parentNode.scrollTo({ top, behavior: 'smooth' }) - } else { - liElement.parentNode.scrollTop = top } } catch (e) { console.log('Dropdown could not scroll into element:', e) diff --git a/packages/dnb-ui-lib/src/components/dropdown/__tests__/Dropdown.test.js b/packages/dnb-ui-lib/src/components/dropdown/__tests__/Dropdown.test.js index 8e351487a03..38599ba3f14 100644 --- a/packages/dnb-ui-lib/src/components/dropdown/__tests__/Dropdown.test.js +++ b/packages/dnb-ui-lib/src/components/dropdown/__tests__/Dropdown.test.js @@ -69,6 +69,36 @@ describe('Dropdown component', () => { expect(Comp.state().hidden).toBe(false) }) + it('has correct selected_item on keydown "ArrowDown" and "Enter"', () => { + expect(Comp.state().selected_item).toBe(props.selected_item) + Comp.find('input').simulate('focus') + expect(Comp.state().active_item).toBe(props.selected_item) + Comp.find('input').simulate('keyDown', { + key: 'ArrowDown', + keyCode: 40 + }) + Comp.find('input').simulate('keyDown', { + key: 'Enter', + keyCode: 13 + }) + expect(Comp.state().active_item).toBe(props.selected_item + 1) + expect(Comp.state().selected_item).toBe(props.selected_item + 1) + }) + + it('has correct selected_item on key search', () => { + Comp.find('input').simulate('focus') + Comp.find('input').simulate('keyDown', { + key: 'B', + keyCode: 66 + }) + expect(Comp.state().active_item).toBe(0) + Comp.find('input').simulate('keyDown', { + key: 'F', + keyCode: 70 + }) + expect(Comp.state().active_item).toBe(2) + }) + it('has correct state after "blur" trigger', () => { Comp.find('input').simulate('blur') expect(Comp.state().opened).toBe(false)