import { _ as y, l as A, p as d, v as u, x as k } from "./vendor-preact-DThS2ZQ_.js";
import { n as cn } from "./loadingIcon-B0ysgiNq.js";
import { t as ErrorIcon } from "./errorIcon-BA4T6iy-.js";
import { l as ChevronDown, n as SearchIcon, o as CloseIcon, u as CheckmarkCompactIcon } from "./icons-CJJbIpBq.js";
import { t as SuccessIcon } from "./successIcon-B5mGvdx1.js";
//#region src/shared/dropdownComposed/dropdownComposed.tsx
var DropdownComposed = ({ id, label, labelHint, placeholder = "Choose an option", value, options, onChange, error, helper, showErrorIcon, showHelperIcon, suppressMessages = false, disabled = false, required, searchable = false, searchPlaceholder = "Search...", noResultsText = "No results found", name, tabIndex, onKeyDown, onBlur, renderSelectedLabel, siblingElement, enterKeyHint: _enterKeyHint, class: className, "aria-label": ariaLabel, "data-testid": dataTestId }) => {
	const [isOpen, setIsOpen] = d(false);
	const [isFocused, setIsFocused] = d(false);
	const [highlightedIndex, setHighlightedIndex] = d(-1);
	const [searchQuery, setSearchQuery] = d("");
	const containerRef = A(null);
	const triggerRef = A(null);
	const optionsRef = A(null);
	const optionRefs = A([]);
	const searchInputRef = A(null);
	const typeaheadRef = A("");
	const typeaheadTimeoutRef = A();
	const selectedOption = options.find((o) => o.value === value);
	const triggerText = selectedOption ? renderSelectedLabel ? renderSelectedLabel(selectedOption) : selectedOption.label : placeholder;
	const filteredOptions = searchable && searchQuery ? options.filter((option) => option.label.toLowerCase().includes(searchQuery.toLowerCase())) : options;
	const labelId = `${id}-label`;
	const valueId = `${id}-value`;
	const listboxId = `${id}-listbox`;
	const helperId = `${id}-helper`;
	const errorId = `${id}-error`;
	const describedByIds = !suppressMessages ? [helper ? helperId : null, error ? errorId : null].filter(Boolean).join(" ") : "";
	y(() => {
		if (!isOpen) return;
		const frame = requestAnimationFrame(() => {
			if (searchable && searchInputRef.current) searchInputRef.current.focus();
			requestAnimationFrame(() => {
				optionsRef.current?.scrollIntoView({
					behavior: "smooth",
					block: "nearest",
					inline: "nearest"
				});
			});
		});
		return () => cancelAnimationFrame(frame);
	}, [isOpen, searchable]);
	y(() => {
		if (!isOpen) {
			setHighlightedIndex(-1);
			setSearchQuery("");
		}
	}, [isOpen]);
	y(() => {
		if (highlightedIndex >= 0 && optionRefs.current[highlightedIndex]) optionRefs.current[highlightedIndex]?.scrollIntoView({
			block: "nearest",
			inline: "nearest"
		});
	}, [highlightedIndex]);
	y(() => {
		return () => {
			if (typeaheadTimeoutRef.current) clearTimeout(typeaheadTimeoutRef.current);
		};
	}, []);
	const handleToggle = () => {
		if (disabled) return;
		setIsOpen((prev) => !prev);
	};
	const handleSelect = (optionValue) => {
		onChange(optionValue);
		setIsOpen(false);
		setHighlightedIndex(-1);
		triggerRef.current?.focus();
	};
	const handleFocus = () => {
		setIsFocused(true);
	};
	const handleBlur = (e) => {
		setIsFocused(false);
		if (!containerRef.current?.contains(e.relatedTarget)) {
			setIsOpen(false);
			onBlur?.();
		}
	};
	const handleKeyboardNavigation = (e) => {
		if (disabled) return;
		onKeyDown?.(e);
		const { key } = e;
		if (key.length === 1 && /^[a-zA-Z0-9]$/.test(key)) {
			e.preventDefault();
			if (typeaheadTimeoutRef.current) clearTimeout(typeaheadTimeoutRef.current);
			typeaheadRef.current += key.toLowerCase();
			const matchIndex = filteredOptions.findIndex((opt) => opt.label.toLowerCase().startsWith(typeaheadRef.current));
			if (matchIndex !== -1) {
				if (!isOpen) setIsOpen(true);
				setHighlightedIndex(matchIndex);
			}
			typeaheadTimeoutRef.current = setTimeout(() => {
				typeaheadRef.current = "";
			}, 500);
			return;
		}
		switch (key) {
			case "ArrowDown":
				e.preventDefault();
				if (!isOpen) {
					setIsOpen(true);
					setHighlightedIndex(0);
				} else setHighlightedIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : prev);
				break;
			case "ArrowUp":
				e.preventDefault();
				if (!isOpen) {
					setIsOpen(true);
					setHighlightedIndex(filteredOptions.length - 1);
				} else setHighlightedIndex((prev) => prev > 0 ? prev - 1 : prev);
				break;
			case "Home":
				e.preventDefault();
				if (isOpen) setHighlightedIndex(0);
				break;
			case "End":
				e.preventDefault();
				if (isOpen) setHighlightedIndex(filteredOptions.length - 1);
				break;
			case "Enter":
				e.preventDefault();
				if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) handleSelect(filteredOptions[highlightedIndex].value);
				else if (!isOpen) setIsOpen(true);
				break;
			case " ":
				e.preventDefault();
				if (isOpen && highlightedIndex >= 0 && filteredOptions[highlightedIndex]) handleSelect(filteredOptions[highlightedIndex].value);
				else if (!isOpen) {
					setIsOpen(true);
					setHighlightedIndex(0);
				}
				break;
			case "Escape":
				e.preventDefault();
				if (isOpen) {
					setIsOpen(false);
					setHighlightedIndex(-1);
					triggerRef.current?.focus();
				}
				break;
			case "Tab":
				if (isOpen) {
					setIsOpen(false);
					setHighlightedIndex(-1);
				}
				break;
			default: break;
		}
	};
	const handleSearchKeyDown = (e) => {
		const { key } = e;
		switch (key) {
			case "ArrowDown":
				e.preventDefault();
				setHighlightedIndex((prev) => prev < filteredOptions.length - 1 ? prev + 1 : prev);
				break;
			case "ArrowUp":
				e.preventDefault();
				setHighlightedIndex((prev) => prev > 0 ? prev - 1 : prev);
				break;
			case "Home":
				e.preventDefault();
				setHighlightedIndex(0);
				break;
			case "End":
				e.preventDefault();
				setHighlightedIndex(filteredOptions.length - 1);
				break;
			case "Enter":
				e.preventDefault();
				if (highlightedIndex >= 0 && filteredOptions[highlightedIndex]) handleSelect(filteredOptions[highlightedIndex].value);
				break;
			case "Escape":
				e.preventDefault();
				setIsOpen(false);
				setHighlightedIndex(-1);
				triggerRef.current?.focus();
				break;
			case "Tab":
				if (!searchQuery) {
					setIsOpen(false);
					setHighlightedIndex(-1);
				}
				break;
			default: break;
		}
	};
	return /* @__PURE__ */ u("div", {
		class: cn("IncodeDropdownComposed", className),
		ref: containerRef,
		onBlur: handleBlur,
		children: [
			name && /* @__PURE__ */ u("input", {
				type: "hidden",
				name,
				value: value || "",
				disabled,
				required
			}),
			label && /* @__PURE__ */ u("label", {
				class: "IncodeDropdownComposedLabel",
				id: labelId,
				htmlFor: id,
				"data-testid": `${id}-label`,
				children: [label, labelHint && /* @__PURE__ */ u("span", {
					class: "IncodeDropdownComposedLabelHint",
					"data-testid": `${id}-label-hint`,
					children: labelHint
				})]
			}),
			/* @__PURE__ */ u("div", {
				class: "IncodeDropdownComposedWrapper",
				children: [/* @__PURE__ */ u("div", {
					class: cn("IncodeDropdownComposedTriggerRow", { IncodeDropdownComposedTriggerRowWithSibling: !!siblingElement }),
					children: [/* @__PURE__ */ u("button", {
						ref: triggerRef,
						type: "button",
						id,
						class: "IncodeDropdownComposedTrigger",
						onClick: handleToggle,
						onFocus: handleFocus,
						onKeyDown: handleKeyboardNavigation,
						tabIndex: disabled ? -1 : tabIndex ?? 0,
						disabled,
						"aria-haspopup": "listbox",
						"aria-expanded": isOpen ? "true" : "false",
						"aria-disabled": disabled ? "true" : void 0,
						"aria-labelledby": label ? `${labelId} ${valueId}` : void 0,
						"aria-label": !label ? ariaLabel : void 0,
						"aria-controls": isOpen ? listboxId : void 0,
						"aria-activedescendant": isOpen && highlightedIndex >= 0 ? `${id}-option-${highlightedIndex}` : void 0,
						"aria-invalid": error ? "true" : void 0,
						"aria-required": required ? "true" : void 0,
						"aria-describedby": describedByIds || void 0,
						"data-error": error ? "true" : void 0,
						"data-focused": isFocused || isOpen ? "true" : void 0,
						"data-testid": dataTestId,
						children: [/* @__PURE__ */ u("span", {
							id: valueId,
							class: selectedOption ? "IncodeDropdownComposedTriggerText" : "IncodeDropdownComposedTriggerPlaceholder",
							"aria-hidden": !label && !!ariaLabel ? "true" : void 0,
							children: selectedOption?.ariaLabel ? /* @__PURE__ */ u(k, { children: [/* @__PURE__ */ u("span", {
								"aria-hidden": "true",
								children: triggerText
							}), /* @__PURE__ */ u("span", {
								class: "IncodeDropdownComposedSrOnly",
								children: selectedOption.ariaLabel
							})] }) : triggerText
						}), /* @__PURE__ */ u("span", {
							class: "IncodeDropdownComposedTriggerIcon",
							"aria-hidden": "true",
							"data-open": isOpen,
							children: /* @__PURE__ */ u(ChevronDown, {})
						})]
					}), siblingElement && /* @__PURE__ */ u("div", {
						class: "IncodeDropdownComposedSibling",
						children: siblingElement
					})]
				}), isOpen && /* @__PURE__ */ u("div", {
					ref: optionsRef,
					class: "IncodeDropdownComposedList",
					"data-error": error ? "true" : void 0,
					children: [searchable && /* @__PURE__ */ u("div", {
						class: "IncodeDropdownComposedSearchWrapper",
						children: /* @__PURE__ */ u("div", {
							class: "IncodeDropdownComposedSearchInner",
							children: [/* @__PURE__ */ u("input", {
								ref: searchInputRef,
								type: "text",
								class: "IncodeDropdownComposedSearchInput",
								value: searchQuery,
								onInput: (e) => {
									setSearchQuery(e.target.value);
									setHighlightedIndex(0);
								},
								onKeyDown: handleSearchKeyDown,
								placeholder: searchPlaceholder,
								role: "combobox",
								"aria-autocomplete": "list",
								"aria-expanded": "true",
								"aria-controls": listboxId,
								"aria-activedescendant": highlightedIndex >= 0 ? `${id}-option-${highlightedIndex}` : void 0,
								"aria-label": searchPlaceholder,
								autocomplete: "off"
							}), searchQuery ? /* @__PURE__ */ u("button", {
								type: "button",
								class: "IncodeDropdownComposedCloseIconButton",
								onMouseDown: (e) => e.preventDefault(),
								onClick: () => {
									if (!searchQuery) return;
									setSearchQuery("");
									searchInputRef.current?.focus();
								},
								"aria-label": "Clear search query",
								children: /* @__PURE__ */ u(CloseIcon, {
									width: 20,
									height: 20,
									fillColor: "var(--icon-neutral-500)"
								})
							}) : /* @__PURE__ */ u("span", {
								class: "IncodeDropdownComposedSearchIcon",
								"aria-hidden": "true",
								children: /* @__PURE__ */ u(SearchIcon, { size: 20 })
							})]
						})
					}), /* @__PURE__ */ u("div", {
						id: listboxId,
						role: "listbox",
						"aria-labelledby": label ? labelId : void 0,
						"aria-label": !label ? ariaLabel ?? placeholder : void 0,
						class: "IncodeDropdownComposedOptionsScroll",
						children: filteredOptions.length === 0 ? /* @__PURE__ */ u("div", {
							class: "IncodeDropdownComposedNoResults",
							children: noResultsText
						}) : filteredOptions.map((option, index) => {
							const selectedOption = value === option.value;
							const optionAriaLabel = option.ariaLabel && selectedOption ? `${option.ariaLabel}, selected` : option.ariaLabel;
							return /* @__PURE__ */ u("div", {
								id: `${id}-option-${index}`,
								role: "option",
								"aria-label": optionAriaLabel,
								"aria-selected": selectedOption ? "true" : "false",
								class: "IncodeDropdownComposedOption",
								"data-highlighted": highlightedIndex === index,
								ref: (el) => {
									optionRefs.current[index] = el;
								},
								onClick: () => handleSelect(option.value),
								onMouseDown: (e) => e.preventDefault(),
								onMouseEnter: () => setHighlightedIndex(index),
								children: [option.ariaLabel ? /* @__PURE__ */ u("span", {
									"aria-hidden": "true",
									children: option.label
								}) : option.label, selectedOption && /* @__PURE__ */ u("span", {
									class: "IncodeDropdownComposedCheckmarkIcon",
									"aria-hidden": "true",
									children: /* @__PURE__ */ u(CheckmarkCompactIcon, {})
								})]
							}, option.value);
						})
					})]
				})]
			}),
			searchable && /* @__PURE__ */ u("div", {
				class: "IncodeDropdownComposedLiveRegion",
				role: "status",
				"aria-live": "polite",
				"aria-atomic": "true",
				children: isOpen && searchQuery ? filteredOptions.length === 0 ? noResultsText : `${filteredOptions.length} result${filteredOptions.length !== 1 ? "s" : ""} available` : ""
			}),
			!suppressMessages && error && /* @__PURE__ */ u("div", {
				class: "IncodeDropdownComposedErrorWrapper",
				role: "alert",
				"data-testid": `${id}-error-wrapper`,
				children: [showErrorIcon && /* @__PURE__ */ u("div", {
					class: "IncodeDropdownComposedIconWrapper",
					children: /* @__PURE__ */ u(ErrorIcon, { size: 17 })
				}), /* @__PURE__ */ u("p", {
					id: errorId,
					class: "IncodeDropdownComposedError",
					children: error
				})]
			}),
			!suppressMessages && helper && !error && /* @__PURE__ */ u("div", {
				class: "IncodeDropdownComposedHelperWrapper",
				"data-testid": `${id}-helper-wrapper`,
				children: [showHelperIcon && /* @__PURE__ */ u("div", {
					class: "IncodeDropdownComposedIconWrapper",
					children: /* @__PURE__ */ u(SuccessIcon, { size: 17 })
				}), /* @__PURE__ */ u("p", {
					id: helperId,
					class: "IncodeDropdownComposedHelper",
					children: helper
				})]
			})
		]
	});
};
//#endregion
export { DropdownComposed as t };
