| import { memo, forwardRef, type ForwardedRef } from 'react'; |
| import { classNames } from '~/utils/classNames'; |
|
|
| type IconSize = 'sm' | 'md' | 'lg' | 'xl' | 'xxl'; |
|
|
| interface BaseIconButtonProps { |
| size?: IconSize; |
| className?: string; |
| iconClassName?: string; |
| disabledClassName?: string; |
| title?: string; |
| disabled?: boolean; |
| onClick?: (event: React.MouseEvent<HTMLButtonElement, MouseEvent>) => void; |
| } |
|
|
| type IconButtonWithoutChildrenProps = { |
| icon: string; |
| children?: undefined; |
| } & BaseIconButtonProps; |
|
|
| type IconButtonWithChildrenProps = { |
| icon?: undefined; |
| children: string | JSX.Element | JSX.Element[]; |
| } & BaseIconButtonProps; |
|
|
| type IconButtonProps = IconButtonWithoutChildrenProps | IconButtonWithChildrenProps; |
|
|
| |
| export const IconButton = memo( |
| forwardRef( |
| ( |
| { |
| icon, |
| size = 'xl', |
| className, |
| iconClassName, |
| disabledClassName, |
| disabled = false, |
| title, |
| onClick, |
| children, |
| }: IconButtonProps, |
| ref: ForwardedRef<HTMLButtonElement>, |
| ) => { |
| return ( |
| <button |
| ref={ref} |
| className={classNames( |
| 'flex items-center text-bolt-elements-item-contentDefault bg-transparent enabled:hover:text-bolt-elements-item-contentActive rounded-md p-1 enabled:hover:bg-bolt-elements-item-backgroundActive disabled:cursor-not-allowed', |
| { |
| [classNames('opacity-30', disabledClassName)]: disabled, |
| }, |
| className, |
| )} |
| title={title} |
| disabled={disabled} |
| onClick={(event) => { |
| if (disabled) { |
| return; |
| } |
| |
| onClick?.(event); |
| }} |
| > |
| {children ? children : <div className={classNames(icon, getIconSize(size), iconClassName)}></div>} |
| </button> |
| ); |
| }, |
| ), |
| ); |
|
|
| function getIconSize(size: IconSize) { |
| if (size === 'sm') { |
| return 'text-sm'; |
| } else if (size === 'md') { |
| return 'text-md'; |
| } else if (size === 'lg') { |
| return 'text-lg'; |
| } else if (size === 'xl') { |
| return 'text-xl'; |
| } else { |
| return 'text-2xl'; |
| } |
| } |
|
|