You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
62 lines
1.2 KiB
62 lines
1.2 KiB
import type { PropsWithChildren } from 'react'; |
|
import { useCallback } from 'react'; |
|
|
|
import classNames from 'classnames'; |
|
|
|
interface BaseProps |
|
extends Omit<React.ButtonHTMLAttributes<HTMLButtonElement>, 'children'> { |
|
block?: boolean; |
|
secondary?: boolean; |
|
dangerous?: boolean; |
|
} |
|
|
|
interface PropsChildren extends PropsWithChildren<BaseProps> { |
|
text?: undefined; |
|
} |
|
|
|
interface PropsWithText extends BaseProps { |
|
text: JSX.Element | string; |
|
children?: undefined; |
|
} |
|
|
|
type Props = PropsWithText | PropsChildren; |
|
|
|
export const Button: React.FC<Props> = ({ |
|
type = 'button', |
|
onClick, |
|
disabled, |
|
block, |
|
secondary, |
|
dangerous, |
|
className, |
|
title, |
|
text, |
|
children, |
|
...props |
|
}) => { |
|
const handleClick = useCallback<React.MouseEventHandler<HTMLButtonElement>>( |
|
(e) => { |
|
if (!disabled && onClick) { |
|
onClick(e); |
|
} |
|
}, |
|
[disabled, onClick], |
|
); |
|
|
|
return ( |
|
<button |
|
className={classNames('button', className, { |
|
'button-secondary': secondary, |
|
'button--block': block, |
|
'button--dangerous': dangerous, |
|
})} |
|
disabled={disabled} |
|
onClick={handleClick} |
|
title={title} |
|
type={type} |
|
{...props} |
|
> |
|
{text ?? children} |
|
</button> |
|
); |
|
};
|
|
|