106 lines
2.9 KiB
JavaScript
106 lines
2.9 KiB
JavaScript
import { Button, Tooltip } from 'antd'
|
||
import { QuestionCircleOutlined } from '@ant-design/icons'
|
||
import './ButtonWithTip.css'
|
||
|
||
/**
|
||
* 带有增强提示的按钮组件
|
||
* @param {Object} props
|
||
* @param {string} props.label - 按钮文本
|
||
* @param {ReactNode} props.icon - 按钮图标
|
||
* @param {string} props.type - 按钮类型
|
||
* @param {boolean} props.danger - 危险按钮
|
||
* @param {boolean} props.disabled - 禁用状态
|
||
* @param {Function} props.onClick - 点击回调
|
||
* @param {Object} props.tip - 提示配置
|
||
* @param {string} props.tip.title - 提示标题
|
||
* @param {string} props.tip.description - 详细描述
|
||
* @param {string} props.tip.shortcut - 快捷键提示
|
||
* @param {Array} props.tip.notes - 注意事项列表
|
||
* @param {string} props.tip.placement - 提示位置
|
||
* @param {boolean} props.showTipIcon - 是否显示提示图标
|
||
* @param {string} props.size - 按钮大小
|
||
*/
|
||
function ButtonWithTip({
|
||
label,
|
||
icon,
|
||
type = 'default',
|
||
danger = false,
|
||
disabled = false,
|
||
onClick,
|
||
tip,
|
||
showTipIcon = true,
|
||
size = 'middle',
|
||
...restProps
|
||
}) {
|
||
// 如果没有提示配置,直接返回普通按钮
|
||
if (!tip) {
|
||
return (
|
||
<Button
|
||
type={type}
|
||
icon={icon}
|
||
danger={danger}
|
||
disabled={disabled}
|
||
onClick={onClick}
|
||
size={size}
|
||
{...restProps}
|
||
>
|
||
{label}
|
||
</Button>
|
||
)
|
||
}
|
||
|
||
// 构建提示内容
|
||
const tooltipContent = (
|
||
<div className="button-tip-content">
|
||
{tip.title && <div className="button-tip-title">{tip.title}</div>}
|
||
{tip.description && <div className="button-tip-description">{tip.description}</div>}
|
||
{tip.shortcut && (
|
||
<div className="button-tip-shortcut">
|
||
<span className="tip-label">快捷键:</span>
|
||
<kbd className="tip-kbd">{tip.shortcut}</kbd>
|
||
</div>
|
||
)}
|
||
{tip.notes && tip.notes.length > 0 && (
|
||
<div className="button-tip-notes">
|
||
<div className="tip-notes-title">注意事项:</div>
|
||
<ul className="tip-notes-list">
|
||
{tip.notes.map((note, index) => (
|
||
<li key={index}>{note}</li>
|
||
))}
|
||
</ul>
|
||
</div>
|
||
)}
|
||
</div>
|
||
)
|
||
|
||
return (
|
||
<Tooltip
|
||
title={tooltipContent}
|
||
placement={tip.placement || 'top'}
|
||
classNames={{ root: 'button-tip-overlay' }}
|
||
mouseEnterDelay={0.3}
|
||
arrow={{ pointAtCenter: true }}
|
||
>
|
||
<div className="button-with-tip-wrapper">
|
||
<Button
|
||
type={type}
|
||
icon={icon}
|
||
danger={danger}
|
||
disabled={disabled}
|
||
onClick={onClick}
|
||
size={size}
|
||
className="button-with-tip"
|
||
{...restProps}
|
||
>
|
||
{label}
|
||
</Button>
|
||
{showTipIcon && !disabled && (
|
||
<QuestionCircleOutlined className="button-tip-indicator" />
|
||
)}
|
||
</div>
|
||
</Tooltip>
|
||
)
|
||
}
|
||
|
||
export default ButtonWithTip
|