From 868ec214cebc8fdeac1deb437676a08e8957e3d7 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 20 May 2021 11:51:39 +0200 Subject: [PATCH 1/4] MultiSelect: enable adding multiple emails with , or space --- app/javascript/components/ComboMultipleDropdownList.jsx | 8 +++++++- package.json | 1 + yarn.lock | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/javascript/components/ComboMultipleDropdownList.jsx b/app/javascript/components/ComboMultipleDropdownList.jsx index 1e25987ec..c88763070 100644 --- a/app/javascript/components/ComboMultipleDropdownList.jsx +++ b/app/javascript/components/ComboMultipleDropdownList.jsx @@ -19,6 +19,7 @@ import '@reach/combobox/styles.css'; import { matchSorter } from 'match-sorter'; import { fire } from '@utils'; import { XIcon } from '@heroicons/react/outline'; +import isHotkey from 'is-hotkey'; const Context = createContext(); @@ -83,7 +84,12 @@ function ComboMultipleDropdownList({ }; const onKeyDown = (event) => { - if (event.key === 'Enter') { + if ( + isHotkey('enter', event) || + isHotkey(' ', event) || + isHotkey(',', event) || + isHotkey(';', event) + ) { if ( term && [...extraOptions, ...options].map(([label]) => label).includes(term) diff --git a/package.json b/package.json index 102d3b750..c9aa65e27 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "email-butler": "^1.0.13", "highcharts": "^8.1.1", "intersection-observer": "^0.12.0", + "is-hotkey": "^0.2.0", "mapbox-gl": "^1.3.0", "match-sorter": "^6.2.0", "prop-types": "^15.7.2", diff --git a/yarn.lock b/yarn.lock index 6b8bf6958..9259fad90 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6982,6 +6982,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-hotkey@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/is-hotkey/-/is-hotkey-0.2.0.tgz#1835a68171a91e5c9460869d96336947c8340cef" + integrity sha512-UknnZK4RakDmTgz4PI1wIph5yxSs/mvChWs9ifnlXsKuXgWmOkY/hAE0H/k2MIqH0RlRye0i1oC07MCRSD28Mw== + is-installed-globally@^0.3.1: version "0.3.2" resolved "https://registry.yarnpkg.com/is-installed-globally/-/is-installed-globally-0.3.2.tgz#fd3efa79ee670d1187233182d5b0a1dd00313141" From e0d8d096f2f8aa1c1eaee99729d4953778b5acac Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 20 May 2021 13:05:36 +0200 Subject: [PATCH 2/4] MultiSelect: improuve setters --- .../components/ComboMultipleDropdownList.jsx | 29 ++++++++++++------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/app/javascript/components/ComboMultipleDropdownList.jsx b/app/javascript/components/ComboMultipleDropdownList.jsx index c88763070..213e9fe07 100644 --- a/app/javascript/components/ComboMultipleDropdownList.jsx +++ b/app/javascript/components/ComboMultipleDropdownList.jsx @@ -100,12 +100,15 @@ function ComboMultipleDropdownList({ } }; - const saveSelection = (selections) => { - setSelections(selections); - if (hiddenField) { - hiddenField.setAttribute('value', JSON.stringify(selections)); - fire(hiddenField, 'autosave:trigger'); - } + const saveSelection = (fn) => { + setSelections((selections) => { + selections = fn(selections); + if (hiddenField) { + hiddenField.setAttribute('value', JSON.stringify(selections)); + fire(hiddenField, 'autosave:trigger'); + } + return selections; + }); }; const onSelect = (value) => { @@ -113,15 +116,15 @@ function ComboMultipleDropdownList({ ([val]) => val == value ); const selectedValue = maybeValue && maybeValue[1]; - if (value) { + if (selectedValue) { if ( acceptNewValues && extraOptions[0] && extraOptions[0][0] == selectedValue ) { - setNewValues([...newValues, selectedValue]); + setNewValues((newValues) => [...newValues, selectedValue]); } - saveSelection([...selections, selectedValue]); + saveSelection((selections) => [...selections, selectedValue]); } setTerm(''); }; @@ -129,8 +132,12 @@ function ComboMultipleDropdownList({ const onRemove = (label) => { const optionValue = optionValueByLabel(label); if (optionValue) { - saveSelection(selections.filter((value) => value != optionValue)); - setNewValues(newValues.filter((value) => value != optionValue)); + saveSelection((selections) => + selections.filter((value) => value != optionValue) + ); + setNewValues((newValues) => + newValues.filter((value) => value != optionValue) + ); } inputRef.current.focus(); }; From 3313ea5885d418629103e44b1b9667c4fbeea711 Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 20 May 2021 13:11:49 +0200 Subject: [PATCH 3/4] MultiSelect: do not show empty results on free form inputs --- app/javascript/components/ComboMultipleDropdownList.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/components/ComboMultipleDropdownList.jsx b/app/javascript/components/ComboMultipleDropdownList.jsx index 213e9fe07..0e6d146ec 100644 --- a/app/javascript/components/ComboMultipleDropdownList.jsx +++ b/app/javascript/components/ComboMultipleDropdownList.jsx @@ -165,7 +165,7 @@ function ComboMultipleDropdownList({ autocomplete={false} /> - {results && ( + {results && (results.length > 0 || !acceptNewValues) && ( {results.length === 0 && (

From bf462380e6aca2c8d83f9db54883a574ac35641a Mon Sep 17 00:00:00 2001 From: Paul Chavard Date: Thu, 20 May 2021 13:15:27 +0200 Subject: [PATCH 4/4] MultiSelect: select values on blur --- .../components/ComboMultipleDropdownList.jsx | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/javascript/components/ComboMultipleDropdownList.jsx b/app/javascript/components/ComboMultipleDropdownList.jsx index 0e6d146ec..1d6ebf01b 100644 --- a/app/javascript/components/ComboMultipleDropdownList.jsx +++ b/app/javascript/components/ComboMultipleDropdownList.jsx @@ -100,6 +100,17 @@ function ComboMultipleDropdownList({ } }; + const onBlur = (event) => { + if ( + acceptNewValues && + term && + [...extraOptions, ...options].map(([label]) => label).includes(term) + ) { + event.preventDefault(); + return onSelect(term); + } + }; + const saveSelection = (fn) => { setSelections((selections) => { selections = fn(selections); @@ -162,6 +173,7 @@ function ComboMultipleDropdownList({ value={term} onChange={handleChange} onKeyDown={onKeyDown} + onBlur={onBlur} autocomplete={false} />