diff options
| author | Oskar Nyberg <oskar@mullvad.net> | 2022-02-23 13:36:12 +0100 |
|---|---|---|
| committer | Oskar Nyberg <oskar@mullvad.net> | 2022-02-23 13:36:12 +0100 |
| commit | 52309e4d193f784081cd7842ba679b0f65ff7e2f (patch) | |
| tree | 51310a26f3b28b503268707ab69c561a2a167ded /gui/src/renderer/components/cell | |
| parent | 20ca77845e5d205fdb2cc72d30d80bdff2f54b7c (diff) | |
| parent | dcbdb46fa54091e6d8c4ccd02fe1be0b25de3987 (diff) | |
| download | mullvadvpn-52309e4d193f784081cd7842ba679b0f65ff7e2f.tar.xz mullvadvpn-52309e4d193f784081cd7842ba679b0f65ff7e2f.zip | |
Merge branch 'improve-escape-shortcut'
Diffstat (limited to 'gui/src/renderer/components/cell')
| -rw-r--r-- | gui/src/renderer/components/cell/Input.tsx | 116 |
1 files changed, 66 insertions, 50 deletions
diff --git a/gui/src/renderer/components/cell/Input.tsx b/gui/src/renderer/components/cell/Input.tsx index 913fb26ece..007ac9cdb6 100644 --- a/gui/src/renderer/components/cell/Input.tsx +++ b/gui/src/renderer/components/cell/Input.tsx @@ -6,6 +6,7 @@ import { CellDisabledContext, Container } from './Container'; import StandaloneSwitch from '../Switch'; import ImageView from '../ImageView'; import { useBoolean } from '../../lib/utilityHooks'; +import { BackAction } from '../KeyboardNavigation'; export const Switch = React.forwardRef(function SwitchT( props: StandaloneSwitch['props'], @@ -113,6 +114,10 @@ export class Input extends React.Component<IInputProps, IInputState> { ); } + public blur = () => { + this.inputRef.current?.blur(); + }; + private onChange = (event: React.ChangeEvent<HTMLInputElement>) => { const value = this.props.modifyValue?.(event.target.value) ?? event.target.value; this.setState({ value }); @@ -176,6 +181,7 @@ export function AutoSizingTextInput(props: IInputProps) { const [value, setValue] = useState(otherProps.value ?? ''); const [focused, setFocused, setBlurred] = useBoolean(false); + const inputRef = useRef() as React.RefObject<Input>; const onChangeValueWrapper = useCallback( (value: string) => { @@ -201,22 +207,27 @@ export function AutoSizingTextInput(props: IInputProps) { [onFocus], ); + const blur = useCallback(() => inputRef.current?.blur(), []); + return ( - <InputFrame focused={focused}> - <StyledAutoSizingTextInputContainer> - <StyledAutoSizingTextInputWrapper> - <Input - onChangeValue={onChangeValueWrapper} - onBlur={onBlurWrapper} - onFocus={onFocusWrapper} - {...otherProps} - /> - </StyledAutoSizingTextInputWrapper> - <StyledAutoSizingTextInputFiller className={otherProps.className} aria-hidden={true}> - {value === '' ? otherProps.placeholder : value} - </StyledAutoSizingTextInputFiller> - </StyledAutoSizingTextInputContainer> - </InputFrame> + <BackAction disabled={!focused} action={blur}> + <InputFrame focused={focused}> + <StyledAutoSizingTextInputContainer> + <StyledAutoSizingTextInputWrapper> + <Input + ref={inputRef} + onChangeValue={onChangeValueWrapper} + onBlur={onBlurWrapper} + onFocus={onFocusWrapper} + {...otherProps} + /> + </StyledAutoSizingTextInputWrapper> + <StyledAutoSizingTextInputFiller className={otherProps.className} aria-hidden={true}> + {value === '' ? otherProps.placeholder : value} + </StyledAutoSizingTextInputFiller> + </StyledAutoSizingTextInputContainer> + </InputFrame> + </BackAction> ); } @@ -282,6 +293,7 @@ interface IRowInputProps { export function RowInput(props: IRowInputProps) { const [value, setValue] = useState(props.initialValue ?? ''); const textAreaRef = useRef() as React.RefObject<HTMLTextAreaElement>; + const [focused, setFocused, setBlurred] = useBoolean(false); const submit = useCallback(() => props.onSubmit(value), [props.onSubmit, value]); const onChange = useCallback( @@ -302,12 +314,17 @@ export function RowInput(props: IRowInputProps) { [submit], ); - const globalKeyListener = useCallback( - (event: KeyboardEvent) => { - if (event.key === 'Escape') { - event.stopPropagation(); - props.onBlur?.(); - } + const onFocus = useCallback( + (event: React.FocusEvent<HTMLTextAreaElement>) => { + setFocused(); + props.onFocus?.(event); + }, + [props.onFocus], + ); + const onBlur = useCallback( + (event: React.FocusEvent<HTMLTextAreaElement>) => { + setBlurred(); + props.onBlur?.(event); }, [props.onBlur], ); @@ -320,6 +337,8 @@ export function RowInput(props: IRowInputProps) { } }, [textAreaRef, value.length]); + const blur = useCallback(() => textAreaRef.current?.blur(), []); + useEffect(() => { if (props.autofocus) { focus(); @@ -332,35 +351,32 @@ export function RowInput(props: IRowInputProps) { } }, [props.invalid, focus]); - useEffect(() => { - document.addEventListener('keydown', globalKeyListener, true); - return () => document.removeEventListener('keydown', globalKeyListener, true); - }, []); - return ( - <StyledCellInputRowContainer> - <StyledInputWrapper marginLeft={props.paddingLeft ?? 0}> - <StyledInputFiller>{value}</StyledInputFiller> - <StyledTextArea - ref={textAreaRef} - onChange={onChange} - onKeyDown={onKeyDown} - rows={1} - value={value} - invalid={props.invalid} - onFocus={props.onFocus} - onBlur={props.onBlur} - placeholder={props.placeholder} - /> - </StyledInputWrapper> - <StyledSubmitButton onClick={submit}> - <ImageView - source="icon-check" - height={18} - tintColor={value === '' ? colors.blue60 : colors.blue} - tintHoverColor={value === '' ? colors.blue60 : colors.blue80} - /> - </StyledSubmitButton> - </StyledCellInputRowContainer> + <BackAction disabled={!focused} action={blur}> + <StyledCellInputRowContainer> + <StyledInputWrapper marginLeft={props.paddingLeft ?? 0}> + <StyledInputFiller>{value}</StyledInputFiller> + <StyledTextArea + ref={textAreaRef} + onChange={onChange} + onKeyDown={onKeyDown} + rows={1} + value={value} + invalid={props.invalid} + onFocus={onFocus} + onBlur={onBlur} + placeholder={props.placeholder} + /> + </StyledInputWrapper> + <StyledSubmitButton onClick={submit}> + <ImageView + source="icon-check" + height={18} + tintColor={value === '' ? colors.blue60 : colors.blue} + tintHoverColor={value === '' ? colors.blue60 : colors.blue80} + /> + </StyledSubmitButton> + </StyledCellInputRowContainer> + </BackAction> ); } |
