Skip to content

Commit

Permalink
review changes
Browse files Browse the repository at this point in the history
  • Loading branch information
lendihop committed Oct 11, 2023
1 parent 23b2abd commit 5d4d584
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 95 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, { FC, memo, useCallback } from 'react';

import { emptyFn } from '@rnw-community/shared';
import classNames from 'clsx';

import styles from './seedLengthOption.module.css';

interface Props {
option: string;
selectedOption: string;
onClick?: (option: string) => void;
onChange?: (option: string) => void;
}

export const SeedLengthOption: FC<Props> = memo(({ option, selectedOption, onClick = emptyFn, onChange = emptyFn }) => {
const handleClick = useCallback(() => onClick(option), [onClick, option]);
const handleChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.value), [onChange]);

return (
<li
value={option}
onClick={handleClick}
className={classNames(
selectedOption === option ? 'bg-gray-200' : 'hover:bg-gray-100',
'py-2',
'text-gray-800',
'flex justify-start px-3 m-2 rounded-md',
'text-lg'
)}
>
<label htmlFor={option} className="flex gap-2 items-center">
<input
type="radio"
id={option}
value={option}
checked={selectedOption === option}
onChange={handleChange}
className={styles.input}
/>
<span className="text-sm">{option}</span>
</label>
</li>
);
});
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import classNames from 'clsx';
import { ReactComponent as SelectArrowDownIcon } from 'app/icons/select-arrow-down.svg';
import { t } from 'lib/i18n';

import styles from './seedLength.module.css';
import { SeedLengthOption } from './SeedLengthOption/SeedLengthOption';

interface SeedLengthSelectProps {
options: Array<string>;
Expand Down Expand Up @@ -62,30 +62,13 @@ export const SeedLengthSelect: FC<SeedLengthSelectProps> = ({ options, currentOp
<ul className={classNames(!isOpen && 'hidden')}>
{options.map(option => {
return (
<li
<SeedLengthOption
key={option}
value={option}
onClick={() => handleClick(option)}
className={classNames(
selectedOption === option ? 'bg-gray-200' : 'hover:bg-gray-100',
'py-2',
'text-gray-800',
'flex justify-start px-3 m-2 rounded-md',
'text-lg'
)}
>
<label htmlFor={option} className="flex gap-2 items-center">
<input
type="radio"
id={option}
value={option}
checked={selectedOption === option}
onChange={e => setSelectedOption(e.target.value)}
className={styles.input}
/>
<span className="text-sm">{option}</span>
</label>
</li>
option={option}
selectedOption={selectedOption}
onClick={handleClick}
onChange={setSelectedOption}
/>
);
})}
</ul>
Expand Down
128 changes: 72 additions & 56 deletions src/app/templates/SeedPhraseInput/SeedWordInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,81 +82,97 @@ export const SeedWordInput: FC<SeedWordInputProps> = ({
onPaste(e);
}
},
[onPaste]
[id, inputsRef, onPaste]
);

const setValueToVariant = (variant: string) => {
if (inputsRef.current[id]) {
onSeedWordChange(id, variant);
setWordSpellingError('');
inputsRef.current[id]!.value = variant;
}
setIsBlur(true);
};
const setValueToVariant = useCallback(
(variant: string) => {
if (inputsRef.current[id]) {
onSeedWordChange(id, variant);
setWordSpellingError('');
inputsRef.current[id]!.value = variant;
}
setIsBlur(true);
},
[id, inputsRef, onSeedWordChange, setWordSpellingError]
);

const handleVariantClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>, variant: string) => {
e.preventDefault();
setValueToVariant(variant);
};
const handleVariantClick = useCallback(
(e: React.MouseEvent<HTMLButtonElement, MouseEvent>, variant: string) => {
e.preventDefault();
setValueToVariant(variant);
},
[setValueToVariant]
);

const handleBlur = (e: React.FocusEvent) => {
const handleBlur = useCallback((e: React.FocusEvent) => {
if (e.relatedTarget?.tagName !== BUTTON_TAG_NAME) {
setIsBlur(true);
setFocusedVariantIndex(-1);
}
};
}, []);

const handleInputKeyDown = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
if (!autoCompleteVariants) {
return;
}
const handleInputKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
if (!autoCompleteVariants) {
return;
}

if (e.key === 'Tab' || e.key === 'Enter') {
setValueToVariant(autoCompleteVariants[0]);
if (e.key === 'Tab' || e.key === 'Enter') {
setValueToVariant(autoCompleteVariants[0]);

if (id < numberOfWords - 1) {
if (id < numberOfWords - 1) {
e.preventDefault();
inputsRef.current[id + 1]?.focus();
}
}

if (e.key === 'ArrowDown' && autoCompleteVariants.length > 1) {
e.preventDefault();
inputsRef.current[id + 1]?.focus();
setFocusedVariantIndex(1);
}
}
},
[autoCompleteVariants, id, inputsRef, numberOfWords, setValueToVariant]
);

if (e.key === 'ArrowDown' && autoCompleteVariants.length > 1) {
e.preventDefault();
setFocusedVariantIndex(1);
}
};
const handleVariantKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLButtonElement>, variant: string) => {
if (!autoCompleteVariants) {
return;
}

const handleVariantKeyDown = (e: React.KeyboardEvent<HTMLButtonElement>, variant: string) => {
if (!autoCompleteVariants) {
return;
}
if (e.key === 'Tab' || e.key === 'Enter') {
setValueToVariant(variant);

if (e.key === 'Tab' || e.key === 'Enter') {
setValueToVariant(variant);
if (id < numberOfWords - 1) {
e.preventDefault();
inputsRef.current[id + 1]?.focus();
}
}

if (id < numberOfWords - 1) {
if (e.key === 'ArrowDown') {
e.preventDefault();
inputsRef.current[id + 1]?.focus();
if (focusedVariantIndex < autoCompleteVariants.length - 1) {
setFocusedVariantIndex(prev => prev + 1);
}
} else if (e.key === 'ArrowUp') {
e.preventDefault();
if (focusedVariantIndex === 0) {
inputsRef.current[id]?.focus();
setFocusedVariantIndex(-1);
}

if (focusedVariantIndex > 0) {
setFocusedVariantIndex(prev => prev - 1);
}
}
}
},
[autoCompleteVariants, focusedVariantIndex, id, inputsRef, numberOfWords, setValueToVariant]
);

if (e.key === 'ArrowDown') {
e.preventDefault();
if (focusedVariantIndex < autoCompleteVariants.length - 1) {
setFocusedVariantIndex(prev => prev + 1);
}
} else if (e.key === 'ArrowUp') {
e.preventDefault();
if (focusedVariantIndex === 0) {
inputsRef.current[id]?.focus();
setFocusedVariantIndex(-1);
}
const setInputRef = useCallback((el: FormFieldElement | null) => (inputsRef.current[id] = el), [id, inputsRef]);

if (focusedVariantIndex > 0) {
setFocusedVariantIndex(prev => prev - 1);
}
}
};
const handleFocus = useCallback(() => setIsBlur(false), []);

return (
<div className="flex flex-col relative">
Expand All @@ -165,13 +181,13 @@ export const SeedWordInput: FC<SeedWordInputProps> = ({
</label>

<FormField
ref={el => (inputsRef.current[id] = el)}
ref={setInputRef}
type="password"
id={id.toString()}
onChange={onChange}
onBlur={handleBlur}
value={value}
onFocus={() => setIsBlur(false)}
onFocus={handleFocus}
onPaste={handlePaste}
revealRef={revealRef}
onReveal={onReveal}
Expand Down
31 changes: 16 additions & 15 deletions src/app/templates/SeedPhraseInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { FC, useCallback, useMemo, useRef, useState } from 'react';

import { validateMnemonic } from 'bip39';
import bip39WordList from 'bip39/src/wordlists/english.json';
import classNames from 'clsx';

import { FormFieldElement } from 'app/atoms/FormField';
Expand All @@ -11,7 +10,7 @@ import { TestIDProperty } from 'lib/analytics';
import { T, t } from 'lib/i18n';
import { clearClipboard } from 'lib/ui/utils';

import { SeedLengthSelect } from './SeedLengthSelect';
import { SeedLengthSelect } from './SeedLengthSelect/SeedLengthSelect';
import { SeedWordInput, SeedWordInputProps } from './SeedWordInput';
import { useRevealRef } from './use-reveal-ref.hook';

Expand Down Expand Up @@ -53,23 +52,25 @@ export const SeedPhraseInput: FC<SeedPhraseInputProps> = ({
const { getRevealRef, onReveal, resetRevealRef } = useRevealRef();

const onSeedChange = useCallback(
(newDraftSeed: Array<string>) => {
let newSeedError = '';
(newDraftSeed: string[]) => {
setDraftSeed(newDraftSeed);

const joinedDraftSeed = newDraftSeed.join(' ');
let newSeedError = '';

if (newDraftSeed.some(Boolean)) {
if (newDraftSeed.some(word => word === '')) {
if (newDraftSeed.some(word => word !== '' && bip39WordList.includes(word))) {
newSeedError = '';
} else {
newSeedError = t('mnemonicWordsAmountConstraint', [numberOfWords]) as string;
}
} else if (!validateMnemonic(formatMnemonic(joinedDraftSeed))) {
newSeedError = t('justValidPreGeneratedMnemonic');
}
if (!newDraftSeed.some(Boolean)) {
onChange(joinedDraftSeed);
return;
}

if (newDraftSeed.some(word => word === '')) {
newSeedError = t('mnemonicWordsAmountConstraint', [numberOfWords]) as string;
}

if (!validateMnemonic(formatMnemonic(joinedDraftSeed))) {
newSeedError = t('justValidPreGeneratedMnemonic');
}

setDraftSeed(newDraftSeed);
setSeedError(newSeedError);
onChange(newSeedError ? '' : joinedDraftSeed);
},
Expand Down

0 comments on commit 5d4d584

Please sign in to comment.