/** @license MIT | @cube-dev/ui-kit v0.123.0 | Cube Dev Team */
import { extractStyles } from "../../../utils/styles.js";
import { mergeProps } from "../../../utils/react/mergeProps.js";
import { resolveIcon } from "../../../utils/react/resolveIcon.js";
import { DisplayTransition } from "../../helpers/DisplayTransition/DisplayTransition.js";
import { useAutoTooltip } from "../../content/use-auto-tooltip.js";
import { DANGER_CLEAR_STYLES, DANGER_LINK_STYLES, DANGER_NEUTRAL_STYLES, DANGER_OUTLINE_STYLES, DANGER_PRIMARY_STYLES, DANGER_SECONDARY_STYLES, DEFAULT_CLEAR_STYLES, DEFAULT_LINK_STYLES, DEFAULT_NEUTRAL_STYLES, DEFAULT_OUTLINE_STYLES, DEFAULT_PRIMARY_STYLES, DEFAULT_SECONDARY_STYLES, NOTE_CLEAR_STYLES, NOTE_LINK_STYLES, NOTE_NEUTRAL_STYLES, NOTE_OUTLINE_STYLES, NOTE_PRIMARY_STYLES, NOTE_SECONDARY_STYLES, SPECIAL_CLEAR_STYLES, SPECIAL_LINK_STYLES, SPECIAL_NEUTRAL_STYLES, SPECIAL_OUTLINE_STYLES, SPECIAL_PRIMARY_STYLES, SPECIAL_SECONDARY_STYLES, SUCCESS_CLEAR_STYLES, SUCCESS_LINK_STYLES, SUCCESS_NEUTRAL_STYLES, SUCCESS_OUTLINE_STYLES, SUCCESS_PRIMARY_STYLES, SUCCESS_SECONDARY_STYLES, WARNING_CLEAR_STYLES, WARNING_LINK_STYLES, WARNING_NEUTRAL_STYLES, WARNING_OUTLINE_STYLES, WARNING_PRIMARY_STYLES, WARNING_SECONDARY_STYLES } from "../../../data/item-themes.js";
import { LoadingIcon } from "../../../icons/LoadingIcon.js";
import { useWarn } from "../../../_internal/hooks/use-warn.js";
import { useIsFirstRender } from "../../../_internal/hooks/use-is-first-render.js";
import { useAction } from "../use-action.js";
import { IconSwitch } from "../../helpers/IconSwitch/IconSwitch.js";
import { useButtonSplitContext } from "../ButtonSplit/context.js";
import { CONTAINER_STYLES, TEXT_STYLES, tasty } from "@tenphi/tasty";
import { Children, forwardRef, isValidElement, useMemo, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";

//#region src/components/actions/Button/Button.tsx
const BUTTON_SIZE_VALUES = [
	"xsmall",
	"small",
	"medium",
	"large",
	"xlarge",
	"inline"
];
const STYLE_PROPS = [...CONTAINER_STYLES, ...TEXT_STYLES];
const DEFAULT_ICON_STYLES = {
	$: ">",
	position: "relative",
	display: "grid",
	placeItems: "center",
	placeContent: "center",
	placeSelf: "stretch",
	width: "fixed ($size - 2bw)",
	height: "fixed ($size - 2bw)",
	pointerEvents: "none",
	transition: "theme, width, height, translate"
};
const DEFAULT_BUTTON_STYLES = {
	recipe: "reset button",
	display: "inline-grid",
	flow: "column dense",
	gap: 0,
	placeItems: {
		"": "stretch",
		"raw-children": "center stretch"
	},
	placeContent: "center",
	position: "relative",
	preset: {
		"": "t3m",
		"size=xsmall": "t4",
		"size=xlarge": "t2m",
		"type=link": "strong"
	},
	outlineOffset: 1,
	padding: {
		"": 0,
		"raw-children & !has-icons": "$block-padding $inline-padding $block-padding $inline-padding",
		"type=link": "0"
	},
	width: {
		"": "min $size",
		"has-icon & has-right-icon": "min ($size * 2 - 2bw)",
		"single-icon": "fixed $size",
		"type=link": "min 1ch"
	},
	height: {
		"": "fixed $size",
		"type=link": "initial"
	},
	whiteSpace: "nowrap",
	radius: {
		"": true,
		"type=link & !focused": 0,
		"@parent(button-split, >) & !:last-child": "1r left",
		"@parent(button-split, >) & !:first-child": "1r right",
		"@parent(button-split, >) & !:first-child & !:last-child": 0
	},
	margin: {
		"": 0,
		"@parent(button-split, >) & !:first-child & (type=secondary | type=outline | type=primary)": "-1bw left"
	},
	zIndex: {
		"@parent(button-split, >) & :hover": 1,
		"@parent(button-split, >) & :focus-visible": 2
	},
	transition: "theme, grid-template, padding",
	verticalAlign: "bottom",
	$size: {
		"": "$size-md",
		"size=xsmall": "$size-xs",
		"size=small": "$size-sm",
		"size=medium": "$size-md",
		"size=large": "$size-lg",
		"size=xlarge": "$size-xl",
		"size=inline": "(1lh + 2bw)"
	},
	"$inline-padding": { "": "max($min-inline-padding, (($size - 1lh - 2bw) / 2 + $inline-compensation))" },
	"$block-padding": {
		"": ".5x",
		"size=xsmall | size=small": ".25x"
	},
	"$inline-compensation": ".5x",
	"$min-inline-padding": "(1x - 1bw)",
	"$left-padding": {
		"": "$inline-padding",
		"is-icon-shown": "0px"
	},
	"$right-padding": {
		"": "$inline-padding",
		"is-right-icon-shown": "0px"
	},
	Icon: {
		...DEFAULT_ICON_STYLES,
		width: {
			"": "fixed 0px",
			"is-icon-shown": "fixed ($size - 2bw)"
		},
		opacity: {
			"": 0,
			"is-icon-shown": 1
		},
		translate: {
			"": "($size * 1 / 4) 0",
			"is-icon-shown": "0 0"
		}
	},
	RightIcon: {
		...DEFAULT_ICON_STYLES,
		width: {
			"": "fixed 0px",
			"is-right-icon-shown": "fixed ($size - 2bw)"
		},
		opacity: {
			"": 0,
			"is-right-icon-shown": 1
		},
		translate: {
			"": "($size * -1 / 4) 0",
			"is-right-icon-shown": "0 0"
		}
	},
	Label: {
		$: ">",
		display: "block",
		placeSelf: "center stretch",
		boxSizing: "border-box",
		whiteSpace: "nowrap",
		overflow: "hidden",
		textOverflow: "ellipsis",
		width: "0 100%",
		textAlign: "center",
		transition: "theme, padding",
		padding: {
			"": "$block-padding $right-padding $block-padding $left-padding",
			"type=link": "0"
		}
	}
};
const ButtonElement = tasty({
	qa: "Button",
	styles: DEFAULT_BUTTON_STYLES,
	variants: {
		"default.primary": DEFAULT_PRIMARY_STYLES,
		"default.secondary": DEFAULT_SECONDARY_STYLES,
		"default.outline": DEFAULT_OUTLINE_STYLES,
		"default.neutral": DEFAULT_NEUTRAL_STYLES,
		"default.clear": DEFAULT_CLEAR_STYLES,
		"default.link": DEFAULT_LINK_STYLES,
		"danger.primary": DANGER_PRIMARY_STYLES,
		"danger.secondary": DANGER_SECONDARY_STYLES,
		"danger.outline": DANGER_OUTLINE_STYLES,
		"danger.neutral": DANGER_NEUTRAL_STYLES,
		"danger.clear": DANGER_CLEAR_STYLES,
		"danger.link": DANGER_LINK_STYLES,
		"success.primary": SUCCESS_PRIMARY_STYLES,
		"success.secondary": SUCCESS_SECONDARY_STYLES,
		"success.outline": SUCCESS_OUTLINE_STYLES,
		"success.neutral": SUCCESS_NEUTRAL_STYLES,
		"success.clear": SUCCESS_CLEAR_STYLES,
		"success.link": SUCCESS_LINK_STYLES,
		"warning.primary": WARNING_PRIMARY_STYLES,
		"warning.secondary": WARNING_SECONDARY_STYLES,
		"warning.outline": WARNING_OUTLINE_STYLES,
		"warning.neutral": WARNING_NEUTRAL_STYLES,
		"warning.clear": WARNING_CLEAR_STYLES,
		"warning.link": WARNING_LINK_STYLES,
		"note.primary": NOTE_PRIMARY_STYLES,
		"note.secondary": NOTE_SECONDARY_STYLES,
		"note.outline": NOTE_OUTLINE_STYLES,
		"note.neutral": NOTE_NEUTRAL_STYLES,
		"note.clear": NOTE_CLEAR_STYLES,
		"note.link": NOTE_LINK_STYLES,
		"special.primary": SPECIAL_PRIMARY_STYLES,
		"special.secondary": SPECIAL_SECONDARY_STYLES,
		"special.outline": SPECIAL_OUTLINE_STYLES,
		"special.neutral": SPECIAL_NEUTRAL_STYLES,
		"special.clear": SPECIAL_CLEAR_STYLES,
		"special.link": SPECIAL_LINK_STYLES
	}
});
const Button = forwardRef(function Button(allProps, ref) {
	const splitContext = useButtonSplitContext();
	let { type, size: sizeProp, label, children, theme = splitContext?.theme ?? "default", icon: iconProp, rightIcon: rightIconProp, mods, download, tooltip = true, defaultTooltipPlacement = "top", ...props } = allProps;
	type = type ?? splitContext?.type;
	const size = sizeProp ?? splitContext?.size ?? (type === "link" ? "inline" : "medium");
	const isDisabled = props.isDisabled ?? props.isLoading ?? splitContext?.isDisabled;
	const isLoading = props.isLoading;
	const isSelected = props.isSelected;
	const { actionProps, isPressed } = useAction({
		...allProps,
		isDisabled,
		...label ? { label } : {}
	}, ref);
	const styles = extractStyles(props, STYLE_PROPS);
	const isDisabledElement = actionProps.isDisabled;
	delete actionProps.isDisabled;
	const baseMods = useMemo(() => ({
		pressed: isPressed && !isDisabled,
		loading: isLoading,
		selected: isSelected,
		...mods
	}), [
		isPressed,
		isDisabled,
		isLoading,
		isSelected,
		mods
	]);
	const resolvedIcon = useMemo(() => resolveIcon(iconProp, baseMods), [iconProp, baseMods]);
	const resolvedRightIcon = useMemo(() => resolveIcon(rightIconProp, baseMods), [rightIconProp, baseMods]);
	const hasLeftSlot = resolvedIcon.hasSlot;
	const hasRightSlot = resolvedRightIcon.hasSlot;
	const icon = resolvedIcon.content;
	const rightIcon = resolvedRightIcon.content;
	const iconKey = isLoading ? "loading" : isValidElement(icon) ? icon.type?.displayName || icon.type?.name || "icon" : icon ? "icon" : "empty";
	const rightIconKey = isValidElement(rightIcon) ? rightIcon.type?.displayName || rightIcon.type?.name || "icon" : rightIcon ? "icon" : "empty";
	children = children || hasLeftSlot || hasRightSlot ? children : label;
	const specifiedLabel = label ?? props["aria-label"] ?? props["aria-labelledby"];
	useWarn(!children && hasLeftSlot && !specifiedLabel, {
		key: ["button-icon-no-label", hasLeftSlot],
		args: ["accessibility issue:", "If you provide `icon` property for a Button and do not provide any children then you should specify the `aria-label` property to make sure the Button element stays accessible."]
	});
	useWarn(!children && !hasLeftSlot && !specifiedLabel, {
		key: ["button-no-content-no-label", hasLeftSlot],
		args: ["accessibility issue:", "If you provide no children for a Button then you should specify the `aria-label` property to make sure the Button element stays accessible."]
	});
	if (!children && !specifiedLabel) label = "Unnamed";
	const hasLeftIcon = !!(hasLeftSlot || isLoading);
	const hasChildren = children != null;
	const singleIcon = !!((hasLeftIcon && !hasRightSlot || hasRightSlot && !hasLeftIcon) && !hasChildren);
	const hasIcons = hasLeftIcon || hasRightSlot;
	const rawChildren = !!(hasChildren && typeof children !== "string" && !Children.toArray(children).some((child) => typeof child === "string"));
	const [isIconShown, setIsIconShown] = useState(hasLeftIcon);
	const [isRightIconShown, setIsRightIconShown] = useState(hasRightSlot);
	const isFirstRender = useIsFirstRender();
	const modifiers = useMemo(() => ({
		...baseMods,
		"has-icons": hasIcons,
		"has-icon": hasLeftIcon,
		"is-icon-shown": isIconShown,
		"has-right-icon": hasRightSlot,
		"is-right-icon-shown": isRightIconShown,
		"single-icon": singleIcon,
		"text-only": !!(hasChildren && typeof children === "string" && !hasIcons),
		"raw-children": rawChildren,
		"has-content": children != null
	}), [
		baseMods,
		children,
		hasLeftIcon,
		hasRightSlot,
		singleIcon,
		hasIcons,
		hasChildren,
		rawChildren,
		isIconShown,
		isRightIconShown
	]);
	const { labelProps: finalLabelProps, labelRef, renderWithTooltip } = useAutoTooltip({
		tooltip,
		children,
		labelProps: void 0
	});
	const renderButtonElement = (tooltipTriggerProps, tooltipRef) => {
		const handleRef = (element) => {
			const domRef = actionProps.ref;
			if (typeof domRef === "function") domRef(element);
			else if (domRef) domRef.current = element;
			if (tooltipRef) tooltipRef.current = element;
		};
		const isCustomSize = typeof size === "number" || size != null && !BUTTON_SIZE_VALUES.includes(size);
		const sizeTokenValue = typeof size === "number" ? `${size}px` : isCustomSize ? size : void 0;
		return /* @__PURE__ */ jsxs(ButtonElement, {
			download,
			...mergeProps(actionProps, tooltipTriggerProps || {}),
			ref: handleRef,
			mods: {
				...actionProps.mods,
				...modifiers
			},
			disabled: isDisabledElement,
			variant: `${theme}.${type ?? "outline"}`,
			"data-theme": theme,
			"data-type": type ?? "outline",
			"data-size": size,
			styles,
			tokens: sizeTokenValue ? { $size: sizeTokenValue } : void 0,
			children: [
				/* @__PURE__ */ jsx(DisplayTransition, {
					isShown: hasLeftIcon,
					animateOnMount: !isFirstRender,
					onToggle: setIsIconShown,
					children: ({ ref }) => /* @__PURE__ */ jsx("div", {
						ref,
						"data-element": "Icon",
						"aria-hidden": "true",
						children: /* @__PURE__ */ jsx(IconSwitch, {
							noWrapper: true,
							contentKey: iconKey,
							children: isLoading ? /* @__PURE__ */ jsx(LoadingIcon, {}) : icon
						})
					})
				}),
				hasChildren && (rawChildren ? children : /* @__PURE__ */ jsx("div", {
					"data-element": "Label",
					...finalLabelProps,
					ref: labelRef,
					children
				})),
				/* @__PURE__ */ jsx(DisplayTransition, {
					isShown: hasRightSlot,
					animateOnMount: !isFirstRender,
					onToggle: setIsRightIconShown,
					children: ({ ref }) => /* @__PURE__ */ jsx("div", {
						ref,
						"data-element": "RightIcon",
						"aria-hidden": "true",
						children: /* @__PURE__ */ jsx(IconSwitch, {
							noWrapper: true,
							contentKey: rightIconKey,
							children: rightIcon
						})
					})
				})
			]
		});
	};
	return renderWithTooltip(renderButtonElement, defaultTooltipPlacement);
});

//#endregion
export { Button, DEFAULT_BUTTON_STYLES };
//# sourceMappingURL=Button.js.map