'use client';
import cx from 'classnames';
import React, { useMemo } from 'react';
import { LoadingSpinner } from '~/components/LoadingSpinner';
import { useLogger } from '~/hooks/useLogger';
import { classNameForBodyText } from '~/styles/classNameForBodyText';
import devWarn from '~/utilities/dev-warn';
import { mapResponsive, wrapResponsive } from '~/utilities/opaque-responsive';
import { classNameForResponsiveValue, createResponsiveClassNameLookup } from '~/utilities/responsive-style';
import { getIconSize, getSpinnerColor } from './theme';
import styles from './Button.module.css';
const classNameFluidLookup = createResponsiveClassNameLookup(styles, {
    true: 'fluidSet',
    false: 'fluidUnset',
});
const useButtonClassList = ({ variant, size, unfilled, isLoading, disabled, textAlign, weight, padding, corners, fluid, className, hasChildren, hasIcon, hasDisclosureIcon, }) => {
    return useMemo(() => {
        const responsiveFluid = mapResponsive(wrapResponsive(fluid), (value) => (value ? 'true' : 'false'));
        return cx(styles.root, {
            [styles.themePrimary]: variant === 'primary',
            [styles.themeSecondary]: variant === 'secondary',
            [styles.themeTertiary]: variant === 'tertiary',
            [styles.themeCritical]: variant === 'critical',
            [styles.themeFloating]: variant === 'floating',
            [styles.themeInsetWhite]: variant === 'insetWhite',
            [styles.themeInsetBlack]: variant === 'insetBlack',
            [styles.sizeXs]: size === 'xs',
            [styles.sizeSm]: size === 'sm',
            [styles.sizeMd]: size === 'md',
            [styles.sizeLg]: size === 'lg',
            [styles.cornersPill]: corners === 'pill',
            [styles.hasDimensions]: padding === 'default',
            [styles.variantIconOnly]: hasIcon && !hasDisclosureIcon && !hasChildren,
            [styles.variantLabelOnly]: !hasIcon && !hasDisclosureIcon && hasChildren,
            [styles.variantLabelAndIcon]: !hasDisclosureIcon && hasChildren && hasIcon,
            [styles.variantDisclosureAndLabel]: !hasIcon && hasDisclosureIcon && hasChildren,
            [styles.variantIconAndDisclosureOnly]: hasIcon && hasDisclosureIcon && !hasChildren,
            [styles.variantIconLabelAndDisclosure]: hasIcon && hasDisclosureIcon && hasChildren,
            [styles.hasTextAlign]: textAlign !== undefined,
            [styles.textAlignLeft]: textAlign === 'left',
            [styles.textAlignRight]: textAlign === 'right',
            [styles.isFilled]: !unfilled,
            [styles.isUnfilled]: unfilled,
            [styles.isActive]: !(disabled || isLoading),
            [styles.isInactive]: disabled || isLoading,
            [styles.isLoading]: isLoading,
        }, classNameForResponsiveValue(responsiveFluid, classNameFluidLookup), classNameForBodyText({ size: size === 'xs' ? 'sm' : size, weight }), className);
    }, [
        fluid,
        variant,
        size,
        corners,
        padding,
        hasIcon,
        hasDisclosureIcon,
        hasChildren,
        textAlign,
        unfilled,
        disabled,
        isLoading,
        weight,
        className,
    ]);
};
export const Button = React.forwardRef(function Button({ variant = 'secondary', unfilled = false, children, size = 'md', disabled = false, onClick, icon, fluid = false, iconProps, isLoading = false, disclosureIcon, href, target, type = 'button', corners = 'rounded', padding: userPadding, textAlign, weight = 'bold', className, style, loggerId, loggerProps, id, 'data-tag': dataTag, ...props // aria props
 }, ref) {
    const log = useLogger();
    const hasChildren = !!children;
    const hasIcon = !!icon;
    const hasDisclosureIcon = !!disclosureIcon;
    const iconSize = getIconSize(size);
    const LeftIcon = icon;
    const RightIcon = disclosureIcon;
    // we're not setting a default value for padding in props because we want to
    // check if the user has passed in a value for padding with a button using
    // a label. If they have, we want to warn them that they should not use
    // padding with a button using a label.
    const iconOnly = hasIcon && !hasDisclosureIcon && !hasChildren;
    const padding = iconOnly ? (userPadding ?? 'default') : 'default';
    const classList = useButtonClassList({
        children,
        icon,
        size,
        unfilled,
        variant,
        isLoading,
        disabled,
        textAlign,
        weight,
        corners,
        padding,
        fluid,
        className,
        hasChildren,
        hasIcon,
        hasDisclosureIcon,
    });
    // Ideally we would catch both of these warnings in the type definition, but we extend the
    // ButtonProps type which means we can't add a intersection type easily. We should revisit
    // this in the future and consider adding a `IconButton` component for icon only buttons
    // instead of using allowing button to have so many responsibilities.
    if (iconOnly && !props['aria-label']) {
        devWarn('`aria-label` must be defined in icon only buttons for accessibility.');
    }
    const content = (<>
      <div className={styles.contentContainer}>
        {LeftIcon && <LeftIcon size={iconSize} color="currentColor" {...iconProps}/>}
        {children && <div className={styles.labelContainer}>{children}</div>}
        {RightIcon && <RightIcon size={iconSize} color="currentColor" {...iconProps}/>}
      </div>

      {isLoading && (<div className={styles.loadingWrapper}>
          <LoadingSpinner color={getSpinnerColor({ variant, unfilled })} size={size === 'lg' ? 'sm' : 'xs'}/>
        </div>)}
    </>);
    if (href || target) {
        const computedHref = isLoading || disabled ? undefined : (href ?? '#');
        return (<a onClick={(e) => {
                if (disabled) {
                    e.preventDefault();
                    return;
                }
                if (computedHref?.length && e.target instanceof HTMLElement) {
                    e.target.style.cursor = 'default';
                }
                log('buttonClick', loggerId, loggerProps);
                onClick?.(e);
            }} onMouseDown={(e) => {
                if (computedHref?.length && e.target instanceof HTMLElement) {
                    e.target.style.cursor = 'default';
                }
                e.preventDefault();
            }} aria-disabled={disabled} ref={ref} rel={target === '_blank' ? 'noopener noreferrer' : undefined} role={disabled ? 'link' : undefined} href={computedHref} target={target} className={classList} style={style} id={id} data-tag={dataTag} {...props}>
        {content}
      </a>);
    }
    const onClickOverride = (e) => {
        if (isLoading || disabled) {
            e.preventDefault();
            return;
        }
        log('buttonClick', loggerId, loggerProps);
        onClick?.(e);
    };
    return (<button onClick={onClickOverride} aria-disabled={disabled} type={type} ref={ref} className={classList} style={style} id={id} data-tag={dataTag} {...props}>
      {content}
    </button>);
});
//# sourceMappingURL=index.jsx.map