/*! ratio-ui · design system for knowledge sharing · https://github.com/losol/ratio-ui · (c) 2026 Losol AS · MPL-2.0 */
"use client";
import { cn } from "../../utils/cn.js";
import { LoaderCircle } from "../../icons/index.js";
import { Avatar } from "../Avatar/Avatar.js";
/* empty css       */
import React, { createContext, forwardRef, useContext } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { Button } from "react-aria-components";
//#region src/core/Button/Button.tsx
var ANIMATION_CLASSES = [
	"ratio-button",
	"transition-all",
	"duration-200",
	"ease-in-out"
].join(" ");
var buttonStyles = {
	primary: `border border-transparent font-medium bg-(--primary) hover:opacity-90 text-(--text-on-primary) rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`,
	secondary: `border border-border-1 font-medium text-(--text-dark) dark:text-(--text-light) bg-card hover:bg-card-hover hover:border-border-2 rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`,
	light: `font-medium bg-primary-100 text-(--text-dark) dark:text-(--text-light) hover:bg-primary-200 dark:bg-primary-800 dark:hover:bg-primary-700 rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`,
	text: `font-medium bg-transparent hover:bg-primary-200 hover:bg-opacity-20 rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`,
	outline: `border border-border-2 font-medium hover:border-(--primary) hover:bg-card-hover rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`,
	danger: `border border-transparent font-medium bg-error hover:opacity-90 text-error-on rounded-[var(--button-radius,9999px)] ${ANIMATION_CLASSES}`
};
var buttonSizes = {
	sm: "px-3 py-1 text-xs",
	md: "px-4 py-2 text-sm",
	lg: "px-6 py-3 text-base"
};
var ButtonSizeContext = createContext("md");
/**
* Per-size trigger-pill tuning:
* - `avatar` — the avatar preset (the tallest child, so it drives pill height).
* - `pull` — negative left margin so the avatar sits ~concentric with the
*   pill's rounded left cap (a small inset, not fully flush).
* - `py` — tightens the pill vertically (overriding the size's default) so the
*   avatar fills the height instead of floating in a too-tall pill.
*/
var AVATAR_PILL = {
	sm: {
		avatar: "sm",
		pull: "-ml-[10px]",
		py: "py-[3px]"
	},
	md: {
		avatar: "sm",
		pull: "-ml-[13px]",
		py: "py-1"
	},
	lg: {
		avatar: "md",
		pull: "-ml-[21px]",
		py: "py-[5px]"
	}
};
/**
* Flush leading avatar for a trigger pill — `<Button><Button.Avatar …/>Name</Button>`.
* Sits concentric with the pill's rounded left edge (via a negative margin that
* eats the button's left padding), so the button keeps its token-driven chrome
* instead of a hand-copied class string.
*/
function ButtonAvatar({ size, className, ...rest }) {
	const preset = AVATAR_PILL[useContext(ButtonSizeContext)];
	return /* @__PURE__ */ jsx(Avatar, {
		size: size ?? preset.avatar,
		className: cn(preset.pull, "shrink-0", className),
		...rest
	});
}
ButtonAvatar.displayName = "Button.Avatar";
/**
* Truncating label for a trigger pill — pairs with {@link ButtonAvatar}. Owns
* the flex `min-w-0` footgun so a long name ellipsizes instead of blowing the
* pill out: `<Button><Button.Avatar …/><Button.Label maxWidth="20ch">{name}</Button.Label></Button>`.
*/
function ButtonLabel({ maxWidth, className, style, children, ...rest }) {
	return /* @__PURE__ */ jsx("span", {
		className: cn("min-w-0 truncate", className),
		style: maxWidth ? {
			maxWidth,
			...style
		} : style,
		...rest,
		children
	});
}
ButtonLabel.displayName = "Button.Label";
/**
* Button — the design system's primary action, built on React Aria's `Button`
* for unified press/keyboard/focus handling. Chrome (shape, shadow, press
* feedback) is token-driven via `.ratio-button` + `--button-*`.
*
* Migration note: `onClick`/`disabled`/`ariaLabel` still work but are
* superseded by `onPress`/`isDisabled`/`aria-label`. Both forms are supported
* until the next major.
*
* Compound: `Button.Avatar` renders a flush leading avatar for trigger pills.
*/
var ButtonRoot = forwardRef(function Button$2({ variant = "primary", size = "md", block = false, disabled, isDisabled, loading = false, icon, children, ariaLabel, className = "", type = "button", onClick, onPress, testId, ...rest }, ref) {
	const sizeClasses = buttonSizes[size];
	const displayClass = block ? "w-full" : "";
	const variantClass = buttonStyles[variant];
	const textColorClass = variant === "text" || variant === "outline" ? "text-(--text)" : "";
	const resolvedDisabled = (isDisabled ?? disabled ?? false) || loading;
	const disabledClasses = resolvedDisabled ? "opacity-75 cursor-not-allowed" : "";
	const { "aria-label": ariaLabelAttr, ...domProps } = rest;
	const childArray = React.Children.toArray(children);
	const hasParts = childArray.some((c) => React.isValidElement(c) && (c.type === ButtonAvatar || c.type === ButtonLabel));
	const hasAvatar = childArray.some((c) => React.isValidElement(c) && c.type === ButtonAvatar);
	const classes = cn(sizeClasses, hasAvatar && AVATAR_PILL[size].py, displayClass, variantClass, textColorClass, disabledClasses, className);
	return /* @__PURE__ */ jsx(Button, {
		ref,
		type,
		isDisabled: resolvedDisabled,
		"aria-label": ariaLabelAttr ?? ariaLabel,
		onPress,
		onClick,
		className: classes,
		"data-testid": testId,
		...domProps,
		children: /* @__PURE__ */ jsx(ButtonSizeContext.Provider, {
			value: size,
			children: /* @__PURE__ */ jsxs("span", {
				className: "flex items-center justify-center gap-2",
				children: [
					loading && /* @__PURE__ */ jsx(LoaderCircle, {
						className: "h-4 w-4 animate-spin shrink-0",
						"aria-hidden": "true"
					}),
					!loading && !hasAvatar && icon && /* @__PURE__ */ jsx("span", {
						className: "shrink-0",
						children: icon
					}),
					hasParts ? children : childArray.length > 0 && /* @__PURE__ */ jsx("span", { children })
				]
			})
		})
	});
});
ButtonRoot.displayName = "Button";
var Button$1 = Object.assign(ButtonRoot, {
	Avatar: ButtonAvatar,
	Label: ButtonLabel
});
//#endregion
export { Button$1 as Button, buttonSizes, buttonStyles };

//# sourceMappingURL=Button2.js.map