Untitled

mail@pastecode.io avatar
unknown
typescript
2 years ago
3.3 kB
10
Indexable
Never
import React, { FC, useState } from 'react';
import { TextField, Autocomplete, Popper } from '@mui/material';
import { PopperPlacementType } from '@mui/material/Popper';
import { useField } from 'formik';
import { IAutocompleteOption } from '../../types/interfaces';
import { ReactComponent as ArrowDownSmall } from '../../../assets/icons/arrow_down_small.svg';
interface AutocompleteFieldProps {
  name: string;
  label: string;
  popperPlacement?: string;
  options: IAutocompleteOption[];
  defaultValue?: IAutocompleteOption;
  value?: IAutocompleteOption;
  loading?: boolean;
  filterSelectedOptions?: boolean;
  clearOnBlur?: boolean;
  multiple?: boolean;
  autoHighlight?: boolean;
  disabled?: boolean;
  onChange?: (value: IAutocompleteOption) => void;
  onInputChange?: (event: React.SyntheticEvent<Element, Event>, value: string) => void;
}
const defaultAutoCompleteValue: IAutocompleteOption = { label: '', value: '' };


const AutocompleteField: FC<AutocompleteFieldProps> = ({
  name,
  label,
  defaultValue = defaultAutoCompleteValue,
  options,
  filterSelectedOptions = false,
  loading = false,
  clearOnBlur = false,
  autoHighlight = false,
  multiple = false,
  disabled,
  onChange,
  onInputChange,
  popperPlacement = 'bottom',
}) => {
  const [field, meta, helpers] = useField(name);
  const showError = meta.touched && Boolean(meta.error);
  const [open, setOpen] = useState<boolean>(false);

  return (
    <>
      {/* {JSON.stringify({ name, meta }, null, 4)} */}

      <Autocomplete
        {...field}
        value={Boolean(field.value?.value) ? field.value : null}
        defaultValue={defaultValue}
        disabled={disabled}
        filterSelectedOptions={filterSelectedOptions}
        filterOptions={(optionsFilter: IAutocompleteOption[]) => optionsFilter}
        open={open}
        options={options}
        clearOnBlur={clearOnBlur}
        autoHighlight={autoHighlight}
        multiple={false}
        loading={loading}
        onBlur={field.onBlur}
        onOpen={() => {
          setOpen(true);
        }}
        onClose={() => {
          setOpen(false);
        }}
        onInputChange={onInputChange}
        onChange={(_, value) => {
          helpers.setValue(value != null ? value : defaultValue);
          if (onChange) {
            onChange(value || defaultValue);
          }
        }}
        popupIcon={<ArrowDownSmall />}
        getOptionLabel={(option: IAutocompleteOption) => option.label}
        PopperComponent={(propsPopper) => {
          return <Popper {...propsPopper} placement={popperPlacement as PopperPlacementType} />;
        }}
        isOptionEqualToValue={(option: IAutocompleteOption, value: IAutocompleteOption) => {
          if (!Boolean(value.value)) {
            return true;
          }
          return option != null ? option.label === value.label : false;
        }}
        renderInput={(params) => {
          const errorMsg = meta.error as { value?: string };
          return (
            <TextField
              {...params}
              id={name}
              label={label}
              name={name}
              error={showError}
              helperText={meta.touched && errorMsg?.value}
            />
          );
        }}
      />
    </>
  );
};

export default AutocompleteField;