/** @license MIT | @cube-dev/ui-kit v0.135.1 | 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 { Icon } from "../../../icons/Icon.js";
import { CheckIcon } from "../../../icons/CheckIcon.js";
import { useWarn } from "../../../_internal/hooks/use-warn.js";
import { useProviderProps } from "../../../provider.js";
import { _CollectionItem, filterCollectionItemProps } from "../../CollectionItem.js";
import { _Item } from "../../content/Item/Item.js";
import { GripVerticalIcon } from "../../../icons/GripVerticalIcon.js";
import { StyledDivider, StyledFooter, StyledHeader, StyledSectionHeading } from "../../actions/Menu/styled.js";
import { SIZES, SIZE_NAME_TO_KEY } from "../../../tokens/sizes.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 { createMockDragState } from "../../shared/DraggableCollection.js";
import { DraggableListBox } from "./DraggableListBox.js";
import { BASE_STYLES, COLOR_STYLES, OUTER_STYLES, mergeStyles, tasty } from "@tenphi/tasty";
import { forwardRef, useEffect, useLayoutEffect, useMemo, useRef, useState } from "react";
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
import { useDraggableItem, useDropIndicator, useKeyboard, useListBox, useListBoxSection, useOption } from "react-aria";
import { Section, useListState } from "react-stately";
import { IconMinus } from "@tabler/icons-react";
import { useHover as useHover$1 } from "@react-aria/interactions";
import { useVirtualizer } from "@tanstack/react-virtual";

//#region src/components/fields/ListBox/ListBox.tsx
const ListBoxWrapperElement = tasty({
	qa: "ListBox",
	styles: {
		display: "grid",
		gridColumns: "1sf",
		gridRows: "max-content max-content max-content 1sf max-content",
		flow: "column",
		gap: 0,
		position: "relative",
		radius: {
			"": "1cr",
			"[data-shape=\"popover\"]": "(1cr - 1bw)",
			"[data-shape=\"plain\"]": "0"
		},
		color: "#dark-02",
		transition: "theme",
		outline: {
			"": "#purple-03.0",
			"invalid & focused": "#danger.50",
			focused: "#purple-03"
		},
		border: {
			"": true,
			focused: "#primary-text",
			valid: "#success-text.50",
			invalid: "#danger-text.50",
			disabled: true,
			"[data-shape=\"plain\"] | [data-shape=\"popover\"] | searchable": false
		}
	}
});
const ListElement = tasty({
	as: "ul",
	styles: {
		display: "block",
		padding: 0,
		listStyle: "none",
		boxSizing: "border-box",
		margin: {
			"": ".5x .5x 0 .5x",
			"[data-shape=\"plain\"]": "0"
		},
		height: "max-content"
	}
});
const ListBoxScrollElement = tasty({
	as: "div",
	styles: {
		display: "grid",
		gridColumns: "1sf",
		gridRows: "1sf",
		overflow: "auto",
		scrollbar: "styled"
	}
});
const ListBoxItem = tasty(_Item, {
	as: "li",
	disableActionsFocus: true,
	styles: {
		margin: {
			"": "0 0 1bw 0",
			":last-of-type": "0",
			all: ".5x"
		},
		Icon: {
			cursor: { draggable: "grab" },
			opacity: {
				draggable: ".4",
				"draggable & :hover": "1"
			},
			transition: { draggable: "opacity" }
		}
	}
});
const ListBoxDropIndicatorElement = tasty({
	as: "li",
	styles: {
		zIndex: 10,
		position: "relative",
		pointerEvents: "none",
		height: 0,
		opacity: {
			"": 0,
			"drop-target": 1
		},
		Indicator: {
			$: ">",
			position: "absolute",
			left: ".5x",
			right: ".5x",
			top: "-1px",
			height: "2px",
			fill: "#primary",
			radius: "round"
		}
	}
});
const SectionWrapperElement = tasty({
	as: "li",
	styles: {
		display: "block",
		padding: {
			"": 0,
			":last-of-type": "0 0 .5x 0"
		}
	}
});
const SectionListElement = tasty({
	qa: "ListBoxSectionList",
	as: "ul",
	styles: {
		display: "flex",
		gap: "0",
		flow: "column",
		margin: "0",
		padding: "0",
		listStyle: "none"
	}
});
const ListBoxCheckbox = tasty({
	as: "div",
	styles: {
		display: "grid",
		placeItems: "center",
		radius: ".5r",
		width: "(2x - 2bw)",
		height: "(2x - 2bw)",
		flexShrink: 0,
		transition: "theme",
		opacity: {
			"": 0,
			"selected | indeterminate | hovered | focused": 1
		},
		fill: {
			"": "#white",
			"selected | indeterminate": "#primary-text",
			"invalid & !(selected | indeterminate)": "#white",
			"invalid & (selected | indeterminate)": "#danger",
			disabled: "#dark.12"
		},
		color: {
			"": "#white",
			"disabled & !selected": "#clear"
		},
		border: {
			"": "#dark.30",
			invalid: "#danger",
			"disabled | ((selected | indeterminate) & !invalid)": "#clear"
		}
	}
});
const ListBoxCheckboxWrapper = tasty({
	as: "div",
	styles: {
		display: "grid",
		placeItems: "center",
		placeContent: "center",
		cursor: "$pointer",
		placeSelf: "stretch"
	}
});
function renderCheckboxIcon({ isSelected, isDisabled, isFocused, isHovered, validationState }) {
	const mods = {
		selected: isSelected,
		disabled: isDisabled,
		focused: isFocused,
		hovered: isHovered,
		invalid: validationState === "invalid"
	};
	return /* @__PURE__ */ jsx(ListBoxCheckboxWrapper, {
		"data-element": "CheckboxWrapper",
		mods,
		children: /* @__PURE__ */ jsx(ListBoxCheckbox, {
			"data-element": "Checkbox",
			mods,
			children: /* @__PURE__ */ jsx(CheckIcon, {
				size: 12,
				stroke: 3
			})
		})
	});
}
const PROP_STYLES = [
	...BASE_STYLES,
	...OUTER_STYLES,
	...COLOR_STYLES
];
const SelectAllOption = ({ label = "Select All", isSelected, isIndeterminate, isDisabled, isCheckable, size = "medium", state, lastFocusSourceRef, onClick, allValueProps = {} }) => {
	const { hoverProps, isHovered } = useHover$1({ isDisabled });
	const markIcon = isIndeterminate ? /* @__PURE__ */ jsx(Icon, {
		size: 12,
		stroke: 3,
		children: /* @__PURE__ */ jsx(IconMinus, {})
	}) : /* @__PURE__ */ jsx(CheckIcon, {
		size: 12,
		stroke: 3
	});
	const localRef = useRef(null);
	const checkboxIcon = useMemo(() => {
		if (!isCheckable) return null;
		return /* @__PURE__ */ jsx(ListBoxCheckboxWrapper, {
			"data-element": "CheckboxWrapper",
			mods: {
				selected: isSelected,
				disabled: isDisabled,
				hovered: isHovered,
				indeterminate: isIndeterminate
			},
			children: /* @__PURE__ */ jsx(ListBoxCheckbox, {
				"data-element": "Checkbox",
				mods: {
					selected: isSelected,
					disabled: isDisabled,
					hovered: isHovered,
					indeterminate: isIndeterminate
				},
				children: (isIndeterminate || isSelected) && markIcon
			})
		});
	}, [
		isCheckable,
		isSelected,
		isDisabled,
		isHovered,
		isIndeterminate,
		markIcon
	]);
	const handleOptionClick = (e) => {
		if (lastFocusSourceRef) lastFocusSourceRef.current = "mouse";
		if (state.selectionManager.selectionMode === "multiple") {
			const clickTarget = e.target;
			const checkboxElement = localRef.current?.querySelector("[data-element=\"CheckboxWrapper\"]");
			if (checkboxElement && (checkboxElement === clickTarget || checkboxElement.contains(clickTarget))) onClick?.(false);
			else onClick?.(true);
		} else onClick?.(true);
	};
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(ListBoxItem, {
		ref: localRef,
		"data-size": size,
		size,
		role: "option",
		"aria-selected": isSelected,
		isSelected,
		isDisabled,
		icon: checkboxIcon,
		mods: {
			listboxitem: true,
			disabled: isDisabled,
			checkable: isCheckable,
			hovered: isHovered,
			indeterminate: isIndeterminate,
			all: true
		},
		...mergeProps$1(hoverProps, allValueProps, { onClick: handleOptionClick }),
		children: label
	}), /* @__PURE__ */ jsx(StyledDivider, {})] });
};
const ListBox = forwardRef(function ListBox(props, ref) {
	props = useProviderProps(props);
	props = useFormProps(props);
	props = useFieldProps(props, { valuePropsMapper: ({ value, onChange }) => {
		const fieldProps = {};
		if (props.selectionMode === "multiple") fieldProps.selectedKeys = value || [];
		else fieldProps.selectedKey = value ?? null;
		fieldProps.onSelectionChange = (key) => {
			if (props.selectionMode === "multiple") onChange(key ? Array.isArray(key) ? key : [key] : []);
			else onChange(Array.isArray(key) ? key[0] : key);
		};
		return fieldProps;
	} });
	let { qa, label, extra, id, labelStyles, isRequired, necessityIndicator, validationState, isDisabled, listStyles, optionStyles, sectionStyles, headingStyles, listRef, message, description, styles, mods: externalMods, size = "medium", labelSuffix, selectedKey, defaultSelectedKey, selectedKeys, defaultSelectedKeys, shouldUseVirtualFocus, onSelectionChange, disableSelectionToggle = false, stateRef, focusOnHover, header, footer, headerStyles, footerStyles, onEscape, isCheckable, onOptionClick, showSelectAll, selectAllLabel, allValueProps, filter, emptyLabel = "No items", shape = "card", isReorderable = false, onReorder, form, ...otherProps } = props;
	const [, forceUpdate] = useState({});
	const lastSelectedKeyRef = useRef(null);
	const externalSelectionHandler = onSelectionChange || props.onChange;
	const wrappedOnSelectionChange = useMemo(() => {
		if (!externalSelectionHandler) return void 0;
		return (keys) => {
			if (isDisabled) return;
			if (keys === "all") externalSelectionHandler("all");
			else if (keys instanceof Set) if (keys.size === 0) {
				if (disableSelectionToggle && props.selectionMode === "single") {
					const prevKey = lastSelectedKeyRef.current;
					if (prevKey != null) {
						externalSelectionHandler(prevKey);
						return;
					}
				}
				externalSelectionHandler(props.selectionMode === "multiple" ? [] : null);
			} else if (props.selectionMode === "multiple") externalSelectionHandler(Array.from(keys));
			else {
				const key = Array.from(keys)[0];
				lastSelectedKeyRef.current = key ?? null;
				externalSelectionHandler(key);
			}
			else {
				lastSelectedKeyRef.current = keys;
				externalSelectionHandler(keys);
			}
		};
	}, [
		externalSelectionHandler,
		isDisabled,
		props.selectionMode,
		disableSelectionToggle
	]);
	const listStateProps = {
		...props,
		onSelectionChange: wrappedOnSelectionChange,
		isDisabled,
		disabledBehavior: "all",
		filter,
		selectionMode: props.selectionMode || "single"
	};
	if (listStateProps.selectionMode === "multiple") {
		if (selectedKeys !== void 0) listStateProps.selectedKeys = selectedKeys === "all" ? "all" : new Set(selectedKeys);
		if (defaultSelectedKeys !== void 0) listStateProps.defaultSelectedKeys = defaultSelectedKeys === "all" ? "all" : new Set(defaultSelectedKeys);
		delete listStateProps.selectedKey;
		delete listStateProps.defaultSelectedKey;
	} else {
		if (selectedKey !== void 0) listStateProps.selectedKeys = selectedKey == null ? /* @__PURE__ */ new Set() : new Set([selectedKey]);
		if (defaultSelectedKey !== void 0) listStateProps.defaultSelectedKeys = defaultSelectedKey == null ? /* @__PURE__ */ new Set() : new Set([defaultSelectedKey]);
		delete listStateProps.selectedKey;
		delete listStateProps.defaultSelectedKey;
	}
	const listState = useListState(listStateProps);
	useLayoutEffect(() => {
		const selected = listState.selectionManager.selectedKeys;
		if (selected && selected.size > 0) lastSelectedKeyRef.current = Array.from(selected)[0] ?? null;
	}, [listState.selectionManager.selectedKeys]);
	const selectAllState = useMemo(() => {
		if (props.selectionMode !== "multiple" || !showSelectAll) return {
			isSelected: false,
			isIndeterminate: false
		};
		if (listState.selectionManager.rawSelection === "all") return {
			isSelected: true,
			isIndeterminate: false
		};
		if (listState.selectionManager.selectedKeys.size === 0) return {
			isSelected: false,
			isIndeterminate: false
		};
		return {
			isSelected: false,
			isIndeterminate: true
		};
	}, [
		props.selectionMode,
		showSelectAll,
		listState.collection,
		listState.disabledKeys,
		listState.selectionManager.selectedKeys,
		listState.selectionManager.rawSelection
	]);
	const handleSelectAllClick = (propagate) => {
		if (isDisabled || props.selectionMode !== "multiple") return;
		if (selectAllState.isSelected) {
			listState.selectionManager.clearSelection();
			wrappedOnSelectionChange?.(/* @__PURE__ */ new Set());
		} else {
			listState.selectionManager.selectAll(true);
			wrappedOnSelectionChange?.("all");
			forceUpdate({});
		}
		if (propagate && !selectAllState.isSelected) onOptionClick?.("__ALL__");
	};
	const lastFocusSourceRef = useRef("other");
	if (stateRef) stateRef.current = {
		...listState,
		lastFocusSourceRef
	};
	useWarn(isCheckable === false && props.selectionMode === "single", {
		key: ["listbox-checkable-single-mode"],
		args: ["CubeUIKit: isCheckable=false is not recommended in single selection mode as it may confuse users about selection behavior."]
	});
	const { keyboardProps } = useKeyboard({ onKeyDown: (e) => {
		if (e.key === "ArrowDown" || e.key === "ArrowUp" || e.key === "Home" || e.key === "End" || e.key === "PageUp" || e.key === "PageDown") lastFocusSourceRef.current = "keyboard";
		if (e.key === "Escape" && onEscape) onEscape();
	} });
	styles = extractStyles(otherProps, PROP_STYLES, styles);
	ref = useCombinedRefs(ref);
	listRef = useCombinedRefs(listRef);
	const itemsArray = useMemo(() => [...listState.collection], [listState.collection]);
	const hasSections = useMemo(() => itemsArray.some((i) => i.type === "section"), [itemsArray]);
	const shouldVirtualize = !hasSections && !isReorderable;
	const { listBoxProps } = useListBox({
		...props,
		id,
		"aria-label": props["aria-label"] || label?.toString(),
		isDisabled,
		isVirtualized: !isReorderable,
		shouldUseVirtualFocus: shouldUseVirtualFocus ?? false,
		escapeKeyBehavior: onEscape ? "none" : "clearSelection"
	}, listState, listRef);
	const { isFocused, focusProps } = useFocus$1({ isDisabled });
	const isInvalid = validationState === "invalid";
	const itemsArrayRef = useRef(itemsArray);
	itemsArrayRef.current = itemsArray;
	const scrollRef = useRef(null);
	const rowVirtualizer = useVirtualizer({
		count: shouldVirtualize ? itemsArray.length : 0,
		getScrollElement: () => scrollRef.current,
		getItemKey: (index) => {
			return itemsArrayRef.current[index]?.key ?? index;
		},
		estimateSize: (index) => {
			if (itemsArrayRef.current[index]?.props?.description) return SIZES.XL + 1;
			return SIZES[SIZE_NAME_TO_KEY[size]] + 1;
		},
		measureElement: (el) => {
			return el.offsetHeight + 1;
		},
		overscan: 10
	});
	useEffect(() => {
		if (shouldVirtualize) rowVirtualizer.measure();
	}, [
		shouldVirtualize,
		itemsArray,
		rowVirtualizer
	]);
	useLayoutEffect(() => {
		const focusedKey = listState.selectionManager.focusedKey;
		if (focusedKey == null) return;
		if (lastFocusSourceRef.current !== "keyboard") return;
		const scrollElement = scrollRef.current;
		if (!scrollElement) return;
		const itemElement = scrollElement.querySelector(`[data-key="${CSS.escape(String(focusedKey))}"]`);
		if (!itemElement) return;
		const scrollTop = scrollElement.scrollTop;
		const viewportBottom = scrollTop + scrollElement.clientHeight;
		const itemRect = itemElement.getBoundingClientRect();
		const scrollRect = scrollElement.getBoundingClientRect();
		const itemTop = itemRect.top - scrollRect.top + scrollTop;
		const itemBottom = itemTop + itemRect.height;
		if (!(itemTop >= scrollTop && itemBottom <= viewportBottom)) itemElement.scrollIntoView({
			block: "nearest",
			behavior: "auto"
		});
	}, [listState.selectionManager.focusedKey, itemsArray]);
	const mergedListBoxProps = mergeProps$1(listBoxProps, keyboardProps);
	const orderedKeys = useMemo(() => {
		if (!isReorderable) return [];
		return itemsArray.filter((i) => i.type === "item").map((i) => String(i.key));
	}, [isReorderable, itemsArray]);
	const mods = useMemo(() => ({
		invalid: isInvalid,
		valid: validationState === "valid",
		disabled: isDisabled,
		focused: isFocused,
		header: !!header || showSelectAll && props.selectionMode === "multiple",
		footer: !!footer,
		selectAll: showSelectAll && props.selectionMode === "multiple",
		...externalMods
	}), [
		isInvalid,
		validationState,
		isDisabled,
		isFocused,
		header,
		footer,
		showSelectAll,
		props.selectionMode,
		externalMods
	]);
	return wrapWithField(/* @__PURE__ */ jsxs(ListBoxWrapperElement, {
		ref,
		qa: "ListBoxWrapper",
		mods,
		styles,
		"data-shape": shape,
		children: [
			header ? /* @__PURE__ */ jsx(StyledHeader, {
				styles: headerStyles,
				"data-size": size,
				children: header
			}) : /* @__PURE__ */ jsx("div", { role: "presentation" }),
			showSelectAll && props.selectionMode === "multiple" ? /* @__PURE__ */ jsx(SelectAllOption, {
				label: selectAllLabel || "Select All",
				state: listState,
				lastFocusSourceRef,
				isSelected: selectAllState.isSelected,
				isIndeterminate: selectAllState.isIndeterminate,
				isDisabled,
				isCheckable,
				size,
				allValueProps,
				onClick: handleSelectAllClick
			}) : /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx("div", { role: "presentation" }), /* @__PURE__ */ jsx("div", { role: "presentation" })] }),
			/* @__PURE__ */ jsx(ListBoxScrollElement, {
				ref: scrollRef,
				mods,
				...focusProps,
				children: listState.collection.size === 0 ? /* @__PURE__ */ jsx(_Item, {
					preset: "t4",
					color: "#dark-03",
					size,
					padding: "(.5x - 1bw)",
					children: emptyLabel
				}) : isReorderable ? /* @__PURE__ */ jsx(DraggableListBox, {
					state: listState,
					listRef,
					orderedKeys,
					onReorder,
					children: (dragState, dropState, collectionProps) => /* @__PURE__ */ jsx(ListElement, {
						qa: qa || "ListBox",
						...mergeProps$1(mergedListBoxProps, collectionProps),
						ref: listRef,
						styles: listStyles,
						"aria-disabled": isDisabled || void 0,
						mods: { sections: false },
						"data-shape": shape,
						"data-input-type": "listbox",
						children: itemsArray.filter((item) => item.type === "item").map((item) => /* @__PURE__ */ jsx(Option, {
							size,
							item,
							state: listState,
							styles: optionStyles,
							isParentDisabled: isDisabled,
							validationState,
							focusOnHover,
							isCheckable,
							lastFocusSourceRef,
							dragState,
							dropState,
							onClick: onOptionClick
						}, item.key))
					})
				}) : /* @__PURE__ */ jsx(ListElement, {
					qa: qa || "ListBox",
					...mergedListBoxProps,
					ref: listRef,
					styles: listStyles,
					"aria-disabled": isDisabled || void 0,
					mods: { sections: hasSections },
					"data-shape": shape,
					"data-input-type": "listbox",
					style: shouldVirtualize ? {
						position: "relative",
						height: `${rowVirtualizer.getTotalSize() + 3}px`
					} : void 0,
					children: shouldVirtualize ? rowVirtualizer.getVirtualItems().map((virtualItem) => {
						const item = itemsArray[virtualItem.index];
						return /* @__PURE__ */ jsx(Option, {
							size,
							item,
							state: listState,
							styles: optionStyles,
							isParentDisabled: isDisabled,
							validationState,
							focusOnHover,
							isCheckable,
							virtualRef: rowVirtualizer.measureElement,
							virtualStyle: {
								position: "absolute",
								top: 0,
								left: 0,
								right: 0,
								transform: `translateY(${virtualItem.start}px)`
							},
							virtualIndex: virtualItem.index,
							lastFocusSourceRef,
							onClick: onOptionClick
						}, item.key);
					}) : (() => {
						const renderedItems = [];
						let isFirstSection = true;
						for (const item of listState.collection) if (item.type === "section") {
							if (!isFirstSection) renderedItems.push(/* @__PURE__ */ jsx(StyledDivider, {
								role: "separator",
								"aria-orientation": "horizontal"
							}, `divider-${String(item.key)}`));
							renderedItems.push(/* @__PURE__ */ jsx(ListBoxSection, {
								item,
								state: listState,
								optionStyles,
								headingStyles,
								sectionStyles,
								isParentDisabled: isDisabled,
								validationState,
								focusOnHover,
								isCheckable,
								size,
								lastFocusSourceRef,
								onClick: onOptionClick
							}, item.key));
							isFirstSection = false;
						} else renderedItems.push(/* @__PURE__ */ jsx(Option, {
							size,
							item,
							state: listState,
							styles: optionStyles,
							isParentDisabled: isDisabled,
							validationState,
							focusOnHover,
							isCheckable,
							lastFocusSourceRef,
							onClick: onOptionClick
						}, item.key));
						return renderedItems;
					})()
				})
			}),
			footer ? /* @__PURE__ */ jsx(StyledFooter, {
				styles: footerStyles,
				"data-size": size,
				children: footer
			}) : /* @__PURE__ */ jsx("div", { role: "presentation" })
		]
	}), ref, props);
});
function Option({ size = "medium", item, state, styles, isParentDisabled, validationState, focusOnHover = false, isCheckable, onClick: onOptionClick, virtualStyle, virtualRef, virtualIndex, lastFocusSourceRef, dragState, dropState }) {
	const localRef = useRef(null);
	const combinedRef = useCombinedRefs(localRef, virtualRef);
	const isDisabled = isParentDisabled || state.disabledKeys.has(item.key);
	const isSelected = state.selectionManager.isSelected(item.key);
	const isFocused = state.selectionManager.focusedKey === item.key;
	const isDraggable = !!dragState && !!dropState;
	const mockDragState = useMemo(() => createMockDragState(state.collection, state.selectionManager), [state.collection, state.selectionManager]);
	const dragResult = useDraggableItem({ key: item.key }, dragState ?? mockDragState);
	const effectiveDragProps = isDraggable ? dragResult.dragProps : {};
	const isDragging = isDraggable && dragResult.isDragging;
	const { hoverProps, isHovered } = useHover$1({ isDisabled });
	const { optionProps, isPressed, labelProps, descriptionProps } = useOption({
		key: item.key,
		isDisabled,
		isSelected,
		shouldSelectOnPressUp: true,
		shouldFocusOnHover: focusOnHover
	}, state, combinedRef);
	const filteredItemProps = filterCollectionItemProps(item.props);
	const effectiveIcon = useMemo(() => {
		if (isDraggable && !filteredItemProps.icon) return /* @__PURE__ */ jsx(GripVerticalIcon, { size: 14 });
		if (!isCheckable || state.selectionManager.selectionMode !== "multiple" || filteredItemProps.icon) return filteredItemProps.icon ?? (state.selectionManager.selectionMode !== "multiple" ? null : void 0);
		return renderCheckboxIcon({
			isSelected,
			isDisabled,
			isFocused,
			isHovered,
			validationState
		});
	}, [
		isDraggable,
		isCheckable,
		state.selectionManager.selectionMode,
		isSelected,
		isDisabled,
		isFocused,
		isHovered,
		validationState,
		filteredItemProps.icon
	]);
	const handleOptionClick = (e) => {
		if (lastFocusSourceRef) lastFocusSourceRef.current = "mouse";
		if (onOptionClick && isCheckable && state.selectionManager.selectionMode === "multiple") {
			const clickTarget = e.target;
			const checkboxElement = localRef.current?.querySelector("[data-element=\"CheckboxWrapper\"]");
			if (checkboxElement && (checkboxElement === clickTarget || checkboxElement.contains(clickTarget))) {
				optionProps.onClick?.(e);
				state.selectionManager.setFocusedKey(item.key);
			} else {
				optionProps.onClick?.(e);
				state.selectionManager.setFocusedKey(item.key);
				if (onOptionClick) onOptionClick(item.key);
			}
		} else {
			optionProps.onClick?.(e);
			state.selectionManager.setFocusedKey(item.key);
			if (onOptionClick) onOptionClick(item.key);
		}
	};
	const { onKeyDown, onKeyUp, tabIndex, "aria-selected": ariaSelected, "aria-disabled": ariaDisabled, role, ...filteredOptionProps } = optionProps;
	const theme = {
		valid: "success",
		invalid: "danger"
	}[validationState] || "default";
	const listBoxItem = /* @__PURE__ */ jsx(ListBoxItem, {
		ref: combinedRef,
		id: `ListBoxItem-${String(item.key)}`,
		"data-key": String(item.key),
		...mergeProps$1(filteredOptionProps, hoverProps, filteredItemProps, {
			onClick: handleOptionClick,
			onKeyDown,
			onKeyUp,
			tabIndex,
			"aria-selected": ariaSelected,
			"aria-disabled": ariaDisabled,
			role
		}, effectiveDragProps),
		theme,
		style: virtualStyle,
		"data-size": size,
		"data-index": virtualIndex,
		size,
		display: isDraggable ? "grid" : void 0,
		isSelected,
		isDisabled,
		icon: effectiveIcon,
		labelProps,
		descriptionProps,
		styles: mergeStyles(styles, filteredItemProps.styles),
		defaultTooltipPlacement: "right",
		mods: {
			listboxitem: true,
			focused: isFocused,
			pressed: isPressed,
			dragging: isDragging,
			draggable: isDraggable,
			valid: isSelected && validationState === "valid",
			invalid: isSelected && validationState === "invalid",
			checkable: isCheckable,
			hovered: isHovered,
			all: false
		},
		children: item.rendered
	});
	if (!isDraggable || !dropState) return listBoxItem;
	return /* @__PURE__ */ jsxs(Fragment$1, { children: [
		/* @__PURE__ */ jsx(ListBoxDropIndicator, {
			target: {
				type: "item",
				key: item.key,
				dropPosition: "before"
			},
			dropState
		}),
		listBoxItem,
		/* @__PURE__ */ jsx(ListBoxDropIndicator, {
			target: {
				type: "item",
				key: item.key,
				dropPosition: "after"
			},
			dropState
		})
	] });
}
function ListBoxDropIndicator({ target, dropState }) {
	const ref = useRef(null);
	const { dropIndicatorProps, isHidden, isDropTarget } = useDropIndicator({ target }, dropState, ref);
	if (isHidden) return null;
	return /* @__PURE__ */ jsx(ListBoxDropIndicatorElement, {
		ref,
		role: "option",
		...dropIndicatorProps,
		mods: { "drop-target": isDropTarget },
		children: /* @__PURE__ */ jsx("div", { "data-element": "Indicator" })
	});
}
function ListBoxSection(props) {
	const { item, state, optionStyles, headingStyles, sectionStyles, isParentDisabled, validationState, focusOnHover, isCheckable, onClick: onOptionClick, lastFocusSourceRef } = props;
	const heading = item.rendered;
	const { itemProps, headingProps, groupProps } = useListBoxSection({
		heading,
		"aria-label": item["aria-label"]
	});
	return /* @__PURE__ */ jsxs(SectionWrapperElement, {
		...itemProps,
		styles: sectionStyles,
		children: [heading && /* @__PURE__ */ jsx(StyledSectionHeading, {
			...headingProps,
			size: props.size,
			styles: headingStyles,
			children: heading
		}), /* @__PURE__ */ jsx(SectionListElement, {
			...groupProps,
			children: [...item.childNodes].filter((node) => state.collection.getItem(node.key)).map((node) => /* @__PURE__ */ jsx(Option, {
				size: props.size,
				item: node,
				state,
				styles: optionStyles,
				isParentDisabled,
				validationState,
				focusOnHover,
				isCheckable,
				lastFocusSourceRef,
				onClick: onOptionClick
			}, node.key))
		})]
	});
}
const ListBoxSectionComponent = Object.assign(Section, { displayName: "Section" });
ListBox.Item = _CollectionItem;
ListBox.Section = ListBoxSectionComponent;
Object.defineProperty(ListBox, "cubeInputType", {
	value: "ListBox",
	enumerable: false,
	configurable: false
});

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