From 6ebce4415c8518c17a2b35f71e984796bd4662f2 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Fri, 2 Apr 2021 02:44:28 -0700 Subject: [PATCH 01/13] DDW-603 - Enable pasting of wallet recovery phrase - updates for single word pasting --- source/components/Autocomplete.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 07bd3be7..29e70136 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -175,10 +175,10 @@ class AutocompleteBase extends Component { this._setInputValue(value); if (hasMultipleValues) { this.open(); - setTimeout(() => { - this.updateSelectedOptions(event, multipleValues); - }, 0); } + setTimeout(() => { + this.updateSelectedOptions(event, multipleValues); + }, 0); }; // passed to Options onChange handler in AutocompleteSkin From 8611a8d08719e97a08ff5cc3b2a3b3eb4d97c9d1 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Fri, 2 Apr 2021 06:47:00 -0700 Subject: [PATCH 02/13] DDW-603 - Enable pasting of wallet recovery phrase - updates for single word focus --- source/components/Autocomplete.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 29e70136..196edfe2 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -231,6 +231,7 @@ class AutocompleteBase extends Component { !selectedOptions.includes(option); if (option && optionCanBeSelected && isOpen) { newSelectedOptions.push(option); + skipValueSelection = true; } } this.selectionChanged(newSelectedOptions, event); @@ -375,7 +376,7 @@ class AutocompleteBase extends Component { selectedOptions = [...selectedOptions, ...this._filterOptions(filteredValue)]; }); this.setState({ - isOpen: true, + isOpen: !!multipleValues.length, inputValue: '', filteredOptions: Array.from(new Set(selectedOptions)), }); @@ -383,7 +384,7 @@ class AutocompleteBase extends Component { const filteredValue = this._filterInvalidChars(value); const filteredOptions = this._filterOptions(filteredValue); this.setState({ - isOpen: !!value, + isOpen: value === '' ? false : !!value, inputValue: filteredValue, filteredOptions, }); From f866f8da67611062edc0ca60a6dbd4e915ae3aae Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 14 Apr 2021 02:38:22 -0700 Subject: [PATCH 03/13] DDW-603 - Enable pasting of wallet recovery phrase - updates for multiple word selection --- source/components/Autocomplete.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 717a7505..581103c8 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -230,7 +230,7 @@ class AutocompleteBase extends Component { !selectedOptions.includes(option); if (option && optionCanBeSelected && isOpen) { newSelectedOptions.push(option); - skipValueSelection = true; + skipValueSelection = false; } } this.selectionChanged(newSelectedOptions, event); From ce4a326ae483a1a3059d7454df71bc9c72299913 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 14 Apr 2021 14:27:42 -0700 Subject: [PATCH 04/13] DDW-603 - Enable pasting of wallet recovery phrase - updates for multiple word selection - part 2 --- source/components/Autocomplete.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 581103c8..53557dd2 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -176,7 +176,7 @@ class AutocompleteBase extends Component { this.open(); } setTimeout(() => { - this.updateSelectedOptions(event, multipleValues); + this.updateSelectedOptions(event, multipleValues, multipleValues.length === 1); }, 0); }; @@ -187,11 +187,12 @@ class AutocompleteBase extends Component { updateSelectedOptions = ( event: SyntheticEvent<>, - selectedOption: any = null + selectedOption: any = null, + singleInput?: boolean, ) => { const { maxSelections, multipleSameSelections, options } = this.props; const { selectedOptions, isOpen } = this.state; - let { filteredOptions } = this.state; + const { filteredOptions } = this.state; const canMoreOptionsBeSelected = maxSelections != null ? selectedOptions.length < maxSelections : true; const areFilteredOptionsAvailable = @@ -206,14 +207,14 @@ class AutocompleteBase extends Component { selectedOption.trim() : selectedOption.filter(item => item); const newSelectedOptions: Array = [...selectedOptions]; if (option && Array.isArray(option)) { - filteredOptions = options; option.forEach(item => { - const optionCanBeSelected = multipleSameSelections && - filteredOptions.includes(item) || - (filteredOptions.includes(item) && + const optionCanBeSelected = (multipleSameSelections && + options.includes(item) && !singleInput) || + (options.includes(item) && !selectedOptions.includes(item) && !newSelectedOptions.includes(item)); - if (!optionCanBeSelected && !skipValueSelection) { + if ((!optionCanBeSelected && !skipValueSelection) || + (singleInput && !selectedOptions.length)) { this._setInputValue(item, true); skipValueSelection = true; return; From fe0f88e242f8d6f2cf2dbcd2f7adc56292307cb5 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Tue, 20 Apr 2021 18:21:39 +0200 Subject: [PATCH 05/13] DDW-603 - Enable pasting of wallet recovery phrase - updates for multiple word selection - part 2 --- source/components/Autocomplete.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 53557dd2..fe6d3f32 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -156,6 +156,7 @@ class AutocompleteBase extends Component { this.state.selectedOptions.length ) { // Remove last selected option + this.close(); this.removeOption(this.state.selectedOptions.length - 1, event); } else if (event.keyCode === 27) { // ESCAPE key: Stops propagation & modal closing @@ -245,6 +246,7 @@ class AutocompleteBase extends Component { removeOption = (index: number, event: SyntheticEvent<>) => { const { selectedOptions } = this.state; _.pullAt(selectedOptions, index); + this.close(); this.selectionChanged(selectedOptions, event); this.setState({ selectedOptions }); }; From d335973f32ee9f1ed6b6f606cb322c694ecce678 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Tue, 20 Apr 2021 22:42:00 +0200 Subject: [PATCH 06/13] DDW-603 - Enable pasting of wallet recovery phrase - fixing event js error --- source/components/Autocomplete.js | 32 ++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index fe6d3f32..03f6d6d0 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -149,21 +149,23 @@ class AutocompleteBase extends Component { }; onKeyDown = (event: SyntheticKeyboardEvent<>) => { - if ( - // Check for backspace in order to delete the last selected option - event.keyCode === 8 && - !event.target.value && - this.state.selectedOptions.length - ) { - // Remove last selected option - this.close(); - this.removeOption(this.state.selectedOptions.length - 1, event); - } else if (event.keyCode === 27) { - // ESCAPE key: Stops propagation & modal closing - event.stopPropagation(); - } else if (event.keyCode === 13) { - // ENTER key: Opens suggestions - this.open(); + if (event) { + if ( + // Check for backspace in order to delete the last selected option + event.keyCode === 8 && + !event.target.value && + this.state.selectedOptions.length + ) { + // Remove last selected option + this.close(); + this.removeOption(this.state.selectedOptions.length - 1, event); + } else if (event.keyCode === 27) { + // ESCAPE key: Stops propagation & modal closing + event.stopPropagation(); + } else if (event.keyCode === 13) { + // ENTER key: Opens suggestions + this.open(); + } } }; From 2f932901114e8e89c2e71928df00d2df88e39522 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Tue, 20 Apr 2021 23:28:46 +0200 Subject: [PATCH 07/13] DDW-603 - Enable pasting of wallet recovery phrase - fixing focus --- source/components/Autocomplete.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 03f6d6d0..79bc2415 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -239,6 +239,8 @@ class AutocompleteBase extends Component { } this.selectionChanged(newSelectedOptions, event); this.setState({ selectedOptions: newSelectedOptions, isOpen: false }); + } else { + skipValueSelection = true; } if (!skipValueSelection) { this._setInputValue(''); From 1fb856a63fe51f6043ea5e0a38bb72006027041e Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 21 Apr 2021 14:39:07 +0200 Subject: [PATCH 08/13] DDW-603 - Enable pasting of wallet recovery phrase - fixing click remove word dropdown show/hide --- source/components/Autocomplete.js | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 79bc2415..c2fb9b65 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -49,6 +49,7 @@ type State = { inputValue: string, mouseIsOverOptions: boolean, selectedOptions: Array, + isRemoveWordClicked: boolean, }; class AutocompleteBase extends Component { @@ -101,6 +102,7 @@ class AutocompleteBase extends Component { filteredOptions: sortAlphabetically && options ? options.sort() : options || [], isOpen: false, + isRemoveWordClicked: false, mouseIsOverOptions: false, composedTheme: composeTheme( addThemeId(theme || context.theme, themeId), @@ -252,7 +254,7 @@ class AutocompleteBase extends Component { _.pullAt(selectedOptions, index); this.close(); this.selectionChanged(selectedOptions, event); - this.setState({ selectedOptions }); + this.setState({ selectedOptions, isRemoveWordClicked: true }); }; selectionChanged = ( @@ -313,7 +315,16 @@ class AutocompleteBase extends Component { error={error || this.state.error} filteredOptions={this.state.filteredOptions} getSelectionProps={this.getSelectionProps} - handleAutocompleteClick={this.handleAutocompleteClick} + handleAutocompleteClick={() => { + setTimeout(() => { + const { removeWordClick } = this.state; + if (!removeWordClick) { + this.handleAutocompleteClick(); + } else { + this.setState((prevState) => ({ isRemoveWordClicked: !prevState.isRemoveWordClicked })); + } + }, 0); + }} handleChange={this.handleChange} handleInputChange={this.handleInputChange} inputRef={this.inputElement} From 5bd423ed8c19c79589898697d4cb7bc6206145b0 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 21 Apr 2021 15:05:17 +0200 Subject: [PATCH 09/13] DDW-603 - Enable pasting of wallet recovery phrase - fixing click remove word dropdown show/hide --- source/components/Autocomplete.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index c2fb9b65..71609add 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -317,8 +317,8 @@ class AutocompleteBase extends Component { getSelectionProps={this.getSelectionProps} handleAutocompleteClick={() => { setTimeout(() => { - const { removeWordClick } = this.state; - if (!removeWordClick) { + const { isRemoveWordClicked } = this.state; + if (!isRemoveWordClicked) { this.handleAutocompleteClick(); } else { this.setState((prevState) => ({ isRemoveWordClicked: !prevState.isRemoveWordClicked })); From f3478bd175f75c76ed2fade14e5eb2f2355d3932 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 21 Apr 2021 16:59:01 +0200 Subject: [PATCH 10/13] DDW-603 - Enable pasting of wallet recovery phrase - updating version to .21 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 48a94ce1..595e0830 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "react-polymorph", "description": "React components with highly customizable logic, markup and styles.", - "version": "0.9.8-rc.18", + "version": "0.9.8-rc.21", "scripts": { "build": "cross-env yarn clean && yarn sass && yarn js", "build:watch": "concurrently 'yarn js:watch' 'yarn sass:watch'", From 4d96e1f8bdb3d69a1442a0dc5536987736d29cfe Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Wed, 21 Apr 2021 17:26:39 +0200 Subject: [PATCH 11/13] DDW-603 - Enable pasting of wallet recovery phrase - fixes for dropdown --- source/components/Autocomplete.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index 71609add..a4044c70 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -214,10 +214,10 @@ class AutocompleteBase extends Component { if (option && Array.isArray(option)) { option.forEach(item => { const optionCanBeSelected = (multipleSameSelections && - options.includes(item) && !singleInput) || + options.includes(item) && !singleInput && option.length > 1) || (options.includes(item) && !selectedOptions.includes(item) && - !newSelectedOptions.includes(item)); + !newSelectedOptions.includes(item) && option.length > 1); if ((!optionCanBeSelected && !skipValueSelection) || (singleInput && !selectedOptions.length)) { this._setInputValue(item, true); From 26e5704c07b11f0603efa2b9895e5346bcd31ca2 Mon Sep 17 00:00:00 2001 From: Aleksandar Djordjevic Date: Thu, 22 Apr 2021 10:39:59 +0200 Subject: [PATCH 12/13] DDW-603 - Enable pasting of wallet recovery phrase - fixes for event js error --- source/components/Autocomplete.js | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index a4044c70..df2825ea 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -160,7 +160,7 @@ class AutocompleteBase extends Component { ) { // Remove last selected option this.close(); - this.removeOption(this.state.selectedOptions.length - 1, event); + this.removeOption(this.state.selectedOptions.length - 1); } else if (event.keyCode === 27) { // ESCAPE key: Stops propagation & modal closing event.stopPropagation(); @@ -181,17 +181,16 @@ class AutocompleteBase extends Component { this.open(); } setTimeout(() => { - this.updateSelectedOptions(event, multipleValues, multipleValues.length === 1); + this.updateSelectedOptions(multipleValues, multipleValues.length === 1); }, 0); }; // passed to Options onChange handler in AutocompleteSkin - handleChange = (option: any, event: SyntheticEvent<>) => { - this.updateSelectedOptions(event, option); + handleChange = (option: any) => { + this.updateSelectedOptions(option); }; updateSelectedOptions = ( - event: SyntheticEvent<>, selectedOption: any = null, singleInput?: boolean, ) => { @@ -239,7 +238,7 @@ class AutocompleteBase extends Component { skipValueSelection = false; } } - this.selectionChanged(newSelectedOptions, event); + this.selectionChanged(newSelectedOptions); this.setState({ selectedOptions: newSelectedOptions, isOpen: false }); } else { skipValueSelection = true; @@ -249,19 +248,18 @@ class AutocompleteBase extends Component { } }; - removeOption = (index: number, event: SyntheticEvent<>) => { + removeOption = (index: number) => { const { selectedOptions } = this.state; _.pullAt(selectedOptions, index); this.close(); - this.selectionChanged(selectedOptions, event); + this.selectionChanged(selectedOptions); this.setState({ selectedOptions, isRemoveWordClicked: true }); }; selectionChanged = ( - selectedOptions: Array, - event: SyntheticEvent + selectedOptions: Array ) => { - if (this.props.onChange) this.props.onChange(selectedOptions, event); + if (this.props.onChange) this.props.onChange(selectedOptions); }; // returns an object containing props, theme, and method handlers @@ -277,10 +275,10 @@ class AutocompleteBase extends Component { isOpen, selectedOptions, theme: composedTheme[themeId], - removeSelection: (index: number, event: SyntheticEvent<>) => + removeSelection: (index: number) => // the user's custom removeSelection event handler is composed with // the internal functionality of Autocomplete (this.removeOption) - composeFunctions(removeSelection, this.removeOption)(index, event), + composeFunctions(removeSelection, this.removeOption)(index), }; }; From ba15d3c906e3755cf507d0c70ad4f20a67c9ebc1 Mon Sep 17 00:00:00 2001 From: Dominik Guzei Date: Fri, 23 Apr 2021 14:40:12 +0200 Subject: [PATCH 13/13] [603] WIP: remove autocomplete click handler --- source/components/Autocomplete.js | 95 +++++++++++++------------ source/skins/simple/AutocompleteSkin.js | 5 +- 2 files changed, 54 insertions(+), 46 deletions(-) diff --git a/source/components/Autocomplete.js b/source/components/Autocomplete.js index df2825ea..b788cfd5 100644 --- a/source/components/Autocomplete.js +++ b/source/components/Autocomplete.js @@ -120,7 +120,12 @@ class AutocompleteBase extends Component { clear = () => this._removeOptions(); - focus = () => this.handleAutocompleteClick(); + focus = () => { + const { inputElement } = this; + if (inputElement && inputElement.current) { + inputElement.current.focus(); + } + }; open = () => this.setState({ isOpen: true }); @@ -139,15 +144,12 @@ class AutocompleteBase extends Component { }; toggleMouseLocation = () => - this.setState((prevState) => ({ mouseIsOverOptions: !prevState.mouseIsOverOptions })); + this.setState((prevState) => ({ + mouseIsOverOptions: !prevState.mouseIsOverOptions, + })); handleAutocompleteClick = () => { - const { inputElement } = this; - if (inputElement && inputElement.current) { - inputElement.current.focus(); - } - // toggle options open/closed - this.toggleOpen(); + this.focus(); }; onKeyDown = (event: SyntheticKeyboardEvent<>) => { @@ -180,9 +182,7 @@ class AutocompleteBase extends Component { if (hasMultipleValues) { this.open(); } - setTimeout(() => { - this.updateSelectedOptions(multipleValues, multipleValues.length === 1); - }, 0); + this.updateSelectedOptions(multipleValues, multipleValues.length === 1); }; // passed to Options onChange handler in AutocompleteSkin @@ -191,8 +191,8 @@ class AutocompleteBase extends Component { }; updateSelectedOptions = ( - selectedOption: any = null, - singleInput?: boolean, + addedOption: string | Array, + singleInput?: boolean ) => { const { maxSelections, multipleSameSelections, options } = this.props; const { selectedOptions, isOpen } = this.state; @@ -206,40 +206,51 @@ class AutocompleteBase extends Component { !maxSelections || (canMoreOptionsBeSelected && areFilteredOptionsAvailable) ) { - if (!selectedOption || !selectedOption.length) return; - const option = _.isString(selectedOption) ? - selectedOption.trim() : selectedOption.filter(item => item); + if (!addedOption || !addedOption.length) return; + const option = _.isString(addedOption) + ? addedOption.trim() + : addedOption.filter((item) => item !== ''); const newSelectedOptions: Array = [...selectedOptions]; + if (option && Array.isArray(option)) { - option.forEach(item => { - const optionCanBeSelected = (multipleSameSelections && - options.includes(item) && !singleInput && option.length > 1) || + option.forEach((item) => { + const optionCanBeSelected = + (multipleSameSelections && + options.includes(item) && + !singleInput && + option.length > 1) || (options.includes(item) && - !selectedOptions.includes(item) && - !newSelectedOptions.includes(item) && option.length > 1); - if ((!optionCanBeSelected && !skipValueSelection) || - (singleInput && !selectedOptions.length)) { + !selectedOptions.includes(item) && + !newSelectedOptions.includes(item) && + option.length > 1); + if ( + (!optionCanBeSelected && !skipValueSelection) || + (singleInput && !selectedOptions.length) + ) { this._setInputValue(item, true); skipValueSelection = true; return; } - if (item && + if ( + item && optionCanBeSelected && - isOpen && !skipValueSelection && - newSelectedOptions.length < maxSelections) { + isOpen && + !skipValueSelection && + newSelectedOptions.length < maxSelections + ) { newSelectedOptions.push(item); } }); } else { - const optionCanBeSelected = multipleSameSelections || - !selectedOptions.includes(option); + const optionCanBeSelected = + multipleSameSelections || !selectedOptions.includes(option); if (option && optionCanBeSelected && isOpen) { newSelectedOptions.push(option); skipValueSelection = false; } } this.selectionChanged(newSelectedOptions); - this.setState({ selectedOptions: newSelectedOptions, isOpen: false }); + this.setState({ selectedOptions: newSelectedOptions }); } else { skipValueSelection = true; } @@ -249,16 +260,16 @@ class AutocompleteBase extends Component { }; removeOption = (index: number) => { + console.log(index); const { selectedOptions } = this.state; _.pullAt(selectedOptions, index); this.close(); this.selectionChanged(selectedOptions); - this.setState({ selectedOptions, isRemoveWordClicked: true }); + this.setState({ selectedOptions }); + this.focus(); }; - selectionChanged = ( - selectedOptions: Array - ) => { + selectionChanged = (selectedOptions: Array) => { if (this.props.onChange) this.props.onChange(selectedOptions); }; @@ -313,16 +324,7 @@ class AutocompleteBase extends Component { error={error || this.state.error} filteredOptions={this.state.filteredOptions} getSelectionProps={this.getSelectionProps} - handleAutocompleteClick={() => { - setTimeout(() => { - const { isRemoveWordClicked } = this.state; - if (!isRemoveWordClicked) { - this.handleAutocompleteClick(); - } else { - this.setState((prevState) => ({ isRemoveWordClicked: !prevState.isRemoveWordClicked })); - } - }, 0); - }} + handleAutocompleteClick={this.handleAutocompleteClick} handleChange={this.handleChange} handleInputChange={this.handleInputChange} inputRef={this.inputElement} @@ -386,9 +388,12 @@ class AutocompleteBase extends Component { const multipleValues = value.split(' '); if (multipleValues && multipleValues.length > 1) { let selectedOptions = []; - multipleValues.forEach(itemValue => { + multipleValues.forEach((itemValue) => { const filteredValue = this._filterInvalidChars(itemValue); - selectedOptions = [...selectedOptions, ...this._filterOptions(filteredValue)]; + selectedOptions = [ + ...selectedOptions, + ...this._filterOptions(filteredValue), + ]; }); this.setState({ isOpen: !!multipleValues.length, diff --git a/source/skins/simple/AutocompleteSkin.js b/source/skins/simple/AutocompleteSkin.js index f8ddc90b..88800d85 100644 --- a/source/skins/simple/AutocompleteSkin.js +++ b/source/skins/simple/AutocompleteSkin.js @@ -67,7 +67,10 @@ export const AutocompleteSkin = (props: Props) => { role="presentation" aria-hidden className={theme.selectedWordRemoveButton} - onClick={props.removeOption.bind(null, index)} + onClick={(e) => { + e.stopPropagation(); + props.removeOption(index); + }} > ×