/** @license MIT | @cube-dev/ui-kit v0.0.0-canary-b859c78 | Cube Dev Team */
import { extractStyles } from "../../../tasty/utils/styles.js";
import { INNER_STYLES, OUTER_STYLES } from "../../../tasty/styles/list.js";
import { mergeStyles } from "../../../tasty/utils/merge-styles.js";
import { tasty } from "../../../tasty/tasty.js";
import { filterBaseProps } from "../../../tasty/utils/filter-base-props.js";
import { mergeProps as mergeProps$1 } from "../../../utils/react/mergeProps.js";
import { useCombinedRefs } from "../../../utils/react/useCombinedRefs.js";
import { useDebouncedValue } from "../../../_internal/hooks/use-debounced-value.js";
import { LayoutContextReset } from "./LayoutContext.js";
import { useTinyScrollbar } from "./hooks/useTinyScrollbar.js";
import { clampSize } from "./utils.js";
import { forwardRef, useCallback, useEffect, useMemo, useRef, useState } from "react";
import { jsx, jsxs } from "react/jsx-runtime";
import { useFocusRing, useHover, useMove } from "react-aria";

//#region src/components/content/Layout/LayoutPane.tsx
const HANDLER_WIDTH = 9;
const HANDLER_RESERVED = 5;
const PaneElement = tasty({
	as: "div",
	qa: "LayoutPane",
	styles: {
		container: "pane / inline-size",
		position: "relative",
		display: "grid",
		gridColumns: "1sf",
		gridRows: "1sf",
		placeContent: "stretch",
		placeItems: "stretch",
		placeSelf: "stretch",
		flexShrink: 0,
		flexGrow: 0,
		width: {
			"": "auto",
			"edge=right": "2x $pane-size $pane-size"
		},
		height: {
			"": "2x $pane-size $pane-size",
			"edge=right": "auto"
		},
		boxSizing: "content-box",
		Inner: {
			$: ">",
			display: "flex",
			flow: "column",
			padding: "($content-padding, 1x)",
			paddingRight: {
				"": "($content-padding, 1x)",
				"edge=right": `calc(($content-padding, 1x) + ${HANDLER_RESERVED}px)`
			},
			paddingBottom: {
				"": "($content-padding, 1x)",
				"edge=bottom": `calc(($content-padding, 1x) + ${HANDLER_RESERVED}px)`
			},
			overflow: {
				"": "auto",
				"scrollbar=none": "clip"
			},
			placeSelf: "stretch",
			scrollbar: {
				"": "thin",
				"scrollbar=tiny | scrollbar=none": "none"
			},
			"$layout-border-size": "0"
		},
		ScrollbarV: {
			position: "absolute",
			right: {
				"": "1px",
				"edge=right": `${HANDLER_RESERVED + 1}px`
			},
			top: "$scrollbar-v-top",
			width: "1ow",
			height: "$scrollbar-v-height",
			radius: "round",
			fill: "#dark.35",
			opacity: {
				"": 0,
				"(focused | scrolling) & scrollbar=tiny": 1
			},
			transition: "opacity 0.15s",
			pointerEvents: "none"
		},
		ScrollbarH: {
			$: ">",
			position: "absolute",
			bottom: {
				"": "1px",
				"edge=bottom": `${HANDLER_RESERVED + 1}px`
			},
			left: "$scrollbar-h-left",
			height: "1ow",
			width: "$scrollbar-h-width",
			radius: "round",
			fill: "#dark.35",
			opacity: {
				"": 0,
				"(focused | scrolling) & scrollbar=tiny": 1
			},
			transition: "opacity 0.15s",
			pointerEvents: "none"
		},
		ResizeHandler: {
			position: "absolute",
			width: {
				"": "100%",
				"edge=right": `${HANDLER_WIDTH}px`
			},
			height: {
				"": `${HANDLER_WIDTH}px`,
				"edge=right": "100%"
			},
			right: {
				"": "initial",
				"edge=right": `${(HANDLER_RESERVED - HANDLER_WIDTH) / 2}px`
			},
			bottom: {
				"": `${(HANDLER_RESERVED - HANDLER_WIDTH) / 2}px`,
				"edge=right": "initial"
			},
			top: {
				"": "initial",
				"edge=right": 0
			},
			left: {
				"": 0,
				"edge=right": "initial"
			},
			cursor: {
				"": "row-resize",
				"edge=right": "col-resize",
				disabled: "not-allowed"
			},
			padding: 0,
			outline: 0,
			boxSizing: "border-box",
			transition: "theme"
		},
		Drag: {
			display: "grid",
			gap: "2bw",
			border: 0,
			flow: {
				"": "row",
				"edge=right": "column"
			},
			gridColumns: {
				"": "3px 3px 3px 3px 3px",
				"edge=right": "auto"
			},
			gridRows: {
				"": "auto",
				"edge=right": "3px 3px 3px 3px 3px"
			},
			width: {
				"": "auto",
				"edge=right": "3px"
			},
			height: {
				"": "3px",
				"edge=right": "auto"
			},
			position: "absolute",
			top: "50%",
			left: "50%",
			transform: "translate(-50%, -50%)",
			transition: "theme",
			radius: "round",
			outline: {
				"": "0",
				"focused | drag": "1bw #primary-text"
			},
			outlineOffset: 1
		},
		DragPart: {
			radius: true,
			fill: {
				"": "#dark-03",
				"handlerHovered | drag | focused": "#primary-text",
				disabled: "#dark-04"
			}
		}
	}
});
function PaneResizeHandler(props) {
	const { edge, isDisabled, moveProps, onDoubleClick, onHoverChange, onFocusChange } = props;
	const { hoverProps, isHovered } = useHover({ onHoverChange });
	const { focusProps, isFocusVisible } = useFocusRing();
	const isHorizontal = edge === "right";
	useEffect(() => {
		onFocusChange?.(isFocusVisible);
	}, [isFocusVisible, onFocusChange]);
	return /* @__PURE__ */ jsx("div", {
		"data-element": "ResizeHandler",
		...mergeProps$1(hoverProps, focusProps, isDisabled ? {} : moveProps, {
			tabIndex: isDisabled ? void 0 : 0,
			role: "separator",
			"aria-orientation": isHorizontal ? "vertical" : "horizontal",
			"aria-label": `Resize pane ${edge}`,
			onDoubleClick: isDisabled ? void 0 : onDoubleClick
		}),
		children: !isDisabled && /* @__PURE__ */ jsxs("div", {
			"data-element": "Drag",
			children: [
				/* @__PURE__ */ jsx("div", { "data-element": "DragPart" }),
				/* @__PURE__ */ jsx("div", { "data-element": "DragPart" }),
				/* @__PURE__ */ jsx("div", { "data-element": "DragPart" }),
				/* @__PURE__ */ jsx("div", { "data-element": "DragPart" }),
				/* @__PURE__ */ jsx("div", { "data-element": "DragPart" })
			]
		})
	});
}
function LayoutPane(props, ref) {
	const { resizeEdge = "right", isResizable = false, size: providedSize, defaultSize = 200, minSize, maxSize, onSizeChange, scrollbar = "thin", styles, mods, children, innerRef: innerRefProp, innerProps, ...otherProps } = props;
	const combinedRef = useCombinedRefs(ref);
	const internalInnerRef = useRef(null);
	const combinedInnerRef = useCombinedRefs(innerRefProp, internalInnerRef);
	const prevProvidedSizeRef = useRef(providedSize);
	const isHorizontal = resizeEdge === "right";
	const [isDragging, setIsDragging] = useState(false);
	const [isHandlerHovered, setIsHandlerHovered] = useState(false);
	const [isHandlerFocused, setIsHandlerFocused] = useState(false);
	const debouncedHandlerHovered = useDebouncedValue(isHandlerHovered, 150);
	const [size, setSize] = useState(() => {
		return clampSize(typeof providedSize === "number" ? providedSize : typeof defaultSize === "number" ? defaultSize : 200, minSize, maxSize);
	});
	const outerStyles = extractStyles(otherProps, OUTER_STYLES);
	const innerStyles = extractStyles(otherProps, INNER_STYLES);
	const isTinyScrollbar = scrollbar === "tiny";
	const { hoverProps, isHovered } = useHover({});
	const { handleVStyle, handleHStyle, hasOverflowY, hasOverflowX, isScrolling } = useTinyScrollbar(internalInnerRef, isTinyScrollbar);
	const clampValue = useCallback((value) => clampSize(value, minSize, maxSize), [minSize, maxSize]);
	const { moveProps } = useMove({
		onMoveStart() {
			if (!isResizable) return;
			setIsDragging(true);
		},
		onMove(e) {
			if (!isResizable) return;
			let delta;
			if (e.pointerType === "keyboard") {
				const step = e.shiftKey ? 50 : 10;
				delta = (isHorizontal ? e.deltaX : e.deltaY) * step;
			} else delta = isHorizontal ? e.deltaX : e.deltaY;
			setSize((currentSize) => clampValue(currentSize + delta));
		},
		onMoveEnd() {
			setIsDragging(false);
			setSize((currentSize) => {
				const finalSize = Math.round(clampValue(currentSize));
				onSizeChange?.(finalSize);
				return finalSize;
			});
		}
	});
	useEffect(() => {
		if (prevProvidedSizeRef.current !== providedSize) {
			prevProvidedSizeRef.current = providedSize;
			if (typeof providedSize === "number" && !isDragging) setSize(clampValue(providedSize));
		}
	}, [
		providedSize,
		isDragging,
		clampValue
	]);
	const handleResetSize = useCallback(() => {
		const clampedSize = clampValue((typeof defaultSize === "number" ? defaultSize : parseInt(defaultSize, 10)) || 200);
		setSize(clampedSize);
		onSizeChange?.(clampedSize);
	}, [
		defaultSize,
		clampValue,
		onSizeChange
	]);
	const scrollbarStyle = useMemo(() => {
		if (!isTinyScrollbar) return {};
		return {
			...handleVStyle,
			...handleHStyle
		};
	}, [
		isTinyScrollbar,
		handleVStyle,
		handleHStyle
	]);
	const paneMods = useMemo(() => ({
		scrollbar,
		hovered: isHovered,
		scrolling: isScrolling,
		handlerHovered: debouncedHandlerHovered,
		focused: isHandlerFocused,
		disabled: !isResizable,
		edge: resizeEdge,
		drag: isDragging,
		...mods
	}), [
		scrollbar,
		isHovered,
		isScrolling,
		debouncedHandlerHovered,
		isHandlerFocused,
		isResizable,
		resizeEdge,
		isDragging,
		mods
	]);
	const finalStyles = useMemo(() => {
		return mergeStyles(styles, outerStyles, innerStyles ? { Inner: innerStyles } : null);
	}, [
		styles,
		outerStyles,
		innerStyles
	]);
	const paneStyle = useMemo(() => ({
		...scrollbarStyle,
		"--pane-size": `${size}px`,
		"--min-size": typeof minSize === "number" ? `${minSize}px` : minSize,
		"--max-size": typeof maxSize === "number" ? `${maxSize}px` : maxSize
	}), [
		scrollbarStyle,
		size,
		minSize,
		maxSize
	]);
	return /* @__PURE__ */ jsxs(PaneElement, {
		ref: combinedRef,
		...filterBaseProps(otherProps, { eventProps: true }),
		...hoverProps,
		mods: paneMods,
		styles: finalStyles,
		style: paneStyle,
		children: [
			/* @__PURE__ */ jsx("div", {
				ref: combinedInnerRef,
				"data-element": "Inner",
				...innerProps,
				children: /* @__PURE__ */ jsx(LayoutContextReset, { children })
			}),
			isTinyScrollbar && hasOverflowY && /* @__PURE__ */ jsx("div", { "data-element": "ScrollbarV" }),
			isTinyScrollbar && hasOverflowX && /* @__PURE__ */ jsx("div", { "data-element": "ScrollbarH" }),
			isResizable && /* @__PURE__ */ jsx(PaneResizeHandler, {
				edge: resizeEdge,
				isDisabled: !isResizable,
				moveProps,
				onDoubleClick: handleResetSize,
				onHoverChange: setIsHandlerHovered,
				onFocusChange: setIsHandlerFocused
			})
		]
	});
}
const _LayoutPane = forwardRef(LayoutPane);
_LayoutPane.displayName = "Layout.Pane";

//#endregion
export { _LayoutPane };
//# sourceMappingURL=LayoutPane.js.map