1- ' use client'
1+ " use client" ;
22
3- import { cn } from ' clsx-for-tailwind'
4- import React , { useCallback , useState } from ' react'
3+ import { cn } from " clsx-for-tailwind" ;
4+ import React , { useCallback , useState } from " react" ;
55
6- type ButtonVariant = 'primary' | 'destructive' | 'outline' | 'ghost'
7- type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'icon-xs' | 'icon-sm' | 'icon-md' | 'icon-lg'
6+ type ButtonVariant = "primary" | "destructive" | "outline" | "ghost" ;
7+ type ButtonSize =
8+ | "xs"
9+ | "sm"
10+ | "md"
11+ | "lg"
12+ | "icon-xs"
13+ | "icon-sm"
14+ | "icon-md"
15+ | "icon-lg" ;
816
917interface GradientButtonProps
1018 extends React . ButtonHTMLAttributes < HTMLButtonElement > {
11- children : React . ReactNode
12- variant ?: ButtonVariant
13- size ?: ButtonSize
14- className ?: string
15- nativeButton ?: boolean
19+ children : React . ReactNode ;
20+ variant ?: ButtonVariant ;
21+ size ?: ButtonSize ;
22+ className ?: string ;
23+ nativeButton ?: boolean ;
1624}
1725
1826const BASE_CLASSES =
19- 'relative inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:border disabled:border-m-slate-4/80 disabled:bg-m-slate-3 disabled:text-m-slate-8 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0 cursor-pointer box-border font-[525] overflow-hidden'
27+ 'relative inline-flex items-center justify-center whitespace-nowrap transition-colors disabled:cursor-not-allowed disabled:border disabled:border-m-slate-4/80 disabled:bg-m-slate-3 disabled:text-m-slate-8 [&_svg]:pointer-events-none [&_svg:not([class*="size-"])]:size-4 shrink-0 [&_svg]:shrink-0 cursor-pointer box-border font-[525] overflow-hidden' ;
2028
2129const VARIANT_CLASSES : Record < ButtonVariant , string > = {
2230 primary :
23- ' bg-primary-9 text-primary-2 dark:text-primary-contrast hover:bg-primary-10 shadow-[0_0_1px_var(--primary-9,#6E56CF)_inset,0_2px_0_0_rgba(255,255,255,0.22)_inset]' ,
24- destructive : ' bg-destructive-9 hover:bg-destructive-10 text-primary-contrast' ,
31+ " bg-primary-9 text-primary-2 dark:text-primary-contrast hover:bg-primary-10 shadow-[0_0_1px_var(--primary-9,#6E56CF)_inset,0_2px_0_0_rgba(255,255,255,0.22)_inset]" ,
32+ destructive : " bg-destructive-9 hover:bg-destructive-10 text-primary-contrast" ,
2533 outline :
26- 'shadow-[0_-1px_0_0_rgba(0,0,0,0.08)_inset,0_0_0_1px_rgba(0,0,0,0.08)_inset,0_1px_2px_0_rgba(0,0,0,0.02),0_1px_4px_0_rgba(0,0,0,0.02)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.16)_inset] bg-white dark:bg-m-slate-10 hover:bg-m-slate-2 dark:hover:bg-m-slate-9 text-m-slate-12 dark:text-m-slate-3' ,
27- ghost : 'text-m-slate-12 dark:text-m-slate-3 hover:text-primary-10 dark:hover:text-primary-9' ,
28- }
34+ "shadow-[0_-1px_0_0_rgba(0,0,0,0.08)_inset,0_0_0_1px_rgba(0,0,0,0.08)_inset,0_1px_2px_0_rgba(0,0,0,0.02),0_1px_4px_0_rgba(0,0,0,0.02)] dark:shadow-[0_1px_0_0_rgba(255,255,255,0.16)_inset] bg-white dark:bg-m-slate-10 hover:bg-m-slate-2 dark:hover:bg-m-slate-9 text-m-slate-12 dark:text-m-slate-3" ,
35+ ghost :
36+ "text-m-slate-12 dark:text-m-slate-3 hover:text-primary-10 dark:hover:text-primary-9" ,
37+ } ;
2938
3039const SIZE_CLASSES : Record < ButtonSize , string > = {
31- xs : ' px-1.5 h-7 rounded-lg gap-1.5 text-sm' ,
32- sm : ' px-2 h-8 rounded-lg gap-2 text-sm' ,
33- md : ' px-2.5 h-9 rounded-[0.625rem] gap-2 text-sm' ,
34- lg : ' px-3 h-10 rounded-[0.625rem] gap-2.5 text-base' ,
35- ' icon-xs' : ' size-7 rounded-lg' ,
36- ' icon-sm' : ' size-8 rounded-lg' ,
37- ' icon-md' : ' size-9 rounded-[0.625rem]' ,
38- ' icon-lg' : ' size-10 rounded-[0.625rem]' ,
39- }
40+ xs : " px-1.5 h-7 rounded-lg gap-1.5 text-sm" ,
41+ sm : " px-2 h-8 rounded-lg gap-2 text-sm" ,
42+ md : " px-2.5 h-9 rounded-[0.625rem] gap-2 text-sm" ,
43+ lg : " px-3 h-10 rounded-[0.625rem] gap-2.5 text-base" ,
44+ " icon-xs" : " size-7 rounded-lg" ,
45+ " icon-sm" : " size-8 rounded-lg" ,
46+ " icon-md" : " size-9 rounded-[0.625rem]" ,
47+ " icon-lg" : " size-10 rounded-[0.625rem]" ,
48+ } ;
4049
4150export function GradientButton ( {
4251 children,
43- variant = ' primary' ,
44- size = 'md' ,
52+ variant = " primary" ,
53+ size = "md" ,
4554 className,
4655 nativeButton = true ,
4756 ...props
4857} : GradientButtonProps ) {
49- const [ isMouseOver , setIsMouseOver ] = useState ( false )
50- const [ x , setX ] = useState ( 0 )
51- const [ y , setY ] = useState ( 0 )
58+ const [ isMouseOver , setIsMouseOver ] = useState ( false ) ;
59+ const [ x , setX ] = useState ( 0 ) ;
60+ const [ y , setY ] = useState ( 0 ) ;
5261
5362 const handleMouseMove = useCallback <
5463 React . MouseEventHandler < HTMLButtonElement >
5564 > ( ( e ) => {
56- const button = e . currentTarget
57- const rect = button . getBoundingClientRect ( )
58- setX ( e . clientX - rect . left )
59- setY ( e . clientY - rect . top )
60- } , [ ] )
65+ const button = e . currentTarget ;
66+ const rect = button . getBoundingClientRect ( ) ;
67+ setX ( e . clientX - rect . left ) ;
68+ setY ( e . clientY - rect . top ) ;
69+ } , [ ] ) ;
6170
6271 const handleMouseEnter = useCallback ( ( ) => {
63- setIsMouseOver ( true )
64- } , [ ] )
72+ setIsMouseOver ( true ) ;
73+ } , [ ] ) ;
6574
6675 const handleMouseLeave = useCallback ( ( ) => {
67- setIsMouseOver ( false )
68- } , [ ] )
76+ setIsMouseOver ( false ) ;
77+ } , [ ] ) ;
6978
70- const Component = nativeButton ? ' button' : ' div'
79+ const Component = nativeButton ? " button" : " div" ;
7180
7281 return (
7382 < Component
@@ -79,34 +88,36 @@ export function GradientButton({
7988 BASE_CLASSES ,
8089 VARIANT_CLASSES [ variant ] ,
8190 SIZE_CLASSES [ size ] ,
82- className
91+ className ,
8392 ) }
8493 >
85- { variant === ' primary' ? (
94+ { variant === " primary" ? (
8695 < >
8796 < span
8897 className = "block absolute rounded-full pointer-events-none"
8998 style = { {
90- width : ' 2.75rem' ,
91- height : ' 2.75rem' ,
99+ width : " 2.75rem" ,
100+ height : " 2.75rem" ,
92101 left : x ,
93102 top : y ,
94- transform : ' translate(-50%, -50%) translateZ(0)' ,
95- background : ' #EB8E90' ,
96- mixBlendMode : ' plus-lighter' ,
97- filter : ' blur(28px)' ,
103+ transform : " translate(-50%, -50%) translateZ(0)" ,
104+ background : " #EB8E90" ,
105+ mixBlendMode : " plus-lighter" ,
106+ filter : " blur(28px)" ,
98107 opacity : isMouseOver ? 1 : 0 ,
99- transition : ' opacity 0.3s ease' ,
100- willChange : ' transform, opacity' ,
108+ transition : " opacity 0.3s ease" ,
109+ willChange : " transform, opacity" ,
101110 } }
102111 />
103- < span className = "inline-flex z-10 relative items-center gap-[inherit]" > { children } </ span >
112+ < span className = "inline-flex z-10 relative items-center gap-[inherit]" >
113+ { children }
114+ </ span >
104115 </ >
105116 ) : (
106117 children
107118 ) }
108119 </ Component >
109- )
120+ ) ;
110121}
111122
112- export default GradientButton
123+ export default GradientButton ;
0 commit comments