@acusti/dropdown 0.54.1 → 0.55.1

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/README.md CHANGED
@@ -6,8 +6,8 @@
6
6
  [![bundle size](https://deno.bundlejs.com/badge?q=@acusti/dropdown)](https://bundlejs.com/?q=%40acusti%2Fdropdown)
7
7
 
8
8
  `Dropdown` is a React component that renders a menu-like UI with a trigger
9
- that the user clicks to disclose a dropdown positioned below the trigger.
10
- The body of the dropdown can include any DOM, and many dropdowns can be
9
+ that the user clicks to disclose a dropdown anchored to that trigger. The
10
+ body of the dropdown can include any DOM, and many dropdowns can be
11
11
  combined to form a multi-item menu, like the system menu in the top toolbar
12
12
  of macOS.
13
13
 
@@ -78,6 +78,39 @@ function CustomTrigger() {
78
78
  }
79
79
  ```
80
80
 
81
+ ## Layout Model
82
+
83
+ `Dropdown` uses CSS anchor positioning for placement and prefers a
84
+ CSS-first sizing model:
85
+
86
+ - The trigger is the anchor
87
+ - The dropdown body is an anchored shell
88
+ - The inner content region becomes scrollable only when the content exceeds
89
+ the available space
90
+ - Placement fallbacks are handled with `position-try-order: most-height`
91
+
92
+ This means the dropdown tends to:
93
+
94
+ - stay content-sized when the contents are small
95
+ - expand to the available viewport space when more room is needed
96
+ - become scrollable when the contents exceed that space
97
+
98
+ Internally, the dropdown renders:
99
+
100
+ - `.uktdropdown-body` as the anchored outer shell
101
+ - `.uktdropdown-content` as the scrollable inner region
102
+
103
+ Custom padding and overflow styling usually belongs on the content region,
104
+ not the outer shell.
105
+
106
+ For the most reliable anchor-positioning behavior:
107
+
108
+ - pass exactly two children when you need a custom trigger
109
+ - ensure the trigger resolves to a stable DOM element
110
+ - keep the trigger first and the dropdown body second
111
+ - prefer CSS variable overrides over custom `top`/`left`/`right` inset
112
+ rules
113
+
81
114
  ## API Reference
82
115
 
83
116
  ### Props
@@ -126,11 +159,11 @@ type Props = {
126
159
  */
127
160
  keepOpenOnSubmit?: boolean;
128
161
  /**
129
- * Label text for the trigger button (when using single child syntax).
162
+ * Label content for the trigger button (when using single child syntax).
130
163
  */
131
- label?: string;
164
+ label?: ReactNode;
132
165
  /**
133
- * Minimum height for the dropdown body in pixels.
166
+ * Minimum height for the dropdown body in pixels. Defaults to 30.
134
167
  */
135
168
  minHeightBody?: number;
136
169
  /**
@@ -336,6 +369,60 @@ function InteractiveDropdown() {
336
369
  }
337
370
  ```
338
371
 
372
+ ### Placement Customization with CSS Variables
373
+
374
+ Placement is best customized in CSS instead of props. The component exposes
375
+ CSS custom properties for the most common low-level placement controls:
376
+
377
+ - `--uktdd-body-position-area`
378
+ - `--uktdd-body-position-try-fallbacks`
379
+ - `--uktdd-body-translate`
380
+ - `--uktdd-body-min-height`
381
+ - `--uktdd-body-min-width`
382
+ - `--uktdd-body-max-height`
383
+ - `--uktdd-body-max-width`
384
+
385
+ Example:
386
+
387
+ ```css
388
+ .settings-dropdown {
389
+ --uktdd-body-position-area: bottom span-left;
390
+ --uktdd-body-position-try-fallbacks:
391
+ --uktdd-top-right, --uktdd-bottom-left, --uktdd-top-left;
392
+ --uktdd-body-translate: -8px 0;
393
+ }
394
+
395
+ .settings-dropdown .uktdropdown-body {
396
+ inline-size: 18rem;
397
+ }
398
+ ```
399
+
400
+ This approach keeps the public React API small while still allowing precise
401
+ placement and sizing control when a product surface needs it.
402
+
403
+ ### End-Aligned, Content-Sized Menu
404
+
405
+ For menus attached to controls near the right edge of the viewport, such as
406
+ an avatar menu in a fixed header, prefer customizing alignment only and let
407
+ the menu size itself from its contents.
408
+
409
+ ```css
410
+ .avatar-menu {
411
+ --uktdd-body-position-area: bottom span-left;
412
+ --uktdd-body-position-try-fallbacks:
413
+ --uktdd-top-right, --uktdd-top-left, --uktdd-bottom-right;
414
+ }
415
+ ```
416
+
417
+ This keeps the menu:
418
+
419
+ - aligned to the end edge of the trigger
420
+ - content-sized by default
421
+ - constrained only by the component’s max available space rules
422
+
423
+ Avoid hardcoding width for this pattern unless the product explicitly needs
424
+ a fixed-size menu.
425
+
339
426
  ## Keyboard Navigation & Accessibility
340
427
 
341
428
  The dropdown implements full keyboard navigation:
package/dist/Dropdown.js CHANGED
@@ -1,13 +1,15 @@
1
1
  import { c } from "react/compiler-runtime";
2
- import useBoundingClientRect from "@acusti/use-bounding-client-rect";
3
2
  import useKeyboardEvents, { isEventTargetUsingKeyEvent } from "@acusti/use-keyboard-events";
4
3
  import clsx from "clsx";
5
4
  import { Children, Fragment, isValidElement, useEffect, useRef, useState } from "react";
6
5
  import { getBestMatch } from "@acusti/matchmaking";
7
6
  import { jsx, jsxs } from "react/jsx-runtime";
8
- var Dropdown_default = ":root{--uktdd-font-family:system-ui, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, Helvetica, Arial, sans-serif;--uktdd-body-bg-color:#fff;--uktdd-body-bg-color-hover:#69a2f9;--uktdd-body-color-hover:#fff;--uktdd-body-buffer:10px;--uktdd-body-max-height:calc(100vh - var(--uktdd-body-buffer));--uktdd-body-max-width: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-body-min-width:min(50px, 100%);--uktdd-label-pad-right:10px}.uktdropdown,.uktdropdown-trigger{font-family:var(--uktdd-font-family)}.uktdropdown{anchor-scope:--uktdd-anchor;width:max-content}.uktdropdown.disabled{pointer-events:none}.uktdropdown>*{cursor:default}.uktdropdown>:first-child{anchor-name:--uktdd-anchor}.uktdropdown-label{align-items:center;display:flex}.uktdropdown-label-text{padding-right:var(--uktdd-label-pad-right)}.uktdropdown-body{box-sizing:border-box;position-anchor:--uktdd-anchor;top:anchor(bottom);left:anchor(left);position-try-fallbacks:--uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;min-height:50px;max-height:var(--uktdd-body-max-height);min-width:var(--uktdd-body-min-width);max-width:var(--uktdd-body-max-width);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);position:absolute;bottom:auto;right:auto;overflow:auto;box-shadow:0 8px 18px #00000040}.uktdropdown-body.has-items{-webkit-user-select:none;user-select:none}.uktdropdown-body [data-ukt-active]{background-color:var(--uktdd-body-bg-color-hover);color:var(--uktdd-body-color-hover)}@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;}";
9
- const ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;
10
- const getItemElements = (dropdownElement) => {
7
+ //#region src/Dropdown.css?inline
8
+ var Dropdown_default = ":root{--uktdd-font-family:system-ui, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue, Helvetica, Arial, sans-serif;--uktdd-body-bg-color:#fff;--uktdd-body-bg-color-hover:#69a2f9;--uktdd-body-color-hover:#fff;--uktdd-body-buffer:10px;--uktdd-body-max-height:calc(100dvh - var(--uktdd-body-buffer));--uktdd-body-max-width:calc(100dvw - var(--uktdd-body-buffer));--uktdd-body-min-height:30px;--uktdd-body-pad-bottom:9px;--uktdd-body-pad-left:12px;--uktdd-body-pad-right:12px;--uktdd-body-pad-top:9px;--uktdd-body-min-width:min(50px, 100%);--uktdd-body-position-area:bottom span-right;--uktdd-body-position-try-fallbacks:--uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;--uktdd-body-translate:0 0;--uktdd-label-pad-right:10px}.uktdropdown,.uktdropdown-trigger{font-family:var(--uktdd-font-family)}.uktdropdown{anchor-scope:--uktdd-anchor;width:max-content}.uktdropdown.disabled{pointer-events:none}.uktdropdown>*{cursor:default}.uktdropdown>:first-child{anchor-name:--uktdd-anchor}.uktdropdown-label{align-items:center;display:flex}.uktdropdown-label-text{padding-right:var(--uktdd-label-pad-right)}.uktdropdown-body{box-sizing:border-box;position-anchor:--uktdd-anchor;position-area:var(--uktdd-body-position-area);position-try-order:most-height;position-try-fallbacks:var(--uktdd-body-position-try-fallbacks);min-block-size:min(var(--uktdd-body-min-height), var(--uktdd-body-max-height));max-block-size:min(var(--uktdd-body-max-height), 100%);min-inline-size:min(var(--uktdd-body-min-width), var(--uktdd-body-max-width));max-inline-size:var(--uktdd-body-max-width);inline-size:max-content;translate:var(--uktdd-body-translate);z-index:2;background-color:var(--uktdd-body-bg-color);flex-direction:column;display:flex;position:fixed;overflow:hidden;box-shadow:0 8px 18px #00000040}.uktdropdown-body.has-items{-webkit-user-select:none;user-select:none}.uktdropdown-body [data-ukt-active]{background-color:var(--uktdd-body-bg-color-hover);color:var(--uktdd-body-color-hover)}.uktdropdown-content{box-sizing:border-box;overscroll-behavior:contain;min-block-size:0;padding:var(--uktdd-body-pad-top) var(--uktdd-body-pad-right) var(--uktdd-body-pad-bottom) var(--uktdd-body-pad-left);overflow:auto}@position-try --uktdd-top-left{position-area: top span-right;}@position-try --uktdd-bottom-left{position-area: bottom span-right;}@position-try --uktdd-bottom-right{position-area: bottom span-left;}@position-try --uktdd-top-right{position-area: top span-left;}";
9
+ //#endregion
10
+ //#region src/helpers.ts
11
+ var ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;
12
+ var getItemElements = (dropdownElement) => {
11
13
  if (!dropdownElement) return null;
12
14
  const bodyElement = dropdownElement.querySelector(".uktdropdown-body");
13
15
  if (!bodyElement) return null;
@@ -21,7 +23,7 @@ const getItemElements = (dropdownElement) => {
21
23
  if (items.length === 1) items = bodyElement.children;
22
24
  return items;
23
25
  };
24
- const getActiveItemElement = (dropdownElement) => {
26
+ var getActiveItemElement = (dropdownElement) => {
25
27
  if (!dropdownElement) return null;
26
28
  return dropdownElement.querySelector("[data-ukt-active]");
27
29
  };
@@ -30,7 +32,7 @@ var clearItemElementsState = (itemElements) => {
30
32
  if (itemElement.hasAttribute("data-ukt-active")) delete itemElement.dataset.uktActive;
31
33
  });
32
34
  };
33
- const setActiveItem = ({ dropdownElement, element, event, index, indexAddend, isExactMatch, onActiveItem, text }) => {
35
+ var setActiveItem = ({ dropdownElement, element, event, index, indexAddend, isExactMatch, onActiveItem, text }) => {
34
36
  const items = getItemElements(dropdownElement);
35
37
  if (!items) return;
36
38
  const itemElements = Array.from(items);
@@ -91,16 +93,17 @@ const setActiveItem = ({ dropdownElement, element, event, index, indexAddend, is
91
93
  }
92
94
  }
93
95
  };
96
+ //#endregion
97
+ //#region src/Dropdown.tsx
94
98
  var CHILDREN_ERROR = "@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.";
95
99
  var CLICKABLE_SELECTOR = "button, a[href], input[type=\"button\"], input[type=\"submit\"]";
96
100
  var TEXT_INPUT_SELECTOR = "input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea";
97
101
  function Dropdown(t0) {
98
- const $ = c(89);
99
- const { allowCreate, allowEmpty: t1, children, className, disabled, hasItems: t2, isOpenOnMount, isSearchable, keepOpenOnSubmit: t3, label, minHeightBody: t4, minWidthBody, name, onActiveItem, onClick, onClose, onMouseDown, onMouseUp, onOpen, onSubmitItem, placeholder, style: styleFromProps, tabIndex, value } = t0;
102
+ const $ = c(82);
103
+ const { allowCreate, allowEmpty: t1, children, className, disabled, hasItems: t2, isOpenOnMount, isSearchable, keepOpenOnSubmit: t3, label, minHeightBody, minWidthBody, name, onActiveItem, onClick, onClose, onMouseDown, onMouseUp, onOpen, onSubmitItem, placeholder, style: styleFromProps, tabIndex, value } = t0;
100
104
  const allowEmpty = t1 === void 0 ? true : t1;
101
105
  const hasItems = t2 === void 0 ? true : t2;
102
106
  const keepOpenOnSubmit = t3 === void 0 ? !hasItems : t3;
103
- const minHeightBody = t4 === void 0 ? 30 : t4;
104
107
  const childrenCount = Children.count(children);
105
108
  if (childrenCount !== 1 && childrenCount !== 2) {
106
109
  if (childrenCount === 0) throw new Error(CHILDREN_ERROR + " Received no children.");
@@ -111,7 +114,6 @@ function Dropdown(t0) {
111
114
  const [isOpen, setIsOpen] = useState(isOpenOnMount ?? false);
112
115
  const [isOpening, setIsOpening] = useState(!isOpenOnMount);
113
116
  const [dropdownElement, setDropdownElement] = useState(null);
114
- const [dropdownBodyElement, setDropdownBodyElement] = useState(null);
115
117
  const inputElementRef = useRef(null);
116
118
  const closingTimerRef = useRef(null);
117
119
  const isOpeningTimerRef = useRef(null);
@@ -129,10 +131,10 @@ function Dropdown(t0) {
129
131
  const onOpenRef = useRef(onOpen);
130
132
  const onSubmitItemRef = useRef(onSubmitItem);
131
133
  const valueRef = useRef(value);
134
+ let t4;
132
135
  let t5;
133
- let t6;
134
136
  if ($[0] !== allowCreate || $[1] !== allowEmpty || $[2] !== hasItems || $[3] !== isOpen || $[4] !== isOpening || $[5] !== keepOpenOnSubmit || $[6] !== onClose || $[7] !== onOpen || $[8] !== onSubmitItem || $[9] !== value) {
135
- t5 = () => {
137
+ t4 = () => {
136
138
  allowCreateRef.current = allowCreate;
137
139
  allowEmptyRef.current = allowEmpty;
138
140
  hasItemsRef.current = hasItems;
@@ -144,7 +146,7 @@ function Dropdown(t0) {
144
146
  onSubmitItemRef.current = onSubmitItem;
145
147
  valueRef.current = value;
146
148
  };
147
- t6 = [
149
+ t5 = [
148
150
  allowCreate,
149
151
  allowEmpty,
150
152
  hasItems,
@@ -166,18 +168,18 @@ function Dropdown(t0) {
166
168
  $[7] = onOpen;
167
169
  $[8] = onSubmitItem;
168
170
  $[9] = value;
169
- $[10] = t5;
170
- $[11] = t6;
171
+ $[10] = t4;
172
+ $[11] = t5;
171
173
  } else {
172
- t5 = $[10];
173
- t6 = $[11];
174
+ t4 = $[10];
175
+ t5 = $[11];
174
176
  }
175
- useEffect(t5, t6);
177
+ useEffect(t4, t5);
176
178
  const isMountedRef = useRef(false);
179
+ let t6;
177
180
  let t7;
178
- let t8;
179
181
  if ($[12] !== isOpen) {
180
- t7 = () => {
182
+ t6 = () => {
181
183
  if (!isMountedRef.current) {
182
184
  isMountedRef.current = true;
183
185
  if (isOpenRef.current && onOpenRef.current) onOpenRef.current();
@@ -186,18 +188,18 @@ function Dropdown(t0) {
186
188
  if (isOpen && onOpenRef.current) onOpenRef.current();
187
189
  else if (!isOpen && onCloseRef.current) onCloseRef.current();
188
190
  };
189
- t8 = [isOpen];
191
+ t7 = [isOpen];
190
192
  $[12] = isOpen;
191
- $[13] = t7;
192
- $[14] = t8;
193
+ $[13] = t6;
194
+ $[14] = t7;
193
195
  } else {
194
- t7 = $[13];
195
- t8 = $[14];
196
+ t6 = $[13];
197
+ t7 = $[14];
196
198
  }
197
- useEffect(t7, t8);
198
- let t9;
199
+ useEffect(t6, t7);
200
+ let t8;
199
201
  if ($[15] === Symbol.for("react.memo_cache_sentinel")) {
200
- t9 = () => {
202
+ t8 = () => {
201
203
  setIsOpen(false);
202
204
  setIsOpening(false);
203
205
  mouseDownPositionRef.current = null;
@@ -206,12 +208,12 @@ function Dropdown(t0) {
206
208
  closingTimerRef.current = null;
207
209
  }
208
210
  };
209
- $[15] = t9;
210
- } else t9 = $[15];
211
- const closeDropdown = t9;
212
- let t10;
211
+ $[15] = t8;
212
+ } else t8 = $[15];
213
+ const closeDropdown = t8;
214
+ let t9;
213
215
  if ($[16] !== dropdownElement) {
214
- t10 = (event) => {
216
+ t9 = (event) => {
215
217
  if (isOpenRef.current && !keepOpenOnSubmitRef.current) closingTimerRef.current = setTimeout(closeDropdown, 90);
216
218
  if (!hasItemsRef.current) return;
217
219
  const element = getActiveItemElement(dropdownElement);
@@ -247,25 +249,25 @@ function Dropdown(t0) {
247
249
  });
248
250
  };
249
251
  $[16] = dropdownElement;
250
- $[17] = t10;
251
- } else t10 = $[17];
252
- const handleSubmitItem = t10;
253
- let t11;
252
+ $[17] = t9;
253
+ } else t9 = $[17];
254
+ const handleSubmitItem = t9;
255
+ let t10;
254
256
  if ($[18] === Symbol.for("react.memo_cache_sentinel")) {
255
- t11 = (t12) => {
256
- const { clientX, clientY } = t12;
257
+ t10 = (t11) => {
258
+ const { clientX, clientY } = t11;
257
259
  currentInputMethodRef.current = "mouse";
258
260
  const initialPosition = mouseDownPositionRef.current;
259
261
  if (!initialPosition) return;
260
262
  if (Math.abs(initialPosition.clientX - clientX) < 12 && Math.abs(initialPosition.clientY - clientY) < 12) return;
261
263
  setIsOpening(false);
262
264
  };
263
- $[18] = t11;
264
- } else t11 = $[18];
265
- const handleMouseMove = t11;
266
- let t12;
265
+ $[18] = t10;
266
+ } else t10 = $[18];
267
+ const handleMouseMove = t10;
268
+ let t11;
267
269
  if ($[19] !== dropdownElement || $[20] !== onActiveItem) {
268
- t12 = (event_0) => {
270
+ t11 = (event_0) => {
269
271
  if (!hasItemsRef.current) return;
270
272
  if (currentInputMethodRef.current !== "mouse") return;
271
273
  if (!dropdownElement) return;
@@ -285,12 +287,12 @@ function Dropdown(t0) {
285
287
  };
286
288
  $[19] = dropdownElement;
287
289
  $[20] = onActiveItem;
288
- $[21] = t12;
289
- } else t12 = $[21];
290
- const handleMouseOver = t12;
291
- let t13;
290
+ $[21] = t11;
291
+ } else t11 = $[21];
292
+ const handleMouseOver = t11;
293
+ let t12;
292
294
  if ($[22] !== dropdownElement) {
293
- t13 = (event_1) => {
295
+ t12 = (event_1) => {
294
296
  if (!hasItemsRef.current) return;
295
297
  const activeItem = getActiveItemElement(dropdownElement);
296
298
  if (!activeItem) return;
@@ -299,12 +301,12 @@ function Dropdown(t0) {
299
301
  delete activeItem.dataset.uktActive;
300
302
  };
301
303
  $[22] = dropdownElement;
302
- $[23] = t13;
303
- } else t13 = $[23];
304
- const handleMouseOut = t13;
305
- let t14;
304
+ $[23] = t12;
305
+ } else t12 = $[23];
306
+ const handleMouseOut = t12;
307
+ let t13;
306
308
  if ($[24] !== onMouseDown) {
307
- t14 = (event_2) => {
309
+ t13 = (event_2) => {
308
310
  if (onMouseDown) onMouseDown(event_2);
309
311
  if (isOpenRef.current) return;
310
312
  setIsOpen(true);
@@ -319,12 +321,12 @@ function Dropdown(t0) {
319
321
  }, 1e3);
320
322
  };
321
323
  $[24] = onMouseDown;
322
- $[25] = t14;
323
- } else t14 = $[25];
324
- const handleMouseDown = t14;
325
- let t15;
324
+ $[25] = t13;
325
+ } else t13 = $[25];
326
+ const handleMouseDown = t13;
327
+ let t14;
326
328
  if ($[26] !== handleSubmitItem || $[27] !== onMouseUp) {
327
- t15 = (event_3) => {
329
+ t14 = (event_3) => {
328
330
  if (onMouseUp) onMouseUp(event_3);
329
331
  if (isOpeningRef.current || !isOpenRef.current || closingTimerRef.current != null) return;
330
332
  const eventTarget_1 = event_3.target;
@@ -337,12 +339,12 @@ function Dropdown(t0) {
337
339
  };
338
340
  $[26] = handleSubmitItem;
339
341
  $[27] = onMouseUp;
340
- $[28] = t15;
341
- } else t15 = $[28];
342
- const handleMouseUp = t15;
343
- let t16;
342
+ $[28] = t14;
343
+ } else t14 = $[28];
344
+ const handleMouseUp = t14;
345
+ let t15;
344
346
  if ($[29] !== dropdownElement || $[30] !== handleSubmitItem || $[31] !== onActiveItem) {
345
- t16 = (event_4) => {
347
+ t15 = (event_4) => {
346
348
  const { altKey, ctrlKey, key, metaKey } = event_4;
347
349
  const eventTarget_2 = event_4.target;
348
350
  if (!dropdownElement) return;
@@ -430,22 +432,22 @@ function Dropdown(t0) {
430
432
  $[29] = dropdownElement;
431
433
  $[30] = handleSubmitItem;
432
434
  $[31] = onActiveItem;
433
- $[32] = t16;
434
- } else t16 = $[32];
435
- const handleKeyDown = t16;
436
- let t17;
435
+ $[32] = t15;
436
+ } else t15 = $[32];
437
+ const handleKeyDown = t15;
438
+ let t16;
437
439
  if ($[33] !== handleKeyDown) {
438
- t17 = {
440
+ t16 = {
439
441
  ignoreUsedKeyboardEvents: false,
440
442
  onKeyDown: handleKeyDown
441
443
  };
442
444
  $[33] = handleKeyDown;
443
- $[34] = t17;
444
- } else t17 = $[34];
445
- useKeyboardEvents(t17);
446
- let t18;
445
+ $[34] = t16;
446
+ } else t16 = $[34];
447
+ useKeyboardEvents(t16);
448
+ let t17;
447
449
  if ($[35] !== isOpenOnMount || $[36] !== onActiveItem) {
448
- t18 = (ref) => {
450
+ t17 = (ref) => {
449
451
  setDropdownElement(ref);
450
452
  if (!ref) return;
451
453
  const { ownerDocument } = ref;
@@ -455,13 +457,13 @@ function Dropdown(t0) {
455
457
  else inputElement = ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);
456
458
  inputElementRef.current = inputElement;
457
459
  }
458
- const handleGlobalMouseDown = (t19) => {
459
- const { target } = t19;
460
+ const handleGlobalMouseDown = (t18) => {
461
+ const { target } = t18;
460
462
  const eventTarget_3 = target;
461
463
  if (!ref.contains(eventTarget_3)) closeDropdown();
462
464
  };
463
- const handleGlobalMouseUp = (t20) => {
464
- const { target: target_0 } = t20;
465
+ const handleGlobalMouseUp = (t19) => {
466
+ const { target: target_0 } = t19;
465
467
  if (!isOpenRef.current || closingTimerRef.current != null) return;
466
468
  if (isOpeningRef.current) {
467
469
  setIsOpening(false);
@@ -474,8 +476,8 @@ function Dropdown(t0) {
474
476
  const eventTarget_4 = target_0;
475
477
  if (!ref.contains(eventTarget_4)) closeDropdown();
476
478
  };
477
- const handleGlobalFocusIn = (t21) => {
478
- const { target: target_1 } = t21;
479
+ const handleGlobalFocusIn = (t20) => {
480
+ const { target: target_1 } = t20;
479
481
  if (!isOpenRef.current) return;
480
482
  const eventTarget_5 = target_1;
481
483
  if (ref.contains(eventTarget_5) || eventTarget_5.contains(ref)) return;
@@ -519,25 +521,25 @@ function Dropdown(t0) {
519
521
  };
520
522
  $[35] = isOpenOnMount;
521
523
  $[36] = onActiveItem;
522
- $[37] = t18;
523
- } else t18 = $[37];
524
- const handleRef = t18;
524
+ $[37] = t17;
525
+ } else t17 = $[37];
526
+ const handleRef = t17;
525
527
  if (!isValidElement(trigger)) if (isSearchable) {
526
- const t19 = value ?? "";
527
- let t20;
528
+ const t18 = value ?? "";
529
+ let t19;
528
530
  if ($[38] === Symbol.for("react.memo_cache_sentinel")) {
529
- t20 = () => setIsOpen(true);
530
- $[38] = t20;
531
- } else t20 = $[38];
532
- let t21;
533
- if ($[39] !== disabled || $[40] !== name || $[41] !== placeholder || $[42] !== t19 || $[43] !== tabIndex) {
534
- t21 = /* @__PURE__ */ jsx("input", {
531
+ t19 = () => setIsOpen(true);
532
+ $[38] = t19;
533
+ } else t19 = $[38];
534
+ let t20;
535
+ if ($[39] !== disabled || $[40] !== name || $[41] !== placeholder || $[42] !== t18 || $[43] !== tabIndex) {
536
+ t20 = /* @__PURE__ */ jsx("input", {
535
537
  autoComplete: "off",
536
538
  className: "uktdropdown-trigger",
537
- defaultValue: t19,
539
+ defaultValue: t18,
538
540
  disabled,
539
541
  name,
540
- onFocus: t20,
542
+ onFocus: t19,
541
543
  placeholder,
542
544
  ref: inputElementRef,
543
545
  tabIndex,
@@ -546,135 +548,113 @@ function Dropdown(t0) {
546
548
  $[39] = disabled;
547
549
  $[40] = name;
548
550
  $[41] = placeholder;
549
- $[42] = t19;
551
+ $[42] = t18;
550
552
  $[43] = tabIndex;
551
- $[44] = t21;
552
- } else t21 = $[44];
553
- trigger = t21;
553
+ $[44] = t20;
554
+ } else t20 = $[44];
555
+ trigger = t20;
554
556
  } else {
555
- let t19;
557
+ let t18;
556
558
  if ($[45] !== trigger) {
557
- t19 = /* @__PURE__ */ jsx("button", {
559
+ t18 = /* @__PURE__ */ jsx("button", {
558
560
  className: "uktdropdown-trigger",
559
561
  tabIndex: 0,
560
562
  type: "button",
561
563
  children: trigger
562
564
  });
563
565
  $[45] = trigger;
564
- $[46] = t19;
565
- } else t19 = $[46];
566
- trigger = t19;
566
+ $[46] = t18;
567
+ } else t18 = $[46];
568
+ trigger = t18;
567
569
  }
568
570
  if (label != null) {
569
- let t19;
571
+ let t18;
570
572
  if ($[47] !== label) {
571
- t19 = /* @__PURE__ */ jsx("div", {
573
+ t18 = /* @__PURE__ */ jsx("div", {
572
574
  className: "uktdropdown-label-text",
573
575
  children: label
574
576
  });
575
577
  $[47] = label;
576
- $[48] = t19;
577
- } else t19 = $[48];
578
- let t20;
579
- if ($[49] !== t19 || $[50] !== trigger) {
580
- t20 = /* @__PURE__ */ jsxs("label", {
578
+ $[48] = t18;
579
+ } else t18 = $[48];
580
+ let t19;
581
+ if ($[49] !== t18 || $[50] !== trigger) {
582
+ t19 = /* @__PURE__ */ jsxs("label", {
581
583
  className: "uktdropdown-label",
582
- children: [t19, trigger]
584
+ children: [t18, trigger]
583
585
  });
584
- $[49] = t19;
586
+ $[49] = t18;
585
587
  $[50] = trigger;
586
- $[51] = t20;
587
- } else t20 = $[51];
588
- trigger = t20;
588
+ $[51] = t19;
589
+ } else t19 = $[51];
590
+ trigger = t19;
589
591
  }
590
- const dropdownRect = useBoundingClientRect(dropdownElement);
591
- const dropdownBodyRect = useBoundingClientRect(dropdownBodyElement);
592
+ let t18;
593
+ if ($[52] !== minHeightBody) {
594
+ t18 = minHeightBody != null && minHeightBody > 0 ? { "--uktdd-body-min-height": `${minHeightBody}px` } : null;
595
+ $[52] = minHeightBody;
596
+ $[53] = t18;
597
+ } else t18 = $[53];
592
598
  let t19;
593
- if ($[52] !== dropdownBodyElement) {
594
- t19 = getBoundingAncestor(dropdownBodyElement);
595
- $[52] = dropdownBodyElement;
596
- $[53] = t19;
597
- } else t19 = $[53];
598
- const boundingElementRect = useBoundingClientRect(t19);
599
- let maxHeight;
600
- if (dropdownBodyRect.top != null && dropdownRect.top != null && boundingElementRect.top != null) {
601
- const maxHeightUp = dropdownBodyRect.bottom - boundingElementRect.top;
602
- const maxHeightDown = boundingElementRect.bottom - dropdownBodyRect.top;
603
- let t20;
604
- if ($[54] !== dropdownBodyRect.top || $[55] !== dropdownRect.top || $[56] !== maxHeightDown || $[57] !== maxHeightUp) {
605
- t20 = Math.round(dropdownBodyRect.top > dropdownRect.top ? maxHeightDown : maxHeightUp);
606
- $[54] = dropdownBodyRect.top;
607
- $[55] = dropdownRect.top;
608
- $[56] = maxHeightDown;
609
- $[57] = maxHeightUp;
610
- $[58] = t20;
611
- } else t20 = $[58];
612
- maxHeight = t20;
613
- }
599
+ if ($[54] !== minWidthBody) {
600
+ t19 = minWidthBody != null && minWidthBody > 0 ? { "--uktdd-body-min-width": `${minWidthBody}px` } : null;
601
+ $[54] = minWidthBody;
602
+ $[55] = t19;
603
+ } else t19 = $[55];
614
604
  let t20;
615
- if ($[59] !== maxHeight || $[60] !== minHeightBody) {
616
- t20 = maxHeight != null && maxHeight > minHeightBody ? { "--uktdd-body-max-height": `calc(${maxHeight}px - var(--uktdd-body-buffer))` } : null;
617
- $[59] = maxHeight;
618
- $[60] = minHeightBody;
619
- $[61] = t20;
620
- } else t20 = $[61];
621
- let t21;
622
- if ($[62] !== minWidthBody) {
623
- t21 = minWidthBody != null && minWidthBody > 0 ? { "--uktdd-body-min-width": `${minWidthBody}px` } : null;
624
- $[62] = minWidthBody;
625
- $[63] = t21;
626
- } else t21 = $[63];
627
- let t22;
628
- if ($[64] !== styleFromProps || $[65] !== t20 || $[66] !== t21) {
629
- t22 = {
605
+ if ($[56] !== styleFromProps || $[57] !== t18 || $[58] !== t19) {
606
+ t20 = {
630
607
  ...styleFromProps,
631
- ...t20,
632
- ...t21
608
+ ...t18,
609
+ ...t19
633
610
  };
634
- $[64] = styleFromProps;
635
- $[65] = t20;
636
- $[66] = t21;
637
- $[67] = t22;
638
- } else t22 = $[67];
639
- const style = t22;
640
- let t23;
641
- if ($[68] === Symbol.for("react.memo_cache_sentinel")) {
642
- t23 = /* @__PURE__ */ jsx("style", {
611
+ $[56] = styleFromProps;
612
+ $[57] = t18;
613
+ $[58] = t19;
614
+ $[59] = t20;
615
+ } else t20 = $[59];
616
+ const style = t20;
617
+ let t21;
618
+ if ($[60] === Symbol.for("react.memo_cache_sentinel")) {
619
+ t21 = /* @__PURE__ */ jsx("style", {
643
620
  href: "@acusti/dropdown/Dropdown",
644
621
  precedence: "medium",
645
622
  children: Dropdown_default
646
623
  });
647
- $[68] = t23;
648
- } else t23 = $[68];
649
- let t24;
650
- if ($[69] !== className || $[70] !== disabled || $[71] !== isOpen || $[72] !== isSearchable) {
651
- t24 = clsx("uktdropdown", className, {
624
+ $[60] = t21;
625
+ } else t21 = $[60];
626
+ let t22;
627
+ if ($[61] !== className || $[62] !== disabled || $[63] !== isOpen || $[64] !== isSearchable) {
628
+ t22 = clsx("uktdropdown", className, {
652
629
  disabled,
653
630
  "is-open": isOpen,
654
631
  "is-searchable": isSearchable
655
632
  });
656
- $[69] = className;
657
- $[70] = disabled;
658
- $[71] = isOpen;
659
- $[72] = isSearchable;
660
- $[73] = t24;
661
- } else t24 = $[73];
662
- let t25;
663
- if ($[74] !== children || $[75] !== childrenCount || $[76] !== isOpen) {
664
- t25 = isOpen ? /* @__PURE__ */ jsx("div", {
665
- className: "uktdropdown-body",
666
- ref: setDropdownBodyElement,
667
- children: childrenCount > 1 ? children[1] : children
633
+ $[61] = className;
634
+ $[62] = disabled;
635
+ $[63] = isOpen;
636
+ $[64] = isSearchable;
637
+ $[65] = t22;
638
+ } else t22 = $[65];
639
+ let t23;
640
+ if ($[66] !== children || $[67] !== childrenCount || $[68] !== hasItems || $[69] !== isOpen) {
641
+ t23 = isOpen ? /* @__PURE__ */ jsx("div", {
642
+ className: clsx("uktdropdown-body", { "has-items": hasItems }),
643
+ children: /* @__PURE__ */ jsx("div", {
644
+ className: "uktdropdown-content",
645
+ children: childrenCount > 1 ? children[1] : children
646
+ })
668
647
  }) : null;
669
- $[74] = children;
670
- $[75] = childrenCount;
671
- $[76] = isOpen;
672
- $[77] = t25;
673
- } else t25 = $[77];
674
- let t26;
675
- if ($[78] !== handleMouseDown || $[79] !== handleMouseOut || $[80] !== handleMouseOver || $[81] !== handleMouseUp || $[82] !== handleRef || $[83] !== onClick || $[84] !== style || $[85] !== t24 || $[86] !== t25 || $[87] !== trigger) {
676
- t26 = /* @__PURE__ */ jsxs(Fragment, { children: [t23, /* @__PURE__ */ jsxs("div", {
677
- className: t24,
648
+ $[66] = children;
649
+ $[67] = childrenCount;
650
+ $[68] = hasItems;
651
+ $[69] = isOpen;
652
+ $[70] = t23;
653
+ } else t23 = $[70];
654
+ let t24;
655
+ if ($[71] !== handleMouseDown || $[72] !== handleMouseOut || $[73] !== handleMouseOver || $[74] !== handleMouseUp || $[75] !== handleRef || $[76] !== onClick || $[77] !== style || $[78] !== t22 || $[79] !== t23 || $[80] !== trigger) {
656
+ t24 = /* @__PURE__ */ jsxs(Fragment, { children: [t21, /* @__PURE__ */ jsxs("div", {
657
+ className: t22,
678
658
  onClick,
679
659
  onMouseDown: handleMouseDown,
680
660
  onMouseMove: handleMouseMove,
@@ -683,30 +663,23 @@ function Dropdown(t0) {
683
663
  onMouseUp: handleMouseUp,
684
664
  ref: handleRef,
685
665
  style,
686
- children: [trigger, t25]
666
+ children: [trigger, t23]
687
667
  })] });
688
- $[78] = handleMouseDown;
689
- $[79] = handleMouseOut;
690
- $[80] = handleMouseOver;
691
- $[81] = handleMouseUp;
692
- $[82] = handleRef;
693
- $[83] = onClick;
694
- $[84] = style;
695
- $[85] = t24;
696
- $[86] = t25;
697
- $[87] = trigger;
698
- $[88] = t26;
699
- } else t26 = $[88];
700
- return t26;
701
- }
702
- function getBoundingAncestor(element) {
703
- while (element?.parentElement) {
704
- if (element.parentElement.tagName === "BODY") return element.parentElement;
705
- if (getComputedStyle(element.parentElement).overflowX !== "visible") return element.parentElement;
706
- element = element.parentElement;
707
- }
708
- return null;
668
+ $[71] = handleMouseDown;
669
+ $[72] = handleMouseOut;
670
+ $[73] = handleMouseOver;
671
+ $[74] = handleMouseUp;
672
+ $[75] = handleRef;
673
+ $[76] = onClick;
674
+ $[77] = style;
675
+ $[78] = t22;
676
+ $[79] = t23;
677
+ $[80] = trigger;
678
+ $[81] = t24;
679
+ } else t24 = $[81];
680
+ return t24;
709
681
  }
682
+ //#endregion
710
683
  export { Dropdown as default };
711
684
 
712
685
  //# sourceMappingURL=Dropdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Dropdown.js","names":["getBestMatch","SyntheticEvent","Item","ITEM_SELECTOR","getItemElements","dropdownElement","HTMLElement","bodyElement","querySelector","items","HTMLCollection","NodeListOf","Element","querySelectorAll","length","children","getActiveItemElement","clearItemElementsState","itemElements","Array","forEach","itemElement","hasAttribute","dataset","uktActive","BaseSetActiveItemPayload","element","event","Event","index","indexAddend","isExactMatch","onActiveItem","payload","text","setActiveItem","Omit","from","lastIndex","currentActiveIndex","findIndex","nextActiveIndex","Math","max","min","itemTexts","map","innerText","textToCompare","toLowerCase","itemText","startsWith","bestMatch","nextActiveItem","setAttribute","label","value","uktValue","parentElement","scrollableParent","isScrollable","scrollHeight","clientHeight","parentRect","getBoundingClientRect","itemRect","isAboveTop","top","isBelowBottom","bottom","scrollTop","useBoundingClientRect","useKeyboardEvents","isEventTargetUsingKeyEvent","clsx","Children","CSSProperties","Fragment","isValidElement","JSX","MouseEvent","ReactMouseEvent","ReactNode","SyntheticEvent","useEffect","useRef","useState","styles","getActiveItemElement","getItemElements","ITEM_SELECTOR","setActiveItem","Item","element","MaybeHTMLElement","event","Event","HTMLElement","label","value","Props","allowCreate","allowEmpty","children","ChildrenTuple","Element","className","disabled","group","hasItems","isOpenOnMount","isSearchable","keepOpenOnSubmit","minHeightBody","minWidthBody","name","onActiveItem","payload","onClick","onClose","onMouseDown","onMouseUp","onOpen","onSubmitItem","placeholder","style","tabIndex","MousePosition","clientX","clientY","TimeoutID","ReturnType","setTimeout","CHILDREN_ERROR","CLICKABLE_SELECTOR","TEXT_INPUT_SELECTOR","Dropdown","t0","$","_c","t1","t2","t3","t4","styleFromProps","undefined","childrenCount","count","Error","console","error","trigger","isOpen","setIsOpen","isOpening","setIsOpening","dropdownElement","setDropdownElement","dropdownBodyElement","setDropdownBodyElement","inputElementRef","closingTimerRef","isOpeningTimerRef","currentInputMethodRef","clearEnteredCharactersTimerRef","enteredCharactersRef","mouseDownPositionRef","allowCreateRef","allowEmptyRef","hasItemsRef","isOpenRef","isOpeningRef","keepOpenOnSubmitRef","onCloseRef","onOpenRef","onSubmitItemRef","valueRef","t5","t6","current","isMountedRef","t7","t8","t9","Symbol","for","clearTimeout","closeDropdown","t10","itemLabel","innerText","ownerDocument","activeElement","blur","nextValue","dataset","uktValue","eventTarget","target","matches","contains","click","clickableElements","querySelectorAll","length","clickableElement","handleSubmitItem","t11","t12","initialPosition","Math","abs","handleMouseMove","event_0","itemElements","eventTarget_0","item","closest","element_0","itemElement","handleMouseOver","t13","event_1","activeItem","eventRelatedTarget","relatedTarget","uktActive","handleMouseOut","t14","event_2","handleMouseDown","t15","event_3","eventTarget_1","handleMouseUp","t16","event_4","altKey","ctrlKey","key","metaKey","eventTarget_2","onEventHandled","stopPropagation","preventDefault","isEventTargetingDropdown","isTargetUsingKeyEvents","isEditingCharacters","test","slice","isExactMatch","text","index","indexAddend","handleKeyDown","t17","ignoreUsedKeyboardEvents","onKeyDown","t18","ref","inputElement","firstElementChild","HTMLInputElement","querySelector","handleGlobalMouseDown","t19","eventTarget_3","handleGlobalMouseUp","t20","target_0","eventTarget_4","handleGlobalFocusIn","t21","target_1","eventTarget_5","document","addEventListener","focus","handleInput","event_5","input","isDeleting","removeEventListener","handleRef","dropdownRect","dropdownBodyRect","getBoundingAncestor","boundingElement","boundingElementRect","maxHeight","top","maxHeightUp","bottom","maxHeightDown","round","t22","t23","t24","t25","t26","parentElement","tagName","getComputedStyle","overflowX"],"sources":["../src/Dropdown.css?inline","../src/helpers.ts","../src/Dropdown.tsx"],"sourcesContent":[":root {\n --uktdd-font-family:\n system-ui, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue,\n Helvetica, Arial, sans-serif;\n --uktdd-body-bg-color: #fff;\n --uktdd-body-bg-color-hover: rgb(105, 162, 249);\n --uktdd-body-color-hover: #fff;\n --uktdd-body-buffer: 10px;\n --uktdd-body-max-height: calc(100vh - var(--uktdd-body-buffer));\n --uktdd-body-max-width: calc(100vw - var(--uktdd-body-buffer));\n --uktdd-body-pad-bottom: 9px;\n --uktdd-body-pad-left: 12px;\n --uktdd-body-pad-right: 12px;\n --uktdd-body-pad-top: 9px;\n --uktdd-body-min-width: min(50px, 100%);\n --uktdd-label-pad-right: 10px;\n}\n\n.uktdropdown,\n.uktdropdown-trigger {\n font-family: var(--uktdd-font-family);\n}\n\n.uktdropdown {\n width: max-content;\n anchor-scope: --uktdd-anchor;\n\n &.disabled {\n pointer-events: none;\n }\n\n > * {\n cursor: default;\n }\n\n > :first-child {\n anchor-name: --uktdd-anchor;\n }\n}\n\n.uktdropdown-label {\n display: flex;\n align-items: center;\n}\n\n.uktdropdown-label-text {\n padding-right: var(--uktdd-label-pad-right);\n}\n\n.uktdropdown-body {\n box-sizing: border-box;\n position: absolute;\n position-anchor: --uktdd-anchor;\n top: anchor(bottom);\n left: anchor(left);\n bottom: auto;\n right: auto;\n position-try-fallbacks: --uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;\n min-height: 50px;\n max-height: var(--uktdd-body-max-height);\n min-width: var(--uktdd-body-min-width);\n max-width: var(--uktdd-body-max-width);\n overflow: auto;\n z-index: 2;\n padding: var(--uktdd-body-pad-top) var(--uktdd-body-pad-right)\n var(--uktdd-body-pad-bottom) var(--uktdd-body-pad-left);\n background-color: var(--uktdd-body-bg-color);\n box-shadow: 0 8px 18px rgba(0, 0, 0, 0.25);\n\n &.has-items {\n user-select: none;\n }\n\n [data-ukt-active] {\n background-color: var(--uktdd-body-bg-color-hover);\n color: var(--uktdd-body-color-hover);\n }\n}\n\n@position-try --uktdd-top-left {\n bottom: anchor(top);\n left: anchor(left);\n top: auto;\n right: auto;\n}\n\n@position-try --uktdd-bottom-right {\n top: anchor(bottom);\n right: anchor(right);\n bottom: auto;\n left: auto;\n}\n\n@position-try --uktdd-top-right {\n bottom: anchor(top);\n right: anchor(right);\n top: auto;\n left: auto;\n}\n","import { getBestMatch } from '@acusti/matchmaking';\nimport { type SyntheticEvent } from 'react';\n\nimport { type Item } from './Dropdown.js';\n\nexport const ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;\n\nexport const getItemElements = (dropdownElement: HTMLElement | null) => {\n if (!dropdownElement) return null;\n\n const bodyElement = dropdownElement.querySelector('.uktdropdown-body');\n if (!bodyElement) return null;\n\n let items: HTMLCollection | NodeListOf<Element> =\n bodyElement.querySelectorAll(ITEM_SELECTOR);\n\n if (items.length) return items;\n // If no items found via [data-ukt-item] or [data-ukt-value] selector,\n // use first instance of multiple children found\n items = bodyElement.children;\n while (items.length === 1) {\n if (items[0].children == null) break;\n items = items[0].children;\n }\n // If unable to find an element with more than one child, treat direct child as items\n if (items.length === 1) {\n items = bodyElement.children;\n }\n return items;\n};\n\nexport const getActiveItemElement = (dropdownElement: HTMLElement | null) => {\n if (!dropdownElement) return null;\n return dropdownElement.querySelector('[data-ukt-active]') as HTMLElement | null;\n};\n\nconst clearItemElementsState = (itemElements: Array<HTMLElement>) => {\n itemElements.forEach((itemElement) => {\n if (itemElement.hasAttribute('data-ukt-active')) {\n delete itemElement.dataset.uktActive;\n }\n });\n};\n\ntype BaseSetActiveItemPayload = {\n dropdownElement: HTMLElement;\n element?: null;\n event: Event | SyntheticEvent<HTMLElement>;\n index?: null;\n indexAddend?: null;\n isExactMatch?: null;\n onActiveItem?: (payload: Item) => void;\n text?: null;\n};\n\nexport const setActiveItem = ({\n dropdownElement,\n element,\n event,\n index,\n indexAddend,\n isExactMatch,\n onActiveItem,\n text,\n}:\n | ({\n element: HTMLElement;\n } & Omit<BaseSetActiveItemPayload, 'element'>)\n | ({\n index: number;\n } & Omit<BaseSetActiveItemPayload, 'index'>)\n | ({\n indexAddend: number;\n } & Omit<BaseSetActiveItemPayload, 'indexAddend'>)\n | ({\n isExactMatch?: boolean;\n text: string;\n } & Omit<BaseSetActiveItemPayload, 'isExactMatch' | 'text'>)) => {\n const items = getItemElements(dropdownElement);\n if (!items) return;\n\n const itemElements = Array.from(items) as Array<HTMLElement>;\n if (!itemElements.length) return;\n\n const lastIndex = itemElements.length - 1;\n const currentActiveIndex = itemElements.findIndex((itemElement) =>\n itemElement.hasAttribute('data-ukt-active'),\n );\n\n let nextActiveIndex = currentActiveIndex;\n if (typeof index === 'number') {\n // Negative index means count back from the end\n nextActiveIndex = index < 0 ? itemElements.length + index : index;\n }\n\n if (element) {\n nextActiveIndex = itemElements.findIndex(\n (itemElement) => itemElement === element,\n );\n } else if (typeof indexAddend === 'number') {\n // If there’s no currentActiveIndex and we are handling -1, start at lastIndex\n if (currentActiveIndex === -1 && indexAddend === -1) {\n nextActiveIndex = lastIndex;\n } else {\n nextActiveIndex += indexAddend;\n }\n // Keep it within the bounds of the items list\n nextActiveIndex = Math.max(0, Math.min(nextActiveIndex, lastIndex));\n } else if (typeof text === 'string') {\n // If text is empty, clear existing active items and early return\n if (!text) {\n clearItemElementsState(itemElements);\n return;\n }\n\n const itemTexts = itemElements.map((itemElement) => itemElement.innerText);\n if (isExactMatch) {\n const textToCompare = text.toLowerCase();\n nextActiveIndex = itemTexts.findIndex((itemText) =>\n itemText.toLowerCase().startsWith(textToCompare),\n );\n // If isExactMatch is required and no exact match was found, clear active items\n if (nextActiveIndex === -1) {\n clearItemElementsState(itemElements);\n }\n } else {\n const bestMatch = getBestMatch({ items: itemTexts, text });\n nextActiveIndex = itemTexts.findIndex((itemText) => itemText === bestMatch);\n }\n }\n\n const nextActiveItem = items[nextActiveIndex] as HTMLElement | null;\n if (nextActiveItem == null || nextActiveIndex === currentActiveIndex) return;\n\n // Clear any existing active dropdown body item state\n clearItemElementsState(itemElements);\n nextActiveItem.setAttribute('data-ukt-active', '');\n const label = nextActiveItem.innerText;\n const value = nextActiveItem.dataset.uktValue ?? label;\n onActiveItem?.({ element: nextActiveItem, event, label, value });\n // Find closest scrollable parent and ensure that next active item is visible\n let { parentElement } = nextActiveItem;\n let scrollableParent = null;\n while (!scrollableParent && parentElement && parentElement !== dropdownElement) {\n const isScrollable = parentElement.scrollHeight > parentElement.clientHeight + 15;\n if (isScrollable) {\n scrollableParent = parentElement;\n } else {\n parentElement = parentElement.parentElement;\n }\n }\n\n if (scrollableParent) {\n const parentRect = scrollableParent.getBoundingClientRect();\n const itemRect = nextActiveItem.getBoundingClientRect();\n const isAboveTop = itemRect.top < parentRect.top;\n const isBelowBottom = itemRect.bottom > parentRect.bottom;\n if (isAboveTop || isBelowBottom) {\n let { scrollTop } = scrollableParent;\n // Item isn’t fully visible; adjust scrollTop to put item within closest edge\n if (isAboveTop) {\n scrollTop -= parentRect.top - itemRect.top;\n } else {\n scrollTop += itemRect.bottom - parentRect.bottom;\n }\n scrollableParent.scrollTop = scrollTop;\n }\n }\n};\n","/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-static-element-interactions */\nimport useBoundingClientRect from '@acusti/use-bounding-client-rect';\nimport useKeyboardEvents, {\n isEventTargetUsingKeyEvent,\n} from '@acusti/use-keyboard-events';\nimport clsx from 'clsx';\nimport {\n Children,\n type CSSProperties,\n Fragment,\n isValidElement,\n type JSX,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './Dropdown.css?inline';\nimport {\n getActiveItemElement,\n getItemElements,\n ITEM_SELECTOR,\n setActiveItem,\n} from './helpers.js';\n\nexport type Item = {\n element: MaybeHTMLElement;\n event: Event | SyntheticEvent<HTMLElement>;\n label: string;\n value: string;\n};\n\nexport type Props = {\n /**\n * Boolean indicating if the user can submit a value not already in the\n * dropdown.\n */\n allowCreate?: boolean;\n /**\n * Boolean indicating if the user can submit an empty value (i.e. clear\n * the value). Defaults to true.\n */\n allowEmpty?: boolean;\n /**\n * Can take a single React element or exactly two renderable children.\n */\n children: ChildrenTuple | JSX.Element;\n className?: string;\n disabled?: boolean;\n /**\n * Group identifier string links dropdowns together into a menu\n * (like macOS top menubar).\n */\n group?: string;\n hasItems?: boolean;\n isOpenOnMount?: boolean;\n isSearchable?: boolean;\n keepOpenOnSubmit?: boolean;\n label?: ReactNode;\n minHeightBody?: number;\n minWidthBody?: number;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s name.\n */\n name?: string;\n onActiveItem?: (payload: Item) => void;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onClose?: () => unknown;\n onMouseDown?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onMouseUp?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onOpen?: () => unknown;\n onSubmitItem?: (payload: Item) => void;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s placeholder.\n */\n placeholder?: string;\n style?: CSSProperties;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s tabIndex.\n */\n tabIndex?: number;\n /**\n * Used as search input’s value if props.isSearchable === true\n * Used to determine if value has changed to avoid triggering onSubmitItem if not\n */\n value?: string;\n};\n\ntype ChildrenTuple = [ReactNode, ReactNode] | readonly [ReactNode, ReactNode];\n\ntype MaybeHTMLElement = HTMLElement | null;\n\ntype MousePosition = { clientX: number; clientY: number };\n\ntype TimeoutID = ReturnType<typeof setTimeout>;\n\nconst CHILDREN_ERROR =\n '@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.';\nconst CLICKABLE_SELECTOR = 'button, a[href], input[type=\"button\"], input[type=\"submit\"]';\nconst TEXT_INPUT_SELECTOR =\n 'input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea';\n\nexport default function Dropdown({\n allowCreate,\n allowEmpty = true,\n children,\n className,\n disabled,\n hasItems = true,\n isOpenOnMount,\n isSearchable,\n keepOpenOnSubmit = !hasItems,\n label,\n minHeightBody = 30,\n minWidthBody,\n name,\n onActiveItem,\n onClick,\n onClose,\n onMouseDown,\n onMouseUp,\n onOpen,\n onSubmitItem,\n placeholder,\n style: styleFromProps,\n tabIndex,\n value,\n}: Props) {\n const childrenCount = Children.count(children);\n if (childrenCount !== 1 && childrenCount !== 2) {\n if (childrenCount === 0) {\n throw new Error(CHILDREN_ERROR + ' Received no children.');\n }\n console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);\n }\n\n let trigger: React.ReactNode;\n if (childrenCount > 1) {\n trigger = (children as ChildrenTuple)[0];\n }\n\n const [isOpen, setIsOpen] = useState<boolean>(isOpenOnMount ?? false);\n const [isOpening, setIsOpening] = useState<boolean>(!isOpenOnMount);\n const [dropdownElement, setDropdownElement] = useState<MaybeHTMLElement>(null);\n const [dropdownBodyElement, setDropdownBodyElement] =\n useState<MaybeHTMLElement>(null);\n const inputElementRef = useRef<HTMLInputElement | null>(null);\n const closingTimerRef = useRef<null | TimeoutID>(null);\n const isOpeningTimerRef = useRef<null | TimeoutID>(null);\n const currentInputMethodRef = useRef<'keyboard' | 'mouse'>('mouse');\n const clearEnteredCharactersTimerRef = useRef<null | TimeoutID>(null);\n const enteredCharactersRef = useRef<string>('');\n const mouseDownPositionRef = useRef<MousePosition | null>(null);\n\n const allowCreateRef = useRef(allowCreate);\n const allowEmptyRef = useRef(allowEmpty);\n const hasItemsRef = useRef(hasItems);\n const isOpenRef = useRef(isOpen);\n const isOpeningRef = useRef(isOpening);\n const keepOpenOnSubmitRef = useRef(keepOpenOnSubmit);\n const onCloseRef = useRef(onClose);\n const onOpenRef = useRef(onOpen);\n const onSubmitItemRef = useRef(onSubmitItem);\n const valueRef = useRef(value);\n\n useEffect(() => {\n allowCreateRef.current = allowCreate;\n allowEmptyRef.current = allowEmpty;\n hasItemsRef.current = hasItems;\n isOpenRef.current = isOpen;\n isOpeningRef.current = isOpening;\n keepOpenOnSubmitRef.current = keepOpenOnSubmit;\n onCloseRef.current = onClose;\n onOpenRef.current = onOpen;\n onSubmitItemRef.current = onSubmitItem;\n valueRef.current = value;\n }, [\n allowCreate,\n allowEmpty,\n hasItems,\n isOpen,\n isOpening,\n keepOpenOnSubmit,\n onClose,\n onOpen,\n onSubmitItem,\n value,\n ]);\n\n const isMountedRef = useRef(false);\n\n useEffect(() => {\n if (!isMountedRef.current) {\n isMountedRef.current = true;\n // If isOpenOnMount, trigger onOpen right away\n if (isOpenRef.current && onOpenRef.current) {\n onOpenRef.current();\n }\n return;\n }\n\n if (isOpen && onOpenRef.current) {\n onOpenRef.current();\n } else if (!isOpen && onCloseRef.current) {\n onCloseRef.current();\n }\n }, [isOpen]);\n\n const closeDropdown = () => {\n setIsOpen(false);\n setIsOpening(false);\n mouseDownPositionRef.current = null;\n if (closingTimerRef.current != null) {\n clearTimeout(closingTimerRef.current);\n closingTimerRef.current = null;\n }\n };\n\n const handleSubmitItem = (event: Event | React.SyntheticEvent<HTMLElement>) => {\n if (isOpenRef.current && !keepOpenOnSubmitRef.current) {\n // A short timeout before closing is better UX when user selects an item so dropdown\n // doesn’t close before expected. It also enables using <Link />s in the dropdown body.\n closingTimerRef.current = setTimeout(closeDropdown, 90);\n }\n\n if (!hasItemsRef.current) return;\n\n const element = getActiveItemElement(dropdownElement);\n if (!element && !allowCreateRef.current) {\n // If not allowEmpty, don’t allow submitting an empty item\n if (!allowEmptyRef.current) return;\n // If we have an input element as trigger & the user didn’t clear the text, do nothing\n if (inputElementRef.current?.value) return;\n }\n\n let itemLabel = element?.innerText ?? '';\n if (inputElementRef.current) {\n if (!element) {\n itemLabel = inputElementRef.current.value;\n } else {\n inputElementRef.current.value = itemLabel;\n }\n\n if (\n inputElementRef.current ===\n inputElementRef.current.ownerDocument.activeElement\n ) {\n inputElementRef.current.blur();\n }\n }\n\n const nextValue = element?.dataset.uktValue ?? itemLabel;\n // If parent is controlling Dropdown via props.value and nextValue is the same, do nothing\n if (valueRef.current && valueRef.current === nextValue) return;\n\n // If the item is clickable or contains exactly one clickable element, invoke it\n // (but only if the event didn’t already originate from that element)\n if (element) {\n const eventTarget = event.target as HTMLElement;\n\n if (element.matches(CLICKABLE_SELECTOR)) {\n // The item element itself is clickable (e.g., <button data-ukt-value=\"…\">)\n if (element !== eventTarget && !element.contains(eventTarget)) {\n element.click();\n }\n } else {\n // Check if item contains exactly one clickable child element\n const clickableElements = element.querySelectorAll(CLICKABLE_SELECTOR);\n if (clickableElements.length === 1) {\n const clickableElement = clickableElements[0] as HTMLElement;\n if (\n clickableElement !== eventTarget &&\n !clickableElement.contains(eventTarget)\n ) {\n clickableElement.click();\n }\n }\n }\n }\n\n onSubmitItemRef.current?.({\n element,\n event,\n label: itemLabel,\n value: nextValue,\n });\n };\n\n const handleMouseMove = ({ clientX, clientY }: ReactMouseEvent<HTMLElement>) => {\n currentInputMethodRef.current = 'mouse';\n const initialPosition = mouseDownPositionRef.current;\n if (!initialPosition) return;\n if (\n Math.abs(initialPosition.clientX - clientX) < 12 &&\n Math.abs(initialPosition.clientY - clientY) < 12\n ) {\n return;\n }\n setIsOpening(false);\n };\n\n const handleMouseOver = (event: ReactMouseEvent<HTMLElement>) => {\n if (!hasItemsRef.current) return;\n\n // If user isn’t currently using the mouse to navigate the dropdown, do nothing\n if (currentInputMethodRef.current !== 'mouse') return;\n\n // Ensure we have the dropdown root HTMLElement\n if (!dropdownElement) return;\n\n const itemElements = getItemElements(dropdownElement);\n if (!itemElements) return;\n\n const eventTarget = event.target as HTMLElement;\n const item = eventTarget.closest(ITEM_SELECTOR) as MaybeHTMLElement;\n const element = item ?? eventTarget;\n for (const itemElement of itemElements) {\n if (itemElement === element) {\n setActiveItem({ dropdownElement, element, event, onActiveItem });\n return;\n }\n }\n };\n\n const handleMouseOut = (event: ReactMouseEvent<HTMLElement>) => {\n if (!hasItemsRef.current) return;\n const activeItem = getActiveItemElement(dropdownElement);\n if (!activeItem) return;\n const eventRelatedTarget = event.relatedTarget as HTMLElement;\n if (activeItem !== event.target || activeItem.contains(eventRelatedTarget)) {\n return;\n }\n // If user moused out of activeItem (not into a descendant), it’s no longer active\n delete activeItem.dataset.uktActive;\n };\n\n const handleMouseDown = (event: ReactMouseEvent<HTMLElement>) => {\n if (onMouseDown) onMouseDown(event);\n if (isOpenRef.current) return;\n\n setIsOpen(true);\n setIsOpening(true);\n mouseDownPositionRef.current = {\n clientX: event.clientX,\n clientY: event.clientY,\n };\n isOpeningTimerRef.current = setTimeout(() => {\n setIsOpening(false);\n isOpeningTimerRef.current = null;\n }, 1000);\n };\n\n const handleMouseUp = (event: ReactMouseEvent<HTMLElement>) => {\n if (onMouseUp) onMouseUp(event);\n // If dropdown is still opening or isn’t open or is closing, do nothing\n if (\n isOpeningRef.current ||\n !isOpenRef.current ||\n closingTimerRef.current != null\n ) {\n return;\n }\n\n const eventTarget = event.target as HTMLElement;\n // If click was outside dropdown body, don’t trigger submit\n if (!eventTarget.closest('.uktdropdown-body')) {\n // Don’t close dropdown if isOpening or search input is focused\n if (\n !isOpeningRef.current &&\n inputElementRef.current !== eventTarget.ownerDocument.activeElement\n ) {\n closeDropdown();\n }\n return;\n }\n\n // If dropdown has no items and click was within dropdown body, do nothing\n if (!hasItemsRef.current) return;\n\n handleSubmitItem(event);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const { altKey, ctrlKey, key, metaKey } = event;\n const eventTarget = event.target as HTMLElement;\n if (!dropdownElement) return;\n\n const onEventHandled = () => {\n event.stopPropagation();\n event.preventDefault();\n currentInputMethodRef.current = 'keyboard';\n };\n\n const isEventTargetingDropdown = dropdownElement.contains(eventTarget);\n\n if (!isOpenRef.current) {\n // If dropdown is closed, don’t handle key events if event target isn’t within dropdown\n if (!isEventTargetingDropdown) return;\n // Open the dropdown on spacebar, enter, or if isSearchable and user hits the ↑/↓ arrows\n if (\n key === ' ' ||\n key === 'Enter' ||\n (hasItemsRef.current && (key === 'ArrowUp' || key === 'ArrowDown'))\n ) {\n onEventHandled();\n setIsOpen(true);\n }\n return;\n }\n\n const isTargetUsingKeyEvents = isEventTargetUsingKeyEvent(event);\n\n // If dropdown isOpen + hasItems & eventTargetNotUsingKeyEvents, handle characters\n if (hasItemsRef.current && !isTargetUsingKeyEvents) {\n let isEditingCharacters = !ctrlKey && !metaKey && /^[A-Za-z0-9]$/.test(key);\n // User could also be editing characters if there are already characters entered\n // and they are hitting delete or spacebar\n if (!isEditingCharacters && enteredCharactersRef.current) {\n isEditingCharacters = key === ' ' || key === 'Backspace';\n }\n\n if (isEditingCharacters) {\n onEventHandled();\n if (key === 'Backspace') {\n enteredCharactersRef.current = enteredCharactersRef.current.slice(\n 0,\n -1,\n );\n } else {\n enteredCharactersRef.current += key;\n }\n\n setActiveItem({\n dropdownElement,\n event,\n // If props.allowCreate, only override the input’s value with an\n // exact text match so user can enter a value not in items\n isExactMatch: allowCreateRef.current,\n onActiveItem,\n text: enteredCharactersRef.current,\n });\n\n if (clearEnteredCharactersTimerRef.current != null) {\n clearTimeout(clearEnteredCharactersTimerRef.current);\n }\n\n clearEnteredCharactersTimerRef.current = setTimeout(() => {\n enteredCharactersRef.current = '';\n clearEnteredCharactersTimerRef.current = null;\n }, 1500);\n\n return;\n }\n }\n\n // If dropdown isOpen, handle submitting the value\n if (key === 'Enter' || (key === ' ' && !inputElementRef.current)) {\n onEventHandled();\n handleSubmitItem(event);\n return;\n }\n\n // If dropdown isOpen, handle closing it on escape or spacebar if !hasItems\n if (\n key === 'Escape' ||\n (isEventTargetingDropdown && key === ' ' && !hasItemsRef.current)\n ) {\n // Close dropdown if hasItems or event target not using key events\n if (hasItemsRef.current || !isTargetUsingKeyEvents) {\n closeDropdown();\n }\n return;\n }\n\n // Handle ↑/↓ arrows\n if (hasItemsRef.current) {\n if (key === 'ArrowUp') {\n onEventHandled();\n if (altKey || metaKey) {\n setActiveItem({ dropdownElement, event, index: 0, onActiveItem });\n } else {\n setActiveItem({\n dropdownElement,\n event,\n indexAddend: -1,\n onActiveItem,\n });\n }\n return;\n }\n if (key === 'ArrowDown') {\n onEventHandled();\n if (altKey || metaKey) {\n // Using a negative index counts back from the end\n setActiveItem({ dropdownElement, event, index: -1, onActiveItem });\n } else {\n setActiveItem({\n dropdownElement,\n event,\n indexAddend: 1,\n onActiveItem,\n });\n }\n return;\n }\n }\n };\n\n useKeyboardEvents({ ignoreUsedKeyboardEvents: false, onKeyDown: handleKeyDown });\n\n const handleRef = (ref: HTMLDivElement | null): (() => void) | void => {\n setDropdownElement(ref);\n if (!ref) return;\n\n const { ownerDocument } = ref;\n let inputElement = inputElementRef.current;\n // Check if trigger is a textual input or textarea element\n if (!inputElement && ref.firstElementChild) {\n if (ref.firstElementChild.matches(TEXT_INPUT_SELECTOR)) {\n inputElement = ref.firstElementChild as HTMLInputElement;\n } else {\n inputElement = ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);\n }\n inputElementRef.current = inputElement;\n }\n\n const handleGlobalMouseDown = ({ target }: MouseEvent) => {\n const eventTarget = target as HTMLElement;\n if (!ref.contains(eventTarget)) {\n // Close dropdown on an outside click\n closeDropdown();\n }\n };\n\n const handleGlobalMouseUp = ({ target }: MouseEvent) => {\n if (!isOpenRef.current || closingTimerRef.current != null) return;\n\n // If still isOpening (gets set false 1s after open triggers), set it to false onMouseUp\n if (isOpeningRef.current) {\n setIsOpening(false);\n if (isOpeningTimerRef.current != null) {\n clearTimeout(isOpeningTimerRef.current);\n isOpeningTimerRef.current = null;\n }\n return;\n }\n\n const eventTarget = target as HTMLElement;\n // Only handle mouseup events from outside the dropdown here\n if (!ref.contains(eventTarget)) {\n closeDropdown();\n }\n };\n\n // Close dropdown if any element is focused outside of this dropdown\n const handleGlobalFocusIn = ({ target }: Event) => {\n if (!isOpenRef.current) return;\n\n const eventTarget = target as HTMLElement;\n // If focused element is a descendant or a parent of the dropdown, do nothing\n if (ref.contains(eventTarget) || eventTarget.contains(ref)) {\n return;\n }\n\n closeDropdown();\n };\n\n document.addEventListener('focusin', handleGlobalFocusIn);\n document.addEventListener('mousedown', handleGlobalMouseDown);\n document.addEventListener('mouseup', handleGlobalMouseUp);\n\n if (ownerDocument !== document) {\n ownerDocument.addEventListener('focusin', handleGlobalFocusIn);\n ownerDocument.addEventListener('mousedown', handleGlobalMouseDown);\n ownerDocument.addEventListener('mouseup', handleGlobalMouseUp);\n }\n\n // If dropdown should be open on mount, focus it\n if (isOpenOnMount) {\n ref.focus();\n }\n\n const handleInput = (event: Event) => {\n if (!isOpenRef.current) setIsOpen(true);\n\n const input = event.target as HTMLInputElement;\n const isDeleting = enteredCharactersRef.current.length > input.value.length;\n enteredCharactersRef.current = input.value;\n // When deleting text, if there’s already an active item and\n // input isn’t empty, preserve the active item, else update it\n if (isDeleting && input.value.length && getActiveItemElement(ref)) {\n return;\n }\n\n setActiveItem({\n dropdownElement: ref,\n event,\n // If props.allowCreate, only override the input’s value with an\n // exact text match so user can enter a value not in items\n isExactMatch: allowCreateRef.current,\n onActiveItem,\n text: enteredCharactersRef.current,\n });\n };\n\n if (inputElement) {\n inputElement.addEventListener('input', handleInput);\n }\n\n return () => {\n document.removeEventListener('focusin', handleGlobalFocusIn);\n document.removeEventListener('mousedown', handleGlobalMouseDown);\n document.removeEventListener('mouseup', handleGlobalMouseUp);\n\n if (ownerDocument !== document) {\n ownerDocument.removeEventListener('focusin', handleGlobalFocusIn);\n ownerDocument.removeEventListener('mousedown', handleGlobalMouseDown);\n ownerDocument.removeEventListener('mouseup', handleGlobalMouseUp);\n }\n\n if (inputElement) {\n inputElement.removeEventListener('input', handleInput);\n }\n };\n };\n\n if (!isValidElement(trigger)) {\n if (isSearchable) {\n trigger = (\n <input\n autoComplete=\"off\"\n className=\"uktdropdown-trigger\"\n defaultValue={value ?? ''}\n disabled={disabled}\n name={name}\n onFocus={() => setIsOpen(true)}\n placeholder={placeholder}\n ref={inputElementRef}\n tabIndex={tabIndex}\n type=\"text\"\n />\n );\n } else {\n trigger = (\n <button className=\"uktdropdown-trigger\" tabIndex={0} type=\"button\">\n {trigger}\n </button>\n );\n }\n }\n\n if (label != null) {\n trigger = (\n <label className=\"uktdropdown-label\">\n <div className=\"uktdropdown-label-text\">{label}</div>\n {trigger}\n </label>\n );\n }\n\n const dropdownRect = useBoundingClientRect(dropdownElement);\n const dropdownBodyRect = useBoundingClientRect(dropdownBodyElement);\n const boundingElement = getBoundingAncestor(dropdownBodyElement);\n const boundingElementRect = useBoundingClientRect(boundingElement);\n let maxHeight;\n if (\n dropdownBodyRect.top != null &&\n dropdownRect.top != null &&\n boundingElementRect.top != null\n ) {\n const maxHeightUp = dropdownBodyRect.bottom - boundingElementRect.top;\n const maxHeightDown = boundingElementRect.bottom - dropdownBodyRect.top;\n maxHeight = Math.round(\n dropdownBodyRect.top > dropdownRect.top ? maxHeightDown : maxHeightUp,\n );\n }\n\n const style = {\n ...styleFromProps,\n ...(maxHeight != null && maxHeight > minHeightBody\n ? {\n '--uktdd-body-max-height': `calc(${maxHeight}px - var(--uktdd-body-buffer))`,\n }\n : null),\n ...(minWidthBody != null && minWidthBody > 0\n ? { '--uktdd-body-min-width': `${minWidthBody}px` }\n : null),\n };\n\n return (\n <Fragment>\n <style href=\"@acusti/dropdown/Dropdown\" precedence=\"medium\">\n {styles}\n </style>\n <div\n className={clsx('uktdropdown', className, {\n disabled,\n 'is-open': isOpen,\n 'is-searchable': isSearchable,\n })}\n onClick={onClick}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseOut={handleMouseOut}\n onMouseOver={handleMouseOver}\n onMouseUp={handleMouseUp}\n ref={handleRef}\n style={style}\n >\n {trigger}\n {/* TODO next version of Dropdown should use <Activity> for body https://react.dev/reference/react/Activity */}\n {isOpen ? (\n <div className=\"uktdropdown-body\" ref={setDropdownBodyElement}>\n {childrenCount > 1 ? (children as ChildrenTuple)[1] : children}\n </div>\n ) : null}\n </div>\n </Fragment>\n );\n}\n\nfunction getBoundingAncestor(element?: MaybeHTMLElement): MaybeHTMLElement {\n while (element?.parentElement) {\n // If we’ve reached the body, use that as boundingElement\n if (element.parentElement.tagName === 'BODY') return element.parentElement;\n // Only need to check one overflow direction, because if either direction\n // is not visible, neither can be visible\n if (getComputedStyle(element.parentElement).overflowX !== 'visible') {\n return element.parentElement;\n }\n\n element = element.parentElement as MaybeHTMLElement;\n }\n\n return null;\n}\n"],"mappings":";;;;;;;;ACKA,MAAaG,gBAAgB;AAE7B,MAAaC,mBAAmBC,oBAAwC;AACpE,KAAI,CAACA,gBAAiB,QAAO;CAE7B,MAAME,cAAcF,gBAAgBG,cAAc,oBAAoB;AACtE,KAAI,CAACD,YAAa,QAAO;CAEzB,IAAIE,QACAF,YAAYM,iBAAiBV,cAAc;AAE/C,KAAIM,MAAMK,OAAQ,QAAOL;AAGzBA,SAAQF,YAAYQ;AACpB,QAAON,MAAMK,WAAW,GAAG;AACvB,MAAIL,MAAM,GAAGM,YAAY,KAAM;AAC/BN,UAAQA,MAAM,GAAGM;;AAGrB,KAAIN,MAAMK,WAAW,EACjBL,SAAQF,YAAYQ;AAExB,QAAON;;AAGX,MAAaO,wBAAwBX,oBAAwC;AACzE,KAAI,CAACA,gBAAiB,QAAO;AAC7B,QAAOA,gBAAgBG,cAAc,oBAAoB;;AAG7D,IAAMS,0BAA0BC,iBAAqC;AACjEA,cAAaE,SAASC,gBAAgB;AAClC,MAAIA,YAAYC,aAAa,kBAAkB,CAC3C,QAAOD,YAAYE,QAAQC;GAEjC;;AAcN,MAAaW,iBAAiB,EAC1B9B,iBACAqB,SACAC,OACAE,OACAC,aACAC,cACAC,cACAE,WAcmE;CACnE,MAAMzB,QAAQL,gBAAgBC,gBAAgB;AAC9C,KAAI,CAACI,MAAO;CAEZ,MAAMS,eAAeC,MAAMkB,KAAK5B,MAAM;AACtC,KAAI,CAACS,aAAaJ,OAAQ;CAE1B,MAAMwB,YAAYpB,aAAaJ,SAAS;CACxC,MAAMyB,qBAAqBrB,aAAasB,WAAWnB,gBAC/CA,YAAYC,aAAa,kBAC7B,CAAC;CAED,IAAImB,kBAAkBF;AACtB,KAAI,OAAOV,UAAU,SAEjBY,mBAAkBZ,QAAQ,IAAIX,aAAaJ,SAASe,QAAQA;AAGhE,KAAIH,QACAe,mBAAkBvB,aAAasB,WAC1BnB,gBAAgBA,gBAAgBK,QACpC;UACM,OAAOI,gBAAgB,UAAU;AAExC,MAAIS,uBAAuB,MAAMT,gBAAgB,GAC7CW,mBAAkBH;MAElBG,oBAAmBX;AAGvBW,oBAAkBC,KAAKC,IAAI,GAAGD,KAAKE,IAAIH,iBAAiBH,UAAU,CAAC;YAC5D,OAAOJ,SAAS,UAAU;AAEjC,MAAI,CAACA,MAAM;AACPjB,0BAAuBC,aAAa;AACpC;;EAGJ,MAAM2B,YAAY3B,aAAa4B,KAAKzB,gBAAgBA,YAAY0B,UAAU;AAC1E,MAAIhB,cAAc;GACd,MAAMiB,gBAAgBd,KAAKe,aAAa;AACxCR,qBAAkBI,UAAUL,WAAWU,aACnCA,SAASD,aAAa,CAACE,WAAWH,cACtC,CAAC;AAED,OAAIP,oBAAoB,GACpBxB,wBAAuBC,aAAa;SAErC;GACH,MAAMkC,YAAYpD,aAAa;IAAES,OAAOoC;IAAWX;IAAM,CAAC;AAC1DO,qBAAkBI,UAAUL,WAAWU,aAAaA,aAAaE,UAAU;;;CAInF,MAAMC,iBAAiB5C,MAAMgC;AAC7B,KAAIY,kBAAkB,QAAQZ,oBAAoBF,mBAAoB;AAGtEtB,wBAAuBC,aAAa;AACpCmC,gBAAeC,aAAa,mBAAmB,GAAG;CAClD,MAAMC,QAAQF,eAAeN;CAC7B,MAAMS,QAAQH,eAAe9B,QAAQkC,YAAYF;AACjDvB,gBAAe;EAAEN,SAAS2B;EAAgB1B;EAAO4B;EAAOC;EAAO,CAAC;CAEhE,IAAI,EAAEE,kBAAkBL;CACxB,IAAIM,mBAAmB;AACvB,QAAO,CAACA,oBAAoBD,iBAAiBA,kBAAkBrD,gBAE3D,KADqBqD,cAAcG,eAAeH,cAAcI,eAAe,GAE3EH,oBAAmBD;KAEnBA,iBAAgBA,cAAcA;AAItC,KAAIC,kBAAkB;EAClB,MAAMI,aAAaJ,iBAAiBK,uBAAuB;EAC3D,MAAMC,WAAWZ,eAAeW,uBAAuB;EACvD,MAAME,aAAaD,SAASE,MAAMJ,WAAWI;EAC7C,MAAMC,gBAAgBH,SAASI,SAASN,WAAWM;AACnD,MAAIH,cAAcE,eAAe;GAC7B,IAAI,EAAEE,cAAcX;AAEpB,OAAIO,WACAI,cAAaP,WAAWI,MAAMF,SAASE;OAEvCG,cAAaL,SAASI,SAASN,WAAWM;AAE9CV,oBAAiBW,YAAYA;;;;AC/DzC,IAAM+D,iBACF;AACJ,IAAMC,qBAAqB;AAC3B,IAAMC,sBACF;AAEJ,SAAeC,SAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,GAAA;CAAkB,MAAA,EAAAtC,aAAAC,YAAAsC,IAAArC,UAAAG,WAAAC,UAAAE,UAAAgC,IAAA/B,eAAAC,cAAAC,kBAAA8B,IAAA5C,OAAAe,eAAA8B,IAAA7B,cAAAC,MAAAC,cAAAE,SAAAC,SAAAC,aAAAC,WAAAC,QAAAC,cAAAC,aAAAC,OAAAmB,gBAAAlB,UAAA3B,UAAAsC;CAE7B,MAAAnC,aAAAsC,OAAAK,KAAAA,IAAA,OAAAL;CAIA,MAAA/B,WAAAgC,OAAAI,KAAAA,IAAA,OAAAJ;CAGA,MAAA7B,mBAAA8B,OAAAG,KAAAA,IAAA,CAAoBpC,WAApBiC;CAEA,MAAA7B,gBAAA8B,OAAAE,KAAAA,IAAA,KAAAF;CAeA,MAAAG,gBAAsBvE,SAAQwE,MAAO5C,SAAS;AAC9C,KAAI2C,kBAAkB,KAAKA,kBAAkB,GAAC;AAC1C,MAAIA,kBAAkB,EAClB,OAAM,IAAIE,MAAMf,iBAAiB,yBAAyB;AAE9DgB,UAAOC,MAAO,GAAGjB,eAAc,YAAaa,cAAa,YAAa;;CAGtEK,IAAAA;AACJ,KAAIL,gBAAgB,EAChBK,WAAWhD,SAAyB;CAGxC,MAAA,CAAAiD,QAAAC,aAA4BnE,SAAkBwB,iBAAA,MAAuB;CACrE,MAAA,CAAA4C,WAAAC,gBAAkCrE,SAAkB,CAACwB,cAAc;CACnE,MAAA,CAAA8C,iBAAAC,sBAA8CvE,SAA2B,KAAK;CAC9E,MAAA,CAAAwE,qBAAAC,0BACIzE,SAA2B,KAAK;CACpC,MAAA0E,kBAAwB3E,OAAgC,KAAK;CAC7D,MAAA4E,kBAAwB5E,OAAyB,KAAK;CACtD,MAAA6E,oBAA0B7E,OAAyB,KAAK;CACxD,MAAA8E,wBAA8B9E,OAA6B,QAAQ;CACnE,MAAA+E,iCAAuC/E,OAAyB,KAAK;CACrE,MAAAgF,uBAA6BhF,OAAe,GAAG;CAC/C,MAAAiF,uBAA6BjF,OAA6B,KAAK;CAE/D,MAAAkF,iBAAuBlF,OAAOgB,YAAY;CAC1C,MAAAmE,gBAAsBnF,OAAOiB,WAAW;CACxC,MAAAmE,cAAoBpF,OAAOwB,SAAS;CACpC,MAAA6D,YAAkBrF,OAAOmE,OAAO;CAChC,MAAAmB,eAAqBtF,OAAOqE,UAAU;CACtC,MAAAkB,sBAA4BvF,OAAO2B,iBAAiB;CACpD,MAAA6D,aAAmBxF,OAAOkC,QAAQ;CAClC,MAAAuD,YAAkBzF,OAAOqC,OAAO;CAChC,MAAAqD,kBAAwB1F,OAAOsC,aAAa;CAC5C,MAAAqD,WAAiB3F,OAAOc,MAAM;CAAC,IAAA8E;CAAA,IAAAC;AAAA,KAAAxC,EAAA,OAAArC,eAAAqC,EAAA,OAAApC,cAAAoC,EAAA,OAAA7B,YAAA6B,EAAA,OAAAc,UAAAd,EAAA,OAAAgB,aAAAhB,EAAA,OAAA1B,oBAAA0B,EAAA,OAAAnB,WAAAmB,EAAA,OAAAhB,UAAAgB,EAAA,OAAAf,gBAAAe,EAAA,OAAAvC,OAAA;AAErB8E,aAAA;AACNV,kBAAcY,UAAW9E;AACzBmE,iBAAaW,UAAW7E;AACxBmE,eAAWU,UAAWtE;AACtB6D,aAASS,UAAW3B;AACpBmB,gBAAYQ,UAAWzB;AACvBkB,uBAAmBO,UAAWnE;AAC9B6D,cAAUM,UAAW5D;AACrBuD,aAASK,UAAWzD;AACpBqD,mBAAeI,UAAWxD;AAC1BqD,YAAQG,UAAWhF;;AACpB+E,OAAA;GACC7E;GACAC;GACAO;GACA2C;GACAE;GACA1C;GACAO;GACAG;GACAC;GACAxB;GACH;AAAAuC,IAAA,KAAArC;AAAAqC,IAAA,KAAApC;AAAAoC,IAAA,KAAA7B;AAAA6B,IAAA,KAAAc;AAAAd,IAAA,KAAAgB;AAAAhB,IAAA,KAAA1B;AAAA0B,IAAA,KAAAnB;AAAAmB,IAAA,KAAAhB;AAAAgB,IAAA,KAAAf;AAAAe,IAAA,KAAAvC;AAAAuC,IAAA,MAAAuC;AAAAvC,IAAA,MAAAwC;QAAA;AAAAD,OAAAvC,EAAA;AAAAwC,OAAAxC,EAAA;;AAtBDtD,WAAU6F,IAWPC,GAWD;CAEF,MAAAE,eAAqB/F,OAAO,MAAM;CAAC,IAAAgG;CAAA,IAAAC;AAAA,KAAA5C,EAAA,QAAAc,QAAA;AAEzB6B,aAAA;AACN,OAAI,CAACD,aAAYD,SAAQ;AACrBC,iBAAYD,UAAW;AAEvB,QAAIT,UAASS,WAAYL,UAASK,QAC9BL,WAASK,SAAU;AACtB;;AAIL,OAAI3B,UAAUsB,UAASK,QACnBL,WAASK,SAAU;YACZ,CAAC3B,UAAUqB,WAAUM,QAC5BN,YAAUM,SAAU;;AAEzBG,OAAA,CAAC9B,OAAO;AAAAd,IAAA,MAAAc;AAAAd,IAAA,MAAA2C;AAAA3C,IAAA,MAAA4C;QAAA;AAAAD,OAAA3C,EAAA;AAAA4C,OAAA5C,EAAA;;AAfXtD,WAAUiG,IAePC,GAAS;CAAA,IAAAC;AAAA,KAAA7C,EAAA,QAAA8C,OAAAC,IAAA,4BAAA,EAAA;AAEUF,aAAA;AAClB9B,aAAU,MAAM;AAChBE,gBAAa,MAAM;AACnBW,wBAAoBa,UAAW;AAC/B,OAAIlB,gBAAekB,WAAY,MAAI;AAC/BO,iBAAazB,gBAAekB,QAAS;AACrClB,oBAAekB,UAAW;;;AAEjCzC,IAAA,MAAA6C;OAAAA,MAAA7C,EAAA;CARD,MAAAiD,gBAAsBJ;CAQpB,IAAAK;AAAA,KAAAlD,EAAA,QAAAkB,iBAAA;AAEuBgC,SAAA7F,UAAA;AACrB,OAAI2E,UAASS,WAAT,CAAsBP,oBAAmBO,QAGzClB,iBAAekB,UAAW/C,WAAWuD,eAAe,GAA7B;AAG3B,OAAI,CAAClB,YAAWU,QAAQ;GAExB,MAAAtF,UAAgBL,qBAAqBoE,gBAAgB;AACrD,OAAI,CAAC/D,WAAD,CAAa0E,eAAcY,SAAQ;AAEnC,QAAI,CAACX,cAAaW,QAAQ;AAE1B,QAAInB,gBAAemB,SAAehF,MAAA;;GAGtC,IAAA0F,YAAgBhG,SAAOiG,aAAP;AAChB,OAAI9B,gBAAemB,SAAQ;AACvB,QAAI,CAACtF,QACDgG,aAAY7B,gBAAemB,QAAQhF;QAEnC6D,iBAAemB,QAAQhF,QAAS0F;AAGpC,QACI7B,gBAAemB,YACfnB,gBAAemB,QAAQY,cAAcC,cAErChC,iBAAemB,QAAQc,MAAO;;GAItC,MAAAC,YAAkBrG,SAAOsG,QAAkBC,YAAzBP;AAElB,OAAIb,SAAQG,WAAYH,SAAQG,YAAae,UAAS;AAItD,OAAIrG,SAAO;IACP,MAAAwG,cAAoBtG,MAAKuG;AAEzB,QAAIzG,QAAO0G,QAASjE,mBAAmB;SAE/BzC,YAAYwG,eAAZ,CAA4BxG,QAAO2G,SAAUH,YAAY,CACzDxG,SAAO4G,OAAQ;WAClB;KAGD,MAAAC,oBAA0B7G,QAAO8G,iBAAkBrE,mBAAmB;AACtE,SAAIoE,kBAAiBE,WAAY,GAAC;MAC9B,MAAAC,mBAAyBH,kBAAiB;AAC1C,UACIG,qBAAqBR,eAArB,CACCQ,iBAAgBL,SAAUH,YAAY,CAEvCQ,kBAAgBJ,OAAQ;;;;AAMxC1B,mBAAeI,UAAW;IAAAtF;IAAAE;IAAAG,OAGf2F;IAAS1F,OACT+F;IACV,CAAC;;AACLxD,IAAA,MAAAkB;AAAAlB,IAAA,MAAAkD;OAAAA,OAAAlD,EAAA;CApED,MAAAoE,mBAAyBlB;CAoEvB,IAAAmB;AAAA,KAAArE,EAAA,QAAA8C,OAAAC,IAAA,4BAAA,EAAA;AAEsBsB,SAAAC,QAAA;GAAC,MAAA,EAAAhF,SAAAC,YAAA+E;AACrB7C,yBAAqBgB,UAAW;GAChC,MAAA8B,kBAAwB3C,qBAAoBa;AAC5C,OAAI,CAAC8B,gBAAe;AACpB,OACIC,KAAIC,IAAKF,gBAAejF,UAAWA,QAAQ,GAAG,MAC9CkF,KAAIC,IAAKF,gBAAehF,UAAWA,QAAQ,GAAG,GAAE;AAIpD0B,gBAAa,MAAM;;AACtBjB,IAAA,MAAAqE;OAAAA,OAAArE,EAAA;CAXD,MAAA0E,kBAAwBL;CAWtB,IAAAC;AAAA,KAAAtE,EAAA,QAAAkB,mBAAAlB,EAAA,QAAAtB,cAAA;AAEsB4F,SAAAK,YAAA;AACpB,OAAI,CAAC5C,YAAWU,QAAQ;AAGxB,OAAIhB,sBAAqBgB,YAAa,QAAO;AAG7C,OAAI,CAACvB,gBAAe;GAEpB,MAAA0D,eAAqB7H,gBAAgBmE,gBAAgB;AACrD,OAAI,CAAC0D,aAAY;GAEjB,MAAAC,gBAAoBxH,QAAKuG;GAEzB,MAAAoB,YADarB,cAAWoB,QAAS/H,cAAc,IAC/B6H;AAChB,QAAK,MAAAI,eAAqBL,aACtB,KAAIK,gBAAgB9H,WAAO;AACvBF,kBAAc;KAAAiE;KAAA/D,SAAmBA;KAAOE,OAAEA;KAAKqB;KAAgB,CAAC;AAAA;;;AAI3EsB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAtB;AAAAsB,IAAA,MAAAsE;OAAAA,OAAAtE,EAAA;CArBD,MAAAkF,kBAAwBZ;CAqBtB,IAAAa;AAAA,KAAAnF,EAAA,QAAAkB,iBAAA;AAEqBiE,SAAAC,YAAA;AACnB,OAAI,CAACrD,YAAWU,QAAQ;GACxB,MAAA4C,aAAmBvI,qBAAqBoE,gBAAgB;AACxD,OAAI,CAACmE,WAAU;GACf,MAAAC,qBAA2BjI,QAAKkI;AAChC,OAAIF,eAAehI,QAAKuG,UAAWyB,WAAUvB,SAAUwB,mBAAmB,CAAA;AAI1E,UAAOD,WAAU5B,QAAQ+B;;AAC5BxF,IAAA,MAAAkB;AAAAlB,IAAA,MAAAmF;OAAAA,OAAAnF,EAAA;CAVD,MAAAyF,iBAAuBN;CAUrB,IAAAO;AAAA,KAAA1F,EAAA,QAAAlB,aAAA;AAEsB4G,SAAAC,YAAA;AACpB,OAAI7G,YAAaA,aAAYzB,QAAM;AACnC,OAAI2E,UAASS,QAAQ;AAErB1B,aAAU,KAAK;AACfE,gBAAa,KAAK;AAClBW,wBAAoBa,UAAW;IAAAnD,SAClBjC,QAAKiC;IAAQC,SACblC,QAAKkC;IAFU;AAI5BiC,qBAAiBiB,UAAW/C,iBAAW;AACnCuB,iBAAa,MAAM;AACnBO,sBAAiBiB,UAAW;MAC7B,IAHsB;;AAI5BzC,IAAA,MAAAlB;AAAAkB,IAAA,MAAA0F;OAAAA,OAAA1F,EAAA;CAdD,MAAA4F,kBAAwBF;CActB,IAAAG;AAAA,KAAA7F,EAAA,QAAAoE,oBAAApE,EAAA,QAAAjB,WAAA;AAEoB8G,SAAAC,YAAA;AAClB,OAAI/G,UAAWA,WAAU1B,QAAM;AAE/B,OACI4E,aAAYQ,WAAZ,CACCT,UAASS,WACVlB,gBAAekB,WAAY,KAAI;GAKnC,MAAAsD,gBAAoB1I,QAAKuG;AAEzB,OAAI,CAACD,cAAWoB,QAAS,oBAAoB,EAAA;AAEzC,QACI,CAAC9C,aAAYQ,WACbnB,gBAAemB,YAAakB,cAAWN,cAAcC,cAErDL,gBAAe;AAClB;;AAKL,OAAI,CAAClB,YAAWU,QAAQ;AAExB2B,oBAAiB/G,QAAM;;AAC1B2C,IAAA,MAAAoE;AAAApE,IAAA,MAAAjB;AAAAiB,IAAA,MAAA6F;OAAAA,OAAA7F,EAAA;CA5BD,MAAAgG,gBAAsBH;CA4BpB,IAAAI;AAAA,KAAAjG,EAAA,QAAAkB,mBAAAlB,EAAA,QAAAoE,oBAAApE,EAAA,QAAAtB,cAAA;AAEoBuH,SAAAC,YAAA;GAClB,MAAA,EAAAC,QAAAC,SAAAC,KAAAC,YAA0CjJ;GAC1C,MAAAkJ,gBAAoBlJ,QAAKuG;AACzB,OAAI,CAAC1C,gBAAe;GAEpB,MAAAsF,uBAAuB;AACnBnJ,YAAKoJ,iBAAkB;AACvBpJ,YAAKqJ,gBAAiB;AACtBjF,0BAAqBgB,UAAW;;GAGpC,MAAAkE,2BAAiCzF,gBAAe4C,SAAUH,cAAY;AAEtE,OAAI,CAAC3B,UAASS,SAAQ;AAElB,QAAI,CAACkE,yBAAwB;AAE7B,QACIN,QAAQ,OACRA,QAAQ,WACPtE,YAAWU,YAAa4D,QAAQ,aAAaA,QAAQ,cAAa;AAEnEG,qBAAgB;AAChBzF,eAAU,KAAK;;AAClB;;GAIL,MAAA6F,yBAA+B7K,2BAA2BsB,QAAM;AAGhE,OAAI0E,YAAWU,WAAX,CAAwBmE,wBAAsB;IAC9C,IAAAC,sBAA0B,CAACT,WAAD,CAAaE,WAAW,gBAAeQ,KAAMT,IAAI;AAG3E,QAAI,CAACQ,uBAAuBlF,qBAAoBc,QAC5CoE,uBAAsBR,QAAQ,OAAOA,QAAQ;AAGjD,QAAIQ,qBAAmB;AACnBL,qBAAgB;AAChB,SAAIH,QAAQ,YACR1E,sBAAoBc,UAAWd,qBAAoBc,QAAQsE,MACvD,GACA,GAFwB;SAK5BpF,sBAAoBc,UAApBd,qBAAoBc,UAAY4D;AAGpCpJ,mBAAc;MAAAiE;MAAA7D,OAEVA;MAAK2J,cAGSnF,eAAcY;MAAQ/D;MAAAuI,MAE9BtF,qBAAoBc;MAC7B,CAAC;AAEF,SAAIf,+BAA8Be,WAAY,KAC1CO,cAAatB,+BAA8Be,QAAS;AAGxDf,oCAA8Be,UAAW/C,iBAAW;AAChDiC,2BAAoBc,UAAW;AAC/Bf,qCAA8Be,UAAW;QAC1C,KAHmC;AAAA;;;AAU9C,OAAI4D,QAAQ,WAAYA,QAAQ,OAAR,CAAgB/E,gBAAemB,SAAS;AAC5D+D,oBAAgB;AAChBpC,qBAAiB/G,QAAM;AAAA;;AAK3B,OACIgJ,QAAQ,YACPM,4BAA4BN,QAAQ,OAApC,CAA4CtE,YAAWU,SAAS;AAGjE,QAAIV,YAAWU,WAAX,CAAwBmE,uBACxB3D,gBAAe;AAClB;;AAKL,OAAIlB,YAAWU,SAAQ;AACnB,QAAI4D,QAAQ,WAAS;AACjBG,qBAAgB;AAChB,SAAIL,UAAAG,QACArJ,eAAc;MAAAiE;MAAA7D,OAAmBA;MAAK6J,OAAS;MAACxI;MAAgB,CAAC;SAEjEzB,eAAc;MAAAiE;MAAA7D,OAEVA;MAAK8J,aACQ;MAAEzI;MAElB,CAAC;AACL;;AAGL,QAAI2H,QAAQ,aAAW;AACnBG,qBAAgB;AAChB,SAAIL,UAAAG,QAEArJ,eAAc;MAAAiE;MAAA7D,OAAmBA;MAAK6J,OAAS;MAAExI;MAAgB,CAAC;SAElEzB,eAAc;MAAAiE;MAAA7D,OAEVA;MAAK8J,aACQ;MAACzI;MAEjB,CAAC;AACL;;;;AAIZsB,IAAA,MAAAkB;AAAAlB,IAAA,MAAAoE;AAAApE,IAAA,MAAAtB;AAAAsB,IAAA,MAAAiG;OAAAA,OAAAjG,EAAA;CA5HD,MAAAoH,gBAAsBnB;CA4HpB,IAAAoB;AAAA,KAAArH,EAAA,QAAAoH,eAAA;AAEgBC,QAAA;GAAAC,0BAA4B;GAAKC,WAAaH;GAAe;AAAApH,IAAA,MAAAoH;AAAApH,IAAA,MAAAqH;OAAAA,OAAArH,EAAA;AAA/ElE,mBAAkBuL,IAA8D;CAAA,IAAAG;AAAA,KAAAxH,EAAA,QAAA5B,iBAAA4B,EAAA,QAAAtB,cAAA;AAE9D8I,SAAAC,QAAA;AACdtG,sBAAmBsG,IAAI;AACvB,OAAI,CAACA,IAAG;GAER,MAAA,EAAApE,kBAA0BoE;GAC1B,IAAAC,eAAmBpG,gBAAemB;AAElC,OAAI,CAACiF,gBAAgBD,IAAGE,mBAAkB;AACtC,QAAIF,IAAGE,kBAAkB9D,QAAShE,oBAAoB,CAClD6H,gBAAeD,IAAGE;QAElBD,gBAAeD,IAAGE,kBAAkBE,cAAehI,oBAAoB;AAE3EyB,oBAAemB,UAAWiF;;GAG9B,MAAAI,yBAA8BC,QAAA;IAAC,MAAA,EAAAnE,WAAAmE;IAC3B,MAAAC,gBAAoBpE;AACpB,QAAI,CAAC6D,IAAG3D,SAAUH,cAAY,CAE1BV,gBAAe;;GAIvB,MAAAgF,uBAA4BC,QAAA;IAAC,MAAA,EAAAtE,QAAAuE,aAAAD;AACzB,QAAI,CAAClG,UAASS,WAAYlB,gBAAekB,WAAY,KAAI;AAGzD,QAAIR,aAAYQ,SAAQ;AACpBxB,kBAAa,MAAM;AACnB,SAAIO,kBAAiBiB,WAAY,MAAI;AACjCO,mBAAaxB,kBAAiBiB,QAAS;AACvCjB,wBAAiBiB,UAAW;;AAC/B;;IAIL,MAAA2F,gBAAoBxE;AAEpB,QAAI,CAAC6D,IAAG3D,SAAUH,cAAY,CAC1BV,gBAAe;;GAKvB,MAAAoF,uBAA4BC,QAAA;IAAC,MAAA,EAAA1E,QAAA2E,aAAAD;AACzB,QAAI,CAACtG,UAASS,QAAQ;IAEtB,MAAA+F,gBAAoB5E;AAEpB,QAAI6D,IAAG3D,SAAUH,cAAyC,IAAzBA,cAAWG,SAAU2D,IAAI,CAAA;AAI1DxE,mBAAe;;AAGnBwF,YAAQC,iBAAkB,WAAWL,oBAAoB;AACzDI,YAAQC,iBAAkB,aAAaZ,sBAAsB;AAC7DW,YAAQC,iBAAkB,WAAWT,oBAAoB;AAEzD,OAAI5E,kBAAkBoF,UAAQ;AAC1BpF,kBAAaqF,iBAAkB,WAAWL,oBAAoB;AAC9DhF,kBAAaqF,iBAAkB,aAAaZ,sBAAsB;AAClEzE,kBAAaqF,iBAAkB,WAAWT,oBAAoB;;AAIlE,OAAI7J,cACAqJ,KAAGkB,OAAQ;GAGf,MAAAC,eAAoBC,YAAA;AAChB,QAAI,CAAC7G,UAASS,QAAU1B,WAAU,KAAK;IAEvC,MAAA+H,QAAczL,QAAKuG;IACnB,MAAAmF,aAAmBpH,qBAAoBc,QAAQyB,SAAU4E,MAAKrL,MAAMyG;AACpEvC,yBAAoBc,UAAWqG,MAAKrL;AAGpC,QAAIsL,cAAcD,MAAKrL,MAAMyG,UAAWpH,qBAAqB2K,IAAI,CAAA;AAIjExK,kBAAc;KAAAiE,iBACOuG;KAAGpK,OACpBA;KAAK2J,cAGSnF,eAAcY;KAAQ/D;KAAAuI,MAE9BtF,qBAAoBc;KAC7B,CAAC;;AAGN,OAAIiF,aACAA,cAAYgB,iBAAkB,SAASE,YAAY;AACtD,gBAEM;AACHH,aAAQO,oBAAqB,WAAWX,oBAAoB;AAC5DI,aAAQO,oBAAqB,aAAalB,sBAAsB;AAChEW,aAAQO,oBAAqB,WAAWf,oBAAoB;AAE5D,QAAI5E,kBAAkBoF,UAAQ;AAC1BpF,mBAAa2F,oBAAqB,WAAWX,oBAAoB;AACjEhF,mBAAa2F,oBAAqB,aAAalB,sBAAsB;AACrEzE,mBAAa2F,oBAAqB,WAAWf,oBAAoB;;AAGrE,QAAIP,aACAA,cAAYsB,oBAAqB,SAASJ,YAAY;;;AAGjE5I,IAAA,MAAA5B;AAAA4B,IAAA,MAAAtB;AAAAsB,IAAA,MAAAwH;OAAAA,OAAAxH,EAAA;CAlHD,MAAAiJ,YAAkBzB;AAoHlB,KAAI,CAACpL,eAAeyE,QAAQ,CACxB,KAAIxC,cAAY;EAKU,MAAA0J,MAAAtK,SAAA;EAAW,IAAAyK;AAAA,MAAAlI,EAAA,QAAA8C,OAAAC,IAAA,4BAAA,EAAA;AAGhBmF,eAAMnH,UAAU,KAAK;AAAAf,KAAA,MAAAkI;QAAAA,OAAAlI,EAAA;EAAA,IAAAsI;AAAA,MAAAtI,EAAA,QAAA/B,YAAA+B,EAAA,QAAAvB,QAAAuB,EAAA,QAAAd,eAAAc,EAAA,QAAA+H,OAAA/H,EAAA,QAAAZ,UAAA;AANlCkJ,SAAA,oBAAA,SAAA;IACiB,cAAA;IACH,WAAA;IACI,cAAAP;IACJ9J;IACJQ;IACG,SAAAyJ;IACIhJ;IACRoC,KAAAA;IACKlC;IACL,MAAA;IACP,CAAA;AAAAY,KAAA,MAAA/B;AAAA+B,KAAA,MAAAvB;AAAAuB,KAAA,MAAAd;AAAAc,KAAA,MAAA+H;AAAA/H,KAAA,MAAAZ;AAAAY,KAAA,MAAAsI;QAAAA,OAAAtI,EAAA;AAZNa,YACIA;QADG;EAAA,IAAAkH;AAAA,MAAA/H,EAAA,QAAAa,SAAA;AAgBHkH,SAAA,oBAAA,UAAA;IAAkB,WAAA;IAAgC,UAAA;IAAQ,MAAA;cACrDlH;IACI,CAAA;AAAAb,KAAA,MAAAa;AAAAb,KAAA,MAAA+H;QAAAA,OAAA/H,EAAA;AAHba,YACIA;;AAOZ,KAAIrD,SAAS,MAAI;EAAA,IAAAuK;AAAA,MAAA/H,EAAA,QAAAxC,OAAA;AAGLuK,SAAA,oBAAA,OAAA;IAAe,WAAA;cAA0BvK;IAAY,CAAA;AAAAwC,KAAA,MAAAxC;AAAAwC,KAAA,MAAA+H;QAAAA,OAAA/H,EAAA;EAAA,IAAAkI;AAAA,MAAAlI,EAAA,QAAA+H,OAAA/H,EAAA,QAAAa,SAAA;AADzDqH,SAAA,qBAAA,SAAA;IAAiB,WAAA;cAAjB,CACIH,KACClH,QACG;;AAAAb,KAAA,MAAA+H;AAAA/H,KAAA,MAAAa;AAAAb,KAAA,MAAAkI;QAAAA,OAAAlI,EAAA;AAJZa,YACIA;;CAOR,MAAAqI,eAAqBrN,sBAAsBqF,gBAAgB;CAC3D,MAAAiI,mBAAyBtN,sBAAsBuF,oBAAoB;CAAC,IAAA2G;AAAA,KAAA/H,EAAA,QAAAoB,qBAAA;AAC5C2G,QAAAqB,oBAAoBhI,oBAAoB;AAAApB,IAAA,MAAAoB;AAAApB,IAAA,MAAA+H;OAAAA,OAAA/H,EAAA;CAChE,MAAAsJ,sBAA4BzN,sBADJkM,IAC0C;CAC9DwB,IAAAA;AACJ,KACIJ,iBAAgBK,OAAQ,QACxBN,aAAYM,OAAQ,QACpBF,oBAAmBE,OAAQ,MAAI;EAE/B,MAAAC,cAAoBN,iBAAgBO,SAAUJ,oBAAmBE;EACjE,MAAAG,gBAAsBL,oBAAmBI,SAAUP,iBAAgBK;EAAK,IAAAtB;AAAA,MAAAlI,EAAA,QAAAmJ,iBAAAK,OAAAxJ,EAAA,QAAAkJ,aAAAM,OAAAxJ,EAAA,QAAA2J,iBAAA3J,EAAA,QAAAyJ,aAAA;AAC5DvB,SAAA1D,KAAIoF,MACZT,iBAAgBK,MAAON,aAAYM,MAAnCG,gBAAAF,YACH;AAAAzJ,KAAA,MAAAmJ,iBAAAK;AAAAxJ,KAAA,MAAAkJ,aAAAM;AAAAxJ,KAAA,MAAA2J;AAAA3J,KAAA,MAAAyJ;AAAAzJ,KAAA,MAAAkI;QAAAA,OAAAlI,EAAA;AAFDuJ,cAAYA;;CAGf,IAAArB;AAAA,KAAAlI,EAAA,QAAAuJ,aAAAvJ,EAAA,QAAAzB,eAAA;AAIO2J,QAAAqB,aAAa,QAAQA,YAAYhL,gBAAjC,EAAA,2BAEiC,QAAQgL,UAAS,iCAE5C,GAJN;AAIMvJ,IAAA,MAAAuJ;AAAAvJ,IAAA,MAAAzB;AAAAyB,IAAA,MAAAkI;OAAAA,OAAAlI,EAAA;CAAA,IAAAsI;AAAA,KAAAtI,EAAA,QAAAxB,cAAA;AACN8J,QAAA9J,gBAAgB,QAAQA,eAAe,IAAvC,EAAA,0BAC8B,GAAGA,aAAY,KACvC,GAFN;AAEMwB,IAAA,MAAAxB;AAAAwB,IAAA,MAAAsI;OAAAA,OAAAtI,EAAA;CAAA,IAAA6J;AAAA,KAAA7J,EAAA,QAAAM,kBAAAN,EAAA,QAAAkI,OAAAlI,EAAA,QAAAsI,KAAA;AATAuB,QAAA;GAAA,GACPvJ;GAAc,GACb4H;GAIM,GACNI;GAGP;AAAAtI,IAAA,MAAAM;AAAAN,IAAA,MAAAkI;AAAAlI,IAAA,MAAAsI;AAAAtI,IAAA,MAAA6J;OAAAA,OAAA7J,EAAA;CAVD,MAAAb,QAAc0K;CAUZ,IAAAC;AAAA,KAAA9J,EAAA,QAAA8C,OAAAC,IAAA,4BAAA,EAAA;AAIM+G,QAAA,oBAAA,SAAA;GAAY,MAAA;GAAuC,YAAA;aAC9CjN;GACG,CAAA;AAAAmD,IAAA,MAAA8J;OAAAA,OAAA9J,EAAA;CAAA,IAAA+J;AAAA,KAAA/J,EAAA,QAAAhC,aAAAgC,EAAA,QAAA/B,YAAA+B,EAAA,QAAAc,UAAAd,EAAA,QAAA3B,cAAA;AAEO0L,QAAA/N,KAAK,eAAegC,WAAW;GAAAC;GAAA,WAE3B6C;GAAM,iBACAzC;GACpB,CAAC;AAAA2B,IAAA,MAAAhC;AAAAgC,IAAA,MAAA/B;AAAA+B,IAAA,MAAAc;AAAAd,IAAA,MAAA3B;AAAA2B,IAAA,MAAA+J;OAAAA,OAAA/J,EAAA;CAAA,IAAAgK;AAAA,KAAAhK,EAAA,QAAAnC,YAAAmC,EAAA,QAAAQ,iBAAAR,EAAA,QAAAc,QAAA;AAYDkJ,QAAAlJ,SACG,oBAAA,OAAA;GAAe,WAAA;GAAwBO,KAAAA;aAClCb,gBAAgB,IAAK3C,SAAyB,KAA9CA;GAED,CAAA,GAJP;AAIOmC,IAAA,MAAAnC;AAAAmC,IAAA,MAAAQ;AAAAR,IAAA,MAAAc;AAAAd,IAAA,MAAAgK;OAAAA,OAAAhK,EAAA;CAAA,IAAAiK;AAAA,KAAAjK,EAAA,QAAA4F,mBAAA5F,EAAA,QAAAyF,kBAAAzF,EAAA,QAAAkF,mBAAAlF,EAAA,QAAAgG,iBAAAhG,EAAA,QAAAiJ,aAAAjJ,EAAA,QAAApB,WAAAoB,EAAA,QAAAb,SAAAa,EAAA,QAAA+J,OAAA/J,EAAA,QAAAgK,OAAAhK,EAAA,QAAAa,SAAA;AAzBhBoJ,QAAA,qBAAC,UAAD,EAAA,UAAA,CACIH,KAGA,qBAAA,OAAA;GACe,WAAAC;GAKFnL;GACIgH,aAAAA;GACAlB,aAAAA;GACDe,YAAAA;GACCP,aAAAA;GACFc,WAAAA;GACNiD,KAAAA;GACE9J;aAbX,CAeK0B,SAEAmJ,IAMT;KAAW,EAAA,CAAA;AAAAhK,IAAA,MAAA4F;AAAA5F,IAAA,MAAAyF;AAAAzF,IAAA,MAAAkF;AAAAlF,IAAA,MAAAgG;AAAAhG,IAAA,MAAAiJ;AAAAjJ,IAAA,MAAApB;AAAAoB,IAAA,MAAAb;AAAAa,IAAA,MAAA+J;AAAA/J,IAAA,MAAAgK;AAAAhK,IAAA,MAAAa;AAAAb,IAAA,MAAAiK;OAAAA,OAAAjK,EAAA;AAAA,QA3BXiK;;AA+BR,SAASb,oBAAoBjM,SAA8C;AACvE,QAAOA,SAAS+M,eAAe;AAE3B,MAAI/M,QAAQ+M,cAAcC,YAAY,OAAQ,QAAOhN,QAAQ+M;AAG7D,MAAIE,iBAAiBjN,QAAQ+M,cAAc,CAACG,cAAc,UACtD,QAAOlN,QAAQ+M;AAGnB/M,YAAUA,QAAQ+M;;AAGtB,QAAO"}
1
+ {"version":3,"file":"Dropdown.js","names":["getBestMatch","SyntheticEvent","Item","ITEM_SELECTOR","getItemElements","dropdownElement","HTMLElement","bodyElement","querySelector","items","HTMLCollection","NodeListOf","Element","querySelectorAll","length","children","getActiveItemElement","clearItemElementsState","itemElements","Array","forEach","itemElement","hasAttribute","dataset","uktActive","BaseSetActiveItemPayload","element","event","Event","index","indexAddend","isExactMatch","onActiveItem","payload","text","setActiveItem","Omit","from","lastIndex","currentActiveIndex","findIndex","nextActiveIndex","Math","max","min","itemTexts","map","innerText","textToCompare","toLowerCase","itemText","startsWith","bestMatch","nextActiveItem","setAttribute","label","value","uktValue","parentElement","scrollableParent","isScrollable","scrollHeight","clientHeight","parentRect","getBoundingClientRect","itemRect","isAboveTop","top","isBelowBottom","bottom","scrollTop","useKeyboardEvents","isEventTargetUsingKeyEvent","clsx","Children","CSSProperties","Fragment","isValidElement","JSX","MouseEvent","ReactMouseEvent","ReactNode","SyntheticEvent","useEffect","useRef","useState","styles","getActiveItemElement","getItemElements","ITEM_SELECTOR","setActiveItem","Item","element","MaybeHTMLElement","event","Event","HTMLElement","label","value","Props","allowCreate","allowEmpty","children","ChildrenTuple","Element","className","disabled","group","hasItems","isOpenOnMount","isSearchable","keepOpenOnSubmit","minHeightBody","minWidthBody","name","onActiveItem","payload","onClick","onClose","onMouseDown","onMouseUp","onOpen","onSubmitItem","placeholder","style","tabIndex","MousePosition","clientX","clientY","TimeoutID","ReturnType","setTimeout","CHILDREN_ERROR","CLICKABLE_SELECTOR","TEXT_INPUT_SELECTOR","Dropdown","t0","$","_c","t1","t2","t3","styleFromProps","undefined","childrenCount","count","Error","console","error","trigger","isOpen","setIsOpen","isOpening","setIsOpening","dropdownElement","setDropdownElement","inputElementRef","closingTimerRef","isOpeningTimerRef","currentInputMethodRef","clearEnteredCharactersTimerRef","enteredCharactersRef","mouseDownPositionRef","allowCreateRef","allowEmptyRef","hasItemsRef","isOpenRef","isOpeningRef","keepOpenOnSubmitRef","onCloseRef","onOpenRef","onSubmitItemRef","valueRef","t4","t5","current","isMountedRef","t6","t7","t8","Symbol","for","clearTimeout","closeDropdown","t9","itemLabel","innerText","ownerDocument","activeElement","blur","nextValue","dataset","uktValue","eventTarget","target","matches","contains","click","clickableElements","querySelectorAll","length","clickableElement","handleSubmitItem","t10","t11","initialPosition","Math","abs","handleMouseMove","event_0","itemElements","eventTarget_0","item","closest","element_0","itemElement","handleMouseOver","t12","event_1","activeItem","eventRelatedTarget","relatedTarget","uktActive","handleMouseOut","t13","event_2","handleMouseDown","t14","event_3","eventTarget_1","handleMouseUp","t15","event_4","altKey","ctrlKey","key","metaKey","eventTarget_2","onEventHandled","stopPropagation","preventDefault","isEventTargetingDropdown","isTargetUsingKeyEvents","isEditingCharacters","test","slice","isExactMatch","text","index","indexAddend","handleKeyDown","t16","ignoreUsedKeyboardEvents","onKeyDown","t17","ref","inputElement","firstElementChild","HTMLInputElement","querySelector","handleGlobalMouseDown","t18","eventTarget_3","handleGlobalMouseUp","t19","target_0","eventTarget_4","handleGlobalFocusIn","t20","target_1","eventTarget_5","document","addEventListener","focus","handleInput","event_5","input","isDeleting","removeEventListener","handleRef","t21","t22","t23","t24"],"sources":["../src/Dropdown.css?inline","../src/helpers.ts","../src/Dropdown.tsx"],"sourcesContent":[":root {\n --uktdd-font-family:\n system-ui, Segoe UI, Roboto, Oxygen-Sans, Ubuntu, Cantarell, Helvetica Neue,\n Helvetica, Arial, sans-serif;\n --uktdd-body-bg-color: #fff;\n --uktdd-body-bg-color-hover: rgb(105, 162, 249);\n --uktdd-body-color-hover: #fff;\n --uktdd-body-buffer: 10px;\n --uktdd-body-max-height: calc(100dvh - var(--uktdd-body-buffer));\n --uktdd-body-max-width: calc(100dvw - var(--uktdd-body-buffer));\n --uktdd-body-min-height: 30px;\n --uktdd-body-pad-bottom: 9px;\n --uktdd-body-pad-left: 12px;\n --uktdd-body-pad-right: 12px;\n --uktdd-body-pad-top: 9px;\n --uktdd-body-min-width: min(50px, 100%);\n --uktdd-body-position-area: bottom span-right;\n --uktdd-body-position-try-fallbacks:\n --uktdd-top-left, --uktdd-bottom-right, --uktdd-top-right;\n --uktdd-body-translate: 0 0;\n --uktdd-label-pad-right: 10px;\n}\n\n.uktdropdown,\n.uktdropdown-trigger {\n font-family: var(--uktdd-font-family);\n}\n\n.uktdropdown {\n width: max-content;\n anchor-scope: --uktdd-anchor;\n\n &.disabled {\n pointer-events: none;\n }\n\n > * {\n cursor: default;\n }\n\n > :first-child {\n anchor-name: --uktdd-anchor;\n }\n}\n\n.uktdropdown-label {\n display: flex;\n align-items: center;\n}\n\n.uktdropdown-label-text {\n padding-right: var(--uktdd-label-pad-right);\n}\n\n.uktdropdown-body {\n box-sizing: border-box;\n display: flex;\n flex-direction: column;\n position: fixed;\n position-anchor: --uktdd-anchor;\n position-area: var(--uktdd-body-position-area);\n position-try-order: most-height;\n position-try-fallbacks: var(--uktdd-body-position-try-fallbacks);\n min-block-size: min(var(--uktdd-body-min-height), var(--uktdd-body-max-height));\n max-block-size: min(var(--uktdd-body-max-height), 100%);\n min-inline-size: min(var(--uktdd-body-min-width), var(--uktdd-body-max-width));\n max-inline-size: var(--uktdd-body-max-width);\n inline-size: max-content;\n overflow: hidden;\n translate: var(--uktdd-body-translate);\n z-index: 2;\n background-color: var(--uktdd-body-bg-color);\n box-shadow: 0 8px 18px rgba(0, 0, 0, 0.25);\n\n &.has-items {\n user-select: none;\n }\n\n [data-ukt-active] {\n background-color: var(--uktdd-body-bg-color-hover);\n color: var(--uktdd-body-color-hover);\n }\n}\n\n.uktdropdown-content {\n box-sizing: border-box;\n min-block-size: 0;\n overflow: auto;\n overscroll-behavior: contain;\n padding: var(--uktdd-body-pad-top) var(--uktdd-body-pad-right)\n var(--uktdd-body-pad-bottom) var(--uktdd-body-pad-left);\n}\n\n@position-try --uktdd-top-left {\n position-area: top span-right;\n}\n\n@position-try --uktdd-bottom-left {\n position-area: bottom span-right;\n}\n\n@position-try --uktdd-bottom-right {\n position-area: bottom span-left;\n}\n\n@position-try --uktdd-top-right {\n position-area: top span-left;\n}\n","import { getBestMatch } from '@acusti/matchmaking';\nimport { type SyntheticEvent } from 'react';\n\nimport { type Item } from './Dropdown.js';\n\nexport const ITEM_SELECTOR = `[data-ukt-item], [data-ukt-value]`;\n\nexport const getItemElements = (dropdownElement: HTMLElement | null) => {\n if (!dropdownElement) return null;\n\n const bodyElement = dropdownElement.querySelector('.uktdropdown-body');\n if (!bodyElement) return null;\n\n let items: HTMLCollection | NodeListOf<Element> =\n bodyElement.querySelectorAll(ITEM_SELECTOR);\n\n if (items.length) return items;\n // If no items found via [data-ukt-item] or [data-ukt-value] selector,\n // use first instance of multiple children found\n items = bodyElement.children;\n while (items.length === 1) {\n if (items[0].children == null) break;\n items = items[0].children;\n }\n // If unable to find an element with more than one child, treat direct child as items\n if (items.length === 1) {\n items = bodyElement.children;\n }\n return items;\n};\n\nexport const getActiveItemElement = (dropdownElement: HTMLElement | null) => {\n if (!dropdownElement) return null;\n return dropdownElement.querySelector('[data-ukt-active]') as HTMLElement | null;\n};\n\nconst clearItemElementsState = (itemElements: Array<HTMLElement>) => {\n itemElements.forEach((itemElement) => {\n if (itemElement.hasAttribute('data-ukt-active')) {\n delete itemElement.dataset.uktActive;\n }\n });\n};\n\ntype BaseSetActiveItemPayload = {\n dropdownElement: HTMLElement;\n element?: null;\n event: Event | SyntheticEvent<HTMLElement>;\n index?: null;\n indexAddend?: null;\n isExactMatch?: null;\n onActiveItem?: (payload: Item) => void;\n text?: null;\n};\n\nexport const setActiveItem = ({\n dropdownElement,\n element,\n event,\n index,\n indexAddend,\n isExactMatch,\n onActiveItem,\n text,\n}:\n | ({\n element: HTMLElement;\n } & Omit<BaseSetActiveItemPayload, 'element'>)\n | ({\n index: number;\n } & Omit<BaseSetActiveItemPayload, 'index'>)\n | ({\n indexAddend: number;\n } & Omit<BaseSetActiveItemPayload, 'indexAddend'>)\n | ({\n isExactMatch?: boolean;\n text: string;\n } & Omit<BaseSetActiveItemPayload, 'isExactMatch' | 'text'>)) => {\n const items = getItemElements(dropdownElement);\n if (!items) return;\n\n const itemElements = Array.from(items) as Array<HTMLElement>;\n if (!itemElements.length) return;\n\n const lastIndex = itemElements.length - 1;\n const currentActiveIndex = itemElements.findIndex((itemElement) =>\n itemElement.hasAttribute('data-ukt-active'),\n );\n\n let nextActiveIndex = currentActiveIndex;\n if (typeof index === 'number') {\n // Negative index means count back from the end\n nextActiveIndex = index < 0 ? itemElements.length + index : index;\n }\n\n if (element) {\n nextActiveIndex = itemElements.findIndex(\n (itemElement) => itemElement === element,\n );\n } else if (typeof indexAddend === 'number') {\n // If there’s no currentActiveIndex and we are handling -1, start at lastIndex\n if (currentActiveIndex === -1 && indexAddend === -1) {\n nextActiveIndex = lastIndex;\n } else {\n nextActiveIndex += indexAddend;\n }\n // Keep it within the bounds of the items list\n nextActiveIndex = Math.max(0, Math.min(nextActiveIndex, lastIndex));\n } else if (typeof text === 'string') {\n // If text is empty, clear existing active items and early return\n if (!text) {\n clearItemElementsState(itemElements);\n return;\n }\n\n const itemTexts = itemElements.map((itemElement) => itemElement.innerText);\n if (isExactMatch) {\n const textToCompare = text.toLowerCase();\n nextActiveIndex = itemTexts.findIndex((itemText) =>\n itemText.toLowerCase().startsWith(textToCompare),\n );\n // If isExactMatch is required and no exact match was found, clear active items\n if (nextActiveIndex === -1) {\n clearItemElementsState(itemElements);\n }\n } else {\n const bestMatch = getBestMatch({ items: itemTexts, text });\n nextActiveIndex = itemTexts.findIndex((itemText) => itemText === bestMatch);\n }\n }\n\n const nextActiveItem = items[nextActiveIndex] as HTMLElement | null;\n if (nextActiveItem == null || nextActiveIndex === currentActiveIndex) return;\n\n // Clear any existing active dropdown body item state\n clearItemElementsState(itemElements);\n nextActiveItem.setAttribute('data-ukt-active', '');\n const label = nextActiveItem.innerText;\n const value = nextActiveItem.dataset.uktValue ?? label;\n onActiveItem?.({ element: nextActiveItem, event, label, value });\n // Find closest scrollable parent and ensure that next active item is visible\n let { parentElement } = nextActiveItem;\n let scrollableParent = null;\n while (!scrollableParent && parentElement && parentElement !== dropdownElement) {\n const isScrollable = parentElement.scrollHeight > parentElement.clientHeight + 15;\n if (isScrollable) {\n scrollableParent = parentElement;\n } else {\n parentElement = parentElement.parentElement;\n }\n }\n\n if (scrollableParent) {\n const parentRect = scrollableParent.getBoundingClientRect();\n const itemRect = nextActiveItem.getBoundingClientRect();\n const isAboveTop = itemRect.top < parentRect.top;\n const isBelowBottom = itemRect.bottom > parentRect.bottom;\n if (isAboveTop || isBelowBottom) {\n let { scrollTop } = scrollableParent;\n // Item isn’t fully visible; adjust scrollTop to put item within closest edge\n if (isAboveTop) {\n scrollTop -= parentRect.top - itemRect.top;\n } else {\n scrollTop += itemRect.bottom - parentRect.bottom;\n }\n scrollableParent.scrollTop = scrollTop;\n }\n }\n};\n","/* eslint-disable jsx-a11y/click-events-have-key-events, jsx-a11y/mouse-events-have-key-events, jsx-a11y/no-static-element-interactions */\nimport useKeyboardEvents, {\n isEventTargetUsingKeyEvent,\n} from '@acusti/use-keyboard-events';\nimport clsx from 'clsx';\nimport {\n Children,\n type CSSProperties,\n Fragment,\n isValidElement,\n type JSX,\n type MouseEvent as ReactMouseEvent,\n type ReactNode,\n type SyntheticEvent,\n useEffect,\n useRef,\n useState,\n} from 'react';\n\nimport styles from './Dropdown.css?inline';\nimport {\n getActiveItemElement,\n getItemElements,\n ITEM_SELECTOR,\n setActiveItem,\n} from './helpers.js';\n\nexport type Item = {\n element: MaybeHTMLElement;\n event: Event | SyntheticEvent<HTMLElement>;\n label: string;\n value: string;\n};\n\nexport type Props = {\n /**\n * Boolean indicating if the user can submit a value not already in the\n * dropdown.\n */\n allowCreate?: boolean;\n /**\n * Boolean indicating if the user can submit an empty value (i.e. clear\n * the value). Defaults to true.\n */\n allowEmpty?: boolean;\n /**\n * Can take a single React element or exactly two renderable children.\n */\n children: ChildrenTuple | JSX.Element;\n className?: string;\n disabled?: boolean;\n /**\n * Group identifier string links dropdowns together into a menu\n * (like macOS top menubar).\n */\n group?: string;\n hasItems?: boolean;\n isOpenOnMount?: boolean;\n isSearchable?: boolean;\n keepOpenOnSubmit?: boolean;\n label?: ReactNode;\n minHeightBody?: number;\n minWidthBody?: number;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s name.\n */\n name?: string;\n onActiveItem?: (payload: Item) => void;\n onClick?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onClose?: () => unknown;\n onMouseDown?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onMouseUp?: (event: ReactMouseEvent<HTMLElement>) => unknown;\n onOpen?: () => unknown;\n onSubmitItem?: (payload: Item) => void;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s placeholder.\n */\n placeholder?: string;\n style?: CSSProperties;\n /**\n * Only usable in conjunction with {isSearchable: true}.\n * Used as search input’s tabIndex.\n */\n tabIndex?: number;\n /**\n * Used as search input’s value if props.isSearchable === true\n * Used to determine if value has changed to avoid triggering onSubmitItem if not\n */\n value?: string;\n};\n\ntype ChildrenTuple = [ReactNode, ReactNode] | readonly [ReactNode, ReactNode];\n\ntype MaybeHTMLElement = HTMLElement | null;\n\ntype MousePosition = { clientX: number; clientY: number };\n\ntype TimeoutID = ReturnType<typeof setTimeout>;\n\nconst CHILDREN_ERROR =\n '@acusti/dropdown requires either 1 child (the dropdown body) or 2 children: the dropdown trigger and the dropdown body.';\nconst CLICKABLE_SELECTOR = 'button, a[href], input[type=\"button\"], input[type=\"submit\"]';\nconst TEXT_INPUT_SELECTOR =\n 'input:not([type=radio]):not([type=checkbox]):not([type=range]),textarea';\n\nexport default function Dropdown({\n allowCreate,\n allowEmpty = true,\n children,\n className,\n disabled,\n hasItems = true,\n isOpenOnMount,\n isSearchable,\n keepOpenOnSubmit = !hasItems,\n label,\n minHeightBody,\n minWidthBody,\n name,\n onActiveItem,\n onClick,\n onClose,\n onMouseDown,\n onMouseUp,\n onOpen,\n onSubmitItem,\n placeholder,\n style: styleFromProps,\n tabIndex,\n value,\n}: Props) {\n const childrenCount = Children.count(children);\n if (childrenCount !== 1 && childrenCount !== 2) {\n if (childrenCount === 0) {\n throw new Error(CHILDREN_ERROR + ' Received no children.');\n }\n console.error(`${CHILDREN_ERROR} Received ${childrenCount} children.`);\n }\n\n let trigger: React.ReactNode;\n if (childrenCount > 1) {\n trigger = (children as ChildrenTuple)[0];\n }\n\n const [isOpen, setIsOpen] = useState<boolean>(isOpenOnMount ?? false);\n const [isOpening, setIsOpening] = useState<boolean>(!isOpenOnMount);\n const [dropdownElement, setDropdownElement] = useState<MaybeHTMLElement>(null);\n const inputElementRef = useRef<HTMLInputElement | null>(null);\n const closingTimerRef = useRef<null | TimeoutID>(null);\n const isOpeningTimerRef = useRef<null | TimeoutID>(null);\n const currentInputMethodRef = useRef<'keyboard' | 'mouse'>('mouse');\n const clearEnteredCharactersTimerRef = useRef<null | TimeoutID>(null);\n const enteredCharactersRef = useRef<string>('');\n const mouseDownPositionRef = useRef<MousePosition | null>(null);\n\n const allowCreateRef = useRef(allowCreate);\n const allowEmptyRef = useRef(allowEmpty);\n const hasItemsRef = useRef(hasItems);\n const isOpenRef = useRef(isOpen);\n const isOpeningRef = useRef(isOpening);\n const keepOpenOnSubmitRef = useRef(keepOpenOnSubmit);\n const onCloseRef = useRef(onClose);\n const onOpenRef = useRef(onOpen);\n const onSubmitItemRef = useRef(onSubmitItem);\n const valueRef = useRef(value);\n\n useEffect(() => {\n allowCreateRef.current = allowCreate;\n allowEmptyRef.current = allowEmpty;\n hasItemsRef.current = hasItems;\n isOpenRef.current = isOpen;\n isOpeningRef.current = isOpening;\n keepOpenOnSubmitRef.current = keepOpenOnSubmit;\n onCloseRef.current = onClose;\n onOpenRef.current = onOpen;\n onSubmitItemRef.current = onSubmitItem;\n valueRef.current = value;\n }, [\n allowCreate,\n allowEmpty,\n hasItems,\n isOpen,\n isOpening,\n keepOpenOnSubmit,\n onClose,\n onOpen,\n onSubmitItem,\n value,\n ]);\n\n const isMountedRef = useRef(false);\n\n useEffect(() => {\n if (!isMountedRef.current) {\n isMountedRef.current = true;\n // If isOpenOnMount, trigger onOpen right away\n if (isOpenRef.current && onOpenRef.current) {\n onOpenRef.current();\n }\n return;\n }\n\n if (isOpen && onOpenRef.current) {\n onOpenRef.current();\n } else if (!isOpen && onCloseRef.current) {\n onCloseRef.current();\n }\n }, [isOpen]);\n\n const closeDropdown = () => {\n setIsOpen(false);\n setIsOpening(false);\n mouseDownPositionRef.current = null;\n if (closingTimerRef.current != null) {\n clearTimeout(closingTimerRef.current);\n closingTimerRef.current = null;\n }\n };\n\n const handleSubmitItem = (event: Event | React.SyntheticEvent<HTMLElement>) => {\n if (isOpenRef.current && !keepOpenOnSubmitRef.current) {\n // A short timeout before closing is better UX when user selects an item so dropdown\n // doesn’t close before expected. It also enables using <Link />s in the dropdown body.\n closingTimerRef.current = setTimeout(closeDropdown, 90);\n }\n\n if (!hasItemsRef.current) return;\n\n const element = getActiveItemElement(dropdownElement);\n if (!element && !allowCreateRef.current) {\n // If not allowEmpty, don’t allow submitting an empty item\n if (!allowEmptyRef.current) return;\n // If we have an input element as trigger & the user didn’t clear the text, do nothing\n if (inputElementRef.current?.value) return;\n }\n\n let itemLabel = element?.innerText ?? '';\n if (inputElementRef.current) {\n if (!element) {\n itemLabel = inputElementRef.current.value;\n } else {\n inputElementRef.current.value = itemLabel;\n }\n\n if (\n inputElementRef.current ===\n inputElementRef.current.ownerDocument.activeElement\n ) {\n inputElementRef.current.blur();\n }\n }\n\n const nextValue = element?.dataset.uktValue ?? itemLabel;\n // If parent is controlling Dropdown via props.value and nextValue is the same, do nothing\n if (valueRef.current && valueRef.current === nextValue) return;\n\n // If the item is clickable or contains exactly one clickable element, invoke it\n // (but only if the event didn’t already originate from that element)\n if (element) {\n const eventTarget = event.target as HTMLElement;\n\n if (element.matches(CLICKABLE_SELECTOR)) {\n // The item element itself is clickable (e.g., <button data-ukt-value=\"…\">)\n if (element !== eventTarget && !element.contains(eventTarget)) {\n element.click();\n }\n } else {\n // Check if item contains exactly one clickable child element\n const clickableElements = element.querySelectorAll(CLICKABLE_SELECTOR);\n if (clickableElements.length === 1) {\n const clickableElement = clickableElements[0] as HTMLElement;\n if (\n clickableElement !== eventTarget &&\n !clickableElement.contains(eventTarget)\n ) {\n clickableElement.click();\n }\n }\n }\n }\n\n onSubmitItemRef.current?.({\n element,\n event,\n label: itemLabel,\n value: nextValue,\n });\n };\n\n const handleMouseMove = ({ clientX, clientY }: ReactMouseEvent<HTMLElement>) => {\n currentInputMethodRef.current = 'mouse';\n const initialPosition = mouseDownPositionRef.current;\n if (!initialPosition) return;\n if (\n Math.abs(initialPosition.clientX - clientX) < 12 &&\n Math.abs(initialPosition.clientY - clientY) < 12\n ) {\n return;\n }\n setIsOpening(false);\n };\n\n const handleMouseOver = (event: ReactMouseEvent<HTMLElement>) => {\n if (!hasItemsRef.current) return;\n\n // If user isn’t currently using the mouse to navigate the dropdown, do nothing\n if (currentInputMethodRef.current !== 'mouse') return;\n\n // Ensure we have the dropdown root HTMLElement\n if (!dropdownElement) return;\n\n const itemElements = getItemElements(dropdownElement);\n if (!itemElements) return;\n\n const eventTarget = event.target as HTMLElement;\n const item = eventTarget.closest(ITEM_SELECTOR) as MaybeHTMLElement;\n const element = item ?? eventTarget;\n for (const itemElement of itemElements) {\n if (itemElement === element) {\n setActiveItem({ dropdownElement, element, event, onActiveItem });\n return;\n }\n }\n };\n\n const handleMouseOut = (event: ReactMouseEvent<HTMLElement>) => {\n if (!hasItemsRef.current) return;\n const activeItem = getActiveItemElement(dropdownElement);\n if (!activeItem) return;\n const eventRelatedTarget = event.relatedTarget as HTMLElement;\n if (activeItem !== event.target || activeItem.contains(eventRelatedTarget)) {\n return;\n }\n // If user moused out of activeItem (not into a descendant), it’s no longer active\n delete activeItem.dataset.uktActive;\n };\n\n const handleMouseDown = (event: ReactMouseEvent<HTMLElement>) => {\n if (onMouseDown) onMouseDown(event);\n if (isOpenRef.current) return;\n\n setIsOpen(true);\n setIsOpening(true);\n mouseDownPositionRef.current = {\n clientX: event.clientX,\n clientY: event.clientY,\n };\n isOpeningTimerRef.current = setTimeout(() => {\n setIsOpening(false);\n isOpeningTimerRef.current = null;\n }, 1000);\n };\n\n const handleMouseUp = (event: ReactMouseEvent<HTMLElement>) => {\n if (onMouseUp) onMouseUp(event);\n // If dropdown is still opening or isn’t open or is closing, do nothing\n if (\n isOpeningRef.current ||\n !isOpenRef.current ||\n closingTimerRef.current != null\n ) {\n return;\n }\n\n const eventTarget = event.target as HTMLElement;\n // If click was outside dropdown body, don’t trigger submit\n if (!eventTarget.closest('.uktdropdown-body')) {\n // Don’t close dropdown if isOpening or search input is focused\n if (\n !isOpeningRef.current &&\n inputElementRef.current !== eventTarget.ownerDocument.activeElement\n ) {\n closeDropdown();\n }\n return;\n }\n\n // If dropdown has no items and click was within dropdown body, do nothing\n if (!hasItemsRef.current) return;\n\n handleSubmitItem(event);\n };\n\n const handleKeyDown = (event: KeyboardEvent) => {\n const { altKey, ctrlKey, key, metaKey } = event;\n const eventTarget = event.target as HTMLElement;\n if (!dropdownElement) return;\n\n const onEventHandled = () => {\n event.stopPropagation();\n event.preventDefault();\n currentInputMethodRef.current = 'keyboard';\n };\n\n const isEventTargetingDropdown = dropdownElement.contains(eventTarget);\n\n if (!isOpenRef.current) {\n // If dropdown is closed, don’t handle key events if event target isn’t within dropdown\n if (!isEventTargetingDropdown) return;\n // Open the dropdown on spacebar, enter, or if isSearchable and user hits the ↑/↓ arrows\n if (\n key === ' ' ||\n key === 'Enter' ||\n (hasItemsRef.current && (key === 'ArrowUp' || key === 'ArrowDown'))\n ) {\n onEventHandled();\n setIsOpen(true);\n }\n return;\n }\n\n const isTargetUsingKeyEvents = isEventTargetUsingKeyEvent(event);\n\n // If dropdown isOpen + hasItems & eventTargetNotUsingKeyEvents, handle characters\n if (hasItemsRef.current && !isTargetUsingKeyEvents) {\n let isEditingCharacters = !ctrlKey && !metaKey && /^[A-Za-z0-9]$/.test(key);\n // User could also be editing characters if there are already characters entered\n // and they are hitting delete or spacebar\n if (!isEditingCharacters && enteredCharactersRef.current) {\n isEditingCharacters = key === ' ' || key === 'Backspace';\n }\n\n if (isEditingCharacters) {\n onEventHandled();\n if (key === 'Backspace') {\n enteredCharactersRef.current = enteredCharactersRef.current.slice(\n 0,\n -1,\n );\n } else {\n enteredCharactersRef.current += key;\n }\n\n setActiveItem({\n dropdownElement,\n event,\n // If props.allowCreate, only override the input’s value with an\n // exact text match so user can enter a value not in items\n isExactMatch: allowCreateRef.current,\n onActiveItem,\n text: enteredCharactersRef.current,\n });\n\n if (clearEnteredCharactersTimerRef.current != null) {\n clearTimeout(clearEnteredCharactersTimerRef.current);\n }\n\n clearEnteredCharactersTimerRef.current = setTimeout(() => {\n enteredCharactersRef.current = '';\n clearEnteredCharactersTimerRef.current = null;\n }, 1500);\n\n return;\n }\n }\n\n // If dropdown isOpen, handle submitting the value\n if (key === 'Enter' || (key === ' ' && !inputElementRef.current)) {\n onEventHandled();\n handleSubmitItem(event);\n return;\n }\n\n // If dropdown isOpen, handle closing it on escape or spacebar if !hasItems\n if (\n key === 'Escape' ||\n (isEventTargetingDropdown && key === ' ' && !hasItemsRef.current)\n ) {\n // Close dropdown if hasItems or event target not using key events\n if (hasItemsRef.current || !isTargetUsingKeyEvents) {\n closeDropdown();\n }\n return;\n }\n\n // Handle ↑/↓ arrows\n if (hasItemsRef.current) {\n if (key === 'ArrowUp') {\n onEventHandled();\n if (altKey || metaKey) {\n setActiveItem({ dropdownElement, event, index: 0, onActiveItem });\n } else {\n setActiveItem({\n dropdownElement,\n event,\n indexAddend: -1,\n onActiveItem,\n });\n }\n return;\n }\n if (key === 'ArrowDown') {\n onEventHandled();\n if (altKey || metaKey) {\n // Using a negative index counts back from the end\n setActiveItem({ dropdownElement, event, index: -1, onActiveItem });\n } else {\n setActiveItem({\n dropdownElement,\n event,\n indexAddend: 1,\n onActiveItem,\n });\n }\n return;\n }\n }\n };\n\n useKeyboardEvents({ ignoreUsedKeyboardEvents: false, onKeyDown: handleKeyDown });\n\n const handleRef = (ref: HTMLDivElement | null): (() => void) | void => {\n setDropdownElement(ref);\n if (!ref) return;\n\n const { ownerDocument } = ref;\n let inputElement = inputElementRef.current;\n // Check if trigger is a textual input or textarea element\n if (!inputElement && ref.firstElementChild) {\n if (ref.firstElementChild.matches(TEXT_INPUT_SELECTOR)) {\n inputElement = ref.firstElementChild as HTMLInputElement;\n } else {\n inputElement = ref.firstElementChild.querySelector(TEXT_INPUT_SELECTOR);\n }\n inputElementRef.current = inputElement;\n }\n\n const handleGlobalMouseDown = ({ target }: MouseEvent) => {\n const eventTarget = target as HTMLElement;\n if (!ref.contains(eventTarget)) {\n // Close dropdown on an outside click\n closeDropdown();\n }\n };\n\n const handleGlobalMouseUp = ({ target }: MouseEvent) => {\n if (!isOpenRef.current || closingTimerRef.current != null) return;\n\n // If still isOpening (gets set false 1s after open triggers), set it to false onMouseUp\n if (isOpeningRef.current) {\n setIsOpening(false);\n if (isOpeningTimerRef.current != null) {\n clearTimeout(isOpeningTimerRef.current);\n isOpeningTimerRef.current = null;\n }\n return;\n }\n\n const eventTarget = target as HTMLElement;\n // Only handle mouseup events from outside the dropdown here\n if (!ref.contains(eventTarget)) {\n closeDropdown();\n }\n };\n\n // Close dropdown if any element is focused outside of this dropdown\n const handleGlobalFocusIn = ({ target }: Event) => {\n if (!isOpenRef.current) return;\n\n const eventTarget = target as HTMLElement;\n // If focused element is a descendant or a parent of the dropdown, do nothing\n if (ref.contains(eventTarget) || eventTarget.contains(ref)) {\n return;\n }\n\n closeDropdown();\n };\n\n document.addEventListener('focusin', handleGlobalFocusIn);\n document.addEventListener('mousedown', handleGlobalMouseDown);\n document.addEventListener('mouseup', handleGlobalMouseUp);\n\n if (ownerDocument !== document) {\n ownerDocument.addEventListener('focusin', handleGlobalFocusIn);\n ownerDocument.addEventListener('mousedown', handleGlobalMouseDown);\n ownerDocument.addEventListener('mouseup', handleGlobalMouseUp);\n }\n\n // If dropdown should be open on mount, focus it\n if (isOpenOnMount) {\n ref.focus();\n }\n\n const handleInput = (event: Event) => {\n if (!isOpenRef.current) setIsOpen(true);\n\n const input = event.target as HTMLInputElement;\n const isDeleting = enteredCharactersRef.current.length > input.value.length;\n enteredCharactersRef.current = input.value;\n // When deleting text, if there’s already an active item and\n // input isn’t empty, preserve the active item, else update it\n if (isDeleting && input.value.length && getActiveItemElement(ref)) {\n return;\n }\n\n setActiveItem({\n dropdownElement: ref,\n event,\n // If props.allowCreate, only override the input’s value with an\n // exact text match so user can enter a value not in items\n isExactMatch: allowCreateRef.current,\n onActiveItem,\n text: enteredCharactersRef.current,\n });\n };\n\n if (inputElement) {\n inputElement.addEventListener('input', handleInput);\n }\n\n return () => {\n document.removeEventListener('focusin', handleGlobalFocusIn);\n document.removeEventListener('mousedown', handleGlobalMouseDown);\n document.removeEventListener('mouseup', handleGlobalMouseUp);\n\n if (ownerDocument !== document) {\n ownerDocument.removeEventListener('focusin', handleGlobalFocusIn);\n ownerDocument.removeEventListener('mousedown', handleGlobalMouseDown);\n ownerDocument.removeEventListener('mouseup', handleGlobalMouseUp);\n }\n\n if (inputElement) {\n inputElement.removeEventListener('input', handleInput);\n }\n };\n };\n\n if (!isValidElement(trigger)) {\n if (isSearchable) {\n trigger = (\n <input\n autoComplete=\"off\"\n className=\"uktdropdown-trigger\"\n defaultValue={value ?? ''}\n disabled={disabled}\n name={name}\n onFocus={() => setIsOpen(true)}\n placeholder={placeholder}\n ref={inputElementRef}\n tabIndex={tabIndex}\n type=\"text\"\n />\n );\n } else {\n trigger = (\n <button className=\"uktdropdown-trigger\" tabIndex={0} type=\"button\">\n {trigger}\n </button>\n );\n }\n }\n\n if (label != null) {\n trigger = (\n <label className=\"uktdropdown-label\">\n <div className=\"uktdropdown-label-text\">{label}</div>\n {trigger}\n </label>\n );\n }\n\n const style = {\n ...styleFromProps,\n ...(minHeightBody != null && minHeightBody > 0\n ? { '--uktdd-body-min-height': `${minHeightBody}px` }\n : null),\n ...(minWidthBody != null && minWidthBody > 0\n ? { '--uktdd-body-min-width': `${minWidthBody}px` }\n : null),\n };\n\n return (\n <Fragment>\n <style href=\"@acusti/dropdown/Dropdown\" precedence=\"medium\">\n {styles}\n </style>\n <div\n className={clsx('uktdropdown', className, {\n disabled,\n 'is-open': isOpen,\n 'is-searchable': isSearchable,\n })}\n onClick={onClick}\n onMouseDown={handleMouseDown}\n onMouseMove={handleMouseMove}\n onMouseOut={handleMouseOut}\n onMouseOver={handleMouseOver}\n onMouseUp={handleMouseUp}\n ref={handleRef}\n style={style}\n >\n {trigger}\n {/* TODO next version of Dropdown should use <Activity> for body https://react.dev/reference/react/Activity */}\n {isOpen ? (\n <div\n className={clsx('uktdropdown-body', {\n 'has-items': hasItems,\n })}\n >\n <div className=\"uktdropdown-content\">\n {childrenCount > 1\n ? (children as ChildrenTuple)[1]\n : children}\n </div>\n </div>\n ) : null}\n </div>\n </Fragment>\n );\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,45 +1,51 @@
1
1
  {
2
2
  "name": "@acusti/dropdown",
3
- "version": "0.54.1",
4
- "type": "module",
5
- "sideEffects": false,
6
- "exports": "./dist/Dropdown.js",
7
- "main": "./dist/Dropdown.js",
8
- "types": "./dist/Dropdown.d.ts",
9
- "files": [
10
- "dist"
11
- ],
3
+ "version": "0.55.1",
12
4
  "description": "React component that renders a dropdown with a trigger and supports searching, keyboard access, and more",
13
5
  "keywords": [
14
- "react",
15
- "react-component",
16
- "dropdown",
17
- "menu",
18
- "combobox",
19
- "search",
20
- "typeahead",
21
6
  "a11y",
22
7
  "accessibility",
8
+ "combobox",
9
+ "dropdown",
23
10
  "key-navigation",
11
+ "menu",
12
+ "react",
13
+ "react-component",
14
+ "search",
24
15
  "ssr",
25
- "typescript",
26
- "ts"
16
+ "ts",
17
+ "typeahead",
18
+ "typescript"
27
19
  ],
28
- "scripts": {
29
- "test": "vitest",
30
- "build": "vite build"
20
+ "homepage": "https://github.com/acusti/uikit/tree/main/packages/dropdown#readme",
21
+ "bugs": {
22
+ "url": "https://github.com/acusti/uikit/issues"
31
23
  },
24
+ "license": "Unlicense",
25
+ "author": "andrew patton <andrew@acusti.ca> (https://www.acusti.ca)",
32
26
  "repository": {
33
27
  "type": "git",
34
28
  "url": "https://github.com/acusti/uikit.git",
35
29
  "directory": "packages/dropdown"
36
30
  },
37
- "author": "andrew patton <andrew@acusti.ca> (https://www.acusti.ca)",
38
- "license": "Unlicense",
39
- "bugs": {
40
- "url": "https://github.com/acusti/uikit/issues"
31
+ "files": [
32
+ "dist"
33
+ ],
34
+ "type": "module",
35
+ "sideEffects": false,
36
+ "main": "./dist/Dropdown.js",
37
+ "types": "./dist/Dropdown.d.ts",
38
+ "exports": "./dist/Dropdown.js",
39
+ "scripts": {
40
+ "test": "vitest",
41
+ "build": "vite build",
42
+ "tsc": "tsc --noEmit"
43
+ },
44
+ "dependencies": {
45
+ "@acusti/matchmaking": "^0.10.0",
46
+ "@acusti/use-keyboard-events": "^0.11.0",
47
+ "clsx": "^2"
41
48
  },
42
- "homepage": "https://github.com/acusti/uikit/tree/main/packages/dropdown#readme",
43
49
  "devDependencies": {
44
50
  "@testing-library/dom": "^10.4.1",
45
51
  "@testing-library/react": "^16.3.2",
@@ -55,12 +61,6 @@
55
61
  "vite": "^8.0.0-0",
56
62
  "vitest": "^4"
57
63
  },
58
- "dependencies": {
59
- "@acusti/matchmaking": "^0.10.0",
60
- "@acusti/use-bounding-client-rect": "^2.0.1",
61
- "@acusti/use-keyboard-events": "^0.11.0",
62
- "clsx": "^2"
63
- },
64
64
  "peerDependencies": {
65
65
  "react": "^19 || ~0.0.0-experimental < 0.0.0-f",
66
66
  "react-dom": "^19 || ~0.0.0-experimental < 0.0.0-f"