@acusti/dropdown
Version:
React component that renders a dropdown with a trigger and supports searching, keyboard access, and more
1,009 lines (1,008 loc) • 30.6 kB
JavaScript
import { jsx, jsxs } from "react/jsx-runtime";
import { c } from "react/compiler-runtime";
import { SYSTEM_UI_FONT, Style } from "@acusti/styling";
import useBoundingClientRect from "@acusti/use-bounding-client-rect";
import useKeyboardEvents, { isEventTargetUsingKeyEvent } from "@acusti/use-keyboard-events";
import clsx from "clsx";
import { Children, useState, useId, useRef, useEffect, isValidElement, Fragment } from "react";
import { getBestMatch } from "@acusti/matchmaking";
const ROOT_CLASS_NAME = "uktdropdown";
const ROOT_SELECTOR = `.${ROOT_CLASS_NAME}`;
const BODY_CLASS_NAME = `${ROOT_CLASS_NAME}-body`;
const LABEL_CLASS_NAME = `${ROOT_CLASS_NAME}-label`;
const LABEL_TEXT_CLASS_NAME = `${ROOT_CLASS_NAME}-label-text`;
const TRIGGER_CLASS_NAME = `${ROOT_CLASS_NAME}-trigger`;
const BODY_SELECTOR = `.${BODY_CLASS_NAME}`;
const LABEL_SELECTOR = `.${LABEL_CLASS_NAME}`;
const LABEL_TEXT_SELECTOR = `.${LABEL_TEXT_CLASS_NAME}`;
const TRIGGER_SELECTOR = `.${TRIGGER_CLASS_NAME}`;
const BODY_MAX_HEIGHT_VAR = "--uktdd-body-max-height";
const BODY_MAX_WIDTH_VAR = "--uktdd-body-max-width";
const STYLES = `
:root {
--uktdd-font-family: ${SYSTEM_UI_FONT};
--uktdd-body-bg-color: #fff;
--uktdd-body-bg-color-hover: rgb(105,162,249);
--uktdd-body-color-hover: #fff;
--uktdd-body-buffer: 10px;
${BODY_MAX_HEIGHT_VAR}: calc(100vh - var(--uktdd-body-buffer));
${BODY_MAX_WIDTH_VAR}: calc(100vw - var(--uktdd-body-buffer));
--uktdd-body-pad-bottom: 9px;
--uktdd-body-pad-left: 12px;
--uktdd-body-pad-right: 12px;
--uktdd-body-pad-top: 9px;
--uktdd-label-pad-right: 10px;
}
${ROOT_SELECTOR},
${TRIGGER_SELECTOR} {
font-family: var(--uktdd-font-family);
}
${ROOT_SELECTOR} {
width: max-content;
}
${ROOT_SELECTOR}.disabled {
pointer-events: none;
}
${ROOT_SELECTOR} > * {
cursor: default;
}
${LABEL_SELECTOR} {
display: flex;
align-items: center;
}
${LABEL_TEXT_SELECTOR} {
padding-right: var(--uktdd-label-pad-right);
}
${BODY_SELECTOR} {
box-sizing: border-box;
position: absolute;
top: anchor(bottom);
left: anchor(left);
bottom: auto;
right: auto;
position-try-fallbacks: --uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;
min-height: 50px;
max-height: var(${BODY_MAX_HEIGHT_VAR});
min-width: min(50px, 100%);
max-width: var(${BODY_MAX_WIDTH_VAR});
overflow: auto;
z-index: 2;
padding: var(--uktdd-body-pad-top) var(--uktdd-body-pad-right) var(--uktdd-body-pad-bottom) var(--uktdd-body-pad-left);
background-color: var(--uktdd-body-bg-color);
box-shadow: 0 8px 18px rgba(0,0,0,0.25);
}
@position-try --uktdd-top-left {
bottom: anchor(top);
left: anchor(left);
top: auto;
right: auto;
}
@position-try --uktdd-bottom-right {
top: anchor(bottom);
right: anchor(right);
bottom: auto;
left: auto;
}
@position-try --uktdd-top-right {
bottom: anchor(top);
right: anchor(right);
top: auto;
left: auto;
}
${BODY_SELECTOR}.has-items {
user-select: none;
}
${BODY_SELECTOR} [data-ukt-active] {
background-color: var(--uktdd-body-bg-color-hover);
color: var(--uktdd-body-color-hover);
}
`;
const ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;
const getItemElements = (dropdownElement) => {
if (!dropdownElement) return null;
const bodyElement = dropdownElement.querySelector(BODY_SELECTOR);
if (!bodyElement) return null;
let items = bodyElement.querySelectorAll(ITEM_SELECTOR);
if (items.length) return items;
items = bodyElement.children;
while (items.length === 1) {
if (items[0].children == null) break;
items = items[0].children;
}
if (items.length === 1) {
items = bodyElement.children;
}
return items;
};
const getActiveItemElement = (dropdownElement) => {
if (!dropdownElement) return null;
return dropdownElement.querySelector("[data-ukt-active]");
};
const clearItemElementsState = (itemElements) => {
itemElements.forEach((itemElement) => {
if (itemElement.hasAttribute("data-ukt-active")) {
delete itemElement.dataset.uktActive;
}
});
};
const setActiveItem = ({
dropdownElement,
element,
index,
indexAddend,
isExactMatch,
text
}) => {
const items = getItemElements(dropdownElement);
if (!items) return;
const itemElements = Array.from(items);
if (!itemElements.length) return;
const lastIndex = itemElements.length - 1;
const currentActiveIndex = itemElements.findIndex((itemElement) => itemElement.hasAttribute("data-ukt-active"));
let nextActiveIndex = currentActiveIndex;
if (typeof index === "number") {
nextActiveIndex = index < 0 ? itemElements.length + index : index;
}
if (element) {
nextActiveIndex = itemElements.findIndex((itemElement) => itemElement === element);
} else if (typeof indexAddend === "number") {
if (currentActiveIndex === -1 && indexAddend === -1) {
nextActiveIndex = lastIndex;
} else {
nextActiveIndex += indexAddend;
}
if (nextActiveIndex < 0) {
nextActiveIndex = 0;
} else if (nextActiveIndex > lastIndex) {
nextActiveIndex = lastIndex;
}
} else if (typeof text === "string") {
if (!text) {
clearItemElementsState(itemElements);
return;
}
const itemTexts = itemElements.map((itemElement) => itemElement.innerText);
if (isExactMatch) {
const textToCompare = text.toLowerCase();
nextActiveIndex = itemTexts.findIndex((itemText) => itemText.toLowerCase().startsWith(textToCompare));
if (nextActiveIndex === -1) {
clearItemElementsState(itemElements);
}
} else {
const bestMatch = getBestMatch({
items: itemTexts,
text
});
nextActiveIndex = itemTexts.findIndex((itemText) => itemText === bestMatch);
}
}
if (nextActiveIndex === -1 || nextActiveIndex === currentActiveIndex) return;
clearItemElementsState(itemElements);
const nextActiveItem = items[nextActiveIndex];
if (nextActiveItem != null) {
nextActiveItem.setAttribute("data-ukt-active", "");
let {
parentElement
} = nextActiveItem;
let scrollableParent = null;
while (!scrollableParent && parentElement && parentElement !== dropdownElement) {
const isScrollable = parentElement.scrollHeight > parentElement.clientHeight + 15;
if (isScrollable) {
scrollableParent = parentElement;
} else {
parentElement = parentElement.parentElement;
}
}
if (scrollableParent) {
const parentRect = scrollableParent.getBoundingClientRect();
const itemRect = nextActiveItem.getBoundingClientRect();
const isAboveTop = itemRect.top < parentRect.top;
const isBelowBottom = itemRect.bottom > parentRect.bottom;
if (isAboveTop || isBelowBottom) {
let {
scrollTop
} = scrollableParent;
if (isAboveTop) {
scrollTop -= parentRect.top - itemRect.top;
} else {
scrollTop += itemRect.bottom - parentRect.bottom;
}
scrollableParent.scrollTop = scrollTop;
}
}
}
};
const CHILDREN_ERROR = "@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.";
const TEXT_INPUT_SELECTOR = "input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea";
function Dropdown(t0) {
const $ = c(99);
const {
allowCreate,
allowEmpty: t1,
children,
className,
disabled,
hasItems: t2,
isOpenOnMount,
isSearchable,
keepOpenOnSubmit: t3,
label,
minHeightBody: t4,
minWidthBody: t5,
name,
onClick,
onClose,
onMouseDown,
onMouseUp,
onOpen,
onSubmitItem,
placeholder,
style: styleFromProps,
tabIndex,
value
} = t0;
const allowEmpty = t1 === void 0 ? true : t1;
const hasItems = t2 === void 0 ? true : t2;
const keepOpenOnSubmit = t3 === void 0 ? !hasItems : t3;
const minHeightBody = t4 === void 0 ? 30 : t4;
const minWidthBody = t5 === void 0 ? 100 : t5;
const childrenCount = Children.count(children);
if (childrenCount !== 1 && childrenCount !== 2) {
if (childrenCount === 0) {
throw new Error(CHILDREN_ERROR + " Received no children.");
}
console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);
}
let trigger;
if (childrenCount > 1) {
trigger = children[0];
}
const [isOpen, setIsOpen] = useState(isOpenOnMount ?? false);
const [isOpening, setIsOpening] = useState(!isOpenOnMount);
const [dropdownElement, setDropdownElement] = useState(null);
const [dropdownBodyElement, setDropdownBodyElement] = useState(null);
const id = useId();
const inputElementRef = useRef(null);
const closingTimerRef = useRef(null);
const isOpeningTimerRef = useRef(null);
const currentInputMethodRef = useRef("mouse");
const clearEnteredCharactersTimerRef = useRef(null);
const enteredCharactersRef = useRef("");
const mouseDownPositionRef = useRef(null);
const allowCreateRef = useRef(allowCreate);
const allowEmptyRef = useRef(allowEmpty);
const hasItemsRef = useRef(hasItems);
const isOpenRef = useRef(isOpen);
const isOpeningRef = useRef(isOpening);
const keepOpenOnSubmitRef = useRef(keepOpenOnSubmit);
const onCloseRef = useRef(onClose);
const onOpenRef = useRef(onOpen);
const onSubmitItemRef = useRef(onSubmitItem);
const valueRef = useRef(value);
let t6;
let t7;
if ($[0] !== allowCreate || $[1] !== allowEmpty || $[2] !== hasItems || $[3] !== isOpen || $[4] !== isOpening || $[5] !== keepOpenOnSubmit || $[6] !== onClose || $[7] !== onOpen || $[8] !== onSubmitItem || $[9] !== value) {
t6 = () => {
allowCreateRef.current = allowCreate;
allowEmptyRef.current = allowEmpty;
hasItemsRef.current = hasItems;
isOpenRef.current = isOpen;
isOpeningRef.current = isOpening;
keepOpenOnSubmitRef.current = keepOpenOnSubmit;
onCloseRef.current = onClose;
onOpenRef.current = onOpen;
onSubmitItemRef.current = onSubmitItem;
valueRef.current = value;
};
t7 = [allowCreate, allowEmpty, hasItems, isOpen, isOpening, keepOpenOnSubmit, onClose, onOpen, onSubmitItem, value];
$[0] = allowCreate;
$[1] = allowEmpty;
$[2] = hasItems;
$[3] = isOpen;
$[4] = isOpening;
$[5] = keepOpenOnSubmit;
$[6] = onClose;
$[7] = onOpen;
$[8] = onSubmitItem;
$[9] = value;
$[10] = t6;
$[11] = t7;
} else {
t6 = $[10];
t7 = $[11];
}
useEffect(t6, t7);
const isMountedRef = useRef(false);
let t8;
let t9;
if ($[12] !== isOpen) {
t8 = () => {
if (!isMountedRef.current) {
isMountedRef.current = true;
if (isOpenRef.current && onOpenRef.current) {
onOpenRef.current();
}
return;
}
if (isOpen && onOpenRef.current) {
onOpenRef.current();
} else {
if (!isOpen && onCloseRef.current) {
onCloseRef.current();
}
}
};
t9 = [isOpen];
$[12] = isOpen;
$[13] = t8;
$[14] = t9;
} else {
t8 = $[13];
t9 = $[14];
}
useEffect(t8, t9);
let t10;
if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
t10 = () => {
setIsOpen(false);
setIsOpening(false);
mouseDownPositionRef.current = null;
if (closingTimerRef.current) {
clearTimeout(closingTimerRef.current);
closingTimerRef.current = null;
}
};
$[15] = t10;
} else {
t10 = $[15];
}
const closeDropdown = t10;
let t11;
if ($[16] !== dropdownElement) {
t11 = (event) => {
if (isOpenRef.current && !keepOpenOnSubmitRef.current) {
closingTimerRef.current = setTimeout(closeDropdown, 90);
}
if (!hasItemsRef.current) {
return;
}
const element = getActiveItemElement(dropdownElement);
if (!element && !allowCreateRef.current) {
if (!allowEmptyRef.current) {
return;
}
if (inputElementRef.current?.value) {
return;
}
}
let itemLabel = element?.innerText ?? "";
if (inputElementRef.current) {
if (!element) {
itemLabel = inputElementRef.current.value;
} else {
inputElementRef.current.value = itemLabel;
}
if (inputElementRef.current === inputElementRef.current.ownerDocument.activeElement) {
inputElementRef.current.blur();
}
}
const nextValue = element?.dataset.uktValue ?? itemLabel;
if (valueRef.current && valueRef.current === nextValue) {
return;
}
if (onSubmitItemRef.current) {
onSubmitItemRef.current({
element,
event,
label: itemLabel,
value: nextValue
});
}
};
$[16] = dropdownElement;
$[17] = t11;
} else {
t11 = $[17];
}
const handleSubmitItem = t11;
let t12;
if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
t12 = (t132) => {
const {
clientX,
clientY
} = t132;
currentInputMethodRef.current = "mouse";
const initialPosition = mouseDownPositionRef.current;
if (!initialPosition) {
return;
}
if (Math.abs(initialPosition.clientX - clientX) < 12 && Math.abs(initialPosition.clientY - clientY) < 12) {
return;
}
setIsOpening(false);
};
$[18] = t12;
} else {
t12 = $[18];
}
const handleMouseMove = t12;
let t13;
if ($[19] !== dropdownElement) {
t13 = (event_0) => {
if (!hasItemsRef.current) {
return;
}
if (currentInputMethodRef.current !== "mouse") {
return;
}
if (!dropdownElement) {
return;
}
const itemElements = getItemElements(dropdownElement);
if (!itemElements) {
return;
}
const eventTarget = event_0.target;
const item = eventTarget.closest(ITEM_SELECTOR);
const element_0 = item ?? eventTarget;
for (const itemElement of itemElements) {
if (itemElement === element_0) {
setActiveItem({
dropdownElement,
element: element_0
});
return;
}
}
};
$[19] = dropdownElement;
$[20] = t13;
} else {
t13 = $[20];
}
const handleMouseOver = t13;
let t14;
if ($[21] !== dropdownElement) {
t14 = (event_1) => {
if (!hasItemsRef.current) {
return;
}
const activeItem = getActiveItemElement(dropdownElement);
if (!activeItem) {
return;
}
const eventRelatedTarget = event_1.relatedTarget;
if (activeItem !== event_1.target || activeItem.contains(eventRelatedTarget)) {
return;
}
delete activeItem.dataset.uktActive;
};
$[21] = dropdownElement;
$[22] = t14;
} else {
t14 = $[22];
}
const handleMouseOut = t14;
let t15;
if ($[23] !== onMouseDown) {
t15 = (event_2) => {
if (onMouseDown) {
onMouseDown(event_2);
}
if (isOpenRef.current) {
return;
}
setIsOpen(true);
setIsOpening(true);
mouseDownPositionRef.current = {
clientX: event_2.clientX,
clientY: event_2.clientY
};
isOpeningTimerRef.current = setTimeout(() => {
setIsOpening(false);
isOpeningTimerRef.current = null;
}, 1e3);
};
$[23] = onMouseDown;
$[24] = t15;
} else {
t15 = $[24];
}
const handleMouseDown = t15;
let t16;
if ($[25] !== handleSubmitItem || $[26] !== onMouseUp) {
t16 = (event_3) => {
if (onMouseUp) {
onMouseUp(event_3);
}
if (isOpeningRef.current || !isOpenRef.current || closingTimerRef.current) {
return;
}
const eventTarget_0 = event_3.target;
if (!eventTarget_0.closest(BODY_SELECTOR)) {
if (!isOpeningRef.current && inputElementRef.current !== eventTarget_0.ownerDocument.activeElement) {
closeDropdown();
}
return;
}
if (!hasItemsRef.current) {
return;
}
handleSubmitItem(event_3);
};
$[25] = handleSubmitItem;
$[26] = onMouseUp;
$[27] = t16;
} else {
t16 = $[27];
}
const handleMouseUp = t16;
let t17;
if ($[28] !== dropdownElement || $[29] !== handleSubmitItem) {
t17 = (event_4) => {
const {
altKey,
ctrlKey,
key,
metaKey
} = event_4;
const eventTarget_1 = event_4.target;
if (!dropdownElement) {
return;
}
const onEventHandled = () => {
event_4.stopPropagation();
event_4.preventDefault();
currentInputMethodRef.current = "keyboard";
};
const isEventTargetingDropdown = dropdownElement.contains(eventTarget_1);
if (!isOpenRef.current) {
if (!isEventTargetingDropdown) {
return;
}
if (key === " " || key === "Enter" || hasItemsRef.current && (key === "ArrowUp" || key === "ArrowDown")) {
onEventHandled();
setIsOpen(true);
}
return;
}
const isTargetUsingKeyEvents = isEventTargetUsingKeyEvent(event_4);
if (hasItemsRef.current && !isTargetUsingKeyEvents) {
let isEditingCharacters = !ctrlKey && !metaKey && /^[A-Za-z0-9]$/.test(key);
if (!isEditingCharacters && enteredCharactersRef.current) {
isEditingCharacters = key === " " || key === "Backspace";
}
if (isEditingCharacters) {
onEventHandled();
if (key === "Backspace") {
enteredCharactersRef.current = enteredCharactersRef.current.slice(0, -1);
} else {
enteredCharactersRef.current = enteredCharactersRef.current + key;
}
setActiveItem({
dropdownElement,
isExactMatch: allowCreateRef.current,
text: enteredCharactersRef.current
});
if (clearEnteredCharactersTimerRef.current) {
clearTimeout(clearEnteredCharactersTimerRef.current);
}
clearEnteredCharactersTimerRef.current = setTimeout(() => {
enteredCharactersRef.current = "";
clearEnteredCharactersTimerRef.current = null;
}, 1500);
return;
}
}
if (key === "Enter" || key === " " && !inputElementRef.current) {
onEventHandled();
handleSubmitItem(event_4);
return;
}
if (key === "Escape" || isEventTargetingDropdown && key === " " && !hasItemsRef.current) {
if (hasItemsRef.current || !isTargetUsingKeyEvents) {
closeDropdown();
}
return;
}
if (hasItemsRef.current) {
if (key === "ArrowUp") {
onEventHandled();
if (altKey || metaKey) {
setActiveItem({
dropdownElement,
index: 0
});
} else {
setActiveItem({
dropdownElement,
indexAddend: -1
});
}
return;
}
if (key === "ArrowDown") {
onEventHandled();
if (altKey || metaKey) {
setActiveItem({
dropdownElement,
index: -1
});
} else {
setActiveItem({
dropdownElement,
indexAddend: 1
});
}
return;
}
}
};
$[28] = dropdownElement;
$[29] = handleSubmitItem;
$[30] = t17;
} else {
t17 = $[30];
}
const handleKeyDown = t17;
let t18;
if ($[31] !== handleKeyDown) {
t18 = {
ignoreUsedKeyboardEvents: false,
onKeyDown: handleKeyDown
};
$[31] = handleKeyDown;
$[32] = t18;
} else {
t18 = $[32];
}
useKeyboardEvents(t18);
let t19;
if ($[33] !== isOpenOnMount) {
t19 = (ref) => {
setDropdownElement(ref);
if (!ref) {
return;
}
const {
ownerDocument
} = ref;
let inputElement = inputElementRef.current;
if (!inputElement && ref.firstElementChild) {
if (ref.firstElementChild.matches(TEXT_INPUT_SELECTOR)) {
inputElement = ref.firstElementChild;
} else {
inputElement = ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);
}
inputElementRef.current = inputElement;
}
const handleGlobalMouseDown = (t202) => {
const {
target
} = t202;
const eventTarget_2 = target;
if (!ref.contains(eventTarget_2)) {
closeDropdown();
}
};
const handleGlobalMouseUp = (t212) => {
const {
target: target_0
} = t212;
if (!isOpenRef.current || closingTimerRef.current) {
return;
}
if (isOpeningRef.current) {
setIsOpening(false);
if (isOpeningTimerRef.current) {
clearTimeout(isOpeningTimerRef.current);
isOpeningTimerRef.current = null;
}
return;
}
const eventTarget_3 = target_0;
if (!ref.contains(eventTarget_3)) {
closeDropdown();
}
};
const handleGlobalFocusIn = (t222) => {
const {
target: target_1
} = t222;
if (!isOpenRef.current) {
return;
}
const eventTarget_4 = target_1;
if (ref.contains(eventTarget_4) || eventTarget_4.contains(ref)) {
return;
}
closeDropdown();
};
document.addEventListener("focusin", handleGlobalFocusIn);
document.addEventListener("mousedown", handleGlobalMouseDown);
document.addEventListener("mouseup", handleGlobalMouseUp);
if (ownerDocument !== document) {
ownerDocument.addEventListener("focusin", handleGlobalFocusIn);
ownerDocument.addEventListener("mousedown", handleGlobalMouseDown);
ownerDocument.addEventListener("mouseup", handleGlobalMouseUp);
}
if (isOpenOnMount) {
ref.focus();
}
const handleInput = (event_5) => {
if (!isOpenRef.current) {
setIsOpen(true);
}
const input = event_5.target;
const isDeleting = enteredCharactersRef.current.length > input.value.length;
enteredCharactersRef.current = input.value;
if (isDeleting && input.value.length && getActiveItemElement(ref)) {
return;
}
setActiveItem({
dropdownElement: ref,
isExactMatch: allowCreateRef.current,
text: enteredCharactersRef.current
});
};
if (inputElement) {
inputElement.addEventListener("input", handleInput);
}
return () => {
document.removeEventListener("focusin", handleGlobalFocusIn);
document.removeEventListener("mousedown", handleGlobalMouseDown);
document.removeEventListener("mouseup", handleGlobalMouseUp);
if (ownerDocument !== document) {
ownerDocument.removeEventListener("focusin", handleGlobalFocusIn);
ownerDocument.removeEventListener("mousedown", handleGlobalMouseDown);
ownerDocument.removeEventListener("mouseup", handleGlobalMouseUp);
}
if (inputElement) {
inputElement.removeEventListener("input", handleInput);
}
};
};
$[33] = isOpenOnMount;
$[34] = t19;
} else {
t19 = $[34];
}
const handleRef = t19;
if (!isValidElement(trigger)) {
if (isSearchable) {
const t202 = value ?? "";
let t212;
if ($[35] === Symbol.for("react.memo_cache_sentinel")) {
t212 = () => setIsOpen(true);
$[35] = t212;
} else {
t212 = $[35];
}
let t222;
if ($[36] !== disabled || $[37] !== name || $[38] !== placeholder || $[39] !== t202 || $[40] !== tabIndex) {
t222 = /* @__PURE__ */ jsx("input", { autoComplete: "off", className: TRIGGER_CLASS_NAME, defaultValue: t202, disabled, name, onFocus: t212, placeholder, ref: inputElementRef, tabIndex, type: "text" });
$[36] = disabled;
$[37] = name;
$[38] = placeholder;
$[39] = t202;
$[40] = tabIndex;
$[41] = t222;
} else {
t222 = $[41];
}
trigger = t222;
} else {
let t202;
if ($[42] !== trigger) {
t202 = /* @__PURE__ */ jsx("button", { className: TRIGGER_CLASS_NAME, tabIndex: 0, children: trigger });
$[42] = trigger;
$[43] = t202;
} else {
t202 = $[43];
}
trigger = t202;
}
}
if (label) {
let t202;
if ($[44] !== label) {
t202 = /* @__PURE__ */ jsx("div", { className: LABEL_TEXT_CLASS_NAME, children: label });
$[44] = label;
$[45] = t202;
} else {
t202 = $[45];
}
let t212;
if ($[46] !== t202 || $[47] !== trigger) {
t212 = /* @__PURE__ */ jsxs("label", { className: LABEL_CLASS_NAME, children: [
t202,
trigger
] });
$[46] = t202;
$[47] = trigger;
$[48] = t212;
} else {
t212 = $[48];
}
trigger = t212;
}
const dropdownRect = useBoundingClientRect(dropdownElement);
const dropdownBodyRect = useBoundingClientRect(dropdownBodyElement);
let t20;
if ($[49] !== dropdownBodyElement) {
t20 = getBoundingAncestor(dropdownBodyElement);
$[49] = dropdownBodyElement;
$[50] = t20;
} else {
t20 = $[50];
}
const boundingElement = t20;
const boundingElementRect = useBoundingClientRect(boundingElement);
let maxHeight;
let maxWidth;
if (dropdownBodyRect.top != null && dropdownRect.top != null && boundingElementRect.top != null) {
const maxHeightUp = dropdownBodyRect.bottom - boundingElementRect.top;
const maxHeightDown = boundingElementRect.bottom - dropdownBodyRect.top;
let t212;
if ($[51] !== dropdownBodyRect.top || $[52] !== dropdownRect.top || $[53] !== maxHeightDown || $[54] !== maxHeightUp) {
t212 = Math.round(dropdownBodyRect.top > dropdownRect.top ? maxHeightDown : maxHeightUp);
$[51] = dropdownBodyRect.top;
$[52] = dropdownRect.top;
$[53] = maxHeightDown;
$[54] = maxHeightUp;
$[55] = t212;
} else {
t212 = $[55];
}
maxHeight = t212;
const maxWidthLeft = dropdownBodyRect.right - boundingElementRect.left;
const maxWidthRight = boundingElementRect.right - dropdownBodyRect.left;
let t222;
if ($[56] !== dropdownBodyRect.left || $[57] !== dropdownRect.left || $[58] !== maxWidthLeft || $[59] !== maxWidthRight) {
t222 = Math.round(dropdownBodyRect.left > dropdownRect.left ? maxWidthRight : maxWidthLeft);
$[56] = dropdownBodyRect.left;
$[57] = dropdownRect.left;
$[58] = maxWidthLeft;
$[59] = maxWidthRight;
$[60] = t222;
} else {
t222 = $[60];
}
maxWidth = t222;
}
let t21;
if ($[61] !== maxHeight || $[62] !== minHeightBody) {
t21 = maxHeight != null && maxHeight > minHeightBody ? {
[BODY_MAX_HEIGHT_VAR]: `calc(${maxHeight}px - var(--uktdd-body-buffer))`
} : null;
$[61] = maxHeight;
$[62] = minHeightBody;
$[63] = t21;
} else {
t21 = $[63];
}
let t22;
if ($[64] !== maxWidth || $[65] !== minWidthBody) {
t22 = maxWidth != null && maxWidth > minWidthBody ? {
[BODY_MAX_WIDTH_VAR]: `calc(${maxWidth}px - var(--uktdd-body-buffer))`
} : null;
$[64] = maxWidth;
$[65] = minWidthBody;
$[66] = t22;
} else {
t22 = $[66];
}
let t23;
if ($[67] !== styleFromProps || $[68] !== t21 || $[69] !== t22) {
t23 = {
...styleFromProps,
...t21,
...t22
};
$[67] = styleFromProps;
$[68] = t21;
$[69] = t22;
$[70] = t23;
} else {
t23 = $[70];
}
const style = t23;
const anchorStyles = `[data-ukt-id="${id}"] > :first-child {
anchor-name: --uktdd-anchor${id};
}
[data-ukt-id="${id}"] ${BODY_SELECTOR} {
position-anchor: --uktdd-anchor${id};
}`;
let t24;
if ($[71] === Symbol.for("react.memo_cache_sentinel")) {
t24 = /* @__PURE__ */ jsx(Style, { href: "@acusti/dropdown/Dropdown", children: STYLES });
$[71] = t24;
} else {
t24 = $[71];
}
const t25 = `@acusti/dropdown/Dropdown/${id}`;
let t26;
if ($[72] !== anchorStyles || $[73] !== t25) {
t26 = /* @__PURE__ */ jsx(Style, { href: t25, children: anchorStyles });
$[72] = anchorStyles;
$[73] = t25;
$[74] = t26;
} else {
t26 = $[74];
}
let t27;
if ($[75] !== className || $[76] !== disabled || $[77] !== isOpen || $[78] !== isSearchable) {
t27 = clsx(ROOT_CLASS_NAME, className, {
disabled,
"is-open": isOpen,
"is-searchable": isSearchable
});
$[75] = className;
$[76] = disabled;
$[77] = isOpen;
$[78] = isSearchable;
$[79] = t27;
} else {
t27 = $[79];
}
let t28;
if ($[80] !== children || $[81] !== childrenCount || $[82] !== isOpen) {
t28 = isOpen ? /* @__PURE__ */ jsx("div", { className: BODY_CLASS_NAME, ref: setDropdownBodyElement, children: childrenCount > 1 ? children[1] : children }) : null;
$[80] = children;
$[81] = childrenCount;
$[82] = isOpen;
$[83] = t28;
} else {
t28 = $[83];
}
let t29;
if ($[84] !== handleMouseDown || $[85] !== handleMouseOut || $[86] !== handleMouseOver || $[87] !== handleMouseUp || $[88] !== handleRef || $[89] !== id || $[90] !== onClick || $[91] !== style || $[92] !== t27 || $[93] !== t28 || $[94] !== trigger) {
t29 = /* @__PURE__ */ jsxs("div", { className: t27, "data-ukt-id": id, onClick, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseOut: handleMouseOut, onMouseOver: handleMouseOver, onMouseUp: handleMouseUp, ref: handleRef, style, children: [
trigger,
t28
] });
$[84] = handleMouseDown;
$[85] = handleMouseOut;
$[86] = handleMouseOver;
$[87] = handleMouseUp;
$[88] = handleRef;
$[89] = id;
$[90] = onClick;
$[91] = style;
$[92] = t27;
$[93] = t28;
$[94] = trigger;
$[95] = t29;
} else {
t29 = $[95];
}
let t30;
if ($[96] !== t26 || $[97] !== t29) {
t30 = /* @__PURE__ */ jsxs(Fragment, { children: [
t24,
t26,
t29
] });
$[96] = t26;
$[97] = t29;
$[98] = t30;
} else {
t30 = $[98];
}
return t30;
}
function getBoundingAncestor(element) {
while (element?.parentElement) {
if (element.parentElement.tagName === "BODY") return element.parentElement;
if (getComputedStyle(element.parentElement).overflowX !== "visible") {
return element.parentElement;
}
element = element.parentElement;
}
return null;
}
export {
Dropdown as default
};
//# sourceMappingURL=Dropdown.js.map