Skip to content

Instantly share code, notes, and snippets.

@huxaiphaer
Created September 17, 2021 12:40
Show Gist options
  • Save huxaiphaer/ee8ce0dc244642c13a606bab110335f0 to your computer and use it in GitHub Desktop.
Save huxaiphaer/ee8ce0dc244642c13a606bab110335f0 to your computer and use it in GitHub Desktop.
import { useCallback, memo, useMemo, useEffect, useState } from 'react';
import { FastField, useFormikContext, FormikValues } from 'formik';
import _get from 'lodash.get';
import { Autocomplete } from 'formik-material-ui-lab';
import { Typography, TextField, TextFieldProps } from '@material-ui/core';
import { shouldFastFieldUpdate } from 'utils/utils';
import { CountryType } from 'utils/commonTypes/types';
import { useCustomerData } from 'context/customer-context';
import Adornment from '../Adornment';
import useStyles from './styles';
import { CountryObject } from '../../context/customer-context/types';
export type TypeOptions = 'internationalPrefix' | 'nationality' | 'country';
interface Props {
name: string;
type: TypeOptions;
textFieldProps?: TextFieldProps;
[propName: string]: any;
}
interface CustomAutocompleteProps {
field: {
value: number | string | boolean;
name: string;
};
}
const CustomAutocomplete = memo((props: CustomAutocompleteProps) => {
const classes = useStyles();
return (
<Autocomplete {...(props as any)} className={props.field.value ? classes.completeField : ''} />
);
});
const getOptionLabel = {
internationalPrefix: (option: CountryType) => `${option.country} (+${option.prefix})`,
nationality: (option: CountryType) => option.nationality,
country: (option: CountryType) => option.country,
};
const getOptionRender = {
internationalPrefix: (option: CountryType) => (
<Typography>
{option.country} +{option.prefix}
</Typography>
),
nationality: (option: CountryType) => <Typography>{option.nationality}</Typography>,
country: (option: CountryType) => <Typography>{option.country}</Typography>,
};
const CountrySelector = ({ name, type, textFieldProps = undefined, ...props }: Props) => {
const classes = useStyles();
const { touched, errors, values } = useFormikContext<FormikValues>();
const { countryList } = useCustomerData();
const [countryFinal, setCountryFinal] = useState<CountryType[]>([])
const value = useMemo(() => _get(values, name), [values, name]);
useEffect(()=>{
if(type === 'nationality'){
setCountryFinal(countryList.sort((a: CountryObject, b: CountryObject) =>
a.nationality.localeCompare(b.nationality)))
}else {
setCountryFinal(countryList.sort((a: CountryObject, b: CountryObject) =>
a.country.localeCompare(b.country)))
}
}, [countryList, type, setCountryFinal])
console.log(' country list ', countryList)
const handleGetOptionLabel = useCallback(option => (option ? getOptionLabel[type](option) : ''), [
type,
]);
const handleGetOptionSelected = useCallback(
(option: CountryType, paramValue: CountryType) =>
option && paramValue ? option.code === paramValue.code : null,
[],
);
const handleGetOptionRender = useCallback(option => getOptionRender[type](option), [type]);
const handleRenderInput = useCallback(
params => {
const { InputProps } = params;
const prevEndAdornment = InputProps.endAdornment;
InputProps.endAdornment = (
<>
{value && <Adornment classes={classes} />}
{prevEndAdornment}
</>
);
return (
<TextField
{...params}
{...textFieldProps}
error={touched[name] && !!errors[name]}
helperText={errors[name]}
variant="outlined"
InputProps={InputProps}
/>
);
},
[errors, touched, name, textFieldProps, value, classes],
);
return (
<FastField
name={name}
component={CustomAutocomplete}
options={countryFinal}
getOptionLabel={handleGetOptionLabel}
getOptionSelected={handleGetOptionSelected}
disableClearable
renderOption={handleGetOptionRender}
renderInput={handleRenderInput}
size="small"
shouldUpdate={shouldFastFieldUpdate}
{...props}
/>
);
};
export default memo(CountrySelector);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment