@acusti/dropdown 0.46.1 → 0.48.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Dropdown.js CHANGED
@@ -1,487 +1,1023 @@
1
- /* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-static-element-interactions */
2
- import { Style } from '@acusti/styling';
3
- import useIsOutOfBounds from '@acusti/use-is-out-of-bounds';
4
- import useKeyboardEvents, { isEventTargetUsingKeyEvent, } from '@acusti/use-keyboard-events';
5
- import clsx from 'clsx';
6
- import * as React from 'react';
7
- import { getActiveItemElement, getItemElements, ITEM_SELECTOR, setActiveItem, } from './helpers.js';
8
- import { BODY_CLASS_NAME, BODY_MAX_HEIGHT_VAR, BODY_MAX_WIDTH_VAR, BODY_SELECTOR, LABEL_CLASS_NAME, LABEL_TEXT_CLASS_NAME, ROOT_CLASS_NAME, STYLES, TRIGGER_CLASS_NAME, } from './styles.js';
9
- const { Children, Fragment, useCallback, useEffect, useMemo, useRef, useState } = React;
10
- const noop = () => { }; // eslint-disable-line @typescript-eslint/no-empty-function
11
- const CHILDREN_ERROR = '@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.';
12
- const TEXT_INPUT_SELECTOR = 'input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea';
13
- export default function Dropdown({ allowCreate, allowEmpty = true, children, className, disabled, hasItems = true, isOpenOnMount, isSearchable, keepOpenOnSubmit = !hasItems, label, name, onClick, onClose, onMouseDown, onMouseUp, onOpen, onSubmitItem, placeholder, style: styleFromProps, tabIndex, value, }) {
14
- const childrenCount = Children.count(children);
15
- if (childrenCount !== 1 && childrenCount !== 2) {
16
- if (childrenCount === 0) {
17
- throw new Error(CHILDREN_ERROR + ' Received no children.');
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { c } from "react/compiler-runtime";
3
+ import { SYSTEM_UI_FONT, Style } from "@acusti/styling";
4
+ import useBoundingClientRect from "@acusti/use-bounding-client-rect";
5
+ import useKeyboardEvents, { isEventTargetUsingKeyEvent } from "@acusti/use-keyboard-events";
6
+ import clsx from "clsx";
7
+ import * as React from "react";
8
+ import { getBestMatch } from "@acusti/matchmaking";
9
+ const ROOT_CLASS_NAME = "uktdropdown";
10
+ const ROOT_SELECTOR = `.${ROOT_CLASS_NAME}`;
11
+ const BODY_CLASS_NAME = `${ROOT_CLASS_NAME}-body`;
12
+ const LABEL_CLASS_NAME = `${ROOT_CLASS_NAME}-label`;
13
+ const LABEL_TEXT_CLASS_NAME = `${ROOT_CLASS_NAME}-label-text`;
14
+ const TRIGGER_CLASS_NAME = `${ROOT_CLASS_NAME}-trigger`;
15
+ const BODY_SELECTOR = `.${BODY_CLASS_NAME}`;
16
+ const LABEL_SELECTOR = `.${LABEL_CLASS_NAME}`;
17
+ const LABEL_TEXT_SELECTOR = `.${LABEL_TEXT_CLASS_NAME}`;
18
+ const TRIGGER_SELECTOR = `.${TRIGGER_CLASS_NAME}`;
19
+ const BODY_MAX_HEIGHT_VAR = "--uktdd-body-max-height";
20
+ const BODY_MAX_WIDTH_VAR = "--uktdd-body-max-width";
21
+ const STYLES = `
22
+ :root {
23
+ --uktdd-font-family: ${SYSTEM_UI_FONT};
24
+ --uktdd-body-bg-color: #fff;
25
+ --uktdd-body-bg-color-hover: rgb(105,162,249);
26
+ --uktdd-body-color-hover: #fff;
27
+ --uktdd-body-buffer: 10px;
28
+ ${BODY_MAX_HEIGHT_VAR}: calc(100vh - var(--uktdd-body-buffer));
29
+ ${BODY_MAX_WIDTH_VAR}: calc(100vw - var(--uktdd-body-buffer));
30
+ --uktdd-body-pad-bottom: 9px;
31
+ --uktdd-body-pad-left: 12px;
32
+ --uktdd-body-pad-right: 12px;
33
+ --uktdd-body-pad-top: 9px;
34
+ --uktdd-label-pad-right: 10px;
35
+ }
36
+ ${ROOT_SELECTOR},
37
+ ${TRIGGER_SELECTOR} {
38
+ font-family: var(--uktdd-font-family);
39
+ }
40
+ ${ROOT_SELECTOR} {
41
+ width: max-content;
42
+ }
43
+ ${ROOT_SELECTOR}.disabled {
44
+ pointer-events: none;
45
+ }
46
+ ${ROOT_SELECTOR} > * {
47
+ cursor: default;
48
+ }
49
+ ${LABEL_SELECTOR} {
50
+ display: flex;
51
+ align-items: center;
52
+ }
53
+ ${LABEL_TEXT_SELECTOR} {
54
+ padding-right: var(--uktdd-label-pad-right);
55
+ }
56
+ ${BODY_SELECTOR} {
57
+ box-sizing: border-box;
58
+ position: absolute;
59
+ top: anchor(bottom);
60
+ left: anchor(left);
61
+ position-try-fallbacks: --uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;
62
+ min-height: 50px;
63
+ max-height: var(${BODY_MAX_HEIGHT_VAR});
64
+ min-width: min(50px, 100%);
65
+ max-width: var(${BODY_MAX_WIDTH_VAR});
66
+ overflow: auto;
67
+ z-index: 2;
68
+ padding: var(--uktdd-body-pad-top) var(--uktdd-body-pad-right) var(--uktdd-body-pad-bottom) var(--uktdd-body-pad-left);
69
+ background-color: var(--uktdd-body-bg-color);
70
+ box-shadow: 0 8px 18px rgba(0,0,0,0.25);
71
+ }
72
+ @position-try --uktdd-top-left {
73
+ bottom: anchor(top);
74
+ left: anchor(left);
75
+ top: revert;
76
+ right: revert;
77
+ }
78
+ @position-try --uktdd-bottom-right {
79
+ top: anchor(bottom);
80
+ right: anchor(right);
81
+ bottom: revert;
82
+ left: revert;
83
+ }
84
+ @position-try --uktdd-top-right {
85
+ bottom: anchor(top);
86
+ right: anchor(right);
87
+ top: revert;
88
+ left: revert;
89
+ }
90
+ ${BODY_SELECTOR}.has-items {
91
+ user-select: none;
92
+ }
93
+ ${BODY_SELECTOR} [data-ukt-active] {
94
+ background-color: var(--uktdd-body-bg-color-hover);
95
+ color: var(--uktdd-body-color-hover);
96
+ }
97
+ `;
98
+ const ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;
99
+ const getItemElements = (dropdownElement) => {
100
+ if (!dropdownElement) return null;
101
+ const bodyElement = dropdownElement.querySelector(BODY_SELECTOR);
102
+ if (!bodyElement) return null;
103
+ let items = bodyElement.querySelectorAll(ITEM_SELECTOR);
104
+ if (items.length) return items;
105
+ items = bodyElement.children;
106
+ while (items.length === 1) {
107
+ if (items[0].children == null) break;
108
+ items = items[0].children;
109
+ }
110
+ if (items.length === 1) {
111
+ items = bodyElement.children;
112
+ }
113
+ return items;
114
+ };
115
+ const getActiveItemElement = (dropdownElement) => {
116
+ if (!dropdownElement) return null;
117
+ return dropdownElement.querySelector("[data-ukt-active]");
118
+ };
119
+ const clearItemElementsState = (itemElements) => {
120
+ itemElements.forEach((itemElement) => {
121
+ if (itemElement.hasAttribute("data-ukt-active")) {
122
+ delete itemElement.dataset.uktActive;
123
+ }
124
+ });
125
+ };
126
+ const setActiveItem = ({
127
+ dropdownElement,
128
+ element,
129
+ index,
130
+ indexAddend,
131
+ isExactMatch,
132
+ text
133
+ }) => {
134
+ const items = getItemElements(dropdownElement);
135
+ if (!items) return;
136
+ const itemElements = Array.from(items);
137
+ if (!itemElements.length) return;
138
+ const lastIndex = itemElements.length - 1;
139
+ const currentActiveIndex = itemElements.findIndex((itemElement) => itemElement.hasAttribute("data-ukt-active"));
140
+ let nextActiveIndex = currentActiveIndex;
141
+ if (typeof index === "number") {
142
+ nextActiveIndex = index < 0 ? itemElements.length + index : index;
143
+ }
144
+ if (element) {
145
+ nextActiveIndex = itemElements.findIndex((itemElement) => itemElement === element);
146
+ } else if (typeof indexAddend === "number") {
147
+ if (currentActiveIndex === -1 && indexAddend === -1) {
148
+ nextActiveIndex = lastIndex;
149
+ } else {
150
+ nextActiveIndex += indexAddend;
151
+ }
152
+ if (nextActiveIndex < 0) {
153
+ nextActiveIndex = 0;
154
+ } else if (nextActiveIndex > lastIndex) {
155
+ nextActiveIndex = lastIndex;
156
+ }
157
+ } else if (typeof text === "string") {
158
+ if (!text) {
159
+ clearItemElementsState(itemElements);
160
+ return;
161
+ }
162
+ const itemTexts = itemElements.map((itemElement) => itemElement.innerText);
163
+ if (isExactMatch) {
164
+ const textToCompare = text.toLowerCase();
165
+ nextActiveIndex = itemTexts.findIndex((itemText) => itemText.toLowerCase().startsWith(textToCompare));
166
+ if (nextActiveIndex === -1) {
167
+ clearItemElementsState(itemElements);
168
+ }
169
+ } else {
170
+ const bestMatch = getBestMatch({
171
+ items: itemTexts,
172
+ text
173
+ });
174
+ nextActiveIndex = itemTexts.findIndex((itemText) => itemText === bestMatch);
175
+ }
176
+ }
177
+ if (nextActiveIndex === -1 || nextActiveIndex === currentActiveIndex) return;
178
+ clearItemElementsState(itemElements);
179
+ const nextActiveItem = items[nextActiveIndex];
180
+ if (nextActiveItem != null) {
181
+ nextActiveItem.setAttribute("data-ukt-active", "");
182
+ let {
183
+ parentElement
184
+ } = nextActiveItem;
185
+ let scrollableParent = null;
186
+ while (!scrollableParent && parentElement && parentElement !== dropdownElement) {
187
+ const isScrollable = parentElement.scrollHeight > parentElement.clientHeight + 15;
188
+ if (isScrollable) {
189
+ scrollableParent = parentElement;
190
+ } else {
191
+ parentElement = parentElement.parentElement;
192
+ }
193
+ }
194
+ if (scrollableParent) {
195
+ const parentRect = scrollableParent.getBoundingClientRect();
196
+ const itemRect = nextActiveItem.getBoundingClientRect();
197
+ const isAboveTop = itemRect.top < parentRect.top;
198
+ const isBelowBottom = itemRect.bottom > parentRect.bottom;
199
+ if (isAboveTop || isBelowBottom) {
200
+ let {
201
+ scrollTop
202
+ } = scrollableParent;
203
+ if (isAboveTop) {
204
+ scrollTop -= parentRect.top - itemRect.top;
205
+ } else {
206
+ scrollTop += itemRect.bottom - parentRect.bottom;
18
207
  }
19
- console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);
208
+ scrollableParent.scrollTop = scrollTop;
209
+ }
20
210
  }
21
- let trigger;
22
- if (childrenCount > 1) {
23
- trigger = children[0];
211
+ }
212
+ };
213
+ const {
214
+ Children,
215
+ Fragment,
216
+ useEffect,
217
+ useRef,
218
+ useState
219
+ } = React;
220
+ const noop = () => {
221
+ };
222
+ const CHILDREN_ERROR = "@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.";
223
+ const TEXT_INPUT_SELECTOR = "input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea";
224
+ let idCounter = 0;
225
+ function Dropdown(t0) {
226
+ const $ = c(106);
227
+ const {
228
+ allowCreate,
229
+ allowEmpty: t1,
230
+ children,
231
+ className,
232
+ disabled,
233
+ hasItems: t2,
234
+ isOpenOnMount,
235
+ isSearchable,
236
+ keepOpenOnSubmit: t3,
237
+ label,
238
+ name,
239
+ onClick,
240
+ onClose,
241
+ onMouseDown,
242
+ onMouseUp,
243
+ onOpen,
244
+ onSubmitItem,
245
+ placeholder,
246
+ style: styleFromProps,
247
+ tabIndex,
248
+ value
249
+ } = t0;
250
+ const allowEmpty = t1 === void 0 ? true : t1;
251
+ const hasItems = t2 === void 0 ? true : t2;
252
+ const keepOpenOnSubmit = t3 === void 0 ? !hasItems : t3;
253
+ const childrenCount = Children.count(children);
254
+ if (childrenCount !== 1 && childrenCount !== 2) {
255
+ if (childrenCount === 0) {
256
+ throw new Error(CHILDREN_ERROR + " Received no children.");
24
257
  }
25
- const isTriggerFromProps = React.isValidElement(trigger);
26
- const [isOpen, setIsOpen] = useState(isOpenOnMount !== null && isOpenOnMount !== void 0 ? isOpenOnMount : false);
27
- const [isOpening, setIsOpening] = useState(!isOpenOnMount);
28
- const [dropdownBodyElement, setDropdownBodyElement] = useState(null);
29
- const dropdownElementRef = useRef(null);
30
- const inputElementRef = useRef(null);
31
- const closingTimerRef = useRef(null);
32
- const isOpeningTimerRef = useRef(null);
33
- const currentInputMethodRef = useRef('mouse');
34
- const clearEnteredCharactersTimerRef = useRef(null);
35
- const enteredCharactersRef = useRef('');
36
- const mouseDownPositionRef = useRef(null);
37
- const outOfBounds = useIsOutOfBounds(dropdownBodyElement);
38
- const setDropdownOpenRef = useRef(() => setIsOpen(true));
39
- const allowCreateRef = useRef(allowCreate);
40
- const allowEmptyRef = useRef(allowEmpty);
41
- const hasItemsRef = useRef(hasItems);
42
- const isOpenRef = useRef(isOpen);
43
- const isOpeningRef = useRef(isOpening);
44
- const keepOpenOnSubmitRef = useRef(keepOpenOnSubmit);
45
- const onCloseRef = useRef(onClose);
46
- const onOpenRef = useRef(onOpen);
47
- const onSubmitItemRef = useRef(onSubmitItem);
48
- const valueRef = useRef(value);
49
- useEffect(() => {
50
- allowCreateRef.current = allowCreate;
51
- allowEmptyRef.current = allowEmpty;
52
- hasItemsRef.current = hasItems;
53
- isOpenRef.current = isOpen;
54
- isOpeningRef.current = isOpening;
55
- keepOpenOnSubmitRef.current = keepOpenOnSubmit;
56
- onCloseRef.current = onClose;
57
- onOpenRef.current = onOpen;
58
- onSubmitItemRef.current = onSubmitItem;
59
- valueRef.current = value;
60
- }, [
61
- allowCreate,
62
- allowEmpty,
63
- hasItems,
64
- isOpen,
65
- isOpening,
66
- keepOpenOnSubmit,
67
- onClose,
68
- onOpen,
69
- onSubmitItem,
70
- value,
71
- ]);
72
- const isMountedRef = useRef(false);
73
- useEffect(() => {
74
- if (!isMountedRef.current) {
75
- isMountedRef.current = true;
76
- // If isOpenOnMount, trigger onOpen right away
77
- if (isOpenRef.current && onOpenRef.current) {
78
- onOpenRef.current();
79
- }
80
- return;
258
+ console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);
259
+ }
260
+ let trigger;
261
+ if (childrenCount > 1) {
262
+ trigger = children[0];
263
+ }
264
+ let t4;
265
+ if ($[0] !== trigger) {
266
+ t4 = React.isValidElement(trigger);
267
+ $[0] = trigger;
268
+ $[1] = t4;
269
+ } else {
270
+ t4 = $[1];
271
+ }
272
+ const isTriggerFromProps = t4;
273
+ const [isOpen, setIsOpen] = useState(isOpenOnMount ?? false);
274
+ const [isOpening, setIsOpening] = useState(!isOpenOnMount);
275
+ const [dropdownElement, setDropdownElement] = useState(null);
276
+ const [dropdownBodyElement, setDropdownBodyElement] = useState(null);
277
+ const [id] = useState(_temp);
278
+ const inputElementRef = useRef(null);
279
+ const closingTimerRef = useRef(null);
280
+ const isOpeningTimerRef = useRef(null);
281
+ const currentInputMethodRef = useRef("mouse");
282
+ const clearEnteredCharactersTimerRef = useRef(null);
283
+ const enteredCharactersRef = useRef("");
284
+ const mouseDownPositionRef = useRef(null);
285
+ const allowCreateRef = useRef(allowCreate);
286
+ const allowEmptyRef = useRef(allowEmpty);
287
+ const hasItemsRef = useRef(hasItems);
288
+ const isOpenRef = useRef(isOpen);
289
+ const isOpeningRef = useRef(isOpening);
290
+ const keepOpenOnSubmitRef = useRef(keepOpenOnSubmit);
291
+ const onCloseRef = useRef(onClose);
292
+ const onOpenRef = useRef(onOpen);
293
+ const onSubmitItemRef = useRef(onSubmitItem);
294
+ const valueRef = useRef(value);
295
+ let t5;
296
+ let t6;
297
+ if ($[2] !== allowCreate || $[3] !== allowEmpty || $[4] !== hasItems || $[5] !== isOpen || $[6] !== isOpening || $[7] !== keepOpenOnSubmit || $[8] !== onClose || $[9] !== onOpen || $[10] !== onSubmitItem || $[11] !== value) {
298
+ t5 = () => {
299
+ allowCreateRef.current = allowCreate;
300
+ allowEmptyRef.current = allowEmpty;
301
+ hasItemsRef.current = hasItems;
302
+ isOpenRef.current = isOpen;
303
+ isOpeningRef.current = isOpening;
304
+ keepOpenOnSubmitRef.current = keepOpenOnSubmit;
305
+ onCloseRef.current = onClose;
306
+ onOpenRef.current = onOpen;
307
+ onSubmitItemRef.current = onSubmitItem;
308
+ valueRef.current = value;
309
+ };
310
+ t6 = [allowCreate, allowEmpty, hasItems, isOpen, isOpening, keepOpenOnSubmit, onClose, onOpen, onSubmitItem, value];
311
+ $[2] = allowCreate;
312
+ $[3] = allowEmpty;
313
+ $[4] = hasItems;
314
+ $[5] = isOpen;
315
+ $[6] = isOpening;
316
+ $[7] = keepOpenOnSubmit;
317
+ $[8] = onClose;
318
+ $[9] = onOpen;
319
+ $[10] = onSubmitItem;
320
+ $[11] = value;
321
+ $[12] = t5;
322
+ $[13] = t6;
323
+ } else {
324
+ t5 = $[12];
325
+ t6 = $[13];
326
+ }
327
+ useEffect(t5, t6);
328
+ const isMountedRef = useRef(false);
329
+ let t7;
330
+ let t8;
331
+ if ($[14] !== isOpen) {
332
+ t7 = () => {
333
+ if (!isMountedRef.current) {
334
+ isMountedRef.current = true;
335
+ if (isOpenRef.current && onOpenRef.current) {
336
+ onOpenRef.current();
81
337
  }
82
- if (isOpen && onOpenRef.current) {
83
- onOpenRef.current();
338
+ return;
339
+ }
340
+ if (isOpen && onOpenRef.current) {
341
+ onOpenRef.current();
342
+ } else {
343
+ if (!isOpen && onCloseRef.current) {
344
+ onCloseRef.current();
84
345
  }
85
- else if (!isOpen && onCloseRef.current) {
86
- onCloseRef.current();
346
+ }
347
+ };
348
+ t8 = [isOpen];
349
+ $[14] = isOpen;
350
+ $[15] = t7;
351
+ $[16] = t8;
352
+ } else {
353
+ t7 = $[15];
354
+ t8 = $[16];
355
+ }
356
+ useEffect(t7, t8);
357
+ let t9;
358
+ if ($[17] !== setIsOpen || $[18] !== setIsOpening) {
359
+ t9 = () => {
360
+ setIsOpen(false);
361
+ setIsOpening(false);
362
+ mouseDownPositionRef.current = null;
363
+ if (closingTimerRef.current) {
364
+ clearTimeout(closingTimerRef.current);
365
+ closingTimerRef.current = null;
366
+ }
367
+ };
368
+ $[17] = setIsOpen;
369
+ $[18] = setIsOpening;
370
+ $[19] = t9;
371
+ } else {
372
+ t9 = $[19];
373
+ }
374
+ const closeDropdown = t9;
375
+ let t10;
376
+ if ($[20] !== closeDropdown || $[21] !== dropdownElement) {
377
+ t10 = (event) => {
378
+ var _a;
379
+ if (isOpenRef.current && !keepOpenOnSubmitRef.current) {
380
+ closingTimerRef.current = setTimeout(closeDropdown, 90);
381
+ }
382
+ if (!hasItemsRef.current) {
383
+ return;
384
+ }
385
+ const element = getActiveItemElement(dropdownElement);
386
+ if (!element && !allowCreateRef.current) {
387
+ if (!allowEmptyRef.current) {
388
+ return;
87
389
  }
88
- }, [isOpen]);
89
- const closeDropdown = useCallback(() => {
90
- setIsOpen(false);
91
- setIsOpening(false);
92
- mouseDownPositionRef.current = null;
93
- if (closingTimerRef.current) {
94
- clearTimeout(closingTimerRef.current);
95
- closingTimerRef.current = null;
390
+ if ((_a = inputElementRef.current) == null ? void 0 : _a.value) {
391
+ return;
96
392
  }
97
- }, []);
98
- const handleSubmitItem = useCallback((event) => {
99
- var _a, _b, _c;
100
- const eventTarget = event.target;
101
- if (isOpenRef.current && !keepOpenOnSubmitRef.current) {
102
- const keepOpen = eventTarget.closest('[data-ukt-keep-open]');
103
- // Don’t close dropdown if event occurs w/in data-ukt-keep-open element
104
- if (!(keepOpen === null || keepOpen === void 0 ? void 0 : keepOpen.dataset.uktKeepOpen) ||
105
- keepOpen.dataset.uktKeepOpen === 'false') {
106
- // A short timeout before closing is better UX when user selects an item so dropdown
107
- // doesn’t close before expected. It also enables using <Link />s in the dropdown body.
108
- closingTimerRef.current = setTimeout(closeDropdown, 90);
109
- }
393
+ }
394
+ let itemLabel = (element == null ? void 0 : element.innerText) ?? "";
395
+ if (inputElementRef.current) {
396
+ if (!element) {
397
+ itemLabel = inputElementRef.current.value;
398
+ } else {
399
+ inputElementRef.current.value = itemLabel;
110
400
  }
111
- if (!hasItemsRef.current)
112
- return;
113
- const element = getActiveItemElement(dropdownElementRef.current);
114
- if (!element && !allowCreateRef.current) {
115
- // If not allowEmpty, don’t allow submitting an empty item
116
- if (!allowEmptyRef.current)
117
- return;
118
- // If we have an input element as trigger & the user didn’t clear the text, do nothing
119
- if ((_a = inputElementRef.current) === null || _a === void 0 ? void 0 : _a.value)
120
- return;
401
+ if (inputElementRef.current === inputElementRef.current.ownerDocument.activeElement) {
402
+ inputElementRef.current.blur();
121
403
  }
122
- let itemLabel = (_b = element === null || element === void 0 ? void 0 : element.innerText) !== null && _b !== void 0 ? _b : '';
123
- if (inputElementRef.current) {
124
- if (!element) {
125
- itemLabel = inputElementRef.current.value;
126
- }
127
- else {
128
- inputElementRef.current.value = itemLabel;
129
- }
130
- if (inputElementRef.current ===
131
- inputElementRef.current.ownerDocument.activeElement) {
132
- inputElementRef.current.blur();
133
- }
404
+ }
405
+ const nextValue = (element == null ? void 0 : element.dataset.uktValue) ?? itemLabel;
406
+ if (valueRef.current && valueRef.current === nextValue) {
407
+ return;
408
+ }
409
+ if (onSubmitItemRef.current) {
410
+ onSubmitItemRef.current({
411
+ element,
412
+ event,
413
+ label: itemLabel,
414
+ value: nextValue
415
+ });
416
+ }
417
+ };
418
+ $[20] = closeDropdown;
419
+ $[21] = dropdownElement;
420
+ $[22] = t10;
421
+ } else {
422
+ t10 = $[22];
423
+ }
424
+ const handleSubmitItem = t10;
425
+ let t11;
426
+ if ($[23] !== setIsOpening) {
427
+ t11 = (t122) => {
428
+ const {
429
+ clientX,
430
+ clientY
431
+ } = t122;
432
+ currentInputMethodRef.current = "mouse";
433
+ const initialPosition = mouseDownPositionRef.current;
434
+ if (!initialPosition) {
435
+ return;
436
+ }
437
+ if (Math.abs(initialPosition.clientX - clientX) < 12 && Math.abs(initialPosition.clientY - clientY) < 12) {
438
+ return;
439
+ }
440
+ setIsOpening(false);
441
+ };
442
+ $[23] = setIsOpening;
443
+ $[24] = t11;
444
+ } else {
445
+ t11 = $[24];
446
+ }
447
+ const handleMouseMove = t11;
448
+ let t12;
449
+ if ($[25] !== dropdownElement) {
450
+ t12 = (event_0) => {
451
+ if (!hasItemsRef.current) {
452
+ return;
453
+ }
454
+ if (currentInputMethodRef.current !== "mouse") {
455
+ return;
456
+ }
457
+ if (!dropdownElement) {
458
+ return;
459
+ }
460
+ const itemElements = getItemElements(dropdownElement);
461
+ if (!itemElements) {
462
+ return;
463
+ }
464
+ const eventTarget = event_0.target;
465
+ const item = eventTarget.closest(ITEM_SELECTOR);
466
+ const element_0 = item ?? eventTarget;
467
+ for (const itemElement of itemElements) {
468
+ if (itemElement === element_0) {
469
+ setActiveItem({
470
+ dropdownElement,
471
+ element: element_0
472
+ });
473
+ return;
134
474
  }
135
- const nextValue = (_c = element === null || element === void 0 ? void 0 : element.dataset.uktValue) !== null && _c !== void 0 ? _c : itemLabel;
136
- // If parent is controlling Dropdown via props.value and nextValue is the same, do nothing
137
- if (valueRef.current && valueRef.current === nextValue)
138
- return;
139
- if (onSubmitItemRef.current) {
140
- onSubmitItemRef.current({
141
- element,
142
- event,
143
- label: itemLabel,
144
- value: nextValue,
145
- });
475
+ }
476
+ };
477
+ $[25] = dropdownElement;
478
+ $[26] = t12;
479
+ } else {
480
+ t12 = $[26];
481
+ }
482
+ const handleMouseOver = t12;
483
+ let t13;
484
+ if ($[27] !== dropdownElement) {
485
+ t13 = (event_1) => {
486
+ if (!hasItemsRef.current) {
487
+ return;
488
+ }
489
+ const activeItem = getActiveItemElement(dropdownElement);
490
+ if (!activeItem) {
491
+ return;
492
+ }
493
+ const eventRelatedTarget = event_1.relatedTarget;
494
+ if (activeItem !== event_1.target || activeItem.contains(eventRelatedTarget)) {
495
+ return;
496
+ }
497
+ delete activeItem.dataset.uktActive;
498
+ };
499
+ $[27] = dropdownElement;
500
+ $[28] = t13;
501
+ } else {
502
+ t13 = $[28];
503
+ }
504
+ const handleMouseOut = t13;
505
+ let t14;
506
+ if ($[29] !== onMouseDown || $[30] !== setIsOpen || $[31] !== setIsOpening) {
507
+ t14 = (event_2) => {
508
+ if (onMouseDown) {
509
+ onMouseDown(event_2);
510
+ }
511
+ if (isOpenRef.current) {
512
+ return;
513
+ }
514
+ setIsOpen(true);
515
+ setIsOpening(true);
516
+ mouseDownPositionRef.current = {
517
+ clientX: event_2.clientX,
518
+ clientY: event_2.clientY
519
+ };
520
+ isOpeningTimerRef.current = setTimeout(() => {
521
+ setIsOpening(false);
522
+ isOpeningTimerRef.current = null;
523
+ }, 1e3);
524
+ };
525
+ $[29] = onMouseDown;
526
+ $[30] = setIsOpen;
527
+ $[31] = setIsOpening;
528
+ $[32] = t14;
529
+ } else {
530
+ t14 = $[32];
531
+ }
532
+ const handleMouseDown = t14;
533
+ let t15;
534
+ if ($[33] !== closeDropdown || $[34] !== handleSubmitItem || $[35] !== onMouseUp) {
535
+ t15 = (event_3) => {
536
+ if (onMouseUp) {
537
+ onMouseUp(event_3);
538
+ }
539
+ if (isOpeningRef.current || !isOpenRef.current || closingTimerRef.current) {
540
+ return;
541
+ }
542
+ const eventTarget_0 = event_3.target;
543
+ if (!eventTarget_0.closest(BODY_SELECTOR)) {
544
+ if (!isOpeningRef.current && inputElementRef.current !== eventTarget_0.ownerDocument.activeElement) {
545
+ closeDropdown();
146
546
  }
147
- }, [closeDropdown]);
148
- const handleMouseMove = useCallback(({ clientX, clientY }) => {
149
- currentInputMethodRef.current = 'mouse';
150
- const initialPosition = mouseDownPositionRef.current;
151
- if (!initialPosition)
152
- return;
153
- if (Math.abs(initialPosition.clientX - clientX) < 12 &&
154
- Math.abs(initialPosition.clientY - clientY) < 12) {
155
- return;
547
+ return;
548
+ }
549
+ if (!hasItemsRef.current) {
550
+ return;
551
+ }
552
+ handleSubmitItem(event_3);
553
+ };
554
+ $[33] = closeDropdown;
555
+ $[34] = handleSubmitItem;
556
+ $[35] = onMouseUp;
557
+ $[36] = t15;
558
+ } else {
559
+ t15 = $[36];
560
+ }
561
+ const handleMouseUp = t15;
562
+ let t16;
563
+ if ($[37] !== closeDropdown || $[38] !== dropdownElement || $[39] !== handleSubmitItem || $[40] !== setIsOpen) {
564
+ t16 = (event_4) => {
565
+ const {
566
+ altKey,
567
+ ctrlKey,
568
+ key,
569
+ metaKey
570
+ } = event_4;
571
+ const eventTarget_1 = event_4.target;
572
+ if (!dropdownElement) {
573
+ return;
574
+ }
575
+ const onEventHandled = () => {
576
+ event_4.stopPropagation();
577
+ event_4.preventDefault();
578
+ currentInputMethodRef.current = "keyboard";
579
+ };
580
+ const isEventTargetingDropdown = dropdownElement.contains(eventTarget_1);
581
+ if (!isOpenRef.current) {
582
+ if (!isEventTargetingDropdown) {
583
+ return;
156
584
  }
157
- setIsOpening(false);
158
- }, []);
159
- const handleMouseOver = useCallback((event) => {
160
- if (!hasItemsRef.current)
161
- return;
162
- // If user isn’t currently using the mouse to navigate the dropdown, do nothing
163
- if (currentInputMethodRef.current !== 'mouse')
164
- return;
165
- // Ensure we have the dropdown root HTMLElement
166
- const dropdownElement = dropdownElementRef.current;
167
- if (!dropdownElement)
168
- return;
169
- const itemElements = getItemElements(dropdownElement);
170
- if (!itemElements)
171
- return;
172
- const eventTarget = event.target;
173
- const item = eventTarget.closest(ITEM_SELECTOR);
174
- const element = item !== null && item !== void 0 ? item : eventTarget;
175
- for (const itemElement of itemElements) {
176
- if (itemElement === element) {
177
- setActiveItem({ dropdownElement, element });
178
- return;
179
- }
585
+ if (key === " " || key === "Enter" || hasItemsRef.current && (key === "ArrowUp" || key === "ArrowDown")) {
586
+ onEventHandled();
587
+ setIsOpen(true);
180
588
  }
181
- }, []);
182
- const handleMouseOut = useCallback((event) => {
183
- if (!hasItemsRef.current)
184
- return;
185
- const activeItem = getActiveItemElement(dropdownElementRef.current);
186
- if (!activeItem)
187
- return;
188
- const eventRelatedTarget = event.relatedTarget;
189
- if (activeItem !== event.target || activeItem.contains(eventRelatedTarget)) {
190
- return;
589
+ return;
590
+ }
591
+ const isTargetUsingKeyEvents = isEventTargetUsingKeyEvent(event_4);
592
+ if (hasItemsRef.current && !isTargetUsingKeyEvents) {
593
+ let isEditingCharacters = !ctrlKey && !metaKey && /^[A-Za-z0-9]$/.test(key);
594
+ if (!isEditingCharacters && enteredCharactersRef.current) {
595
+ isEditingCharacters = key === " " || key === "Backspace";
191
596
  }
192
- // If user moused out of activeItem (not into a descendant), it’s no longer active
193
- delete activeItem.dataset.uktActive;
194
- }, []);
195
- const handleMouseDown = useCallback((event) => {
196
- if (onMouseDown)
197
- onMouseDown(event);
198
- if (isOpenRef.current)
199
- return;
200
- setIsOpen(true);
201
- setIsOpening(true);
202
- mouseDownPositionRef.current = {
203
- clientX: event.clientX,
204
- clientY: event.clientY,
205
- };
206
- isOpeningTimerRef.current = setTimeout(() => {
207
- setIsOpening(false);
208
- isOpeningTimerRef.current = null;
209
- }, 1000);
210
- }, [onMouseDown]);
211
- const handleMouseUp = useCallback((event) => {
212
- if (onMouseUp)
213
- onMouseUp(event);
214
- // If dropdown is still opening or isn’t open or is closing, do nothing
215
- if (isOpeningRef.current || !isOpenRef.current || closingTimerRef.current) {
216
- return;
597
+ if (isEditingCharacters) {
598
+ onEventHandled();
599
+ if (key === "Backspace") {
600
+ enteredCharactersRef.current = enteredCharactersRef.current.slice(0, -1);
601
+ } else {
602
+ enteredCharactersRef.current = enteredCharactersRef.current + key;
603
+ }
604
+ setActiveItem({
605
+ dropdownElement,
606
+ isExactMatch: allowCreateRef.current,
607
+ text: enteredCharactersRef.current
608
+ });
609
+ if (clearEnteredCharactersTimerRef.current) {
610
+ clearTimeout(clearEnteredCharactersTimerRef.current);
611
+ }
612
+ clearEnteredCharactersTimerRef.current = setTimeout(() => {
613
+ enteredCharactersRef.current = "";
614
+ clearEnteredCharactersTimerRef.current = null;
615
+ }, 1500);
616
+ return;
217
617
  }
218
- const eventTarget = event.target;
219
- // If click was outside dropdown body, don’t trigger submit
220
- if (!eventTarget.closest(BODY_SELECTOR)) {
221
- // Don’t close dropdown if isOpening or search input is focused
222
- if (!isOpeningRef.current &&
223
- inputElementRef.current !== eventTarget.ownerDocument.activeElement) {
224
- closeDropdown();
225
- }
226
- return;
618
+ }
619
+ if (key === "Enter" || key === " " && !inputElementRef.current) {
620
+ onEventHandled();
621
+ handleSubmitItem(event_4);
622
+ return;
623
+ }
624
+ if (key === "Escape" || isEventTargetingDropdown && key === " " && !hasItemsRef.current) {
625
+ if (hasItemsRef.current || !isTargetUsingKeyEvents) {
626
+ closeDropdown();
227
627
  }
228
- // If dropdown has no items and click was within dropdown body, do nothing
229
- if (!hasItemsRef.current)
230
- return;
231
- handleSubmitItem(event);
232
- }, [closeDropdown, handleSubmitItem, onMouseUp]);
233
- const handleKeyDown = useCallback((event) => {
234
- const { altKey, ctrlKey, key, metaKey } = event;
235
- const eventTarget = event.target;
236
- const dropdownElement = dropdownElementRef.current;
237
- if (!dropdownElement)
238
- return;
239
- const onEventHandled = () => {
240
- event.stopPropagation();
241
- event.preventDefault();
242
- currentInputMethodRef.current = 'keyboard';
243
- };
244
- const isEventTargetingDropdown = dropdownElement.contains(eventTarget);
245
- if (!isOpenRef.current) {
246
- // If dropdown is closed, don’t handle key events if event target isn’t within dropdown
247
- if (!isEventTargetingDropdown)
248
- return;
249
- // Open the dropdown on spacebar, enter, or if isSearchable and user hits the ↑/↓ arrows
250
- if (key === ' ' ||
251
- key === 'Enter' ||
252
- (hasItemsRef.current && (key === 'ArrowUp' || key === 'ArrowDown'))) {
253
- onEventHandled();
254
- setIsOpen(true);
255
- }
256
- return;
628
+ return;
629
+ }
630
+ if (hasItemsRef.current) {
631
+ if (key === "ArrowUp") {
632
+ onEventHandled();
633
+ if (altKey || metaKey) {
634
+ setActiveItem({
635
+ dropdownElement,
636
+ index: 0
637
+ });
638
+ } else {
639
+ setActiveItem({
640
+ dropdownElement,
641
+ indexAddend: -1
642
+ });
643
+ }
644
+ return;
257
645
  }
258
- const isTargetUsingKeyEvents = isEventTargetUsingKeyEvent(event);
259
- // If dropdown isOpen + hasItems & eventTargetNotUsingKeyEvents, handle characters
260
- if (hasItemsRef.current && !isTargetUsingKeyEvents) {
261
- let isEditingCharacters = !ctrlKey && !metaKey && /^[A-Za-z0-9]$/.test(key);
262
- // User could also be editing characters if there are already characters entered
263
- // and they are hitting delete or spacebar
264
- if (!isEditingCharacters && enteredCharactersRef.current) {
265
- isEditingCharacters = key === ' ' || key === 'Backspace';
266
- }
267
- if (isEditingCharacters) {
268
- onEventHandled();
269
- if (key === 'Backspace') {
270
- enteredCharactersRef.current = enteredCharactersRef.current.slice(0, -1);
271
- }
272
- else {
273
- enteredCharactersRef.current += key;
274
- }
275
- setActiveItem({
276
- dropdownElement,
277
- // If props.allowCreate, only override the input’s value with an
278
- // exact text match so user can enter a value not in items
279
- isExactMatch: allowCreateRef.current,
280
- text: enteredCharactersRef.current,
281
- });
282
- if (clearEnteredCharactersTimerRef.current) {
283
- clearTimeout(clearEnteredCharactersTimerRef.current);
284
- }
285
- clearEnteredCharactersTimerRef.current = setTimeout(() => {
286
- enteredCharactersRef.current = '';
287
- clearEnteredCharactersTimerRef.current = null;
288
- }, 1500);
289
- return;
290
- }
646
+ if (key === "ArrowDown") {
647
+ onEventHandled();
648
+ if (altKey || metaKey) {
649
+ setActiveItem({
650
+ dropdownElement,
651
+ index: -1
652
+ });
653
+ } else {
654
+ setActiveItem({
655
+ dropdownElement,
656
+ indexAddend: 1
657
+ });
658
+ }
659
+ return;
291
660
  }
292
- // If dropdown isOpen, handle submitting the value
293
- if (key === 'Enter' || (key === ' ' && !inputElementRef.current)) {
294
- onEventHandled();
295
- handleSubmitItem(event);
296
- return;
661
+ }
662
+ };
663
+ $[37] = closeDropdown;
664
+ $[38] = dropdownElement;
665
+ $[39] = handleSubmitItem;
666
+ $[40] = setIsOpen;
667
+ $[41] = t16;
668
+ } else {
669
+ t16 = $[41];
670
+ }
671
+ const handleKeyDown = t16;
672
+ let t17;
673
+ if ($[42] !== handleKeyDown) {
674
+ t17 = {
675
+ ignoreUsedKeyboardEvents: false,
676
+ onKeyDown: handleKeyDown
677
+ };
678
+ $[42] = handleKeyDown;
679
+ $[43] = t17;
680
+ } else {
681
+ t17 = $[43];
682
+ }
683
+ useKeyboardEvents(t17);
684
+ const cleanupEventListenersRef = useRef(noop);
685
+ let t18;
686
+ if ($[44] !== closeDropdown || $[45] !== isOpenOnMount || $[46] !== isTriggerFromProps || $[47] !== setDropdownElement || $[48] !== setIsOpen || $[49] !== setIsOpening) {
687
+ t18 = (ref) => {
688
+ setDropdownElement(ref);
689
+ if (!ref) {
690
+ cleanupEventListenersRef.current();
691
+ cleanupEventListenersRef.current = noop;
692
+ return;
693
+ }
694
+ const {
695
+ ownerDocument
696
+ } = ref;
697
+ let inputElement = inputElementRef.current;
698
+ if (isTriggerFromProps && !inputElement && ref.firstElementChild) {
699
+ if (ref.firstElementChild.matches(TEXT_INPUT_SELECTOR)) {
700
+ inputElement = ref.firstElementChild;
701
+ } else {
702
+ inputElement = ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);
297
703
  }
298
- // If dropdown isOpen, handle closing it on escape or spacebar if !hasItems
299
- if (key === 'Escape' ||
300
- (isEventTargetingDropdown && key === ' ' && !hasItemsRef.current)) {
301
- // Close dropdown if hasItems or event target not using key events
302
- if (hasItemsRef.current || !isTargetUsingKeyEvents) {
303
- closeDropdown();
304
- }
305
- return;
704
+ inputElementRef.current = inputElement;
705
+ }
706
+ const handleGlobalMouseDown = (t192) => {
707
+ const {
708
+ target
709
+ } = t192;
710
+ const eventTarget_2 = target;
711
+ if (!ref.contains(eventTarget_2)) {
712
+ closeDropdown();
306
713
  }
307
- // Handle ↑/↓ arrows
308
- if (hasItemsRef.current) {
309
- if (key === 'ArrowUp') {
310
- onEventHandled();
311
- if (altKey || metaKey) {
312
- setActiveItem({ dropdownElement, index: 0 });
313
- }
314
- else {
315
- setActiveItem({ dropdownElement, indexAddend: -1 });
316
- }
317
- return;
318
- }
319
- if (key === 'ArrowDown') {
320
- onEventHandled();
321
- if (altKey || metaKey) {
322
- // Using a negative index counts back from the end
323
- setActiveItem({ dropdownElement, index: -1 });
324
- }
325
- else {
326
- setActiveItem({ dropdownElement, indexAddend: 1 });
327
- }
328
- return;
329
- }
714
+ };
715
+ const handleGlobalMouseUp = (t202) => {
716
+ const {
717
+ target: target_0
718
+ } = t202;
719
+ if (!isOpenRef.current || closingTimerRef.current) {
720
+ return;
330
721
  }
331
- }, [closeDropdown, handleSubmitItem]);
332
- useKeyboardEvents({ ignoreUsedKeyboardEvents: false, onKeyDown: handleKeyDown });
333
- const cleanupEventListenersRef = useRef(noop);
334
- const handleRef = useCallback((ref) => {
335
- dropdownElementRef.current = ref;
336
- if (!ref) {
337
- // If component was unmounted, cleanup handlers
338
- cleanupEventListenersRef.current();
339
- cleanupEventListenersRef.current = noop;
340
- return;
722
+ if (isOpeningRef.current) {
723
+ setIsOpening(false);
724
+ if (isOpeningTimerRef.current) {
725
+ clearTimeout(isOpeningTimerRef.current);
726
+ isOpeningTimerRef.current = null;
727
+ }
728
+ return;
341
729
  }
342
- const { ownerDocument } = ref;
343
- let inputElement = inputElementRef.current;
344
- // Check if trigger from props is a textual input or textarea element
345
- if (isTriggerFromProps && !inputElement && ref.firstElementChild) {
346
- if (ref.firstElementChild.matches(TEXT_INPUT_SELECTOR)) {
347
- inputElement = ref.firstElementChild;
348
- }
349
- else {
350
- inputElement =
351
- ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);
352
- }
353
- inputElementRef.current = inputElement;
730
+ const eventTarget_3 = target_0;
731
+ if (!ref.contains(eventTarget_3)) {
732
+ closeDropdown();
354
733
  }
355
- const handleGlobalMouseDown = ({ target }) => {
356
- const eventTarget = target;
357
- if (dropdownElementRef.current &&
358
- !dropdownElementRef.current.contains(eventTarget)) {
359
- // Close dropdown on an outside click
360
- closeDropdown();
361
- }
362
- };
363
- const handleGlobalMouseUp = ({ target }) => {
364
- var _a;
365
- if (!isOpenRef.current || closingTimerRef.current)
366
- return;
367
- // If still isOpening (gets set false 1s after open triggers), set it to false onMouseUp
368
- if (isOpeningRef.current) {
369
- setIsOpening(false);
370
- if (isOpeningTimerRef.current) {
371
- clearTimeout(isOpeningTimerRef.current);
372
- isOpeningTimerRef.current = null;
373
- }
374
- return;
375
- }
376
- const eventTarget = target;
377
- // Only handle mouseup events from outside the dropdown here
378
- if (!((_a = dropdownElementRef.current) === null || _a === void 0 ? void 0 : _a.contains(eventTarget))) {
379
- closeDropdown();
380
- }
381
- };
382
- // Close dropdown if any element is focused outside of this dropdown
383
- const handleGlobalFocusIn = ({ target }) => {
384
- if (!isOpenRef.current)
385
- return;
386
- const eventTarget = target;
387
- // If focused element is a descendant or a parent of the dropdown, do nothing
388
- if (!dropdownElementRef.current ||
389
- dropdownElementRef.current.contains(eventTarget) ||
390
- eventTarget.contains(dropdownElementRef.current)) {
391
- return;
392
- }
393
- closeDropdown();
394
- };
395
- document.addEventListener('focusin', handleGlobalFocusIn);
396
- document.addEventListener('mousedown', handleGlobalMouseDown);
397
- document.addEventListener('mouseup', handleGlobalMouseUp);
398
- if (ownerDocument !== document) {
399
- ownerDocument.addEventListener('focusin', handleGlobalFocusIn);
400
- ownerDocument.addEventListener('mousedown', handleGlobalMouseDown);
401
- ownerDocument.addEventListener('mouseup', handleGlobalMouseUp);
734
+ };
735
+ const handleGlobalFocusIn = (t212) => {
736
+ const {
737
+ target: target_1
738
+ } = t212;
739
+ if (!isOpenRef.current) {
740
+ return;
402
741
  }
403
- // If dropdown should be open on mount, focus it
404
- if (isOpenOnMount) {
405
- ref.focus();
742
+ const eventTarget_4 = target_1;
743
+ if (ref.contains(eventTarget_4) || eventTarget_4.contains(ref)) {
744
+ return;
406
745
  }
407
- const handleInput = (event) => {
408
- const dropdownElement = dropdownElementRef.current;
409
- if (!dropdownElement)
410
- return;
411
- if (!isOpenRef.current)
412
- setIsOpen(true);
413
- const input = event.target;
414
- const isDeleting = enteredCharactersRef.current.length > input.value.length;
415
- enteredCharactersRef.current = input.value;
416
- // When deleting text, if there’s already an active item and
417
- // input isn’t empty, preserve the active item, else update it
418
- if (isDeleting &&
419
- input.value.length &&
420
- getActiveItemElement(dropdownElement)) {
421
- return;
422
- }
423
- setActiveItem({
424
- dropdownElement,
425
- // If props.allowCreate, only override the input’s value with an
426
- // exact text match so user can enter a value not in items
427
- isExactMatch: allowCreateRef.current,
428
- text: enteredCharactersRef.current,
429
- });
430
- };
431
- if (inputElement) {
432
- inputElement.addEventListener('input', handleInput);
746
+ closeDropdown();
747
+ };
748
+ document.addEventListener("focusin", handleGlobalFocusIn);
749
+ document.addEventListener("mousedown", handleGlobalMouseDown);
750
+ document.addEventListener("mouseup", handleGlobalMouseUp);
751
+ if (ownerDocument !== document) {
752
+ ownerDocument.addEventListener("focusin", handleGlobalFocusIn);
753
+ ownerDocument.addEventListener("mousedown", handleGlobalMouseDown);
754
+ ownerDocument.addEventListener("mouseup", handleGlobalMouseUp);
755
+ }
756
+ if (isOpenOnMount) {
757
+ ref.focus();
758
+ }
759
+ const handleInput = (event_5) => {
760
+ if (!isOpenRef.current) {
761
+ setIsOpen(true);
762
+ }
763
+ const input = event_5.target;
764
+ const isDeleting = enteredCharactersRef.current.length > input.value.length;
765
+ enteredCharactersRef.current = input.value;
766
+ if (isDeleting && input.value.length && getActiveItemElement(ref)) {
767
+ return;
433
768
  }
434
- cleanupEventListenersRef.current = () => {
435
- document.removeEventListener('focusin', handleGlobalFocusIn);
436
- document.removeEventListener('mousedown', handleGlobalMouseDown);
437
- document.removeEventListener('mouseup', handleGlobalMouseUp);
438
- if (ownerDocument !== document) {
439
- ownerDocument.removeEventListener('focusin', handleGlobalFocusIn);
440
- ownerDocument.removeEventListener('mousedown', handleGlobalMouseDown);
441
- ownerDocument.removeEventListener('mouseup', handleGlobalMouseUp);
442
- }
443
- if (inputElement) {
444
- inputElement.removeEventListener('input', handleInput);
445
- }
446
- };
447
- }, [closeDropdown, isOpenOnMount, isTriggerFromProps]);
448
- if (!isTriggerFromProps) {
449
- if (isSearchable) {
450
- trigger = (React.createElement("input", { autoComplete: "off", className: TRIGGER_CLASS_NAME, defaultValue: value !== null && value !== void 0 ? value : '', disabled: disabled, name: name, onFocus: setDropdownOpenRef.current, placeholder: placeholder, ref: inputElementRef, tabIndex: tabIndex, type: "text" }));
769
+ setActiveItem({
770
+ dropdownElement: ref,
771
+ isExactMatch: allowCreateRef.current,
772
+ text: enteredCharactersRef.current
773
+ });
774
+ };
775
+ if (inputElement) {
776
+ inputElement.addEventListener("input", handleInput);
777
+ }
778
+ cleanupEventListenersRef.current = () => {
779
+ document.removeEventListener("focusin", handleGlobalFocusIn);
780
+ document.removeEventListener("mousedown", handleGlobalMouseDown);
781
+ document.removeEventListener("mouseup", handleGlobalMouseUp);
782
+ if (ownerDocument !== document) {
783
+ ownerDocument.removeEventListener("focusin", handleGlobalFocusIn);
784
+ ownerDocument.removeEventListener("mousedown", handleGlobalMouseDown);
785
+ ownerDocument.removeEventListener("mouseup", handleGlobalMouseUp);
451
786
  }
452
- else {
453
- trigger = (React.createElement("button", { className: TRIGGER_CLASS_NAME, tabIndex: 0 }, trigger));
787
+ if (inputElement) {
788
+ inputElement.removeEventListener("input", handleInput);
454
789
  }
790
+ };
791
+ };
792
+ $[44] = closeDropdown;
793
+ $[45] = isOpenOnMount;
794
+ $[46] = isTriggerFromProps;
795
+ $[47] = setDropdownElement;
796
+ $[48] = setIsOpen;
797
+ $[49] = setIsOpening;
798
+ $[50] = t18;
799
+ } else {
800
+ t18 = $[50];
801
+ }
802
+ const handleRef = t18;
803
+ if (!isTriggerFromProps) {
804
+ if (isSearchable) {
805
+ const t192 = value ?? "";
806
+ let t202;
807
+ if ($[51] !== setIsOpen) {
808
+ t202 = () => setIsOpen(true);
809
+ $[51] = setIsOpen;
810
+ $[52] = t202;
811
+ } else {
812
+ t202 = $[52];
813
+ }
814
+ let t212;
815
+ if ($[53] !== disabled || $[54] !== name || $[55] !== placeholder || $[56] !== t192 || $[57] !== t202 || $[58] !== tabIndex) {
816
+ t212 = /* @__PURE__ */ jsx("input", { autoComplete: "off", className: TRIGGER_CLASS_NAME, defaultValue: t192, disabled, name, onFocus: t202, placeholder, ref: inputElementRef, tabIndex, type: "text" });
817
+ $[53] = disabled;
818
+ $[54] = name;
819
+ $[55] = placeholder;
820
+ $[56] = t192;
821
+ $[57] = t202;
822
+ $[58] = tabIndex;
823
+ $[59] = t212;
824
+ } else {
825
+ t212 = $[59];
826
+ }
827
+ trigger = t212;
828
+ } else {
829
+ let t192;
830
+ if ($[60] !== trigger) {
831
+ t192 = /* @__PURE__ */ jsx("button", { className: TRIGGER_CLASS_NAME, tabIndex: 0, children: trigger });
832
+ $[60] = trigger;
833
+ $[61] = t192;
834
+ } else {
835
+ t192 = $[61];
836
+ }
837
+ trigger = t192;
455
838
  }
456
- if (label) {
457
- trigger = (React.createElement("label", { className: LABEL_CLASS_NAME },
458
- React.createElement("div", { className: LABEL_TEXT_CLASS_NAME }, label),
459
- trigger));
839
+ }
840
+ if (label) {
841
+ let t192;
842
+ if ($[62] !== label) {
843
+ t192 = /* @__PURE__ */ jsx("div", { className: LABEL_TEXT_CLASS_NAME, children: label });
844
+ $[62] = label;
845
+ $[63] = t192;
846
+ } else {
847
+ t192 = $[63];
460
848
  }
461
- const style = useMemo(() => (Object.assign(Object.assign(Object.assign({}, styleFromProps), (outOfBounds.maxHeight != null && outOfBounds.maxHeight > 0
462
- ? {
463
- [BODY_MAX_HEIGHT_VAR]: `calc(${outOfBounds.maxHeight}px - var(--uktdd-body-buffer))`,
464
- }
465
- : null)), (outOfBounds.maxWidth != null && outOfBounds.maxWidth > 0
466
- ? {
467
- [BODY_MAX_WIDTH_VAR]: `calc(${outOfBounds.maxWidth}px - var(--uktdd-body-buffer))`,
468
- }
469
- : null))), [outOfBounds.maxHeight, outOfBounds.maxWidth, styleFromProps]);
470
- return (React.createElement(Fragment, null,
471
- React.createElement(Style, { href: "@acusti/dropdown/Dropdown" }, STYLES),
472
- React.createElement("div", { className: clsx(ROOT_CLASS_NAME, className, {
473
- disabled,
474
- 'is-open': isOpen,
475
- 'is-searchable': isSearchable,
476
- }), onClick: onClick, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseOut: handleMouseOut, onMouseOver: handleMouseOver, onMouseUp: handleMouseUp, ref: handleRef, style: style },
477
- trigger,
478
- isOpen ? (React.createElement("div", { className: clsx(BODY_CLASS_NAME, {
479
- 'calculating-position': !outOfBounds.hasLayout,
480
- 'has-items': hasItems,
481
- 'out-of-bounds-bottom': outOfBounds.bottom && !outOfBounds.top,
482
- 'out-of-bounds-left': outOfBounds.left && !outOfBounds.right,
483
- 'out-of-bounds-right': outOfBounds.right && !outOfBounds.left,
484
- 'out-of-bounds-top': outOfBounds.top && !outOfBounds.bottom,
485
- }), ref: setDropdownBodyElement }, childrenCount > 1 ? children[1] : children)) : null)));
849
+ let t202;
850
+ if ($[64] !== t192 || $[65] !== trigger) {
851
+ t202 = /* @__PURE__ */ jsxs("label", { className: LABEL_CLASS_NAME, children: [
852
+ t192,
853
+ trigger
854
+ ] });
855
+ $[64] = t192;
856
+ $[65] = trigger;
857
+ $[66] = t202;
858
+ } else {
859
+ t202 = $[66];
860
+ }
861
+ trigger = t202;
862
+ }
863
+ const dropdownRect = useBoundingClientRect(dropdownElement);
864
+ const dropdownBodyRect = useBoundingClientRect(dropdownBodyElement);
865
+ let t19;
866
+ if ($[67] !== dropdownBodyElement) {
867
+ t19 = getBoundingAncestor(dropdownBodyElement);
868
+ $[67] = dropdownBodyElement;
869
+ $[68] = t19;
870
+ } else {
871
+ t19 = $[68];
872
+ }
873
+ const boundingElement = t19;
874
+ const boundingElementRect = useBoundingClientRect(boundingElement);
875
+ let maxHeight;
876
+ let maxWidth;
877
+ if (dropdownBodyRect.top != null && dropdownRect.top != null && boundingElementRect.top != null) {
878
+ const maxHeightUp = dropdownBodyRect.bottom - boundingElementRect.top;
879
+ const maxHeightDown = boundingElementRect.bottom - dropdownBodyRect.top;
880
+ maxHeight = dropdownBodyRect.top > dropdownRect.top ? maxHeightDown : maxHeightUp;
881
+ const maxWidthLeft = dropdownBodyRect.right - boundingElementRect.left;
882
+ const maxWidthRight = boundingElementRect.right - dropdownBodyRect.left;
883
+ maxWidth = dropdownBodyRect.left > dropdownRect.left ? maxWidthRight : maxWidthLeft;
884
+ }
885
+ let t20;
886
+ if ($[69] !== maxHeight) {
887
+ t20 = maxHeight != null && maxHeight > 0 ? {
888
+ [BODY_MAX_HEIGHT_VAR]: `calc(${maxHeight}px - var(--uktdd-body-buffer))`
889
+ } : null;
890
+ $[69] = maxHeight;
891
+ $[70] = t20;
892
+ } else {
893
+ t20 = $[70];
894
+ }
895
+ let t21;
896
+ if ($[71] !== maxWidth) {
897
+ t21 = maxWidth != null && maxWidth > 0 ? {
898
+ [BODY_MAX_WIDTH_VAR]: `calc(${maxWidth}px - var(--uktdd-body-buffer))`
899
+ } : null;
900
+ $[71] = maxWidth;
901
+ $[72] = t21;
902
+ } else {
903
+ t21 = $[72];
904
+ }
905
+ let t22;
906
+ if ($[73] !== styleFromProps || $[74] !== t20 || $[75] !== t21) {
907
+ t22 = {
908
+ ...styleFromProps,
909
+ ...t20,
910
+ ...t21
911
+ };
912
+ $[73] = styleFromProps;
913
+ $[74] = t20;
914
+ $[75] = t21;
915
+ $[76] = t22;
916
+ } else {
917
+ t22 = $[76];
918
+ }
919
+ const style = t22;
920
+ let t23;
921
+ if ($[77] === Symbol.for("react.memo_cache_sentinel")) {
922
+ t23 = /* @__PURE__ */ jsx(Style, { href: "@acusti/dropdown/Dropdown", children: STYLES });
923
+ $[77] = t23;
924
+ } else {
925
+ t23 = $[77];
926
+ }
927
+ const t24 = `
928
+ [data-ukt-id="${id}"] > :first-child {
929
+ anchor-name: --uktdd-anchor${id};
930
+ }
931
+ [data-ukt-id="${id}"] ${BODY_SELECTOR} {
932
+ position-anchor: --uktdd-anchor${id};
933
+ }
934
+ `;
935
+ let t25;
936
+ if ($[78] !== t24) {
937
+ t25 = /* @__PURE__ */ jsx(Style, { children: t24 });
938
+ $[78] = t24;
939
+ $[79] = t25;
940
+ } else {
941
+ t25 = $[79];
942
+ }
943
+ let t26;
944
+ if ($[80] !== className || $[81] !== disabled || $[82] !== isOpen || $[83] !== isSearchable) {
945
+ t26 = clsx(ROOT_CLASS_NAME, className, {
946
+ disabled,
947
+ "is-open": isOpen,
948
+ "is-searchable": isSearchable
949
+ });
950
+ $[80] = className;
951
+ $[81] = disabled;
952
+ $[82] = isOpen;
953
+ $[83] = isSearchable;
954
+ $[84] = t26;
955
+ } else {
956
+ t26 = $[84];
957
+ }
958
+ let t27;
959
+ if ($[85] !== children || $[86] !== childrenCount || $[87] !== isOpen || $[88] !== setDropdownBodyElement) {
960
+ t27 = isOpen ? /* @__PURE__ */ jsx("div", { className: BODY_CLASS_NAME, ref: setDropdownBodyElement, children: childrenCount > 1 ? children[1] : children }) : null;
961
+ $[85] = children;
962
+ $[86] = childrenCount;
963
+ $[87] = isOpen;
964
+ $[88] = setDropdownBodyElement;
965
+ $[89] = t27;
966
+ } else {
967
+ t27 = $[89];
968
+ }
969
+ let t28;
970
+ if ($[90] !== handleMouseDown || $[91] !== handleMouseMove || $[92] !== handleMouseOut || $[93] !== handleMouseOver || $[94] !== handleMouseUp || $[95] !== handleRef || $[96] !== id || $[97] !== onClick || $[98] !== style || $[99] !== t26 || $[100] !== t27 || $[101] !== trigger) {
971
+ t28 = /* @__PURE__ */ jsxs("div", { className: t26, "data-ukt-id": id, onClick, onMouseDown: handleMouseDown, onMouseMove: handleMouseMove, onMouseOut: handleMouseOut, onMouseOver: handleMouseOver, onMouseUp: handleMouseUp, ref: handleRef, style, children: [
972
+ trigger,
973
+ t27
974
+ ] });
975
+ $[90] = handleMouseDown;
976
+ $[91] = handleMouseMove;
977
+ $[92] = handleMouseOut;
978
+ $[93] = handleMouseOver;
979
+ $[94] = handleMouseUp;
980
+ $[95] = handleRef;
981
+ $[96] = id;
982
+ $[97] = onClick;
983
+ $[98] = style;
984
+ $[99] = t26;
985
+ $[100] = t27;
986
+ $[101] = trigger;
987
+ $[102] = t28;
988
+ } else {
989
+ t28 = $[102];
990
+ }
991
+ let t29;
992
+ if ($[103] !== t25 || $[104] !== t28) {
993
+ t29 = /* @__PURE__ */ jsxs(Fragment, { children: [
994
+ t23,
995
+ t25,
996
+ t28
997
+ ] });
998
+ $[103] = t25;
999
+ $[104] = t28;
1000
+ $[105] = t29;
1001
+ } else {
1002
+ t29 = $[105];
1003
+ }
1004
+ return t29;
1005
+ }
1006
+ function _temp() {
1007
+ idCounter = idCounter >= 999999 ? 0 : idCounter + 1;
1008
+ return idCounter;
1009
+ }
1010
+ function getBoundingAncestor(element) {
1011
+ while (element == null ? void 0 : element.parentElement) {
1012
+ if (element.parentElement.tagName === "BODY") return element.parentElement;
1013
+ if (getComputedStyle(element.parentElement).overflowX !== "visible") {
1014
+ return element.parentElement;
1015
+ }
1016
+ element = element.parentElement;
1017
+ }
1018
+ return null;
486
1019
  }
487
- //# sourceMappingURL=Dropdown.js.map
1020
+ export {
1021
+ Dropdown as default
1022
+ };
1023
+ //# sourceMappingURL=Dropdown.js.map