Spaces:
Build error
Build error
File size: 3,067 Bytes
75fefa7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 | "use client";
import React from "react";
import { cn } from "@/utils/cn";
import { LucideIcon } from "lucide-react";
interface SlateButtonProps
extends React.ButtonHTMLAttributes<HTMLButtonElement> {
icon?:
| LucideIcon
| React.ComponentType<{
className?: string;
isHovered?: boolean;
isOpen?: boolean;
}>
| React.ReactNode;
iconPosition?: "left" | "right";
children: React.ReactNode;
size?: "sm" | "md" | "lg";
fullWidth?: boolean;
isLoading?: boolean;
isOpen?: boolean;
}
export const SlateButton = React.forwardRef<
HTMLButtonElement,
SlateButtonProps
>(
(
{
icon: Icon,
iconPosition = "left",
children,
className,
size = "md",
fullWidth = false,
isLoading = false,
isOpen = false,
disabled,
...props
},
ref,
) => {
const [isHovered, setIsHovered] = React.useState(false);
const sizeClasses = {
sm: "h-32 px-12 text-body-small gap-6",
md: "h-40 px-16 text-body-medium gap-8",
lg: "h-48 px-24 text-body-large gap-10",
};
const iconSizes = {
sm: "w-14 h-14",
md: "w-16 h-16",
lg: "w-20 h-20",
};
return (
<button
ref={ref}
className={cn(
// Base styles
"inline-flex items-center justify-center rounded-12 transition-all",
// Colors
"bg-black-alpha-4 text-accent-black",
"hover:bg-black-alpha-6",
"active:scale-[0.98]",
// Border
// "border-0",
// Size
sizeClasses[size],
// States
disabled && "opacity-50 cursor-not-allowed",
isLoading && "cursor-wait",
// Full width
fullWidth && "w-full",
className,
)}
disabled={disabled || isLoading}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
{...props}
>
{isLoading ? (
<div className={cn("animate-spin rounded-full", iconSizes[size])} />
) : (
<>
{Icon &&
iconPosition === "left" &&
(React.isValidElement(Icon) ? (
Icon
) : (
//@ts-expect-error - Icon component type allows JSX element
<Icon
className={cn(iconSizes[size], "flex-shrink-0")}
isHovered={isHovered}
isOpen={isOpen}
/>
))}
{children}
{Icon &&
iconPosition === "right" &&
(React.isValidElement(Icon) ? (
Icon
) : (
//@ts-expect-error - Icon component type allows JSX element
<Icon
className={cn(iconSizes[size], "flex-shrink-0")}
isHovered={isHovered}
isOpen={isOpen}
/>
))}
</>
)}
</button>
);
},
);
SlateButton.displayName = "SlateButton";
|