2
2
3
3
import * as React from "react"
4
4
import { cva , type VariantProps } from "class-variance-authority"
5
+ import { Sparkles } from "lucide-react"
5
6
import { Slot } from "@radix-ui/react-slot"
6
7
7
8
import { cn } from "@/lib/utils/cn"
@@ -10,6 +11,26 @@ import { scrollIntoView } from "@/lib/utils/scrollIntoView"
10
11
11
12
import { BaseLink , type LinkProps } from "../Link"
12
13
14
+ const variants = {
15
+ variant : {
16
+ solid : cn (
17
+ "text-white bg-primary-action border-transparent" ,
18
+ "hover:!text-white hover:bg-primary-action-hover" , // Hover
19
+ "active:bg-primary-action-hover" , // Active
20
+ "disabled:bg-disabled disabled:text-background" // Disabled
21
+ ) ,
22
+ outline : "" , // Base styling
23
+ ghost : "border-transparent hover:shadow-none" ,
24
+ link : "border-transparent hover:shadow-none underline !min-h-0 !py-0 !px-1 active:text-primary" ,
25
+ glow : "group relative rounded-lg border-none p-px text-body [&_[data-label='inner']]:!rounded-[7px]" ,
26
+ } ,
27
+ size : {
28
+ lg : "text-lg py-3 px-8 [&>svg]:size-6 [&>svg]:text-2xl rounded-lg focus-visible:rounded-lg" ,
29
+ md : "min-h-10.5 px-4 py-2 [&>svg]:size-6 [&>svg]:text-2xl" ,
30
+ sm : "text-xs min-h-[31px] py-1.5 px-2 [&>svg]:size-4 [&>svg]:text-md" ,
31
+ } ,
32
+ }
33
+
13
34
const buttonVariants = cva (
14
35
cn (
15
36
// Sizing and positioning classes:
@@ -28,24 +49,7 @@ const buttonVariants = cva(
28
49
"[&[data-secondary='true']]:text-body"
29
50
) ,
30
51
{
31
- variants : {
32
- variant : {
33
- solid : cn (
34
- "text-white bg-primary-action border-transparent" ,
35
- "hover:!text-white hover:bg-primary-action-hover" , // Hover
36
- "active:bg-primary-action-hover" , // Active
37
- "disabled:bg-disabled disabled:text-background" // Disabled
38
- ) ,
39
- outline : "" , // Base styling
40
- ghost : "border-transparent hover:shadow-none" ,
41
- link : "border-transparent hover:shadow-none underline !min-h-0 !py-0 !px-1 active:text-primary" ,
42
- } ,
43
- size : {
44
- lg : "text-lg py-3 px-8 [&>svg]:text-2xl rounded-lg focus-visible:rounded-lg" ,
45
- md : "min-h-10.5 px-4 py-2 [&>svg]:text-2xl" ,
46
- sm : "text-xs min-h-[31px] py-1.5 px-2 [&>svg]:text-md" ,
47
- } ,
48
- } ,
52
+ variants,
49
53
defaultVariants : {
50
54
variant : "solid" ,
51
55
size : "md" ,
@@ -110,6 +114,30 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
110
114
111
115
onClick ?.( e )
112
116
}
117
+ if ( variant === "glow" ) {
118
+ const { children, ...buttonProps } = props
119
+ return (
120
+ < button
121
+ className = { cn ( variants . variant . glow , className ) }
122
+ { ...buttonProps }
123
+ >
124
+ { /* Glow */ }
125
+ < div className = "absolute inset-0 overflow-hidden rounded-[inherit] opacity-50 blur-md transition-transform duration-300 after:absolute after:-inset-[200%] after:bg-rainbow-gradient group-hover:scale-110 group-hover:transition-transform group-hover:duration-300 after:motion-safe:animate-spin-4" />
126
+ { /* Border */ }
127
+ < div className = "absolute inset-0 overflow-hidden rounded-[inherit] after:absolute after:-inset-[200%] after:bg-rainbow-gradient after:motion-safe:animate-spin-4" />
128
+ < div
129
+ data-label = "inner"
130
+ className = { cn (
131
+ variants . size [ size || "md" ] ,
132
+ "relative z-[1] inline-flex gap-2 bg-background/90 px-6 pb-2 pt-3 font-semibold shadow-inner ring-[1px] ring-white/25 backdrop-blur-lg"
133
+ ) }
134
+ >
135
+ { children }
136
+ < Sparkles className = "rotate//-12 mb-1 transition-transform group-hover:animate-wave group-hover:transition-transform" />
137
+ </ div >
138
+ </ button >
139
+ )
140
+ }
113
141
114
142
const Comp = asChild ? Slot : "button"
115
143
return (
0 commit comments