/*! © 2026 Yahoo, Inc. UDS v0.0.0-development */
"use client";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const require_runtime = require("../../_virtual/_rolldown/runtime.cjs");
const require_styles_styler = require("../../styles/styler.cjs");
const require_components_IconSlot = require("../IconSlot.cjs");
const require_components_Box = require("../Box.cjs");
const require_components_FormLabel = require("../FormLabel.cjs");
const require_components_client_SpringMotionConfig = require("./SpringMotionConfig.cjs");
let react = require("react");
react = require_runtime.__toESM(react);
let react_jsx_runtime = require("react/jsx-runtime");
let motion_react = require("motion/react");
//#region src/components/client/Switch.tsx
const SIZE_MAP = {
	md: { isOnX: "1.25rem" },
	sm: { isOnX: "0.75rem" }
};
const MotionBox = motion_react.m.create(require_components_Box.Box);
const toggleTransition = {
	layoutVariant: "bouncy",
	layoutSpeed: "4"
};
/**
* **⚙️️ An switch.
*
* @componentType Client component
*
* @description
* A switch (also called a toggle) is a binary on/off input control. It is clickable or touchable on mobile devices allowing users to pick between two clearly opposite choices.
*
* @see
* Check out the {@link https://uds.build/docs/components/switch Switch Docs} for more info
*
* @usage
* - Forms: switch
*
* @example
* ```tsx
* 'use client';
* import { Switch } from "@yahoo/uds";
*
* <Switch label="Name" required />
*```
*
* @related [Checkbox](https://uds.build/docs/components/checkbox).
**/
const Switch = (0, react.forwardRef)(function Switch({ id, isOn: isOnProp, defaultIsOn, onChange, label, labelPosition = "start", size = "md", onIcon, offIcon, reduceMotion: forceReduceMotion, disabled, required, onFocus, onBlur, className, style, slotProps, ...switchProps }, parentRef) {
	const generatedId = (0, react.useId)();
	const uid = id ?? `uds-input-${generatedId}`;
	const rootSlotProps = slotProps?.root ?? {};
	const switchSlotProps = slotProps?.switch ?? {};
	const handleSlotProps = slotProps?.handle ?? {};
	const labelSlotProps = slotProps?.label ?? {};
	const innerRef = (0, react.useRef)(null);
	/**
	* State
	*/
	const isControlled = isOnProp !== void 0;
	const [isOn, setIsOn] = (0, react.useState)(isControlled ? isOnProp : defaultIsOn);
	const [isHovered, setIsHovered] = (0, react.useState)(false);
	/**
	* Derived values
	*/
	const showHoverEffect = (0, react.useMemo)(() => {
		return !disabled && isHovered;
	}, [disabled, isHovered]);
	const { isOnX } = SIZE_MAP[size];
	const motionInitialAndAnimate = (0, react.useMemo)(() => ({
		initial: {
			scale: 1,
			x: isOn ? isOnX : 0
		},
		animate: {
			scale: showHoverEffect ? 1.05 : 1,
			x: isOn ? isOnX : 0
		}
	}), [
		showHoverEffect,
		isOn,
		isOnX
	]);
	/**
	* Handlers
	*/
	const handleChange = (0, react.useCallback)((e) => {
		onChange?.(e);
		if (!isControlled) setIsOn(e.target.checked);
	}, [isControlled, onChange]);
	const handleFocus = (0, react.useCallback)((e) => {
		onFocus?.(e);
	}, [onFocus]);
	const handleBlur = (0, react.useCallback)((e) => {
		onBlur?.(e);
	}, [onBlur]);
	const handleHoverStart = (0, react.useCallback)(() => {
		setIsHovered(true);
	}, []);
	const handleHoverEnd = (0, react.useCallback)(() => {
		setIsHovered(false);
	}, []);
	const prefersReducedMotion = (0, motion_react.useReducedMotion)();
	const reduceMotion = forceReduceMotion ? "always" : "user";
	const cssAnimationDuration = prefersReducedMotion || forceReduceMotion ? "duration-0" : "duration-120";
	/**
	* Effects
	*/
	(0, react.useEffect)(() => {
		if (isControlled) setIsOn(isOnProp);
	}, [isOnProp, isControlled]);
	const classNames = {
		root: require_styles_styler.getStyles({
			switchSizeRoot: size,
			switchVariantRoot: "default",
			switchVariantActiveRoot: isOn ? "on" : "off",
			display: "flex",
			flexDirection: labelPosition === "start" ? "row" : "row-reverse",
			alignItems: "center",
			className: require_styles_styler.cx("group", {
				"cursor-pointer": !disabled,
				"cursor-default": disabled,
				"opacity-50": disabled
			}, className)
		}),
		switch: require_styles_styler.getStyles({
			switchVariantSwitch: "default",
			switchSizeSwitch: size,
			switchVariantActiveSwitch: isOn ? "on" : "off",
			borderRadius: "full",
			position: "relative",
			alignItems: "center",
			className: require_styles_styler.cx("uds-ring", "uds-ring-within", cssAnimationDuration, "transition-[background-color,box-shadow]")
		}),
		handle: require_styles_styler.getStyles({
			switchSizeHandle: size,
			className: require_styles_styler.cx("relative", "pointer-events-none", "uds-border-radius-full", "overflow-hidden")
		}),
		handleCircle: require_styles_styler.getStyles({
			switchVariantActiveHandle: isOn ? "on" : "off",
			switchVariantHandle: "default",
			className: require_styles_styler.cx("absolute", "top-0", "left-0", "right-0", "bottom-0", "opacity-95 group-hover:opacity-100", cssAnimationDuration, "transition-[background-color,box-shadow,opacity]")
		}),
		handleIcon: require_styles_styler.getStyles({
			switchSizeHandleIcon: size,
			switchVariantHandleIcon: "default",
			switchVariantActiveHandleIcon: isOn ? "on" : "off",
			className: require_styles_styler.cx("absolute", "opacity-0", "top-1/2", "left-1/2", "transform", "translate-x-[-50%]", "translate-y-[-50%]", cssAnimationDuration, "transition-opacity")
		}),
		htmlCheckbox: require_styles_styler.cx("cursor-[inherit]", "absolute", "opacity-0", "top-1/2", "left-1/2", "w-[calc(100%+2px)]", "h-[calc(100%+2px)]", "transform", "translate-x-[-50%]", "translate-y-[-50%]"),
		label: require_styles_styler.cx(labelPosition === "start" ? "text-start" : "text-end")
	};
	const RootElement = label ? motion_react.m.label : motion_react.m.div;
	return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_client_SpringMotionConfig.SpringMotionConfig, {
		reducedMotion: reduceMotion,
		...toggleTransition,
		children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(RootElement, {
			className: classNames.root,
			"data-testid": "container",
			style,
			onHoverStart: handleHoverStart,
			onHoverEnd: handleHoverEnd,
			tabIndex: -1,
			...rootSlotProps,
			children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(MotionBox, {
				className: classNames.switch,
				...switchSlotProps,
				children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
					type: "checkbox",
					tabIndex: 0,
					...switchProps,
					ref: (ref) => {
						innerRef.current = ref;
						if (typeof parentRef === "function") parentRef(ref);
						else if (parentRef !== null) parentRef.current = ref;
					},
					onFocus: handleFocus,
					onBlur: handleBlur,
					id: uid,
					disabled,
					required,
					checked: isControlled ? isOn : void 0,
					defaultChecked: isControlled ? void 0 : defaultIsOn,
					onChange: handleChange,
					className: classNames.htmlCheckbox
				}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(MotionBox, {
					className: classNames.handle,
					...motionInitialAndAnimate,
					...handleSlotProps,
					children: [
						/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_Box.Box, { className: classNames.handleCircle }),
						onIcon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_IconSlot.IconSlot, {
							icon: onIcon,
							iconProps: {
								variant: "fill",
								size: "sm"
							},
							"data-testid": "on-icon",
							className: require_styles_styler.cx(classNames.handleIcon, isOn ? "opacity-100" : "opacity-0")
						}),
						offIcon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_IconSlot.IconSlot, {
							icon: offIcon,
							iconProps: {
								variant: "fill",
								size: "sm"
							},
							"data-testid": "off-icon",
							className: require_styles_styler.cx(classNames.handleIcon, !isOn ? "opacity-100" : "opacity-0")
						})
					]
				})]
			}), label && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_components_FormLabel.FormLabel, {
				as: "div",
				variant: "inherit",
				color: "inherit",
				required,
				label,
				className: classNames.label,
				...labelSlotProps
			})]
		})
	});
});
Switch.displayName = "Switch";
//#endregion
exports.Switch = Switch;
