-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathButton.tsx
More file actions
59 lines (53 loc) · 1.78 KB
/
Button.tsx
File metadata and controls
59 lines (53 loc) · 1.78 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
import classNames from 'classnames';
import { LoaderCircleIcon, type LucideIcon } from 'lucide-react';
import type { ComponentPropsWithRef } from 'react';
export function Button({
children,
className,
onClick,
secondary,
disabled,
loading,
type = 'submit',
icon: Icon,
iconRight: IconRight,
iconClassName,
}: {
secondary?: boolean;
loading?: boolean;
icon?: LucideIcon;
iconRight?: LucideIcon;
iconClassName?: string;
} & ComponentPropsWithRef<'button'>) {
const primary = !secondary;
const classPrimary =
'bg-indigo-500 hover:bg-indigo-400 focus-visible:outline-indigo-500 border-indigo-500 text-white focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2';
const classSecondary =
'bg-white/10 hover:bg-white/20 text-white border-white/10';
const iconClass = classNames('size-4 shrink-0', iconClassName);
const loaderClass = classNames('size-4 shrink-0 animate-spin', iconClassName);
const showLoaderLeft = loading && !IconRight;
const showLoaderRight = loading && !!IconRight;
return (
<button
onClick={onClick}
className={classNames(
'border rounded-md px-2.5 py-1.5 text-xs font-medium shadow-sm disabled:cursor-not-allowed disabled:opacity-50 flex items-center gap-1',
primary && classPrimary,
secondary && classSecondary,
loading && 'animate-pulse-tailwind',
className,
)}
type={type}
disabled={disabled}
>
{/* LEFT */}
{!loading && Icon && <Icon className={iconClass} />}
{showLoaderLeft && <LoaderCircleIcon className={loaderClass} />}
{children}
{/* RIGHT */}
{!loading && IconRight && <IconRight className={iconClass} />}
{showLoaderRight && <LoaderCircleIcon className={loaderClass} />}
</button>
);
}