import { cn } from "./index3.js";
import { FieldTooltip } from "./index19.js";
import { hasFieldProps, splitFieldProps } from "./index20.js";
import { Field, FieldBottom, FieldBottomRight, FieldControl, FieldDescription, FieldError, FieldLabel, FieldTop, FieldTopRight } from "./index22.js";
import { ChevronDown, ChevronUp, Minus, Plus } from "lucide-react";
import * as React from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { Input } from "@base-ui/react/input";
//#region src/components/atoms/forms/NumberInput/NumberInput.tsx
var sizeClasses = {
	sm: "h-8 text-sm",
	md: "h-9 text-sm",
	lg: "h-11 text-base"
};
var inputSizeClasses = {
	sm: "px-2",
	md: "px-3",
	lg: "px-4"
};
var buttonSizeClasses = {
	sm: "[&>svg]:size-3.5",
	md: "[&>svg]:size-4",
	lg: "[&>svg]:size-5"
};
function clamp(value, min, max) {
	let result = value;
	if (min !== void 0 && result < min) result = min;
	if (max !== void 0 && result > max) result = max;
	return result;
}
function useHoldRepeat(callback, { delay = 400, interval = 100 } = {}) {
	const timeoutRef = React.useRef(void 0);
	const intervalRef = React.useRef(void 0);
	const start = React.useCallback(() => {
		callback();
		timeoutRef.current = setTimeout(() => {
			intervalRef.current = setInterval(callback, interval);
		}, delay);
	}, [
		callback,
		delay,
		interval
	]);
	const stop = React.useCallback(() => {
		if (timeoutRef.current) clearTimeout(timeoutRef.current);
		if (intervalRef.current) clearInterval(intervalRef.current);
	}, []);
	React.useEffect(() => {
		return stop;
	}, [stop]);
	return {
		start,
		stop
	};
}
function StepButton({ onClick, disabled, children, className, ...props }) {
	const { start, stop } = useHoldRepeat(onClick);
	return /* @__PURE__ */ jsx("button", {
		type: "button",
		tabIndex: -1,
		disabled,
		onMouseDown: disabled ? void 0 : start,
		onMouseUp: stop,
		onMouseLeave: stop,
		onTouchStart: disabled ? void 0 : start,
		onTouchEnd: stop,
		className: cn("flex items-center justify-center transition-[colors,transform] duration-150 ease-smooth motion-reduce:transition-none", "hover:bg-muted active:bg-muted/80 active:scale-95 motion-reduce:active:scale-100", "disabled:opacity-50 disabled:pointer-events-none", "[@media(pointer:coarse)]:min-h-11 [@media(pointer:coarse)]:min-w-11", className),
		...props,
		children
	});
}
var NumberInputControl = React.forwardRef(({ className, value: controlledValue, defaultValue = 0, onChange, min, max, step = 1, variant = "default", size = "md", destructive = false, disabled, readOnly, ...props }, ref) => {
	const isControlled = controlledValue !== void 0;
	const [internalValue, setInternalValue] = React.useState(defaultValue);
	const value = isControlled ? controlledValue : internalValue;
	const [inputValue, setInputValue] = React.useState(String(value));
	React.useEffect(() => {
		setInputValue(String(value));
	}, [value]);
	const updateValue = React.useCallback((newValue) => {
		const clamped = clamp(newValue, min, max);
		if (!isControlled) setInternalValue(clamped);
		onChange?.(clamped);
		setInputValue(String(clamped));
	}, [
		isControlled,
		min,
		max,
		onChange
	]);
	const increment = React.useCallback(() => {
		updateValue(value + step);
	}, [
		value,
		step,
		updateValue
	]);
	const decrement = React.useCallback(() => {
		updateValue(value - step);
	}, [
		value,
		step,
		updateValue
	]);
	const handleInputChange = (e) => {
		setInputValue(e.target.value);
	};
	const handleBlur = (e) => {
		const parsed = parseFloat(inputValue);
		if (!Number.isNaN(parsed)) updateValue(parsed);
		else setInputValue(String(value));
		props.onBlur?.(e);
	};
	const handleKeyDown = (e) => {
		if (e.key === "ArrowUp") {
			e.preventDefault();
			updateValue(value + step * (e.shiftKey ? 10 : 1));
		} else if (e.key === "ArrowDown") {
			e.preventDefault();
			updateValue(value - step * (e.shiftKey ? 10 : 1));
		}
		props.onKeyDown?.(e);
	};
	const isAtMin = min !== void 0 && value <= min;
	const isAtMax = max !== void 0 && value >= max;
	const showButtons = !readOnly;
	if (variant === "default") return /* @__PURE__ */ jsx("div", {
		"data-slot": "number-input",
		className: cn("relative flex", className),
		children: /* @__PURE__ */ jsxs("div", {
			className: cn("flex w-full items-center overflow-hidden rounded-lg border transition-[border-color,box-shadow] duration-200 ease-smooth motion-reduce:transition-none", "border-input bg-card", destructive && "border-destructive", disabled && "opacity-50"),
			children: [/* @__PURE__ */ jsx(Input, {
				ref,
				type: "text",
				inputMode: "numeric",
				role: "spinbutton",
				"data-slot": "number-input-field",
				value: inputValue,
				onChange: handleInputChange,
				onBlur: handleBlur,
				onKeyDown: handleKeyDown,
				disabled,
				readOnly,
				"aria-invalid": destructive || void 0,
				"aria-valuemin": min,
				"aria-valuemax": max,
				"aria-valuenow": value,
				className: cn("flex-1 border-0 bg-transparent text-center outline-none", "focus:ring-0", sizeClasses[size], inputSizeClasses[size]),
				...props
			}), showButtons && /* @__PURE__ */ jsxs("div", {
				className: "flex items-center gap-1.5 px-1.5",
				children: [/* @__PURE__ */ jsx(StepButton, {
					onClick: decrement,
					disabled: disabled || isAtMin,
					"aria-label": "Decrease value",
					className: cn("rounded bg-primary/10 p-1 text-primary", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Minus, {})
				}), /* @__PURE__ */ jsx(StepButton, {
					onClick: increment,
					disabled: disabled || isAtMax,
					"aria-label": "Increase value",
					className: cn("rounded bg-primary/10 p-1 text-primary", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Plus, {})
				})]
			})]
		})
	});
	if (variant === "verticalButtons") return /* @__PURE__ */ jsx("div", {
		"data-slot": "number-input",
		className: cn("relative flex", className),
		children: /* @__PURE__ */ jsxs("div", {
			className: cn("flex w-full items-center overflow-hidden rounded-lg border transition-[border-color,box-shadow] duration-200 ease-smooth motion-reduce:transition-none", "border-input bg-card", destructive && "border-destructive", disabled && "opacity-50"),
			children: [/* @__PURE__ */ jsx(Input, {
				ref,
				type: "text",
				inputMode: "numeric",
				role: "spinbutton",
				"data-slot": "number-input-field",
				value: inputValue,
				onChange: handleInputChange,
				onBlur: handleBlur,
				onKeyDown: handleKeyDown,
				disabled,
				readOnly,
				"aria-invalid": destructive || void 0,
				"aria-valuemin": min,
				"aria-valuemax": max,
				"aria-valuenow": value,
				className: cn("flex-1 border-0 bg-transparent text-center outline-none", "focus:ring-0", sizeClasses[size], inputSizeClasses[size]),
				...props
			}), showButtons && /* @__PURE__ */ jsxs("div", {
				className: "flex h-full flex-col border-l border-input",
				children: [/* @__PURE__ */ jsx(StepButton, {
					onClick: increment,
					disabled: disabled || isAtMax,
					"aria-label": "Increase value",
					className: cn("flex-1 border-b border-input px-1.5 text-muted-foreground", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(ChevronUp, {})
				}), /* @__PURE__ */ jsx(StepButton, {
					onClick: decrement,
					disabled: disabled || isAtMin,
					"aria-label": "Decrease value",
					className: cn("flex-1 px-1.5 text-muted-foreground", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(ChevronDown, {})
				})]
			})]
		})
	});
	if (variant === "horizontalButtons") return /* @__PURE__ */ jsx("div", {
		"data-slot": "number-input",
		className: cn("relative flex", className),
		children: /* @__PURE__ */ jsxs("div", {
			className: cn("flex w-full items-center overflow-hidden rounded-lg border transition-[border-color,box-shadow] duration-200 ease-smooth motion-reduce:transition-none", "border-input bg-card", destructive && "border-destructive", disabled && "opacity-50"),
			children: [/* @__PURE__ */ jsx(Input, {
				ref,
				type: "text",
				inputMode: "numeric",
				role: "spinbutton",
				"data-slot": "number-input-field",
				value: inputValue,
				onChange: handleInputChange,
				onBlur: handleBlur,
				onKeyDown: handleKeyDown,
				disabled,
				readOnly,
				"aria-invalid": destructive || void 0,
				"aria-valuemin": min,
				"aria-valuemax": max,
				"aria-valuenow": value,
				className: cn("flex-1 border-0 bg-transparent text-center outline-none", "focus:ring-0", sizeClasses[size], inputSizeClasses[size]),
				...props
			}), showButtons && /* @__PURE__ */ jsxs("div", {
				className: "flex h-full items-center",
				children: [/* @__PURE__ */ jsx(StepButton, {
					onClick: decrement,
					disabled: disabled || isAtMin,
					"aria-label": "Decrease value",
					className: cn("h-full border-l border-input px-2.5 text-muted-foreground", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Minus, {})
				}), /* @__PURE__ */ jsx(StepButton, {
					onClick: increment,
					disabled: disabled || isAtMax,
					"aria-label": "Increase value",
					className: cn("h-full border-l border-input px-2.5 text-muted-foreground", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Plus, {})
				})]
			})]
		})
	});
	if (variant === "stretchedButtons") return /* @__PURE__ */ jsx("div", {
		"data-slot": "number-input",
		className: cn("relative flex", className),
		children: /* @__PURE__ */ jsxs("div", {
			className: cn("flex w-full items-center overflow-hidden rounded-lg border transition-[border-color,box-shadow] duration-200 ease-smooth motion-reduce:transition-none", "border-input bg-card", destructive && "border-destructive", disabled && "opacity-50"),
			children: [
				showButtons && /* @__PURE__ */ jsx(StepButton, {
					onClick: decrement,
					disabled: disabled || isAtMin,
					"aria-label": "Decrease value",
					className: cn("h-full border-r border-input px-2.5 text-muted-foreground", buttonSizeClasses[size], sizeClasses[size]),
					children: /* @__PURE__ */ jsx(Minus, {})
				}),
				/* @__PURE__ */ jsx(Input, {
					ref,
					type: "text",
					inputMode: "numeric",
					role: "spinbutton",
					"data-slot": "number-input-field",
					value: inputValue,
					onChange: handleInputChange,
					onBlur: handleBlur,
					onKeyDown: handleKeyDown,
					disabled,
					readOnly,
					"aria-invalid": destructive || void 0,
					"aria-valuemin": min,
					"aria-valuemax": max,
					"aria-valuenow": value,
					className: cn("flex-1 border-0 bg-transparent text-center outline-none", "focus:ring-0", sizeClasses[size], inputSizeClasses[size]),
					...props
				}),
				showButtons && /* @__PURE__ */ jsx(StepButton, {
					onClick: increment,
					disabled: disabled || isAtMax,
					"aria-label": "Increase value",
					className: cn("h-full border-l border-input px-2.5 text-muted-foreground", buttonSizeClasses[size], sizeClasses[size]),
					children: /* @__PURE__ */ jsx(Plus, {})
				})
			]
		})
	});
	if (variant === "mini") return /* @__PURE__ */ jsx("div", {
		"data-slot": "number-input",
		className: cn("relative flex w-32", className),
		children: /* @__PURE__ */ jsxs("div", {
			className: cn("flex w-full items-center gap-1.5 overflow-hidden rounded-lg border px-3 py-2", "border-input bg-card", destructive && "border-destructive", disabled && "opacity-50"),
			children: [
				showButtons && /* @__PURE__ */ jsx(StepButton, {
					onClick: decrement,
					disabled: disabled || isAtMin,
					"aria-label": "Decrease value",
					className: cn("rounded bg-primary/10 p-1 text-primary", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Minus, {})
				}),
				/* @__PURE__ */ jsx(Input, {
					ref,
					type: "text",
					inputMode: "numeric",
					role: "spinbutton",
					"data-slot": "number-input-field",
					value: inputValue,
					onChange: handleInputChange,
					onBlur: handleBlur,
					onKeyDown: handleKeyDown,
					disabled,
					readOnly,
					"aria-invalid": destructive || void 0,
					"aria-valuemin": min,
					"aria-valuemax": max,
					"aria-valuenow": value,
					className: cn("flex-1 border-0 bg-transparent text-center text-sm outline-none", "focus:ring-0"),
					...props
				}),
				showButtons && /* @__PURE__ */ jsx(StepButton, {
					onClick: increment,
					disabled: disabled || isAtMax,
					"aria-label": "Increase value",
					className: cn("rounded bg-primary/10 p-1 text-primary", buttonSizeClasses[size]),
					children: /* @__PURE__ */ jsx(Plus, {})
				})
			]
		})
	});
	return null;
});
NumberInputControl.displayName = "NumberInputControl";
var NumberInput = React.forwardRef((props, ref) => {
	const [fieldPropsObj, controlProps] = splitFieldProps(props);
	if (!hasFieldProps(fieldPropsObj)) return /* @__PURE__ */ jsx(NumberInputControl, {
		ref,
		...controlProps,
		required: fieldPropsObj.required
	});
	const { label, required, labelIcon, tooltip, topRight, description, bottomRight, error, fieldClassName } = fieldPropsObj;
	const cp = controlProps;
	const hasTopRow = label || topRight;
	const hasBottomRow = description || bottomRight || error;
	return /* @__PURE__ */ jsxs(Field, {
		state: error ? "destructive" : void 0,
		disabled: cp.disabled,
		className: fieldClassName,
		children: [
			hasTopRow && /* @__PURE__ */ jsxs(FieldTop, { children: [label && /* @__PURE__ */ jsxs(FieldLabel, {
				required,
				labelIcon,
				children: [label, tooltip && /* @__PURE__ */ jsx(FieldTooltip, { content: tooltip })]
			}), topRight && /* @__PURE__ */ jsx(FieldTopRight, { children: topRight })] }),
			/* @__PURE__ */ jsx(FieldControl, { children: () => /* @__PURE__ */ jsx(NumberInputControl, {
				ref,
				...cp,
				required,
				destructive: !!error || cp.destructive
			}) }),
			hasBottomRow && /* @__PURE__ */ jsxs(FieldBottom, { children: [
				error && /* @__PURE__ */ jsx(FieldError, { children: error }),
				!error && description && /* @__PURE__ */ jsx(FieldDescription, { children: description }),
				bottomRight && /* @__PURE__ */ jsx(FieldBottomRight, {
					className: "ms-auto",
					children: bottomRight
				})
			] })
		]
	});
});
NumberInput.displayName = "NumberInput";
//#endregion
export { NumberInput };

//# sourceMappingURL=index30.js.map