'use client';


import { cn } from "../../utils/cn.mjs";
import { useCallback, useEffect, useRef, useState } from "react";
import { jsx } from "react/jsx-runtime";

//#region src/components/PressableSpan/PressableSpan.tsx
const DEFAULT_PRESS_DETECT_DURATION = 400;
/**
* PressableSpan - An interactive span element that responds to long press gestures
*
* A versatile component that detects long press interactions and provides visual feedback.
* Commonly used for text editing interfaces, selection systems, and interactive content
* that requires differentiation between quick clicks and intentional long presses.
*
* ## Key Features
* - **Long Press Detection**: Configurable press duration for different interaction patterns
* - **Visual Feedback**: Smooth outline transitions to indicate interactive and selected states
* - **Click Outside Detection**: Automatically deselects when clicking outside the component
* - **Touch Support**: Works seamlessly on both desktop and mobile devices
* - **Accessible**: Keyboard navigation support and proper ARIA attributes
*
* ## Use Cases
* - Text editing interfaces where long press activates edit mode
* - Content selection systems with visual feedback
* - Interactive cards or elements that need press-and-hold activation
* - Mobile-friendly interfaces requiring long press gestures
*
* ## Accessibility
* - Uses semantic `role="button"` for proper screen reader announcement
* - Keyboard navigable with `tabIndex={0}`
* - Focus management with proper blur handling
* - Visual outline indicators for focus and selection states
*
* @example
* Basic usage with long press detection:
* ```tsx
* <PressableSpan onPress={() => setIsEditing(true)}>
*   Press and hold to edit this text
* </PressableSpan>
* ```
*
* @example
* With custom press duration and click outside handling:
* ```tsx
* <PressableSpan
*   pressDuration={600}
*   onPress={() => setIsEditing(true)}
*   onClickOutside={() => setIsEditing(false)}
*   isSelecting={isEditing}
* >
*   Custom behavior configuration
* </PressableSpan>
* ```
*
* @example
* In a content editing context:
* ```tsx
* <PressableSpan
*   onPress={() => startEditingContent(contentId)}
*   onClickOutside={() => saveAndExitEditing()}
*   className="prose-text"
* >
*   {editableContent}
* </PressableSpan>
* ```
*/
const PressableSpan = ({ children, onPress: onSelect, onClickOutside: onUnselect, pressDuration = DEFAULT_PRESS_DETECT_DURATION, isSelecting: isSelectingProp,...props }) => {
	const elementRef = useRef(null);
	const [isSelectingState, setIsSelectingState] = useState(isSelectingProp);
	const pressTimerRef = useRef(null);
	const handleOnLongPress = () => {
		setIsSelectingState(true);
		onSelect();
	};
	const startPressTimer = () => {
		pressTimerRef.current = setTimeout(() => {
			handleOnLongPress();
		}, pressDuration);
	};
	const clearPressTimer = () => {
		if (pressTimerRef.current) {
			clearTimeout(pressTimerRef.current);
			pressTimerRef.current = null;
		}
	};
	const handleMouseDown = () => {
		clearPressTimer();
		startPressTimer();
	};
	const handleMouseUp = () => {
		clearPressTimer();
	};
	const handleClickOutside = useCallback((event) => {
		if (elementRef.current && !elementRef.current.contains(event.target)) {
			setIsSelectingState(false);
			onUnselect?.();
		}
	}, [onUnselect]);
	useEffect(() => {
		document.addEventListener("mousedown", handleClickOutside);
		return () => {
			document.removeEventListener("mousedown", handleClickOutside);
		};
	}, [handleClickOutside]);
	const handleOnClick = (e) => {
		if (isSelectingState) {
			e.preventDefault();
			e.stopPropagation();
		}
	};
	const handleOnBlur = () => {
		setIsSelectingState(false);
	};
	/**
	* Handle keyboard interactions
	* - Enter/Space: Trigger long press action immediately
	* - Escape: Cancel selection/editing state
	*/
	const handleKeyDown = (e) => {
		switch (e.key) {
			case "Enter":
			case " ":
				e.preventDefault();
				handleOnLongPress();
				break;
			case "Escape":
				e.preventDefault();
				setIsSelectingState(false);
				onUnselect?.();
				break;
			default: break;
		}
	};
	const isCurrentlySelecting = isSelectingProp ?? isSelectingState;
	return /* @__PURE__ */ jsx("span", {
		className: cn("inline cursor-pointer select-none rounded-md outline outline-2 outline-transparent outline-offset-4 transition-all delay-100 duration-200", isCurrentlySelecting ? "outline-inherit" : "hover:outline-inherit"),
		role: "button",
		tabIndex: 0,
		"aria-pressed": isCurrentlySelecting ? "true" : "false",
		"aria-label": `${isCurrentlySelecting ? "Selected" : "Selectable"} content`,
		onKeyDown: handleKeyDown,
		onClick: handleOnClick,
		onMouseDown: handleMouseDown,
		onMouseUp: handleMouseUp,
		onMouseLeave: handleMouseUp,
		onTouchStart: handleMouseDown,
		onTouchEnd: handleMouseUp,
		onTouchCancel: handleMouseUp,
		onBlur: handleOnBlur,
		ref: elementRef,
		...props,
		children
	});
};

//#endregion
export { PressableSpan };
//# sourceMappingURL=PressableSpan.mjs.map