File size: 2,395 Bytes
bc4a7e8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"use client";

import { cn } from "@/shared/utils/cn";

const variants = {
  primary: "bg-gradient-to-b from-primary to-primary-hover text-white shadow-sm",
  secondary:
    "bg-white dark:bg-white/10 border border-black/10 dark:border-white/10 text-text-main hover:bg-black/5 dark:hover:bg-white/5",
  outline: "border border-black/15 dark:border-white/15 text-text-main hover:bg-black/5",
  ghost: "text-text-muted hover:bg-black/5 dark:hover:bg-white/5 hover:text-text-main",
  danger: "bg-red-500 text-white hover:bg-red-600 shadow-sm",
};

const sizes = {
  sm: "h-7 px-3 text-xs rounded-md",
  md: "h-9 px-4 text-sm rounded-lg",
  lg: "h-11 px-6 text-sm rounded-lg",
};

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  children?: React.ReactNode;
  variant?: keyof typeof variants;
  size?: keyof typeof sizes;
  icon?: string;
  iconRight?: string;
  loading?: boolean;
  fullWidth?: boolean;
  className?: string;
}

export default function Button({

  children,

  variant = "primary",

  size = "md",

  icon,

  iconRight,

  disabled = false,

  loading = false,

  fullWidth = false,

  className,

  ...props

}: ButtonProps) {
  return (
    <button

      type="button"

      className={cn(

        "inline-flex items-center justify-center gap-2 font-medium transition-all duration-200 cursor-pointer",

        "active:scale-[0.99] disabled:opacity-50 disabled:cursor-not-allowed disabled:active:scale-100",

        variants[variant],

        sizes[size],

        fullWidth && "w-full",

        className

      )}

      disabled={disabled || loading}

      aria-busy={loading || undefined}

      {...props}

    >

      {loading ? (

        <span

          className="material-symbols-outlined animate-spin text-[18px] pointer-events-none"

          aria-hidden="true"

        >

          progress_activity

        </span>

      ) : icon ? (

        <span

          className="material-symbols-outlined text-[18px] pointer-events-none"

          aria-hidden="true"

        >

          {icon}

        </span>

      ) : null}

      {children}

      {iconRight && !loading && (

        <span

          className="material-symbols-outlined text-[18px] pointer-events-none"

          aria-hidden="true"

        >

          {iconRight}

        </span>

      )}

    </button>
  );
}