Material UI 多个 Select 中的可删除筹码

Deletable Chips in Material UI Multiple Select

Material UI 文档包含一个 multiple select 示例,其中通过使用 renderValue 属性使用 Chip 组件呈现所选选项在 Select 上。 Select 组件的标准行为是单击当前值打开选项列表。

我正在尝试对此进行调整,以便 Chip 显示 X 按钮,单击 X 应该会立即从选择中删除该项目,而不是打开选项列表。

这看起来很简单,但我无法触发 ChiponDelete 事件。单击 X 仍然只是打开 Select

如何让 onDelete 事件优先?根据我对事件冒泡的了解,似乎 Chip 应该 首先处理事件。

Code Sandbox Demo

代码:

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>
  );
}

Select 的打开是由 mouse-down event 触发的 -- 而不是点击事件。

您可以通过在 Chip 的删除图标上发生 mouse-down 事件的传播来获得您想要的行为:

                  <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")}
                  />