- Add warning/success token roles across light and dark themes - Add Light/Dark/System theme mode (localStorage + Appwrite prefs) - Derive dark token stacks from existing theme seeds - Remove forced light app-shell background; dynamic color-scheme - Add Button/Card/Field/Badge/EmptyState primitives under src/components/ui
36 lines
975 B
TypeScript
36 lines
975 B
TypeScript
import { Loader2 } from "lucide-react";
|
|
import type { ButtonHTMLAttributes, ReactNode } from "react";
|
|
|
|
export type ButtonVariant = "primary" | "secondary" | "danger";
|
|
|
|
export type ButtonProps = {
|
|
variant?: ButtonVariant;
|
|
loading?: boolean;
|
|
icon?: ReactNode;
|
|
} & ButtonHTMLAttributes<HTMLButtonElement>;
|
|
|
|
const BUTTON_VARIANT_CLASSES: Record<ButtonVariant, string> = {
|
|
primary: "primary-button",
|
|
secondary: "secondary-button",
|
|
danger: "danger-button",
|
|
};
|
|
|
|
export function Button({
|
|
variant = "primary",
|
|
loading = false,
|
|
icon,
|
|
className,
|
|
children,
|
|
disabled,
|
|
type = "button",
|
|
...rest
|
|
}: ButtonProps) {
|
|
const classes = [BUTTON_VARIANT_CLASSES[variant], className].filter(Boolean).join(" ");
|
|
return (
|
|
<button className={classes} type={type} disabled={disabled || loading} aria-busy={loading || undefined} {...rest}>
|
|
{loading ? <Loader2 className="animate-spin" size={17} aria-hidden="true" /> : icon}
|
|
{children}
|
|
</button>
|
|
);
|
|
}
|