velxio/frontend/src/components/ui/Button.tsx

57 lines
1.3 KiB
TypeScript

import { forwardRef, type ButtonHTMLAttributes, type ReactNode } from 'react';
import './Button.css';
type Variant = 'primary' | 'secondary' | 'ghost' | 'white';
type Size = 'sm' | 'md' | 'lg';
interface Props extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: Variant;
size?: Size;
loading?: boolean;
iconLeft?: ReactNode;
iconRight?: ReactNode;
fullWidth?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, Props>(function Button(
{
variant = 'primary',
size = 'md',
loading = false,
iconLeft,
iconRight,
fullWidth = false,
disabled,
className,
children,
...rest
},
ref,
) {
const classes = [
'ui-btn',
`ui-btn--${variant}`,
`ui-btn--${size}`,
fullWidth ? 'ui-btn--full' : '',
loading ? 'ui-btn--loading' : '',
className ?? '',
]
.filter(Boolean)
.join(' ');
return (
<button
ref={ref}
className={classes}
disabled={disabled || loading}
aria-busy={loading || undefined}
{...rest}
>
{loading ? <span className="ui-btn__spinner" aria-hidden="true" /> : null}
{!loading && iconLeft ? <span className="ui-btn__icon">{iconLeft}</span> : null}
<span className="ui-btn__label">{children}</span>
{!loading && iconRight ? <span className="ui-btn__icon">{iconRight}</span> : null}
</button>
);
});