feat: Add button loading states

This commit is contained in:
gpt-engineer-app[bot]
2025-11-04 18:11:31 +00:00
parent 2deab69ebe
commit 6b5be8a70b
11 changed files with 98 additions and 23 deletions

View File

@@ -1,6 +1,7 @@
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { Loader2 } from "lucide-react";
import { cn } from "@/lib/utils";
import { breadcrumb } from "@/lib/errorBreadcrumbs";
@@ -36,13 +37,33 @@ export interface ButtonProps
VariantProps<typeof buttonVariants> {
asChild?: boolean;
trackingLabel?: string; // Optional label for breadcrumb tracking
loading?: boolean; // Show loading state with spinner
loadingText?: string; // Optional text to display during loading
}
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
({ className, variant, size, asChild = false, onClick, trackingLabel, ...props }, ref) => {
({
className,
variant,
size,
asChild = false,
onClick,
trackingLabel,
loading = false,
loadingText,
children,
disabled,
...props
}, ref) => {
const Comp = asChild ? Slot : "button";
const handleClick = (e: React.MouseEvent<HTMLButtonElement>) => {
// Prevent clicks while loading
if (loading) {
e.preventDefault();
return;
}
// Add breadcrumb for button click
if (trackingLabel) {
breadcrumb.userAction('clicked', trackingLabel);
@@ -57,8 +78,18 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
className={cn(buttonVariants({ variant, size, className }))}
ref={ref}
onClick={handleClick}
{...props}
/>
disabled={disabled || loading}
{...props}
>
{loading ? (
<>
<Loader2 className="mr-2 h-4 w-4 animate-spin" />
{loadingText || children}
</>
) : (
children
)}
</Comp>
);
},
);