From a04c8adb5e3f5b4f40531d843884a19c63d80ea5 Mon Sep 17 00:00:00 2001 From: AlicjaSzu Date: Mon, 6 May 2019 13:38:48 +0200 Subject: [PATCH] fix autofill functionality in Select --- src/components/Select/Select.tsx | 44 ++++++++++++++++++++++----- src/components/Select/scss/index.scss | 1 - src/components/Select/types.ts | 4 ++- 3 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/components/Select/Select.tsx b/src/components/Select/Select.tsx index b061eb0b77..454dd56246 100644 --- a/src/components/Select/Select.tsx +++ b/src/components/Select/Select.tsx @@ -1,11 +1,22 @@ import "./scss/index.scss"; import classNames from "classnames"; -import { filter, map } from "lodash"; +import { filter, find } from "lodash"; import * as React from "react"; import { useClickedOutside } from "../../hooks"; -import { IFilteredListArgs, IListArgs, ISelectProps } from "./types"; +import { + IFilteredListArgs, + IListArgs, + ISelectChange, + ISelectItem, + ISelectProps +} from "./types"; + +const updateOptions = ( + { label, value }: ISelectItem, + onChange: ISelectChange +) => onChange({ country: label, code: value }); const renderNoOptions = () => (

@@ -18,12 +29,12 @@ const renderList = ( setOpen: React.Dispatch> ) => options.length - ? map(options, ({ label, value }) => ( + ? options.map(({ label, value }) => (

{ - onChange({ country: label, code: value }); + updateOptions({ label, value }, onChange); setOpen(false); }} > @@ -37,6 +48,16 @@ const filterList = ({ searchPhrase, options }: IFilteredListArgs) => label.toLowerCase().includes(searchPhrase.toLowerCase()) ); +const isAutofilled = (inputValue: string, newInputValue: string) => + newInputValue.length > 1 && + newInputValue.substring(0, newInputValue.length - 1) !== inputValue; + +const findAutofilledOption = (options: ISelectItem[], inputValue: string) => + find( + options, + ({ label }) => label.toLowerCase() === inputValue.toLowerCase() + ); + export const Select = (props: ISelectProps) => { const { autoComplete, defaultValue, label, onChange, options, name } = props; @@ -45,8 +66,10 @@ export const Select = (props: ISelectProps) => { const { clickedOutside, setElementRef } = useClickedOutside(); const inputRef = React.useRef(null); + const resetInputValueToDefault = () => setSearchPhrase(defaultValue.label); + React.useEffect(() => { - setSearchPhrase(defaultValue.label); + resetInputValueToDefault(); }, [clickedOutside, defaultValue]); const shouldOpen = clickedOutside ? false : open; @@ -77,11 +100,18 @@ export const Select = (props: ISelectProps) => { setSearchPhrase(e.target.value)} + onChange={e => { + const { value } = e.target; + setSearchPhrase(value); + if (isAutofilled(searchPhrase, value)) { + const country = findAutofilledOption(options, value); + return country && updateOptions(country, onChange); + } + }} onClick={e => { changeSelectionRange(e); if (open) { - setSearchPhrase(defaultValue.label); + resetInputValueToDefault(); } setOpen(!open); }} diff --git a/src/components/Select/scss/index.scss b/src/components/Select/scss/index.scss index 21184c872e..46ad46c415 100644 --- a/src/components/Select/scss/index.scss +++ b/src/components/Select/scss/index.scss @@ -56,7 +56,6 @@ max-height: 40vh; opacity: 0; z-index: -1; - transition: all 0.1s ease; box-shadow: $select-menu-shadow; overflow: hidden; &--open { diff --git a/src/components/Select/types.ts b/src/components/Select/types.ts index 53db0d9125..1e27bea04c 100644 --- a/src/components/Select/types.ts +++ b/src/components/Select/types.ts @@ -1,3 +1,5 @@ +export type ISelectChange = (value: { country: string; code: string }) => void; + export interface ISelectItem { label: string; value: string; @@ -18,7 +20,7 @@ export interface ISelectProps { export interface IListArgs { options: ISelectItem[]; - onChange: (value: { country: string; code: string }) => void; + onChange: ISelectChange; } export interface IFilteredListArgs {