Created
March 25, 2021 15:51
-
-
Save MGustav0/a238a80e95e54978d522d868318e49ab to your computer and use it in GitHub Desktop.
Componente para ser integrado
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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