import * as React from "react" import { Slot } from "@radix-ui/react-slot" import { cva, type VariantProps } from "class-variance-authority" import { VTooltip } from "@vertesia/ui/core" import { cn } from "../libs/utils" import { Check, CopyIcon, Loader2 } from "lucide-react" import clsx from "clsx" import { useState } from "react" import { i18nInstance, NAMESPACE } from '../../../i18n/instance.js' const buttonVariants = cva( "hover:cursor-pointer inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0", { variants: { variant: { destructive: "bg-destructive dark:bg-destructive/10 text-destructive ring-1 ring-inset ring-destructive-muted/50 dark:ring-destructive-muted/50 shadow-xs hover:bg-destructive/50", outline: "border border-input bg-background shadow-xs hover:bg-muted ring-inset", secondary: "bg-primary/5 dark:bg-primary/10 text-primary shadow-xs hover:bg-primary/10 dark:hover:bg-primary/20 ring-inset", ghost: "hover:bg-muted/50 dark:hover:bg-muted/20 ring-inset", link: "text-foreground underline-offset-4 hover:underline ring-inset", primary: "bg-primary text-white shadow-xs hover:bg-primary/90 ring-inset", unstyled: "" }, size: { xs: 'h-7 rounded px-2 py-1 text-xs gap-x-1', sm: "h-8 rounded px-3 text-xs", md: "h-9 rounded-md px-4 py-2", lg: "h-10 rounded-md px-3", xl: 'rounded-md px-3.5 py-2.5 text-sm gap-x-2', icon: "p-0 m-0 rounded-full", }, }, defaultVariants: { variant: "primary", size: "md", }, } ) export interface ButtonProps extends React.ButtonHTMLAttributes, VariantProps { asChild?: boolean alt?: string title?: string isDisabled?: boolean isLoading?: boolean } const Button = React.forwardRef( ({ className, variant, size, asChild = false, alt, isDisabled, isLoading, title, onClick, type, ...props }, ref) => { const Comp = asChild ? Slot : "button" const buttonElement = ( {isLoading && } {props.children} ) if (alt || title) { return ( {buttonElement} ) } return buttonElement } ) Button.displayName = "Button" interface CopyButtonProps { content: string alt?: string size?: "xs" | "sm" | "md" | "lg" | "xl" | "icon" toast?: { toast: any, message: string } className?: string } const CopyButton = React.forwardRef( ({ size, content, toast, className, alt, ...props }, ref) => { const [isCopied, setIsCopied] = useState(false); const t = i18nInstance.getFixedT(null, NAMESPACE); const handleCopy = (e: React.MouseEvent) => { e.stopPropagation(); navigator.clipboard.writeText(content).then(() => { setIsCopied(true) setTimeout(() => setIsCopied(false), 2000) if (!toast || !toast.toast) { return } toast.toast({ status: "success", title: toast.message || t('misc.copiedToClipboard'), duration: 2000, }) }).catch((err) => { console.error("Failed to copy text: ", err) if (toast && toast.toast) toast.toast({ status: "error", title: t('misc.failedToCopy'), duration: 2000, }) }) } return ( ) } ) CopyButton.displayName = "CopyButton" export { Button, CopyButton, buttonVariants }