/** * 画布等工具栏使用的图标按钮。统一按钮尺寸、图标与可访问名称,并按反馈Provider决定使用浮层提示还是原生title。 * 按钮的业务动作由onClick等原生属性传入;这里不维护工具选择状态。 */ "use client"; import { FeedbackContext } from "./app-feedback"; import * as Tooltip from "@radix-ui/react-tooltip"; import { useContext, forwardRef, type ButtonHTMLAttributes } from "react"; import type { LucideIcon } from "lucide-react"; import styles from "./icon-button.module.css"; /** icon提供Lucide图标实现,label提供默认可访问名称与提示;不接受任意children替换内部图标。 */ export type IconButtonProps = Omit, "children"> & { icon: LucideIcon; label: string; }; /** 将ref交给真实button;type默认为button,避免放进表单时意外提交。 * 调用方仍可传aria-pressed、disabled等状态,组件不会自行判断命令是否可用。 */ export const IconButton = forwardRef( function IconButton({ icon: Icon, label, title = label, className = "", type = "button", ...props }, ref) { // Provider存在时由Radix显示提示,移除原生title以免出现两层提示;图标自身对读屏隐藏。 const feedback = useContext(FeedbackContext); const button = ( ); // 没有全局提示环境就返回原生按钮;空title也不创建Tooltip。提示通过Portal避免被工具栏裁切。 if (!feedback || !title) return button; return {button} {title} ; }, );