import type { ButtonHTMLAttributes, ReactNode } from "react"; import { cn } from "../../lib/cn"; import { Spinner } from "../feedback"; export type ButtonTone = "primary" | "secondary" | "ghost" | "destructive"; type ButtonSize = "compact" | "regular" | "large"; export type ButtonProps = ButtonHTMLAttributes & { iconOnly?: boolean; leadingIcon?: ReactNode; leadingContent?: ReactNode; loading?: boolean; loadingLabel?: string; size?: ButtonSize; trailingIcon?: ReactNode; trailingContent?: ReactNode; tone?: ButtonTone; }; const toneClasses: Record = { primary: "bg-[var(--uhuru-action-primary)] text-[var(--uhuru-text-inverse)] shadow-[var(--uhuru-shadow-sm)] hover:bg-[var(--uhuru-action-primary-hover)]", secondary: "border-[var(--uhuru-border-default)] bg-[var(--uhuru-surface-default)] text-[var(--uhuru-text-primary)] hover:border-[var(--uhuru-border-accent)] hover:bg-[var(--uhuru-surface-muted)]", ghost: "border-transparent bg-transparent text-[var(--uhuru-text-primary)] hover:border-[var(--uhuru-border-subtle)] hover:bg-[var(--uhuru-surface-muted)]", destructive: "border-[var(--uhuru-error-border)] bg-[var(--uhuru-error-text)] text-[var(--uhuru-text-inverse)] shadow-[var(--uhuru-shadow-sm)] hover:bg-[var(--uhuru-error-border)]", }; const sizeClasses: Record = { compact: "h-[calc(var(--uhuru-control-height)-0.5rem)] px-3 text-[0.8125rem]", regular: "h-[var(--uhuru-control-height)] px-[var(--uhuru-control-padding-x)] text-sm", large: "h-[calc(var(--uhuru-control-height)+0.5rem)] px-5 text-sm", }; export function Button({ className, children, iconOnly = false, leadingIcon, leadingContent, loading = false, loadingLabel = "Loading", size = "regular", tone = "primary", trailingIcon, trailingContent, type = "button", ...props }: ButtonProps) { const startAdornment = loading ? : leadingIcon ?? leadingContent; const endAdornment = !loading ? trailingIcon ?? trailingContent : null; return ( ); }