import { isReactText, isString } from "../utils/assertion.js";
import { activeClassName } from "../utils/consts.js";
import { filterUndefined } from "../utils/object.js";
import { cs } from "../utils/styles.js";
import "../utils/index.js";
import { useStyleConfig } from "../core/theme.js";
import { styled } from "../core/styled.js";
import { vui } from "../core/vui.js";
import { useButtonGroupContext } from "../buttonGroup/context.js";
import { ButtonProvider } from "./context.js";
import buttonIcon_default from "./buttonIcon.js";
import buttonText_default from "./buttonText.js";
import { buttonStateMapping, loadingIconProps } from "./consts.js";
import "../core/index.js";
import { Fragment, useCallback, useMemo } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";

//#region src/button/button.tsx
const DEFAULT_BORDER_WIDTH = 1;
const DEFAULT_BOX_SHADOW = "2";
const DEFAULT_DISABLED_OPACITY = .5;
const BUTTON_TYPE = "button";
const FOCUS_RING_SIZE = 3;
const ContentWrapper = styled.span`
  visibility: hidden;
`;
const StateWrapper = styled.span`
  bottom: 0;
  display: flex;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
`;
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;

  &.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 = useStyleConfig("Button", {
		...mergedProps,
		...variant
	}) || {};
	return useMemo(() => {
		const { borderWidth = DEFAULT_BORDER_WIDTH, h = 32, spaceX = 0, ...buttonStyles } = styles.container || {};
		return {
			styles,
			borderWidth,
			h,
			spaceX,
			buttonStyles
		};
	}, [mergedProps, variant]);
};
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 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 useMemo(() => disabled ? {
		"aria-disabled": disabled,
		disabledBg: styles?.container?.disabledBg ?? "bg",
		disabledBorderColor: styles?.container?.disabledBorderColor ?? "borderColor",
		disabledColor: styles?.container?.disabledColor ?? "color",
		hoverBg: styles?.container?.disabledBg ?? "bg",
		hoverBorderColor: styles?.container?.disabledBorderColor ?? "borderColor",
		hoverColor: styles?.container?.disabledColor ?? "color",
		activeBg: styles?.container?.disabledBg ?? "bg",
		cursor: "not-allowed",
		opacity: styles?.container?.disabledOpacity ?? DEFAULT_DISABLED_OPACITY
	} : {}, [disabled, styles?.container]);
};
const useActiveProps = (isActive, styles) => {
	return useMemo(() => isActive ? filterUndefined({
		bg: styles?.container?.activeBg,
		borderBg: styles?.container?.activeBorderBg,
		color: styles?.container?.activeColor
	}) : {}, [isActive, styles?.container]);
};
const useAliasedProps = (isRound, h, styles, isElevated, icon, hasState, isFullWidth) => {
	return useMemo(() => filterUndefined({
		borderRadius: isRound ? h / 2 : styles?.container?.borderRadius || 0,
		boxShadow: isElevated ? DEFAULT_BOX_SHADOW : void 0,
		minW: icon ? 0 : void 0,
		pointerEvents: hasState ? "none" : void 0,
		w: isFullWidth ? "100%" : void 0
	}), [
		isRound,
		h,
		styles?.container?.borderRadius,
		isElevated,
		icon,
		hasState,
		isFullWidth
	]);
};
const useButtonClassName = (className, isActive, variantProp) => {
	return useMemo(() => cs("vui-button", className, isActive && activeClassName, variantProp ? `vui-button-variant-${variantProp}` : void 0), [
		className,
		isActive,
		variantProp
	]);
};
const useIconRenderer = (icon, iconLeft, iconRight, isLoading, spacingProps, children, text, isTruncated) => {
	return useMemo(() => ({
		main: isString(icon) ? /* @__PURE__ */ jsx(buttonIcon_default, { name: icon }) : icon,
		left: isLoading ? /* @__PURE__ */ jsx(buttonIcon_default, {
			mr: spacingProps.iconLeftMr,
			...loadingIconProps
		}) : isString(iconLeft) ? /* @__PURE__ */ jsx(buttonIcon_default, {
			mr: spacingProps.iconLeftMr,
			name: iconLeft
		}) : iconLeft,
		right: isString(iconRight) ? /* @__PURE__ */ jsx(buttonIcon_default, {
			ml: !children && !text ? 0 : spacingProps.iconRightMl,
			name: iconRight
		}) : iconRight,
		content: children ?? (isReactText(text) ? /* @__PURE__ */ jsx(buttonText_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.
*/
const Button = vui((props, ref) => {
	const mergedProps = {
		...useButtonGroupContext(),
		...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, ...rest } = mergedProps;
	const hasState = useMemo(() => Boolean(state) && state !== "idle", [state]);
	const states = useMemo(() => ({
		...buttonStateMapping,
		...stateMapping
	}), [stateMapping]);
	const stateData = useMemo(() => states[state] ?? {}, [states, state]);
	const { iconProps: stateIconProps, ...stateProps } = stateData;
	const iconRight = useMemo(() => isDropDown ? "falAngleDown" : iconRightProp, [isDropDown, iconRightProp]);
	const variant = useMemo(() => filterUndefined({ variant: stateData?.variant ?? variantProp }), [stateData?.variant, variantProp]);
	const { styles, borderWidth, h, spaceX, buttonStyles } = useButtonStyles(mergedProps, variant);
	const spacingProps = useSpacingProps(borderWidthProp, borderWidth, spaceX, icon, iconLeft, iconRight, isLoading ?? false, isSplit ?? false);
	const disabledProps = useDisabledProps(disabled ?? false, styles);
	const isActiveProps = useActiveProps(isActive ?? false, styles);
	const aliasedProps = useAliasedProps(isRound ?? false, h, styles, isElevated ?? false, icon, hasState, isFullWidth ?? false);
	const buttonClassName = useButtonClassName(className, isActive ?? false, variantProp);
	const IconRenderer = useIconRenderer(icon, iconLeft, iconRight, isLoading ?? false, spacingProps, children, text, isTruncated ?? false);
	const contextValue = useMemo(() => filterUndefined({
		disabled,
		size,
		variant: variant.variant
	}), [
		disabled,
		size,
		variant.variant
	]);
	const Content = useMemo(() => hasState ? ContentWrapper : Fragment, [hasState]);
	const ariaLabel = useMemo(() => title || "", [title]);
	const handleStateClick = useCallback((e) => {
		e.stopPropagation();
	}, []);
	return /* @__PURE__ */ jsx(ButtonProvider, {
		value: contextValue,
		children: /* @__PURE__ */ jsxs(ButtonBase, {
			...useMemo(() => ({
				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
			]),
			children: [hasState && /* @__PURE__ */ jsx(StateWrapper, {
				onClick: handleStateClick,
				...stateProps,
				children: /* @__PURE__ */ jsx(buttonIcon_default, {
					m: "auto",
					...stateIconProps
				})
			}), /* @__PURE__ */ jsxs(Content, { children: [IconRenderer.main, !icon && /* @__PURE__ */ jsxs(Fragment$1, { children: [
				IconRenderer.left,
				IconRenderer.content,
				IconRenderer.right
			] })] })]
		})
	});
});
Button.Icon = buttonIcon_default;
Button.Text = buttonText_default;
Button.displayName = "Button";
var button_default = Button;

//#endregion
export { Button, ButtonBase, button_default as default };
globalThis.__vuiVersion__ = "4.0.0-beta.1"
//# sourceMappingURL=button.js.map