我正在尝试创建一个具有禁用按钮和工具提示的 Material UI
ButtonGroup
。
以下代码块正确显示按钮,但如此处所述 (https://material-ui.com/components/tooltips/#disabled-elements) 禁用的元素无法提供工具提示。
<ButtonGroup>
<Tooltip title={"This is button A"}>
<Button>{"Button A"}</Button>
</Tooltip>
<Tooltip title={"This is button B"}>
<Button disabled>{"Button B"}</Button>
</Tooltip>
</ButtonGroup>
但是如果我在禁用按钮周围添加
span
,则组布局将被破坏。
<ButtonGroup>
<Tooltip title={"This is button A"}>
<Button>{"Button A"}</Button>
</Tooltip>
<Tooltip title={"This is button B"}>
<span>
<Button disabled>{"Button B"}</Button>
</span>
</Tooltip>
</ButtonGroup>
是的,这是可能的。您需要将按钮包装在
<span>
标签中:
<Tooltip title={YOUR_MESSAGE_HERE}>
<span>
<Button disabled>my button is disabled</Button>
</span>
</Tooltip>
禁用按钮有两个方面会妨碍工具提示行为:
<button>
元素(独立于 Material-UI)不会以支持工具提示正确行为的方式触发事件。ButtonBase
组件(由
Button
利用)中的指针事件。
第二个问题可以通过覆盖 Material-UI 的禁用样式以允许指针事件来解决:
import MuiButton from "@material-ui/core/Button";
import { withStyles } from "@material-ui/core/styles";
const Button = withStyles({
root: {
"&.Mui-disabled": {
pointerEvents: "auto"
}
}
})(MuiButton);
第一个问题可以通过使用 Button 的
component
属性来使用 <div>
元素而不是 <button>
元素来解决。禁用的按钮元素不会接收单击事件,因此为了让按钮仍然以禁用的方式运行,此代码在禁用时删除 onClick
属性。
const ButtonWithTooltip = ({ tooltipText, disabled, onClick, ...other }) => {
const adjustedButtonProps = {
disabled: disabled,
component: disabled ? "div" : undefined,
onClick: disabled ? undefined : onClick
};
return (
<Tooltip title={tooltipText}>
<Button {...other} {...adjustedButtonProps} />
</Tooltip>
);
};
下面是按钮 B 和 C 均禁用的工作演示。按钮 A 和 B 使用上述方法,按钮 C 是一个常规的 Material-UI 按钮,没有用于比较的工具提示。它们下方的附加按钮可切换 B 和 C 的禁用状态。
import React from "react";
import Tooltip from "@material-ui/core/Tooltip";
import MuiButton from "@material-ui/core/Button";
import { withStyles } from "@material-ui/core/styles";
import ButtonGroup from "@material-ui/core/ButtonGroup";
const Button = withStyles({
root: {
"&.Mui-disabled": {
pointerEvents: "auto"
}
}
})(MuiButton);
const ButtonWithTooltip = ({ tooltipText, disabled, onClick, ...other }) => {
const adjustedButtonProps = {
disabled: disabled,
component: disabled ? "div" : undefined,
onClick: disabled ? undefined : onClick
};
return (
<Tooltip title={tooltipText}>
<Button {...other} {...adjustedButtonProps} />
</Tooltip>
);
};
export default function App() {
const [bAndCDisabled, setBAndCDisabled] = React.useState(true);
return (
<>
<ButtonGroup>
<ButtonWithTooltip
tooltipText="This is Button A"
onClick={() => console.log("A")}
>
{"Button A"}
</ButtonWithTooltip>
<ButtonWithTooltip
tooltipText="This is Button B"
onClick={() => console.log("B")}
disabled={bAndCDisabled}
>
{"Button B"}
</ButtonWithTooltip>
<MuiButton onClick={() => console.log("C")} disabled={bAndCDisabled}>
{"Button C"}
</MuiButton>
</ButtonGroup>
<br />
<br />
<MuiButton
variant="contained"
onClick={() => setBAndCDisabled(!bAndCDisabled)}
>
Toggle disabled for B and C
</MuiButton>
</>
);
}
在按钮周围添加 div/span 有时会扰乱按钮样式。所以我们最好使用
<>
或 <React.Fragment>
。但工具提示不适用于反应片段,因此我们可以使用问题中提到的 <span>
。但在这种情况下,由于此处使用了 ButtonGroup
,并且它通过克隆子按钮元素并传递样式属性来工作,因此在这种情况下,我们必须将样式属性发送到“按钮 B”。
import React from "react";
import "./styles.css";
import { Tooltip, Button } from "@material-ui/core";
import ButtonGroup from "@material-ui/core/ButtonGroup";
export default function App() {
const ButtonDemo = (props) => {
return (
<Tooltip title={"This is button B"}>
<span>
<Button {...props} disabled>
{"Button B"}
</Button>
</span>
</Tooltip>
);
};
return (
<ButtonGroup>
<Tooltip title={"This is button A"}>
<Button>{"Button A"}</Button>
</Tooltip>
<ButtonDemo />
</ButtonGroup>
);
}
对于 MUI 5.11 及更高版本,您需要将按钮包裹在 span 标签中。
<Tooltip title="tooltip text">
<span>
<Button disabled>Disabled Button</Button>
</span>
</Tooltip>
将此用于 mui > v5
<Tooltip title={YOUR_MESSAGE_HERE}>
<Button disabled>
<span>
my button is disabled
</span>
</Button>
</Tooltip>