Skip to content

Commit

Permalink
[DDW-409] Refactor + fix edge-cases (e.g. arm/armed/armor)
Browse files Browse the repository at this point in the history
  • Loading branch information
przemyslaw-wlodek committed Jun 24, 2022
1 parent e25b73a commit f6cfe8d
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 79 deletions.
@@ -1,4 +1,5 @@
import React, {
ChangeEventHandler,
ClipboardEventHandler,
MouseEventHandler,
RefObject,
Expand Down Expand Up @@ -33,7 +34,7 @@ const MnemonicAutocompleteContainer = ({
onPaste,
reset,
ordinalNumber,
value,
value = '',
options,
maxVisibleOptions,
disabled,
Expand All @@ -44,7 +45,6 @@ const MnemonicAutocompleteContainer = ({
const initialState = useMemo(
() => ({
inputValue: value,
selectedOption: '',
filteredOptions: options.slice(0, maxVisibleOptions),
isOpen: false,
mouseIsOverOptions: false,
Expand Down Expand Up @@ -75,29 +75,36 @@ const MnemonicAutocompleteContainer = ({
event.currentTarget.setSelectionRange(0, event.currentTarget.value.length);
};

const handleInputChange = useCallback(
(inputValue) => {
const handleInputChange = useCallback<ChangeEventHandler<HTMLInputElement>>(
(event) => {
if (disabled) return;
const { value: inputValue } = event.currentTarget;
let selectedOption = '';
let isOpen = true;
const trimmedInputValue = inputValue.trim();
const filteredOptions = options
.filter(startsWith(trimmedInputValue))
.slice(0, maxVisibleOptions);
const isOpen =
filteredOptions.length > 1 || filteredOptions[0] !== trimmedInputValue;

if (options.includes(trimmedInputValue)) {
isOpen = false;
if (filteredOptions.includes(trimmedInputValue)) {
selectedOption = trimmedInputValue;
}

setState((prevState) => ({
...prevState,
isOpen,
filteredOptions: options
.filter(startsWith(trimmedInputValue))
.slice(0, maxVisibleOptions),
filteredOptions,
inputValue: trimmedInputValue,
selectedOption,
}));

onChange(selectedOption);

if (selectedOption && filteredOptions.length === 1) {
onConfirmSelection();
}
},
[options, disabled]
[disabled, options, onChange, onConfirmSelection, maxVisibleOptions]
);

const handleInputSelect = useCallback(
Expand All @@ -107,27 +114,34 @@ const MnemonicAutocompleteContainer = ({
...prevState,
isOpen: false,
filteredOptions: [inputValue],
selectedOption: inputValue,
inputValue,
}));

onChange(inputValue);
onConfirmSelection();
},
[disabled]
[disabled, onChange, onConfirmSelection]
);

const handleBlur = useCallback(() => {
if (disabled) return;
setState((prevState) => ({ ...prevState, blurred: true }));
}, [disabled]);

// this useEffect handles input paste event
useEffect(() => {
onChange(state.selectedOption);
if (state.selectedOption) {
onConfirmSelection();
}
}, [state.selectedOption]);
if (!value) return;

useEffect(() => {
if (value) {
const filteredOptions = options
.filter(startsWith(value))
.slice(0, maxVisibleOptions);

if (filteredOptions.length > 1) {
setState((prevState) => ({
...prevState,
inputValue: value,
}));
} else {
handleInputSelect(value);
}
}, [value]);
Expand Down
@@ -1,8 +1,8 @@
import React, {
ChangeEventHandler,
ClipboardEventHandler,
MouseEventHandler,
RefObject,
useCallback,
} from 'react';
import cx from 'classnames';
import { FormField } from 'react-polymorph/lib/components/FormField';
Expand All @@ -12,7 +12,7 @@ import * as styles from './MnemonicAutocompleteLayout.scss';

interface MnemonicInputSkinProps {
onClick: MouseEventHandler<HTMLInputElement>;
onChange: (value: string) => void;
onChange: ChangeEventHandler<HTMLInputElement>;
onSelect: (value: string) => void;
onBlur: () => void;
onPaste: ClipboardEventHandler<HTMLInputElement>;
Expand Down Expand Up @@ -58,57 +58,46 @@ const MnemonicAutocompleteLayout = ({
rootRef,
inputRef,
suggestionsRef,
}: MnemonicInputSkinProps) => {
const handleInputChange = useCallback(
(event: React.FormEvent<HTMLInputElement>) => {
const { value: inputValue } = event.currentTarget;

onChange(inputValue);
},
[]
);

return (
<div aria-hidden className={styles.root} ref={rootRef} role="presentation">
<div className={styles.inputLabel}>{ordinalNumber}.</div>
<FormField
error={error}
disabled={disabled}
formFieldRef={inputRef}
isErrorHidden={isOpen}
render={(setFormFieldRef) => (
<div ref={suggestionsRef} className={styles.inputWrapper}>
<input
className={cx(styles.input, error && styles.inputError)}
ref={setFormFieldRef}
value={value}
onBlur={onBlur}
onChange={handleInputChange}
onClick={onClick}
onPaste={onPaste}
disabled={disabled}
/>
</div>
)}
/>
<Options
isOpen={isOpen}
noResults={!options.length}
onChange={onSelect}
options={options}
persistSearchValue
optionsRef={optionsRef}
optionsMaxHeight={optionsMaxHeight}
resetOnClose
skin={OptionsSkin}
targetRef={suggestionsRef}
toggleMouseLocation={toggleMouseLocation}
toggleOpen={toggleOpen}
optionHeight={optionHeight}
noResultsMessage={noResultsMessage}
/>
</div>
);
};
}: MnemonicInputSkinProps) => (
<div aria-hidden className={styles.root} ref={rootRef} role="presentation">
<div className={styles.inputLabel}>{ordinalNumber}.</div>
<FormField
error={error}
disabled={disabled}
formFieldRef={inputRef}
isErrorHidden={isOpen}
render={(setFormFieldRef) => (
<div ref={suggestionsRef} className={styles.inputWrapper}>
<input
className={cx(styles.input, error && styles.inputError)}
ref={setFormFieldRef}
value={value}
onBlur={onBlur}
onChange={onChange}
onClick={onClick}
onPaste={onPaste}
disabled={disabled}
/>
</div>
)}
/>
<Options
isOpen={isOpen}
noResults={!options.length}
onChange={onSelect}
options={options}
persistSearchValue
optionsRef={optionsRef}
optionsMaxHeight={optionsMaxHeight}
resetOnClose
skin={OptionsSkin}
targetRef={suggestionsRef}
toggleMouseLocation={toggleMouseLocation}
toggleOpen={toggleOpen}
optionHeight={optionHeight}
noResultsMessage={noResultsMessage}
/>
</div>
);

export { MnemonicAutocompleteLayout };
Expand Up @@ -71,9 +71,8 @@ const MnemonicInput: VFC<

const providedWordCount = selectedWords.filter((word) => word?.length)
.length;
const requiredWordCount = selectedWords.length;
const showError =
providedWordCount === requiredWordCount &&
providedWordCount === wordCount &&
error &&
error !== INCOMPLETE_MNEMONIC_MARKER;
const wordsPerColumn = Math.ceil(wordCount / COLUMNS_COUNT);
Expand Down Expand Up @@ -145,7 +144,7 @@ const MnemonicInput: VFC<
? error
: intl.formatMessage(messages.mnemonicCounter, {
providedWordCount,
requiredWordCount,
requiredWordCount: wordCount,
})}
</div>
</div>
Expand All @@ -154,7 +153,7 @@ const MnemonicInput: VFC<
{inputIndicesByColumnIndex.map((inputIndices) => (
<div key={inputIndices.join('')} className={styles.inputList}>
{inputIndices.map((idx) => {
const value = selectedWords[idx] || '';
const value = selectedWords[idx];
return (
<div key={idx} className={styles.inputWrapper}>
<MnemonicAutocompleteContainer
Expand Down

0 comments on commit f6cfe8d

Please sign in to comment.