mhsf-dev/src/components/ui/loading-button.tsx

67 lines
1.8 KiB
TypeScript
Raw Normal View History

2024-08-07 16:37:54 -05:00
import * as React from "react";
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
import { Loader2 } from "lucide-react";
import { Button, buttonVariants } from "./button";
2024-08-03 09:51:45 -05:00
export interface ButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
VariantProps<typeof buttonVariants> {
asChild?: boolean;
loading?: boolean;
}
const LoadingButton = React.forwardRef<HTMLButtonElement, ButtonProps>(
2024-08-07 16:37:54 -05:00
(
{ className, variant, size, asChild = false, loading, children, ...props },
ref
) => {
2024-08-03 09:51:45 -05:00
if (asChild) {
return (
<Slot ref={ref} {...props}>
<>
2024-08-07 16:37:54 -05:00
{React.Children.map(
children as React.ReactElement,
(child: React.ReactElement) => {
return React.cloneElement(child, {
className: cn(buttonVariants({ variant, size }), className),
children: (
<>
{loading && (
<Loader2
className={cn(
"h-4 w-4 animate-spin",
children && "mr-2"
)}
/>
)}
{child.props.children}
</>
),
});
}
)}
2024-08-03 09:51:45 -05:00
</>
</Slot>
);
}
return (
2024-08-07 16:37:54 -05:00
<Button disabled={loading} variant={variant} ref={ref} {...props}>
2024-08-03 09:51:45 -05:00
<>
2024-08-07 16:37:54 -05:00
{loading && (
<Loader2
className={cn("h-4 w-4 animate-spin", children && "mr-2")}
/>
)}
2024-08-03 09:51:45 -05:00
{children}
</>
2024-08-07 16:37:54 -05:00
</Button>
2024-08-03 09:51:45 -05:00
);
2024-08-07 16:37:54 -05:00
}
2024-08-03 09:51:45 -05:00
);
2024-08-07 16:37:54 -05:00
LoadingButton.displayName = "LoadingButton";
2024-08-03 09:51:45 -05:00
export { LoadingButton, buttonVariants };