| import { ButtonHTMLAttributes, FC, ReactNode, useEffect, useRef } from 'react'; | |
| import { classNames } from '@/shared/lib/classNames/classNames'; | |
| import ButtonSpinner from '@/shared/assets/icons/buttonSpinner.svg?react'; | |
| import cls from './Button.module.scss'; | |
| export enum ButtonTheme { | |
| PRIMARY = 'primary', | |
| NAVIGATION = 'navigation', | |
| } | |
| export enum ButtonSize { | |
| XL = 'xl', | |
| L = 'l', | |
| M = 'm', | |
| S = 's', | |
| NULL = 'null', | |
| } | |
| export interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> { | |
| theme?: ButtonTheme; | |
| size?: ButtonSize; | |
| reverse?: boolean; | |
| showSpinner?: boolean; | |
| className?: string; | |
| icon?: ReactNode; | |
| width?: string; | |
| } | |
| export const Button: FC<ButtonProps> = (props) => { | |
| const { className, children, reverse, theme = '', icon, showSpinner, width = 'auto', size = '', ...otherProps } = props; | |
| const $button = useRef<HTMLButtonElement | null>(null); | |
| useEffect(() => { | |
| if ($button.current) $button.current.style.setProperty('--custom-width', width); | |
| }, []); | |
| const mods = { | |
| [cls.reverse]: reverse, | |
| }; | |
| return ( | |
| <button | |
| type="button" | |
| className={classNames(cls.Button, mods, [className, cls[theme], cls[size]])} | |
| ref={$button} | |
| {...otherProps} | |
| > | |
| {showSpinner && ( | |
| <span className={classNames(cls.spinnerBox, {}, [])}> | |
| <ButtonSpinner className={cls.spinner} /> | |
| </span> | |
| )} | |
| {icon && <span className={classNames(cls.icon, {}, [])}>{icon}</span>} | |
| {children && <span className={cls.text}>{children}</span>} | |
| </button> | |
| ); | |
| }; | |