Skip to content

Instantly share code, notes, and snippets.

@MGustav0
Created March 25, 2021 15:51
Show Gist options
  • Save MGustav0/a238a80e95e54978d522d868318e49ab to your computer and use it in GitHub Desktop.
Save MGustav0/a238a80e95e54978d522d868318e49ab to your computer and use it in GitHub Desktop.
Componente para ser integrado
import React, { InputHTMLAttributes, useEffect, useRef } from 'react';
import { useField } from '@unform/core';
import Autocomplete from '@material-ui/lab/Autocomplete';
import { Container, StyledTextField } from './styles';
interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
name: string;
}
interface SelectProps {
value?: any;
text: string;
noOptions?: boolean;
}
interface AutoCompleteProps extends InputProps {
label?: string;
id?: string;
placeholder?: string;
disabled?: boolean;
error?: boolean;
required?: boolean;
noOptionText?: string;
optionsRequest?: () => SelectProps[];
asyncOptionsRequest?: (search: string) => Promise<SelectProps[]>;
}
const AutoComplete: React.FC<AutoCompleteProps> = ({
name,
label,
id,
placeholder,
disabled,
required,
error,
noOptionText = 'Sem opção disponível',
optionsRequest,
asyncOptionsRequest,
}) => {
const [value, setValue] = React.useState<SelectProps | null>(null);
const [options, setOptions] = React.useState<SelectProps[]>([]);
const [open, setOpen] = React.useState(false);
const [loading, setLoading] = React.useState(false);
const { fieldName, registerField } = useField(name);
const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => {
registerField({
name: fieldName,
ref: inputRef.current,
getValue: ref => {
return ref.value;
},
});
}, [fieldName, registerField]);
useEffect(() => {
if (optionsRequest) {
setOptions(optionsRequest());
}
if (!open && !optionsRequest) {
setOptions([]);
return;
}
setLoading(!asyncOptionsRequest);
}, [asyncOptionsRequest, open, optionsRequest]);
return (
<Container>
<label htmlFor={id}>{label}</label>
<Autocomplete
id={id}
selectOnFocus
clearOnBlur
handleHomeEndKeys
disabled={disabled}
open={open}
noOptionsText={noOptionText}
onOpen={() => {
setOpen(true);
}}
onClose={() => {
setOpen(false);
}}
onChange={(_event, newValue) => {
const valueOption =
typeof newValue === 'string' ? newValue : newValue?.value;
setValue({ text: valueOption });
}}
options={options}
getOptionLabel={option => {
return option.text;
}}
getOptionSelected={option => option.value === value?.value}
loading={loading}
renderInput={params => (
<StyledTextField
{...params}
id={fieldName}
name={fieldName}
inputRef={inputRef}
variant="outlined"
size="small"
placeholder={placeholder}
required={required}
error={error}
onChange={async event => {
if (asyncOptionsRequest) {
setLoading(true);
setOptions(await asyncOptionsRequest(event.target.value));
setLoading(false);
return;
}
if (!options.length && !asyncOptionsRequest && optionsRequest) {
setLoading(false);
setOptions(optionsRequest());
}
}}
InputProps={{
...params.InputProps,
}}
/>
)}
/>
</Container>
);
};
export default AutoComplete;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment