I am trying to add an edit button (which currently triggers an alert) to my react-select component. However, this makes the newly added button unclickable; instead, it opens the react-select menu. Stopping propagation does not solve the issue.
const CustomOption = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This is working like I want");
};
return (
<components.Option {...props}>
<div className="test">
<span>{props.children}</span>
<button onClick={handleEdit}>Edit</button>
</div>
</components.Option>
);
};
export default function App() {
const option = [
{ value: "Spring", label: "Spring" },
{ value: "Summer", label: "Summer" },
{ value: "Autumn", label: "Autumn" },
{ value: "Winter", label: "Winter" },
];
return (
<div className="App">
<Select
className="dropdown"
options={option}
components={{ SingleValue: CustomSingleValue }}
/>
</div>
);
}
Question: Why doesn't the button inside CustomSingleValue work (while the one inside CustomOption does), and how can I fix it?
This is especially frustrating because CustomOption, which uses the exact same code, works fine.
Full code including working CustomOption:
// This isn't working like I want
const CustomSingleValue = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This I can't click");
};
return (
<components.SingleValue {...props}>
<div className="test">
<span>{props.children}</span>
<div>
<button onClick={handleEdit}>Edit</button>
</div>
</div>
</components.SingleValue>
);
};
// This is working how I want
const CustomOption = (props) => {
const handleEdit = (e) => {
e.stopPropagation();
alert("This is working like I want");
};
return (
<components.Option {...props}>
<div className="test">
<span>{props.children}</span>
<button onClick={handleEdit}>Edit</button>
</div>
</components.Option>
);
};
export default function App() {
const option = [
{ value: "Spring", label: "Spring" },
{ value: "Summer", label: "Summer" },
{ value: "Autumn", label: "Autumn" },
{ value: "Winter", label: "Winter" },
];
return (
<div className="App">
<Select
className="dropdown"
options={option}
placeholder="Click on a option and then try to click the edit button"
components={{ SingleValue: CustomSingleValue, Option: CustomOption }}
/>
</div>
);
}
Issue number one: you have a react-select input overlayed your component, hence you click it instead of your single value component:
To address that, you need to add z-index
:
const singleValueStyles = {
singleValue: (styles) => ({ ...styles, "z-index": 2 }),
};
...
<Select
className="dropdown"
options={option}
styles={singleValueStyles} // 👈
...
After that, the button works well, however, we still get the dropdown opened. That's because react-select uses onMouseDown
rather that onClick
. The easiest way to fix it is to use onMouseDown
too:
<button onMouseDown={handleEdit}>Edit</button>
If you want to keep onClick
, just add another handler for onMouseDown
that only stops propagation.