@acusti/dropdown 0.54.0 → 0.55.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -5
- package/dist/Dropdown.d.ts +1 -1
- package/dist/Dropdown.js +77 -103
- package/dist/Dropdown.js.map +1 -1
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
[](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
|
|
10
|
-
|
|
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
|
|
162
|
+
* Label content for the trigger button (when using single child syntax).
|
|
130
163
|
*/
|
|
131
|
-
label?:
|
|
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.d.ts
CHANGED
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
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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;scrollbar-gutter:stable;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
|
-
|
|
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
|
-
|
|
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,11 +93,13 @@ 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(
|
|
102
|
+
const $ = c(82);
|
|
99
103
|
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;
|
|
100
104
|
const allowEmpty = t1 === void 0 ? true : t1;
|
|
101
105
|
const hasItems = t2 === void 0 ? true : t2;
|
|
@@ -111,7 +115,6 @@ function Dropdown(t0) {
|
|
|
111
115
|
const [isOpen, setIsOpen] = useState(isOpenOnMount ?? false);
|
|
112
116
|
const [isOpening, setIsOpening] = useState(!isOpenOnMount);
|
|
113
117
|
const [dropdownElement, setDropdownElement] = useState(null);
|
|
114
|
-
const [dropdownBodyElement, setDropdownBodyElement] = useState(null);
|
|
115
118
|
const inputElementRef = useRef(null);
|
|
116
119
|
const closingTimerRef = useRef(null);
|
|
117
120
|
const isOpeningTimerRef = useRef(null);
|
|
@@ -565,7 +568,7 @@ function Dropdown(t0) {
|
|
|
565
568
|
} else t19 = $[46];
|
|
566
569
|
trigger = t19;
|
|
567
570
|
}
|
|
568
|
-
if (label) {
|
|
571
|
+
if (label != null) {
|
|
569
572
|
let t19;
|
|
570
573
|
if ($[47] !== label) {
|
|
571
574
|
t19 = /* @__PURE__ */ jsx("div", {
|
|
@@ -587,94 +590,72 @@ function Dropdown(t0) {
|
|
|
587
590
|
} else t20 = $[51];
|
|
588
591
|
trigger = t20;
|
|
589
592
|
}
|
|
590
|
-
const dropdownRect = useBoundingClientRect(dropdownElement);
|
|
591
|
-
const dropdownBodyRect = useBoundingClientRect(dropdownBodyElement);
|
|
592
593
|
let t19;
|
|
593
|
-
if ($[52] !==
|
|
594
|
-
t19 =
|
|
595
|
-
$[52] =
|
|
594
|
+
if ($[52] !== minHeightBody) {
|
|
595
|
+
t19 = minHeightBody != null && minHeightBody > 0 ? { "--uktdd-body-min-height": `${minHeightBody}px` } : null;
|
|
596
|
+
$[52] = minHeightBody;
|
|
596
597
|
$[53] = t19;
|
|
597
598
|
} 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
|
-
}
|
|
614
599
|
let t20;
|
|
615
|
-
if ($[
|
|
616
|
-
t20 =
|
|
617
|
-
$[
|
|
618
|
-
$[
|
|
619
|
-
|
|
620
|
-
} else t20 = $[61];
|
|
600
|
+
if ($[54] !== minWidthBody) {
|
|
601
|
+
t20 = minWidthBody != null && minWidthBody > 0 ? { "--uktdd-body-min-width": `${minWidthBody}px` } : null;
|
|
602
|
+
$[54] = minWidthBody;
|
|
603
|
+
$[55] = t20;
|
|
604
|
+
} else t20 = $[55];
|
|
621
605
|
let t21;
|
|
622
|
-
if ($[
|
|
623
|
-
t21 =
|
|
624
|
-
$[62] = minWidthBody;
|
|
625
|
-
$[63] = t21;
|
|
626
|
-
} else t21 = $[63];
|
|
627
|
-
let t22;
|
|
628
|
-
if ($[64] !== styleFromProps || $[65] !== t20 || $[66] !== t21) {
|
|
629
|
-
t22 = {
|
|
606
|
+
if ($[56] !== styleFromProps || $[57] !== t19 || $[58] !== t20) {
|
|
607
|
+
t21 = {
|
|
630
608
|
...styleFromProps,
|
|
631
|
-
...
|
|
632
|
-
...
|
|
609
|
+
...t19,
|
|
610
|
+
...t20
|
|
633
611
|
};
|
|
634
|
-
$[
|
|
635
|
-
$[
|
|
636
|
-
$[
|
|
637
|
-
$[
|
|
638
|
-
} else
|
|
639
|
-
const style =
|
|
640
|
-
let
|
|
641
|
-
if ($[
|
|
642
|
-
|
|
612
|
+
$[56] = styleFromProps;
|
|
613
|
+
$[57] = t19;
|
|
614
|
+
$[58] = t20;
|
|
615
|
+
$[59] = t21;
|
|
616
|
+
} else t21 = $[59];
|
|
617
|
+
const style = t21;
|
|
618
|
+
let t22;
|
|
619
|
+
if ($[60] === Symbol.for("react.memo_cache_sentinel")) {
|
|
620
|
+
t22 = /* @__PURE__ */ jsx("style", {
|
|
643
621
|
href: "@acusti/dropdown/Dropdown",
|
|
644
622
|
precedence: "medium",
|
|
645
623
|
children: Dropdown_default
|
|
646
624
|
});
|
|
647
|
-
$[
|
|
648
|
-
} else
|
|
649
|
-
let
|
|
650
|
-
if ($[
|
|
651
|
-
|
|
625
|
+
$[60] = t22;
|
|
626
|
+
} else t22 = $[60];
|
|
627
|
+
let t23;
|
|
628
|
+
if ($[61] !== className || $[62] !== disabled || $[63] !== isOpen || $[64] !== isSearchable) {
|
|
629
|
+
t23 = clsx("uktdropdown", className, {
|
|
652
630
|
disabled,
|
|
653
631
|
"is-open": isOpen,
|
|
654
632
|
"is-searchable": isSearchable
|
|
655
633
|
});
|
|
656
|
-
$[
|
|
657
|
-
$[
|
|
658
|
-
$[
|
|
659
|
-
$[
|
|
660
|
-
$[
|
|
661
|
-
} else
|
|
662
|
-
let
|
|
663
|
-
if ($[
|
|
664
|
-
|
|
665
|
-
className: "uktdropdown-body",
|
|
666
|
-
|
|
667
|
-
|
|
634
|
+
$[61] = className;
|
|
635
|
+
$[62] = disabled;
|
|
636
|
+
$[63] = isOpen;
|
|
637
|
+
$[64] = isSearchable;
|
|
638
|
+
$[65] = t23;
|
|
639
|
+
} else t23 = $[65];
|
|
640
|
+
let t24;
|
|
641
|
+
if ($[66] !== children || $[67] !== childrenCount || $[68] !== hasItems || $[69] !== isOpen) {
|
|
642
|
+
t24 = isOpen ? /* @__PURE__ */ jsx("div", {
|
|
643
|
+
className: clsx("uktdropdown-body", { "has-items": hasItems }),
|
|
644
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
645
|
+
className: "uktdropdown-content",
|
|
646
|
+
children: childrenCount > 1 ? children[1] : children
|
|
647
|
+
})
|
|
668
648
|
}) : null;
|
|
669
|
-
$[
|
|
670
|
-
$[
|
|
671
|
-
$[
|
|
672
|
-
$[
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
649
|
+
$[66] = children;
|
|
650
|
+
$[67] = childrenCount;
|
|
651
|
+
$[68] = hasItems;
|
|
652
|
+
$[69] = isOpen;
|
|
653
|
+
$[70] = t24;
|
|
654
|
+
} else t24 = $[70];
|
|
655
|
+
let t25;
|
|
656
|
+
if ($[71] !== handleMouseDown || $[72] !== handleMouseOut || $[73] !== handleMouseOver || $[74] !== handleMouseUp || $[75] !== handleRef || $[76] !== onClick || $[77] !== style || $[78] !== t23 || $[79] !== t24 || $[80] !== trigger) {
|
|
657
|
+
t25 = /* @__PURE__ */ jsxs(Fragment, { children: [t22, /* @__PURE__ */ jsxs("div", {
|
|
658
|
+
className: t23,
|
|
678
659
|
onClick,
|
|
679
660
|
onMouseDown: handleMouseDown,
|
|
680
661
|
onMouseMove: handleMouseMove,
|
|
@@ -683,30 +664,23 @@ function Dropdown(t0) {
|
|
|
683
664
|
onMouseUp: handleMouseUp,
|
|
684
665
|
ref: handleRef,
|
|
685
666
|
style,
|
|
686
|
-
children: [trigger,
|
|
667
|
+
children: [trigger, t24]
|
|
687
668
|
})] });
|
|
688
|
-
$[
|
|
689
|
-
$[
|
|
690
|
-
$[
|
|
691
|
-
$[
|
|
692
|
-
$[
|
|
693
|
-
$[
|
|
694
|
-
$[
|
|
695
|
-
$[
|
|
696
|
-
$[
|
|
697
|
-
$[
|
|
698
|
-
$[
|
|
699
|
-
} else
|
|
700
|
-
return
|
|
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;
|
|
669
|
+
$[71] = handleMouseDown;
|
|
670
|
+
$[72] = handleMouseOut;
|
|
671
|
+
$[73] = handleMouseOver;
|
|
672
|
+
$[74] = handleMouseUp;
|
|
673
|
+
$[75] = handleRef;
|
|
674
|
+
$[76] = onClick;
|
|
675
|
+
$[77] = style;
|
|
676
|
+
$[78] = t23;
|
|
677
|
+
$[79] = t24;
|
|
678
|
+
$[80] = trigger;
|
|
679
|
+
$[81] = t25;
|
|
680
|
+
} else t25 = $[81];
|
|
681
|
+
return t25;
|
|
709
682
|
}
|
|
683
|
+
//#endregion
|
|
710
684
|
export { Dropdown as default };
|
|
711
685
|
|
|
712
686
|
//# sourceMappingURL=Dropdown.js.map
|
package/dist/Dropdown.js.map
CHANGED
|
@@ -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?: string;\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) {\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":"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"}
|
|
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","t4","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","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","t22","t23","t24","t25"],"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 scrollbar-gutter: stable;\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 = 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 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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@acusti/dropdown",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.55.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"exports": "./dist/Dropdown.js",
|
|
@@ -27,7 +27,8 @@
|
|
|
27
27
|
],
|
|
28
28
|
"scripts": {
|
|
29
29
|
"test": "vitest",
|
|
30
|
-
"build": "vite build"
|
|
30
|
+
"build": "vite build",
|
|
31
|
+
"tsc": "tsc --noEmit"
|
|
31
32
|
},
|
|
32
33
|
"repository": {
|
|
33
34
|
"type": "git",
|
|
@@ -57,7 +58,6 @@
|
|
|
57
58
|
},
|
|
58
59
|
"dependencies": {
|
|
59
60
|
"@acusti/matchmaking": "^0.10.0",
|
|
60
|
-
"@acusti/use-bounding-client-rect": "^2.0.1",
|
|
61
61
|
"@acusti/use-keyboard-events": "^0.11.0",
|
|
62
62
|
"clsx": "^2"
|
|
63
63
|
},
|