The Material UI documentation includes an example of a multiple select where the selected options are rendered with the Chip component by using the renderValue prop on the Select. The standard behavior for the Select component is that clicking on the current value opens the list of options.
I am trying to tweak this so that the Chips show the X button, and clicking on the X should instantly remove that item from the selections rather than opening the options list.
That seems easy, but I can't get the onDelete event of the Chip to fire. Clicking the X still just opens the Select.
How can I get the onDelete event to take priority? From what I know about event bubbling, it seems like the Chip should handle the event first.
Code Sandbox Demo
Code:
const MultipleSelectDemo = () => {
const [personName, setPersonName] = React.useState<string[]>(initialSelected);
const handleChange = (event: React.ChangeEvent<{ value: unknown }>) => {
setPersonName(event.target.value as string[]);
};
// this never gets called
const handleDelete = (e: React.MouseEvent, value: string) => {
e.preventDefault();
console.log("clicked delete");
setPersonName((current) => _without(current, value));
};
return (
<div>
<FormControl>
<InputLabel id="demo-mutiple-chip-checkbox-label">
Chip + Check
</InputLabel>
<Select
labelId="demo-mutiple-chip-checkbox-label"
id="demo-mutiple-chip-checkbox"
multiple
value={personName}
onChange={handleChange}
onOpen={() => console.log("select opened")}
IconComponent={KeyboardArrowDownIcon}
renderValue={(selected) => (
<div>
{(selected as string[]).map((value) => (
<Chip
key={value}
label={value}
clickable
className={classes.chip}
onDelete={(e) => handleDelete(e, value)}
onClick={() => console.log("clicked chip")}
/>
))}
</div>
)}
>
{names.map((name) => (
<MenuItem key={name} value={name}>
<Checkbox checked={personName.includes(name)} />
<ListItemText primary={name} />
</MenuItem>
))}
</Select>
</FormControl>
</div>
);
}
The opening of the Select is triggered by the mouse-down event -- not the click event.
You can get your desired behavior by stopping propagation of the mouse-down event when it occurs on the delete icon of the Chip:
<Chip
key={value}
label={value}
clickable
deleteIcon={
<CancelIcon
onMouseDown={(event) => event.stopPropagation()}
/>
}
className={classes.chip}
onDelete={(e) => handleDelete(e, value)}
onClick={() => console.log("clicked chip")}
/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With