"use strict";
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Button = exports.ButtonBase = void 0;
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = require("react");
const context_1 = require("../buttonGroup/context");
const core_1 = require("../core");
const utils_1 = require("../utils");
const buttonIcon_1 = __importDefault(require("./buttonIcon"));
const buttonText_1 = __importDefault(require("./buttonText"));
const consts_1 = require("./consts");
const context_2 = require("./context");
// Constants
const DEFAULT_BORDER_WIDTH = 1;
const DEFAULT_BOX_SHADOW = '2';
const DEFAULT_DISABLED_OPACITY = 0.5;
const BUTTON_TYPE = 'button';
const FOCUS_RING_SIZE = 3;
// Memoized styled components
const ContentWrapper = core_1.styled.span `
  visibility: hidden;
`;
const StateWrapper = core_1.styled.span `
  bottom: 0;
  display: flex;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
`;
exports.ButtonBase = core_1.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;

  &.vui-button-variant-menuLight.vui-button-variant-menuLight.vui-active:hover {
    background-color: #d3eef8;
    color: #003591;
    border-color-left: #003591;
  }
  &.vui-button-variant-menuDark.vui-button-variant-menuDark.vui-active:hover {
    background-color: #003591;
    color: #91ffba;
    border-color-left: #91ffba;
  }
  &.vui-button-variant-menuDark.vui-button-variant-menuDark:focus,
  &.vui-button-variant-menuDark.vui-button-variant-menuDark:focus-visible,
  &.vui-button-variant-menuLight.vui-button-variant-menuLight:focus,
  &.vui-button-variant-menuLight.vui-button-variant-menuLight:focus-visible {
    box-shadow: none;
    outline: none;
    border-bottom: 0 solid transparent;
  }
  &.vui-button-variant-menuDark.vui-button-variant-menuDark.focusAsBorder:focus,
  &.vui-button-variant-menuDark.vui-button-variant-menuDark.focusAsBorder:focus-visible,
  &.vui-button-variant-menuLight.vui-button-variant-menuLight.focusAsBorder:focus,
  &.vui-button-variant-menuLight.vui-button-variant-menuLight.focusAsBorder:focus-visible {
    transition: border-bottom 0s linear;
    border-bottom: 3px solid #d3eef8;
  }
`;
const useButtonStyles = (mergedProps, variant) => {
    const styles = (0, core_1.useStyleConfig)('Button', Object.assign(Object.assign({}, mergedProps), variant)) || {};
    return (0, react_1.useMemo)(() => {
        const container = styles.container || {};
        const { borderWidth = DEFAULT_BORDER_WIDTH, h = 32, spaceX = 0 } = container, buttonStyles = __rest(container, ["borderWidth", "h", "spaceX"]);
        return { styles, borderWidth, h, spaceX, buttonStyles };
    }, [mergedProps, variant]);
};
// Utility function to extract numeric value from responsive or themed props
const extractNumericValue = (value) => {
    if (typeof value === 'number')
        return value;
    if (typeof value === 'string') {
        const parsed = parseInt(value, 10);
        return isNaN(parsed) ? DEFAULT_BORDER_WIDTH : parsed;
    }
    return DEFAULT_BORDER_WIDTH;
};
const useSpacingProps = (borderWidthProp, borderWidth, spaceX, icon, iconLeft, iconRight, isLoading, isSplit) => {
    return (0, react_1.useMemo)(() => {
        const border = extractNumericValue(borderWidthProp) || borderWidth || DEFAULT_BORDER_WIDTH;
        const spaceXItem = spaceX - border;
        const spaceXText = spaceX * 2 - border;
        return {
            border,
            iconLeftMr: `${spaceXItem + 1}px`,
            iconRightMl: isSplit ? 'auto' : `${spaceXItem + 1}px`,
            pl: `${icon || iconLeft || isLoading ? spaceXItem : spaceXText}px`,
            pr: `${icon || iconRight ? spaceXItem : spaceXText}px`,
        };
    }, [borderWidthProp, borderWidth, spaceX, icon, iconLeft, iconRight, isLoading, isSplit]);
};
const useDisabledProps = (disabled, styles) => {
    return (0, react_1.useMemo)(() => {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
        return disabled
            ? {
                'aria-disabled': disabled,
                disabledBg: (_b = (_a = styles === null || styles === void 0 ? void 0 : styles.container) === null || _a === void 0 ? void 0 : _a.disabledBg) !== null && _b !== void 0 ? _b : 'bg',
                disabledBorderColor: (_d = (_c = styles === null || styles === void 0 ? void 0 : styles.container) === null || _c === void 0 ? void 0 : _c.disabledBorderColor) !== null && _d !== void 0 ? _d : 'borderColor',
                disabledColor: (_f = (_e = styles === null || styles === void 0 ? void 0 : styles.container) === null || _e === void 0 ? void 0 : _e.disabledColor) !== null && _f !== void 0 ? _f : 'color',
                hoverBg: (_h = (_g = styles === null || styles === void 0 ? void 0 : styles.container) === null || _g === void 0 ? void 0 : _g.disabledBg) !== null && _h !== void 0 ? _h : 'bg',
                hoverBorderColor: (_k = (_j = styles === null || styles === void 0 ? void 0 : styles.container) === null || _j === void 0 ? void 0 : _j.disabledBorderColor) !== null && _k !== void 0 ? _k : 'borderColor',
                hoverColor: (_m = (_l = styles === null || styles === void 0 ? void 0 : styles.container) === null || _l === void 0 ? void 0 : _l.disabledColor) !== null && _m !== void 0 ? _m : 'color',
                activeBg: (_p = (_o = styles === null || styles === void 0 ? void 0 : styles.container) === null || _o === void 0 ? void 0 : _o.disabledBg) !== null && _p !== void 0 ? _p : 'bg',
                cursor: 'not-allowed',
                opacity: (_r = (_q = styles === null || styles === void 0 ? void 0 : styles.container) === null || _q === void 0 ? void 0 : _q.disabledOpacity) !== null && _r !== void 0 ? _r : DEFAULT_DISABLED_OPACITY,
            }
            : {};
    }, [disabled, styles === null || styles === void 0 ? void 0 : styles.container]);
};
const useActiveProps = (isActive, styles) => {
    return (0, react_1.useMemo)(() => {
        var _a, _b, _c;
        return isActive
            ? (0, utils_1.filterUndefined)({
                bg: (_a = styles === null || styles === void 0 ? void 0 : styles.container) === null || _a === void 0 ? void 0 : _a.activeBg,
                borderBg: (_b = styles === null || styles === void 0 ? void 0 : styles.container) === null || _b === void 0 ? void 0 : _b.activeBorderBg,
                color: (_c = styles === null || styles === void 0 ? void 0 : styles.container) === null || _c === void 0 ? void 0 : _c.activeColor,
            })
            : {};
    }, [isActive, styles === null || styles === void 0 ? void 0 : styles.container]);
};
const useAliasedProps = (isRound, h, styles, isElevated, icon, hasState, isFullWidth) => {
    var _a;
    return (0, react_1.useMemo)(() => {
        var _a;
        return (0, utils_1.filterUndefined)({
            borderRadius: isRound ? h / 2 : ((_a = styles === null || styles === void 0 ? void 0 : styles.container) === null || _a === void 0 ? void 0 : _a.borderRadius) || 0,
            boxShadow: isElevated ? DEFAULT_BOX_SHADOW : undefined,
            minW: icon ? 0 : undefined,
            pointerEvents: hasState ? 'none' : undefined,
            w: isFullWidth ? '100%' : undefined,
        });
    }, [isRound, h, (_a = styles === null || styles === void 0 ? void 0 : styles.container) === null || _a === void 0 ? void 0 : _a.borderRadius, isElevated, icon, hasState, isFullWidth]);
};
const useButtonClassName = (className, isActive, variantProp) => {
    return (0, react_1.useMemo)(() => (0, utils_1.cs)('vui-button', className, isActive && utils_1.activeClassName, variantProp ? `vui-button-variant-${variantProp}` : undefined), [className, isActive, variantProp]);
};
const useIconRenderer = (icon, iconLeft, iconRight, isLoading, spacingProps, children, text, isTruncated) => {
    return (0, react_1.useMemo)(() => ({
        main: (0, utils_1.isString)(icon) ? (0, jsx_runtime_1.jsx)(buttonIcon_1.default, { name: icon }) : icon,
        left: isLoading ? ((0, jsx_runtime_1.jsx)(buttonIcon_1.default, Object.assign({ mr: spacingProps.iconLeftMr }, consts_1.loadingIconProps))) : (0, utils_1.isString)(iconLeft) ? ((0, jsx_runtime_1.jsx)(buttonIcon_1.default, { mr: spacingProps.iconLeftMr, name: iconLeft })) : (iconLeft),
        right: (0, utils_1.isString)(iconRight) ? ((0, jsx_runtime_1.jsx)(buttonIcon_1.default, { ml: !children && !text ? 0 : spacingProps.iconRightMl, name: iconRight })) : (iconRight),
        content: children !== null && children !== void 0 ? children : ((0, utils_1.isReactText)(text) ? (0, jsx_runtime_1.jsx)(buttonText_1.default, { isTruncated, text }) : text),
    }), [icon, iconLeft, iconRight, isLoading, spacingProps, children, text, isTruncated]);
};
/**
 * 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.
 */
exports.Button = (0, core_1.vui)((props, ref) => {
    const buttonGroupProps = (0, context_1.useButtonGroupContext)();
    const mergedProps = Object.assign(Object.assign({}, buttonGroupProps), props);
    const { borderWidth: borderWidthProp, children, className, colorScheme, disabled, dropDownIcon = 'falAngleDown', icon, iconLeft, iconRight: iconRightProp, isActive, isDropDown, isElevated, isFullWidth, isLoading, isRound, isSplit, isTruncated, size, state = '', stateMapping, text, title, variant: variantProp } = mergedProps, rest = __rest(mergedProps
    // Memoized calculations
    , ["borderWidth", "children", "className", "colorScheme", "disabled", "dropDownIcon", "icon", "iconLeft", "iconRight", "isActive", "isDropDown", "isElevated", "isFullWidth", "isLoading", "isRound", "isSplit", "isTruncated", "size", "state", "stateMapping", "text", "title", "variant"]);
    // Memoized calculations
    const hasState = (0, react_1.useMemo)(() => Boolean(state) && state !== 'idle', [state]);
    const states = (0, react_1.useMemo)(() => (Object.assign(Object.assign({}, consts_1.buttonStateMapping), stateMapping)), [stateMapping]);
    const stateData = (0, react_1.useMemo)(() => { var _a; return (_a = states[state]) !== null && _a !== void 0 ? _a : {}; }, [states, state]);
    const { iconProps: stateIconProps } = stateData, stateProps = __rest(stateData, ["iconProps"]);
    const iconRight = (0, react_1.useMemo)(() => (isDropDown ? 'falAngleDown' : iconRightProp), [isDropDown, iconRightProp]);
    const variant = (0, react_1.useMemo)(() => {
        var _a;
        return (0, utils_1.filterUndefined)({
            variant: (_a = stateData === null || stateData === void 0 ? void 0 : stateData.variant) !== null && _a !== void 0 ? _a : variantProp,
        });
    }, [stateData === null || stateData === void 0 ? void 0 : stateData.variant, variantProp]);
    // Custom hooks for optimization
    const { styles, borderWidth, h, spaceX, buttonStyles } = useButtonStyles(mergedProps, variant);
    const spacingProps = useSpacingProps(borderWidthProp, borderWidth, spaceX, icon, iconLeft, iconRight, isLoading !== null && isLoading !== void 0 ? isLoading : false, isSplit !== null && isSplit !== void 0 ? isSplit : false);
    const disabledProps = useDisabledProps(disabled !== null && disabled !== void 0 ? disabled : false, styles);
    const isActiveProps = useActiveProps(isActive !== null && isActive !== void 0 ? isActive : false, styles);
    const aliasedProps = useAliasedProps(isRound !== null && isRound !== void 0 ? isRound : false, h, styles, isElevated !== null && isElevated !== void 0 ? isElevated : false, icon, hasState, isFullWidth !== null && isFullWidth !== void 0 ? isFullWidth : false);
    const buttonClassName = useButtonClassName(className, isActive !== null && isActive !== void 0 ? isActive : false, variantProp);
    const IconRenderer = useIconRenderer(icon, iconLeft, iconRight, isLoading !== null && isLoading !== void 0 ? isLoading : false, spacingProps, children, text, isTruncated !== null && isTruncated !== void 0 ? isTruncated : false);
    // Memoized context value
    const contextValue = (0, react_1.useMemo)(() => (0, utils_1.filterUndefined)({ disabled, size, variant: variant.variant }), [disabled, size, variant.variant]);
    // Memoized content wrapper
    const Content = (0, react_1.useMemo)(() => (hasState ? ContentWrapper : react_1.Fragment), [hasState]);
    // Memoized aria label
    const ariaLabel = (0, react_1.useMemo)(() => title || '', [title]);
    // Optimized event handler
    const handleStateClick = (0, react_1.useCallback)((e) => {
        e.stopPropagation();
    }, []);
    // Memoized final props
    const finalProps = (0, react_1.useMemo)(() => (Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ borderWidth: spacingProps.border, className: buttonClassName, disabled, focusRing: FOCUS_RING_SIZE, h, pl: spacingProps.pl, pr: spacingProps.pr, ref, title: title || ariaLabel, type: BUTTON_TYPE, variant }, buttonStyles), isActiveProps), disabledProps), aliasedProps), rest)), [
        spacingProps,
        buttonClassName,
        disabled,
        h,
        ref,
        title,
        ariaLabel,
        variant,
        buttonStyles,
        isActiveProps,
        disabledProps,
        aliasedProps,
        rest,
    ]);
    return ((0, jsx_runtime_1.jsx)(context_2.ButtonProvider, { value: contextValue, children: (0, jsx_runtime_1.jsxs)(exports.ButtonBase, Object.assign({}, finalProps, { children: [hasState && ((0, jsx_runtime_1.jsx)(StateWrapper, Object.assign({ onClick: handleStateClick }, stateProps, { children: (0, jsx_runtime_1.jsx)(buttonIcon_1.default, Object.assign({ m: "auto" }, stateIconProps)) }))), (0, jsx_runtime_1.jsxs)(Content, { children: [IconRenderer.main, !icon && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [IconRenderer.left, IconRenderer.content, IconRenderer.right] }))] })] })) }));
});
exports.Button.Icon = buttonIcon_1.default;
exports.Button.Text = buttonText_1.default;
exports.Button.displayName = 'Button';
exports.default = exports.Button;
//# sourceMappingURL=button.js.map