-
Notifications
You must be signed in to change notification settings - Fork 3.6k
Expand file tree
/
Copy pathbranded-button.tsx
More file actions
102 lines (95 loc) · 3.16 KB
/
branded-button.tsx
File metadata and controls
102 lines (95 loc) · 3.16 KB
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
'use client'
import { forwardRef, useState } from 'react'
import { ArrowRight, ChevronRight, Loader2 } from 'lucide-react'
import { cn } from '@/lib/core/utils/cn'
import { useBrandConfig } from '@/ee/whitelabeling'
export interface BrandedButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
loading?: boolean
loadingText?: string
showArrow?: boolean
fullWidth?: boolean
}
/**
* Branded button for auth and status pages.
* Default: white button matching the landing page "Get started" style.
* Whitelabel: uses the brand's primary color as background with white text.
*/
export const BrandedButton = forwardRef<HTMLButtonElement, BrandedButtonProps>(
(
{
children,
loading = false,
loadingText,
showArrow = true,
fullWidth = true,
className,
disabled,
onMouseEnter,
onMouseLeave,
...props
},
ref
) => {
const brand = useBrandConfig()
const hasCustomColor = brand.isWhitelabeled && Boolean(brand.theme?.primaryColor)
const [isHovered, setIsHovered] = useState(false)
const handleMouseEnter = (e: React.MouseEvent<HTMLButtonElement>) => {
setIsHovered(true)
onMouseEnter?.(e)
}
const handleMouseLeave = (e: React.MouseEvent<HTMLButtonElement>) => {
setIsHovered(false)
onMouseLeave?.(e)
}
return (
<button
ref={ref}
{...props}
disabled={disabled || loading}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className={cn(
'group inline-flex h-[32px] items-center justify-center gap-2 rounded-[5px] border px-2.5 font-[430] font-season text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-50',
!hasCustomColor &&
'border-[var(--white)] bg-[var(--white)] text-black hover:border-[var(--border-1)] hover:bg-[var(--border-1)]',
fullWidth && 'w-full',
className
)}
style={
hasCustomColor
? {
backgroundColor: isHovered
? (brand.theme?.primaryHoverColor ?? brand.theme?.primaryColor)
: brand.theme?.primaryColor,
borderColor: isHovered
? (brand.theme?.primaryHoverColor ?? brand.theme?.primaryColor)
: brand.theme?.primaryColor,
color: '#FFFFFF',
}
: undefined
}
>
{loading ? (
<span className='flex items-center gap-2'>
<Loader2 className='h-4 w-4 animate-spin' />
{loadingText ? `${loadingText}...` : children}
</span>
) : showArrow ? (
<span className='flex items-center gap-1'>
{children}
<span className='inline-flex transition-transform duration-200 group-hover:translate-x-0.5'>
{isHovered ? (
<ArrowRight className='h-4 w-4' aria-hidden='true' />
) : (
<ChevronRight className='h-4 w-4' aria-hidden='true' />
)}
</span>
</span>
) : (
children
)}
</button>
)
}
)
BrandedButton.displayName = 'BrandedButton'