import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from "react";
import clsx from "clsx";
import { getAction, executeAction } from "@/platform/actions";
import { shortcutLabel } from "@/platform/keymap";
import { Icon, type IconName } from "./icons";
import { tooltipAttrs } from "./Tooltip";
import styles from "./Button.module.css";
import { useTx } from "@/platform/i18n";
export interface ButtonProps extends ButtonHTMLAttributes {
variant?: "primary" | "secondary" | "ghost";
size?: "normal" | "small";
icon?: IconName | (string & {});
children?: ReactNode;
}
export const Button = forwardRef(function Button(
{ variant = "secondary", size = "normal", icon, className, children, type = "button", title, ...rest },
ref,
) {
const tx = useTx();
return (
);
});
export interface IconButtonProps extends Omit, "title"> {
icon: IconName | (string & {});
/** Accessible label and tooltip text. Defaults to the action's title. */
title?: string;
/** Run this action on click; supplies title + shortcut. */
action?: string;
actionArg?: unknown;
/** Explicit shortcut label shown in the tooltip (defaults to the action's binding). */
shortcut?: string;
/** Toggle state (renders `aria-pressed`). */
pressed?: boolean;
size?: "small" | "normal" | "large";
iconSize?: number;
tone?: "default" | "danger" | "accent";
}
export const IconButton = forwardRef(function IconButton(
{
icon,
title,
action,
actionArg,
shortcut,
pressed,
size = "normal",
iconSize,
tone = "default",
className,
onClick,
disabled,
type = "button",
"aria-label": ariaLabel,
...rest
},
ref,
) {
const tx = useTx();
const a = action ? getAction(action) : undefined;
const label = tx(title) ?? a?.title ?? action ?? icon;
const keys = shortcut ?? (action ? shortcutLabel(action) : undefined);
return (
);
});