nex_design/src/components/ButtonWithGuideBadge/ButtonWithGuideBadge.jsx

223 lines
6.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { useState } from 'react'
import { Button, Badge, Modal, Steps, Tag, Divider } from 'antd'
import {
QuestionCircleOutlined,
BulbOutlined,
WarningOutlined,
CheckCircleOutlined,
InfoCircleOutlined,
} from '@ant-design/icons'
import './ButtonWithGuideBadge.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.guide - 引导配置
* @param {boolean} props.showBadge - 是否显示徽章
* @param {string} props.badgeType - 徽章类型new, help, warn
* @param {string} props.size - 按钮大小
*/
function ButtonWithGuideBadge({
label,
icon,
type = 'default',
danger = false,
disabled = false,
onClick,
guide,
showBadge = true,
badgeType = 'help',
size = 'middle',
...restProps
}) {
const [showGuideModal, setShowGuideModal] = useState(false)
const handleBadgeClick = (e) => {
e.stopPropagation()
if (guide) {
setShowGuideModal(true)
}
}
const getBadgeConfig = () => {
const configs = {
new: {
text: 'NEW',
color: '#52c41a',
icon: <InfoCircleOutlined />,
},
help: {
text: '?',
color: '#1677ff',
icon: <QuestionCircleOutlined />,
},
warn: {
text: '!',
color: '#faad14',
icon: <WarningOutlined />,
},
}
return configs[badgeType] || configs.help
}
const badgeConfig = getBadgeConfig()
return (
<>
<div className="button-guide-badge-wrapper">
{showBadge && guide && !disabled ? (
<Badge
count={
<div
className={`guide-badge guide-badge-${badgeType}`}
onClick={handleBadgeClick}
>
{badgeConfig.icon}
</div>
}
offset={[-5, 5]}
>
<Button
type={type}
icon={icon}
danger={danger}
disabled={disabled}
onClick={onClick}
size={size}
{...restProps}
>
{label}
</Button>
</Badge>
) : (
<Button
type={type}
icon={icon}
danger={danger}
disabled={disabled}
onClick={onClick}
size={size}
{...restProps}
>
{label}
</Button>
)}
</div>
{/* 引导弹窗 */}
{guide && (
<Modal
title={
<div className="guide-modal-header">
<span className="guide-modal-icon">{guide.icon || icon}</span>
<span className="guide-modal-title">{guide.title}</span>
{guide.badge && (
<Tag color={guide.badge.color} className="guide-modal-badge">
{guide.badge.text}
</Tag>
)}
</div>
}
open={showGuideModal}
onCancel={() => setShowGuideModal(false)}
footer={[
<Button key="close" type="primary" onClick={() => setShowGuideModal(false)}>
知道了
</Button>,
]}
width={600}
className="button-guide-modal"
>
{/* 功能描述 */}
{guide.description && (
<div className="guide-section">
<div className="guide-section-title">
<InfoCircleOutlined className="guide-section-icon" />
功能说明
</div>
<p className="guide-section-content">{guide.description}</p>
</div>
)}
{/* 使用步骤 */}
{guide.steps && guide.steps.length > 0 && (
<div className="guide-section">
<div className="guide-section-title">
<CheckCircleOutlined className="guide-section-icon" />
操作步骤
</div>
<Steps
direction="vertical"
current={-1}
items={guide.steps.map((step, index) => ({
title: `步骤 ${index + 1}`,
description: step,
status: 'wait',
}))}
className="guide-steps"
/>
</div>
)}
{/* 使用场景 */}
{guide.scenarios && guide.scenarios.length > 0 && (
<div className="guide-section">
<div className="guide-section-title">
<BulbOutlined className="guide-section-icon" />
适用场景
</div>
<ul className="guide-list">
{guide.scenarios.map((scenario, index) => (
<li key={index}>{scenario}</li>
))}
</ul>
</div>
)}
{/* 注意事项 */}
{guide.warnings && guide.warnings.length > 0 && (
<div className="guide-section guide-section-warning">
<div className="guide-section-title">
<WarningOutlined className="guide-section-icon" />
注意事项
</div>
<ul className="guide-list">
{guide.warnings.map((warning, index) => (
<li key={index}>{warning}</li>
))}
</ul>
</div>
)}
{/* 快捷键和权限 */}
{(guide.shortcut || guide.permission) && (
<div className="guide-footer">
{guide.shortcut && (
<div className="guide-footer-item">
<span className="guide-footer-label">快捷键</span>
<kbd className="guide-footer-kbd">{guide.shortcut}</kbd>
</div>
)}
{guide.permission && (
<div className="guide-footer-item">
<span className="guide-footer-label">权限要求</span>
<Tag color="blue">{guide.permission}</Tag>
</div>
)}
</div>
)}
</Modal>
)}
</>
)
}
export default ButtonWithGuideBadge