feat(ui): extend design tokens, add dark mode, add UI primitives
- 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
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
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>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user