mirror of
https://github.com/Significant-Gravitas/AutoGPT.git
synced 2026-01-09 15:17:59 -05:00
feat(frontend): Loading indicator for button click handlers (#9573)
Show that something is happening when a click handler doesn't return immediately. ### Changes 🏗️ - Show a loading indicator on buttons while their click handler is running https://github.com/user-attachments/assets/5878c5a4-cba2-4125-a101-21220d713232 ### Checklist 📋 #### For code changes: - [x] I have clearly listed my changes in the PR description - [x] I have made a test plan - [x] I have tested my changes according to the test plan: - Go to `/library/agents/[id]`; click "Run again" on an existing run - [x] -> loading indicator should show - [x] -> button state should reset once the API request completes - [x] Check that existing `Button` elements aren't adversely affected by the styling changes, especially `overflow-hidden`
This commit is contained in:
committed by
GitHub
parent
c091a7be62
commit
595d2020c9
@@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import * as React from "react";
|
||||
import { Slot } from "@radix-ui/react-slot";
|
||||
import { cva, type VariantProps } from "class-variance-authority";
|
||||
@@ -5,7 +7,7 @@ import { cva, type VariantProps } from "class-variance-authority";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
const buttonVariants = cva(
|
||||
"inline-flex items-center whitespace-nowrap font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-neutral-950 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-neutral-300 font-neue leading-9 tracking-tight",
|
||||
"inline-flex items-center whitespace-nowrap overflow-hidden font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-neutral-950 disabled:pointer-events-none disabled:opacity-50 dark:focus-visible:ring-neutral-300 font-neue leading-9 tracking-tight",
|
||||
{
|
||||
variants: {
|
||||
variant: {
|
||||
@@ -55,14 +57,39 @@ export interface ButtonProps
|
||||
}
|
||||
|
||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||
({ className, variant, size, asChild = false, ...props }, ref) => {
|
||||
({ className, variant, size, asChild = false, onClick, ...props }, ref) => {
|
||||
const [isLoading, setIsLoading] = React.useState(false);
|
||||
const Comp = asChild ? Slot : "button";
|
||||
|
||||
const handleClick = async (e: React.MouseEvent<HTMLButtonElement>) => {
|
||||
if (!onClick) return;
|
||||
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const result: any = onClick(e);
|
||||
if (result instanceof Promise) {
|
||||
await result;
|
||||
}
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Comp
|
||||
className={cn(buttonVariants({ variant, size, className }))}
|
||||
className={cn("relative", buttonVariants({ variant, size, className }))}
|
||||
ref={ref}
|
||||
onClick={handleClick}
|
||||
disabled={props.disabled}
|
||||
{...props}
|
||||
/>
|
||||
>
|
||||
{props.children}
|
||||
{isLoading && (
|
||||
<div className="absolute inset-0 flex items-center justify-center bg-background/60">
|
||||
<div className="h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
||||
</div>
|
||||
)}
|
||||
</Comp>
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user