Skip to content
File

Blob: src/client/components/ui/button.tsx

typescript40 lines
1import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from "react";
2import { Loader2 } from "lucide-react";
3 
4import {
5 BUTTON_BASE_CLASSES,
6 BUTTON_SIZE_CLASSES,
7 BUTTON_VARIANT_CLASSES,
8 type ButtonSize,
9 type ButtonVariant,
10} from "@/client/components/ui/button-classes";
11 
12export type { ButtonSize, ButtonVariant };
13 
14type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement> & {
15 variant?: ButtonVariant;
16 size?: ButtonSize;
17 loading?: boolean;
18 leftIcon?: ReactNode;
19 rightIcon?: ReactNode;
20};
21 
22export const Button = forwardRef<HTMLButtonElement, ButtonProps>(function Button(
23 { variant = "secondary", size = "md", loading, leftIcon, rightIcon, className = "", children, disabled, ...rest },
24 ref,
25) {
26 return (
27 <button
28 ref={ref}
29 disabled={disabled || loading}
30 aria-busy={loading || undefined}
31 className={`${BUTTON_BASE_CLASSES} ${BUTTON_VARIANT_CLASSES[variant]} ${BUTTON_SIZE_CLASSES[size]} ${className}`}
32 {...rest}
33 >
34 {loading ? <Loader2 className="h-3.5 w-3.5 animate-spin" strokeWidth={2.25} aria-hidden="true" /> : leftIcon}
35 {children}
36 {!loading && rightIcon}
37 </button>
38 );
39});