/** @license MIT | @cube-dev/ui-kit v0.142.7 | Cube Dev Team */
import { extractStyles } from "../../../utils/styles.js";
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
import { useCombinedRefs } from "../../../utils/react/useCombinedRefs.js";
import { useFocus as useFocus$1 } from "../../../utils/react/interactions.js";
import { LoadingIcon } from "../../../icons/LoadingIcon.js";
import { useProviderProps } from "../../../provider.js";
import { useFormProps } from "../../form/Form/Form.js";
import { useFieldProps } from "../../form/Form/use-field/use-field-props.js";
import { wrapWithField } from "../../form/wrapper.js";
import { InvalidIcon } from "../../shared/InvalidIcon.js";
import { ValidIcon } from "../../shared/ValidIcon.js";
import { BASE_STYLES, BLOCK_STYLES, COLOR_STYLES, OUTER_STYLES, tasty } from "@tenphi/tasty";
import { cloneElement, forwardRef, useImperativeHandle, useMemo, useRef } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { useHover } from "react-aria";
import { createFocusableRef } from "@react-spectrum/utils";

//#region src/components/fields/TextInput/TextInputBase.tsx
const ADD_STYLES = {
	$: ">",
	display: "grid",
	placeContent: "stretch",
	placeItems: "center",
	gridRows: "1sf",
	flow: "column",
	gap: 0,
	cursor: "inherit",
	opacity: {
		"": 1,
		disabled: "$disabled-opacity"
	}
};
const INPUT_WRAPPER_STYLES = {
	display: "grid",
	flow: "row",
	position: "relative",
	gridColumns: {
		"": "1sf",
		prefix: "max-content 1sf",
		suffix: "1sf max-content",
		"prefix & suffix": "max-content 1sf max-content"
	},
	gridRows: "1sf",
	placeItems: "stretch",
	fill: {
		"": "#surface",
		disabled: "#disabled-surface"
	},
	border: {
		"": true,
		valid: "#success-text.50",
		invalid: "#danger-text.50",
		focused: "#primary-text",
		"valid & focused": "#success-text",
		"invalid & focused": "#danger-text",
		disabled: true
	},
	preset: "t3",
	radius: true,
	cursor: "text",
	color: {
		"": "#dark-02",
		focused: "#dark-02",
		invalid: "#danger-text",
		disabled: "#dark.30"
	},
	zIndex: {
		"": "initial",
		focused: 1
	},
	boxSizing: "border-box",
	transition: "theme",
	backgroundClip: "content-box",
	height: {
		"": "$size $size",
		multiline: "min $size"
	},
	$size: {
		"": "$size-md",
		"size=small": "$size-sm",
		"size=medium": "$size-md",
		"size=large": "$size-lg"
	},
	Prefix: ADD_STYLES,
	Suffix: ADD_STYLES,
	State: {
		$: "> Suffix >",
		display: "flex"
	},
	InputIcon: {
		display: "grid",
		placeItems: "center",
		width: "min $size-sm",
		color: "inherit",
		fontSize: "$icon-size"
	},
	ValidationIcon: {
		$: "> Suffix > State >",
		display: "grid",
		placeItems: "center",
		width: {
			"": "min $size-sm",
			suffix: "min $size-xs"
		},
		fontSize: "$icon-size"
	}
};
const InputWrapperElement = tasty({
	qa: "InputWrapper",
	styles: INPUT_WRAPPER_STYLES
});
const PROP_STYLES = [
	...BASE_STYLES,
	...OUTER_STYLES,
	...BLOCK_STYLES,
	...COLOR_STYLES
];
const DEFAULT_INPUT_STYLES = {
	recipe: "reset input / input-autofill",
	placeSelf: "stretch",
	width: "initial 100% 100%",
	transition: "theme",
	radius: true,
	padding: "$vertical-padding $right-padding $vertical-padding $left-padding",
	textAlign: "left",
	preset: "t3",
	flexGrow: 1,
	margin: {
		"": 0,
		multiline: "((($size-md - 1lh) / 2) - 1bw) 0",
		"multiline & size=small": "((($size-sm - 1lh) / 2) - 1bw) 0",
		"multiline & size=large": "((($size-lg - 1lh) / 2) - 1bw) 0"
	},
	resize: "none",
	userSelect: "auto",
	Placeholder: {
		$: "&::placeholder",
		recipe: "input-placeholder"
	},
	"&::-webkit-search-cancel-button": { recipe: "input-search-cancel-button" },
	"$vertical-padding": 0,
	"$left-padding": {
		"": "(1x - 1bw)",
		"size=small": "(1x - 1bw)",
		"size=large": "(1.25x - 1bw)",
		"size=xlarge": "(1.5x - 1bw)",
		prefix: "0"
	},
	"$right-padding": {
		"": "(1x - 1bw)",
		"size=small": "(1x - 1bw)",
		"size=large": "(1.25x - 1bw)",
		"size=xlarge": "(1.5x - 1bw)",
		suffix: "0"
	}
};
const InputElement = tasty({
	qa: "Input",
	styles: DEFAULT_INPUT_STYLES
});
function _TextInputBase(props, ref) {
	props = useProviderProps(props);
	props = useFormProps(props);
	props = useFieldProps(props, {
		defaultValidationTrigger: "onBlur",
		valuePropsMapper: ({ value, onChange }) => ({
			value: typeof value === "string" || typeof value === "number" ? String(value) : "",
			onChange
		})
	});
	let { qa, mods, validationState, prefix, isDisabled, multiLine, autoFocus, inputProps, wrapperProps, inputRef, isLoading, loadingIndicator, value, inputStyles = {}, suffix, suffixPosition = "before", wrapperRef, tooltip, rows = 1, size = "medium", autocomplete, icon, maxLength, minLength, form, resize, ...otherProps } = props;
	let styles = extractStyles(otherProps, PROP_STYLES);
	let type = otherProps.type;
	if (resize) inputStyles = {
		...inputStyles,
		resize
	};
	let ElementType = multiLine ? "textarea" : "input";
	let { isFocused, focusProps } = useFocus$1({ isDisabled });
	let { hoverProps, isHovered } = useHover({ isDisabled });
	let domRef = useRef(null);
	inputRef = useCombinedRefs(inputRef);
	useImperativeHandle(ref, () => ({
		...createFocusableRef(domRef, inputRef),
		select() {
			if (inputRef?.current) inputRef.current.select();
		},
		getInputElement() {
			return inputRef?.current;
		}
	}));
	let isInvalid = validationState === "invalid";
	let validation = cloneElement(isInvalid ? InvalidIcon : ValidIcon);
	if (!inputProps?.placeholder) {
		if (!inputProps) inputProps = {};
		inputProps.placeholder = " ";
	}
	if (icon) {
		icon = /* @__PURE__ */ jsx("div", {
			"data-element": "InputIcon",
			children: icon
		});
		if (prefix) prefix = /* @__PURE__ */ jsxs(Fragment$1, { children: [icon, prefix] });
		else prefix = icon;
	}
	const modifiers = useMemo(() => ({
		invalid: isInvalid,
		valid: validationState === "valid",
		loadable: !!loadingIndicator,
		focused: isFocused,
		hovered: isHovered,
		disabled: isDisabled,
		multiline: multiLine,
		prefix: !!prefix,
		suffix: validationState && !isLoading || isLoading || !!suffix,
		...mods
	}), [
		mods,
		isInvalid,
		validationState,
		loadingIndicator,
		isFocused,
		isDisabled,
		isHovered,
		multiLine,
		prefix,
		suffix
	]);
	const textSecurityStyles = multiLine && type === "password" && inputProps.value?.length ? { fontFamily: "text-security-disc" } : {};
	return wrapWithField(/* @__PURE__ */ jsxs(InputWrapperElement, {
		ref: wrapperRef,
		mods: modifiers,
		"data-size": size,
		styles,
		...wrapperProps,
		children: [
			prefix ? /* @__PURE__ */ jsx("div", {
				"data-element": "Prefix",
				children: prefix
			}) : null,
			/* @__PURE__ */ jsx(InputElement, {
				qa: qa || "Input",
				as: ElementType,
				"data-input-type": "textinput",
				...mergeProps$1(inputProps, focusProps, hoverProps),
				ref: inputRef,
				rows: multiLine ? rows : void 0,
				mods: modifiers,
				style: textSecurityStyles,
				"data-autofocus": autoFocus ? "" : void 0,
				autoFocus,
				"data-size": size,
				autoComplete: autocomplete,
				styles: inputStyles,
				disabled: !!isDisabled,
				maxLength,
				minLength
			}),
			validationState && !isLoading || isLoading || suffix ? /* @__PURE__ */ jsxs("div", {
				"data-element": "Suffix",
				children: [
					suffixPosition === "before" ? suffix : null,
					validationState && !isLoading || isLoading ? /* @__PURE__ */ jsxs("div", {
						"data-element": "State",
						children: [validationState && !isLoading ? validation : null, isLoading && /* @__PURE__ */ jsx(LoadingIcon, { "data-element": "InputIcon" })]
					}) : null,
					suffixPosition === "after" ? suffix : null
				]
			}) : null
		]
	}), domRef, {
		...props,
		form: void 0
	});
}
const TextInputBase = forwardRef(_TextInputBase);

//#endregion
export { DEFAULT_INPUT_STYLES, INPUT_WRAPPER_STYLES, TextInputBase };
//# sourceMappingURL=TextInputBase.js.map