Modularized Loading on buttons
This commit is contained in:
parent
5b2791a2c4
commit
1f2cd32340
1 changed files with 26 additions and 9 deletions
|
|
@ -2,6 +2,7 @@ import { Slot } from "@radix-ui/react-slot";
|
||||||
import { cva, type VariantProps } from "class-variance-authority";
|
import { cva, type VariantProps } from "class-variance-authority";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import { cn } from "../../utils/utils";
|
import { cn } from "../../utils/utils";
|
||||||
|
import ForwardedIconComponent from "../genericIconComponent";
|
||||||
|
|
||||||
const buttonVariants = cva(
|
const buttonVariants = cva(
|
||||||
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
"inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:opacity-50 disabled:pointer-events-none ring-offset-background",
|
||||||
|
|
@ -32,13 +33,14 @@ const buttonVariants = cva(
|
||||||
variant: "default",
|
variant: "default",
|
||||||
size: "default",
|
size: "default",
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
export interface ButtonProps
|
export interface ButtonProps
|
||||||
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
extends React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||||
VariantProps<typeof buttonVariants> {
|
VariantProps<typeof buttonVariants> {
|
||||||
asChild?: boolean;
|
asChild?: boolean;
|
||||||
|
loading?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
function toTitleCase(text: string) {
|
function toTitleCase(text: string) {
|
||||||
|
|
@ -49,21 +51,36 @@ function toTitleCase(text: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
|
||||||
({ className, variant, size, asChild = false, children, ...props }, ref) => {
|
(
|
||||||
|
{ className, variant, size, loading, asChild = false, children, ...props },
|
||||||
|
ref,
|
||||||
|
) => {
|
||||||
const Comp = asChild ? Slot : "button";
|
const Comp = asChild ? Slot : "button";
|
||||||
let newChildren = children;
|
let newChildren = children;
|
||||||
if (typeof children === "string") {
|
if (typeof children === "string") {
|
||||||
newChildren = toTitleCase(children);
|
newChildren = toTitleCase(children);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<Comp
|
<Comp className={"relative"} ref={ref} {...props}>
|
||||||
className={cn(buttonVariants({ variant, size, className }))}
|
<div
|
||||||
ref={ref}
|
className={cn(
|
||||||
children={newChildren}
|
loading ? "opacity-100" : "opacity-0",
|
||||||
{...props}
|
"absolute self-center",
|
||||||
/>
|
)}
|
||||||
|
>
|
||||||
|
<ForwardedIconComponent name={"Loader2"} className={"animate-spin"} />
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cn(
|
||||||
|
loading ? "opacity-0" : "opacity-100",
|
||||||
|
buttonVariants({ variant, size, className }),
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{newChildren}
|
||||||
|
</div>
|
||||||
|
</Comp>
|
||||||
);
|
);
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
Button.displayName = "Button";
|
Button.displayName = "Button";
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue