50 lines
1.4 KiB
TypeScript
50 lines
1.4 KiB
TypeScript
import type { ButtonHTMLAttributes, FC, ReactNode } from 'react'
|
|
import { memo } from 'react'
|
|
import MoonLoader from "react-spinners/MoonLoader"
|
|
import { type XOR } from '@/helpers/types'
|
|
import { clx } from '@/helpers/utils'
|
|
|
|
type Props = {
|
|
className?: string;
|
|
isLoading?: boolean,
|
|
percentage?: number,
|
|
} & ButtonHTMLAttributes<HTMLButtonElement> &
|
|
XOR<{ children: ReactNode }, { label: string }>;
|
|
|
|
const Button: FC<Props> = memo((props: Props) => {
|
|
const {
|
|
className,
|
|
disabled,
|
|
isLoading,
|
|
percentage,
|
|
label,
|
|
children,
|
|
...buttonProps
|
|
} = props
|
|
|
|
const buttonClass = clx(
|
|
'flex rounded-xl items-center justify-center text-center h-10 text-sm bg-primary w-full',
|
|
disabled && 'cursor-not-allowed opacity-60',
|
|
className
|
|
);
|
|
|
|
return (
|
|
<button {...buttonProps} className={`${buttonClass} ${className}`} disabled={disabled || isLoading}>
|
|
{
|
|
isLoading ?
|
|
<div className='flex gap-2 items-center'>
|
|
{
|
|
!percentage ?
|
|
<MoonLoader size={20} color='#000' />
|
|
:
|
|
<span>{percentage}%</span>
|
|
}
|
|
</div>
|
|
:
|
|
label || children
|
|
}
|
|
</button>
|
|
)
|
|
})
|
|
|
|
export default Button |