import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { Fragment, useMemo } from 'react';
import { useButtonGroupContext } from '../buttonGroup/context';
import { styled, useStyleConfig, vui } from '../core';
import { activeClassName, cs, filterUndefined, isReactText, isString } from '../utils';
import ButtonIcon from './buttonIcon';
import ButtonText from './buttonText';
import { buttonStateMapping, loadingIconProps } from './consts';
import { ButtonProvider } from './context';
const ContentWrapper = styled.span `
  visibility: hidden;
`;
const StateWrapper = styled.span `
  bottom: 0;
  display: flex;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
`;
export const ButtonBase = styled.buttonBox `
  align-items: center;
  display: inline-flex;
  flex-shrink: 0;
  font-weight: medium;
  justify-content: center;
  line-height: normal;
  overflow: hidden;
  position: relative;
  transition-duration: fast;
  user-select: none;
  width: fit-content;
`;
/**
 * Triggers given actions on click. Supports multiple states, sizes and variants.
 *
 * Comes with additional props for extra behavior, like loading, disabled or elevated.
 *
 * Exposes some props to the children via context.
 */
export const Button = vui((props, ref) => {
    const buttonGroupProps = useButtonGroupContext();
    const mergedProps = { ...buttonGroupProps, ...props };
    const { borderWidth: borderWidthProp, children, className, colorScheme, disabled, dropDownIcon = 'falAngleDown', icon, iconLeft, iconRight: iconRightProp, isActive, isDropDown, isElevated, isFullWidth, isLoading, // eslint-disable-line
    isRound, isSplit, isTruncated, size, state = '', stateMapping, text, title, variant: variantProp, ...rest } = mergedProps;
    const hasState = Boolean(state) && state !== 'idle';
    const states = { ...buttonStateMapping, ...stateMapping };
    const { iconProps: stateIconProps, ...stateProps } = states[state] ?? {};
    const iconRight = isDropDown ? 'falAngleDown' : iconRightProp;
    const variant = filterUndefined({
        variant: states[state]?.variant ?? variantProp,
    });
    const styles = useStyleConfig('Button', { ...mergedProps, ...variant });
    const { borderWidth, h, spaceX = 0, ...buttonStyles } = styles.container;
    const context = useMemo(() => filterUndefined({ disabled, size, variant }), [disabled, size, variant]);
    const Content = hasState ? ContentWrapper : Fragment;
    // Apply more space for text and less space for icons
    const border = borderWidthProp ?? borderWidth ?? 1;
    const spaceXItem = spaceX - border;
    const spaceXText = spaceX * 2 - border;
    const iconLeftMr = spaceXItem + 1 + 'px';
    const iconRightMl = isSplit ? 'auto' : spaceXItem + 1 + 'px';
    const pl = (icon || iconLeft || isLoading ? spaceXItem : spaceXText) + 'px';
    const pr = (icon || iconRight ? spaceXItem : spaceXText) + 'px';
    let ariaLabel = '';
    if (title)
        ariaLabel = title;
    const isActiveProps = isActive
        ? filterUndefined({
            bg: styles?.container?.activeBg,
            borderBg: styles?.container?.activeBorderBg,
            color: styles?.container?.activeColor,
        })
        : {};
    const disabledProps = disabled
        ? {
            'aria-disabled': disabled,
            disabledBg: 'bg',
            disabledBorderColor: 'borderColor',
            disabledColor: 'color',
            hoverBg: 'bg',
            hoverBorderColor: 'borderColor',
            hoverColor: 'color',
            activeBg: 'bg',
            cursor: 'not-allowed',
            opacity: 0.5,
        }
        : {};
    const aliasedProps = filterUndefined({
        borderRadius: isRound ? h / 2 : styles?.container?.borderRadius || 0,
        boxShadow: isElevated ? '2' : undefined,
        minW: icon ? 0 : undefined,
        pointerEvents: hasState ? 'none' : undefined,
        w: isFullWidth ? '100%' : undefined,
    });
    return (_jsx(ButtonProvider, { value: context, children: _jsxs(ButtonBase, { borderWidth: border, className: cs('vui-button', className, isActive && activeClassName, variantProp ? `vui-button-variant-${variantProp}` : undefined), disabled: disabled, focusRing: 3, h: h, pl: pl, pr: pr, ref: ref, title: title || ariaLabel, type: "button", variant: variant, ...buttonStyles, ...isActiveProps, ...disabledProps, ...aliasedProps, ...rest, children: [hasState && (_jsx(StateWrapper, { onClick: (e) => e.stopPropagation(), ...stateProps, children: _jsx(ButtonIcon, { m: "auto", ...stateIconProps }) })), _jsxs(Content, { children: [isString(icon) ? _jsx(ButtonIcon, { name: icon }) : icon, !icon && (_jsxs(_Fragment, { children: [isLoading ? (_jsx(ButtonIcon, { mr: iconLeftMr, ...loadingIconProps })) : isString(iconLeft) ? (_jsx(ButtonIcon, { mr: iconLeftMr, name: iconLeft })) : (iconLeft), children ?? (isReactText(text) ? _jsx(ButtonText, { isTruncated, text }) : text), isString(iconRight) ? (_jsx(ButtonIcon, { ml: !children && !text ? 0 : iconRightMl, name: iconRight })) : (iconRight)] }))] })] }) }));
});
Button.Icon = ButtonIcon;
Button.Text = ButtonText;
Button.displayName = 'Button';
export default Button;
//# sourceMappingURL=button.js.map