import type React from 'react'; import type { ReactNode } from 'react'; import { useCallback } from 'react'; import classNames from 'classnames'; import { Link } from 'react-router-dom'; import type { LinkProps } from 'react-router-dom'; import { CircularProgress } from '../circular_progress'; import type { IconProp } from '../icon'; import { Icon } from '../icon'; import classes from './redesign.module.scss'; interface ButtonPropsBase { size?: 'lg' | 'md' | 'sm' | 'xs'; variant?: 'solid' | 'ghost'; color?: 'accent' | 'neutral' | 'tonal' | 'destructive'; onClick?: React.MouseEventHandler< As extends 'button' ? HTMLButtonElement : HTMLAnchorElement >; loading?: boolean; children: ReactNode; } type ButtonButtonProps = { as?: 'button' } & ButtonPropsBase<'button'> & Omit, 'children'>; type ButtonAnchorProps = { as: 'a' } & ButtonPropsBase<'a'> & Omit, 'children'>; type ButtonLinkProps = { as: 'link' } & ButtonPropsBase<'a'> & Omit; type ButtonProps = ButtonButtonProps | ButtonAnchorProps | ButtonLinkProps; const BaseButton: React.FC = ({ size = 'md', variant = 'solid', color = 'tonal', as: asComp = 'button', children, className, onClick, loading, 'aria-disabled': ariaDisabled, 'aria-live': ariaLive, ...props }) => { const disabled = 'disabled' in props ? props.disabled : false; const handleClick: React.MouseEventHandler< HTMLButtonElement & HTMLAnchorElement > = useCallback( (event) => { if (disabled || loading) { event.stopPropagation(); event.preventDefault(); } else if (onClick) { onClick(event); } }, [loading, onClick, disabled], ); let Comp: React.ElementType = asComp; if (asComp === 'link') { Comp = Link; } return ( {children} ); }; export const Button: React.FC< ButtonProps & { leadingIcon?: IconProp; trailingIcon?: IconProp; } > = ({ children, leadingIcon, trailingIcon, ...props }) => ( {leadingIcon && !props.loading && ( )} {props.loading && } {children} {trailingIcon && ( )} ); export const IconButton: React.FC = ({ icon, className, children, ...props }) => ( {props.loading ? ( ) : ( )} {children} ); const LoadingIcon: React.FC = () => ( );