Created
May 6, 2023 03:37
-
-
Save jonathasborges1/111121a7c339acc2d25c45add1cd9044 to your computer and use it in GitHub Desktop.
MultipleSelectCheckBox component
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 { useState, useMemo, useCallback, useEffect } from "react"; | |
import KeyboardArrowDownIcon from "@mui/icons-material/KeyboardArrowDown"; | |
import { | |
FormControl, | |
Select, | |
MenuItem, | |
Checkbox, | |
Typography, | |
ListItemText, | |
} from "@mui/material"; | |
import { useTheme } from "@mui/material/styles"; | |
interface Option { | |
value: string; | |
label: string; | |
} | |
interface Props { | |
label: string; | |
options: Option[]; | |
value: string[]; | |
onChange: (values: string[]) => void; | |
} | |
const MultipleSelectCheckbox: React.FC<Props> = ({ | |
label, | |
options, | |
value, | |
onChange, | |
}) => { | |
const theme = useTheme(); | |
const [selectAll, setSelectAll] = useState<boolean>(false); | |
const [selectedValues, setSelectedValues] = useState<string[] | undefined>(value); | |
const handleSelectAll = () => { | |
if (selectAll) { | |
setSelectedValues([]); | |
setSelectAll(false); | |
} else { | |
setSelectedValues(options.map((option) => option.value)); | |
setSelectAll(true); | |
} | |
}; | |
const handleOptionChange = (optionValue: string, optionSelected: boolean) => { | |
setSelectedValues((prevSelectedValues) => { | |
if (optionSelected) { | |
if (prevSelectedValues?.includes(optionValue)) { | |
// Se a opção já estiver selecionada, não faz nada | |
return prevSelectedValues; | |
} else { | |
// Se a opção não estiver selecionada, adiciona à lista de selecionados | |
return prevSelectedValues | |
? [...prevSelectedValues, optionValue] | |
: [optionValue]; | |
} | |
} else { | |
// Se a opção estiver sendo desmarcada, remove da lista de selecionados | |
return prevSelectedValues?.filter((value) => value !== optionValue); | |
} | |
}); | |
}; | |
const allOptionsSelected = useMemo( | |
() => selectedValues?.length === options.length || false, | |
[selectedValues, options] | |
); | |
const someOptionsSelected = useMemo( | |
() => selectedValues.length > 0 && !allOptionsSelected, | |
[selectedValues, allOptionsSelected] | |
); | |
const handle = useCallback(()=>{ | |
onChange(selectedValues); | |
},[selectedValues]) | |
useEffect(()=>{handle()},[]) | |
return ( | |
<FormControl sx={{ maxWidth: 241, minWidth: 241 }}> | |
{label && ( | |
<Typography | |
fontFamily={"Open Sans"} | |
fontWeight={700} | |
color={"shadesOfDark.dark"} | |
mb={0.5} | |
> | |
{label} | |
</Typography> | |
)} | |
<Select | |
multiple | |
displayEmpty | |
placeholder={selectedValues?.length === 0 ? "Selecione" : ""} | |
value={selectedValues || []} | |
renderValue={(selected) => { | |
const allSelected = | |
Array.isArray(selected) && selected.length === options.length; | |
if (selected.length === 0) { | |
return "Selecione"; | |
} else if (allSelected) { | |
return "Todos"; | |
} else { | |
const selectedLabels = selectedValues?.map( | |
(value) => options.find((option) => option.value === value)?.label | |
); | |
return selectedLabels?.join(", ") || ""; | |
} | |
}} | |
IconComponent={KeyboardArrowDownIcon} | |
sx={{ | |
bgcolor: "background.paper", | |
border: "none", | |
borderRadius: 1, | |
padding: 0, | |
maxWidth: 200, | |
minWidth: 200, | |
height: 40, | |
"& .MuiInputBase-input::placeholder": { | |
color: "#888", | |
fontStyle: "italic", | |
opacity: 1, | |
}, | |
"& .MuiSelect-root": { | |
backgroundColor: "transparent", | |
paddingLeft: 0, | |
paddingRight: 0, | |
"&:focus": { | |
backgroundColor: "transparent", | |
border: "none", | |
outline: "none !important", | |
}, | |
}, | |
"& .MuiSelect-icon": { | |
top: "calc(50% - 12px)", | |
}, | |
}} | |
> | |
<MenuItem value="" disabled> | |
Selecione | |
</MenuItem> | |
<MenuItem | |
key="select-all" | |
aria-expanded={open ? "true" : undefined} | |
> | |
<label style={{ display: "flex", alignItems: "center" , width: "100%",cursor:"pointer", border:"0px solid red" }}> | |
<Checkbox | |
checked={allOptionsSelected} | |
indeterminate={someOptionsSelected} | |
onChange={handleSelectAll} | |
sx={{ | |
"&.MuiCheckbox-colorPrimary": { | |
color: theme.palette.shadesOfDark.dark, | |
}, | |
}} | |
/> | |
<ListItemText primary={"Todos"} /> | |
</label> | |
</MenuItem> | |
{options.map((option) => ( | |
<MenuItem | |
key={option.value} | |
value={option.value} | |
onClick={() => { handleOptionChange(option.value,!selectedValues.includes(option.value)); | |
}} | |
sx={{ | |
minWidth: 200, | |
fontSize: 14, | |
fontFamily: "Open Sans", | |
"&.Mui-selected": { | |
color: "shadesOfDark.dark", | |
backgroundColor: "shadesOfDark.ultraLight", | |
fontWeight: 700, | |
}, | |
"&.Mui-selected:hover": { | |
backgroundColor: "shadesOfDark.ultraLight", | |
}, | |
}} | |
> | |
<Checkbox | |
checked={selectedValues.includes(option.value)} | |
sx={{ | |
"&.Mui-checked": { | |
color: theme.palette.shadesOfDark.dark, | |
}, | |
}} | |
/> | |
<ListItemText primary={option.label} /> | |
</MenuItem> | |
))} | |
</Select> | |
</FormControl> | |
); | |
}; | |
export default MultipleSelectCheckbox; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment