@mieweb/ui 0.8.0-dev.0 → 0.8.0-dev.2
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 +162 -739
- package/agent/mieweb-ui.instructions.md +34 -16
- package/dist/{chunk-IILJGFI5.js → chunk-2AB4PQYL.js} +3 -3
- package/dist/{chunk-IILJGFI5.js.map → chunk-2AB4PQYL.js.map} +1 -1
- package/dist/{chunk-SK7H3Z67.cjs → chunk-2PEVRI26.cjs} +8 -8
- package/dist/{chunk-SK7H3Z67.cjs.map → chunk-2PEVRI26.cjs.map} +1 -1
- package/dist/{chunk-JHGMZX4I.cjs → chunk-2SSAAE3I.cjs} +4 -4
- package/dist/{chunk-JHGMZX4I.cjs.map → chunk-2SSAAE3I.cjs.map} +1 -1
- package/dist/{chunk-LQHI44OZ.cjs → chunk-3RADKLLD.cjs} +5 -5
- package/dist/{chunk-LQHI44OZ.cjs.map → chunk-3RADKLLD.cjs.map} +1 -1
- package/dist/{chunk-L6D4CKLV.cjs → chunk-5BPUZK2B.cjs} +15 -2
- package/dist/chunk-5BPUZK2B.cjs.map +1 -0
- package/dist/{chunk-XWYKLEKG.js → chunk-6GKX36JX.js} +3 -3
- package/dist/{chunk-XWYKLEKG.js.map → chunk-6GKX36JX.js.map} +1 -1
- package/dist/{chunk-ELYGV32O.cjs → chunk-AHHFFXJR.cjs} +4 -4
- package/dist/{chunk-ELYGV32O.cjs.map → chunk-AHHFFXJR.cjs.map} +1 -1
- package/dist/{chunk-LZU7YBXG.js → chunk-AHUYW673.js} +167 -8
- package/dist/chunk-AHUYW673.js.map +1 -0
- package/dist/{chunk-MYFZYUPR.cjs → chunk-AOHJILLU.cjs} +38 -3
- package/dist/chunk-AOHJILLU.cjs.map +1 -0
- package/dist/{chunk-XBKOZRDO.js → chunk-ATOWMVZH.js} +3 -3
- package/dist/{chunk-XBKOZRDO.js.map → chunk-ATOWMVZH.js.map} +1 -1
- package/dist/{chunk-4PIW3Y5M.js → chunk-DJ4JPFWI.js} +3 -3
- package/dist/{chunk-4PIW3Y5M.js.map → chunk-DJ4JPFWI.js.map} +1 -1
- package/dist/{chunk-FDV7EQWH.js → chunk-EK6DYGFG.js} +3 -3
- package/dist/{chunk-FDV7EQWH.js.map → chunk-EK6DYGFG.js.map} +1 -1
- package/dist/{chunk-IYXCFIMP.js → chunk-F2S6NV5N.js} +4 -4
- package/dist/{chunk-IYXCFIMP.js.map → chunk-F2S6NV5N.js.map} +1 -1
- package/dist/{chunk-26DPQUSB.cjs → chunk-G52YRAJC.cjs} +4 -4
- package/dist/{chunk-26DPQUSB.cjs.map → chunk-G52YRAJC.cjs.map} +1 -1
- package/dist/{chunk-QHTDWIED.js → chunk-JQQABHDN.js} +3 -3
- package/dist/{chunk-QHTDWIED.js.map → chunk-JQQABHDN.js.map} +1 -1
- package/dist/{chunk-7L7OPISJ.cjs → chunk-JR4QIU54.cjs} +4 -4
- package/dist/{chunk-7L7OPISJ.cjs.map → chunk-JR4QIU54.cjs.map} +1 -1
- package/dist/{chunk-56QJHQ5C.cjs → chunk-K5GQPTTA.cjs} +4 -4
- package/dist/{chunk-56QJHQ5C.cjs.map → chunk-K5GQPTTA.cjs.map} +1 -1
- package/dist/{chunk-XMECP2MD.js → chunk-KFEN2SRZ.js} +3 -3
- package/dist/{chunk-XMECP2MD.js.map → chunk-KFEN2SRZ.js.map} +1 -1
- package/dist/{chunk-RYQ3S3KO.cjs → chunk-LDCFNWJC.cjs} +5 -5
- package/dist/{chunk-RYQ3S3KO.cjs.map → chunk-LDCFNWJC.cjs.map} +1 -1
- package/dist/{chunk-A5YOIJKL.js → chunk-LDQ2T27A.js} +3 -3
- package/dist/{chunk-A5YOIJKL.js.map → chunk-LDQ2T27A.js.map} +1 -1
- package/dist/{chunk-SPWVKDGC.cjs → chunk-QMKYJ4AT.cjs} +4 -4
- package/dist/{chunk-SPWVKDGC.cjs.map → chunk-QMKYJ4AT.cjs.map} +1 -1
- package/dist/{chunk-BOW7ZGI2.cjs → chunk-QOJ4V7YX.cjs} +168 -8
- package/dist/chunk-QOJ4V7YX.cjs.map +1 -0
- package/dist/{chunk-QGZC43L7.js → chunk-SVZ4MQVQ.js} +3 -3
- package/dist/{chunk-QGZC43L7.js.map → chunk-SVZ4MQVQ.js.map} +1 -1
- package/dist/{chunk-KVE7PQ5P.cjs → chunk-TQZPYDUL.cjs} +7 -7
- package/dist/{chunk-KVE7PQ5P.cjs.map → chunk-TQZPYDUL.cjs.map} +1 -1
- package/dist/{chunk-EKRT7K2K.js → chunk-UJS3JTVT.js} +3 -3
- package/dist/{chunk-EKRT7K2K.js.map → chunk-UJS3JTVT.js.map} +1 -1
- package/dist/{chunk-AESFOMSH.js → chunk-VQ5HJCTP.js} +15 -2
- package/dist/chunk-VQ5HJCTP.js.map +1 -0
- package/dist/{chunk-BOOJDRJO.js → chunk-WSNMQQ4P.js} +38 -3
- package/dist/chunk-WSNMQQ4P.js.map +1 -0
- package/dist/{chunk-U5TTXN45.cjs → chunk-YRLCR76L.cjs} +4 -4
- package/dist/{chunk-U5TTXN45.cjs.map → chunk-YRLCR76L.cjs.map} +1 -1
- package/dist/components/Autocomplete/index.cjs +3 -3
- package/dist/components/Autocomplete/index.js +2 -2
- package/dist/components/CountryCodeDropdown/index.cjs +5 -5
- package/dist/components/CountryCodeDropdown/index.js +2 -2
- package/dist/components/DateInput/index.cjs +3 -3
- package/dist/components/DateInput/index.js +2 -2
- package/dist/components/Dropdown/index.cjs +12 -8
- package/dist/components/Dropdown/index.d.cts +38 -2
- package/dist/components/Dropdown/index.d.ts +38 -2
- package/dist/components/Dropdown/index.js +2 -2
- package/dist/components/GlossaryTooltip/index.cjs +3 -3
- package/dist/components/GlossaryTooltip/index.js +2 -2
- package/dist/components/MediaEditor/index.cjs +8 -8
- package/dist/components/MediaEditor/index.js +3 -3
- package/dist/components/RichTextEditor/index.cjs +6 -6
- package/dist/components/RichTextEditor/index.js +3 -3
- package/dist/components/Select/index.cjs +4 -4
- package/dist/components/Select/index.js +2 -2
- package/dist/components/SourceTip/index.cjs +3 -3
- package/dist/components/SourceTip/index.js +2 -2
- package/dist/components/SuperChat/index.cjs +249 -91
- package/dist/components/SuperChat/index.cjs.map +1 -1
- package/dist/components/SuperChat/index.d.cts +13 -5
- package/dist/components/SuperChat/index.d.ts +13 -5
- package/dist/components/SuperChat/index.js +246 -88
- package/dist/components/SuperChat/index.js.map +1 -1
- package/dist/components/SuperChat/plugins/index.cjs +4 -4
- package/dist/components/SuperChat/plugins/index.d.cts +2 -2
- package/dist/components/SuperChat/plugins/index.d.ts +2 -2
- package/dist/components/SuperChat/plugins/index.js +3 -3
- package/dist/esheet.cjs +7 -7
- package/dist/esheet.js +4 -4
- package/dist/hooks/index.cjs +2 -2
- package/dist/hooks/index.d.cts +1 -1
- package/dist/hooks/index.d.ts +1 -1
- package/dist/hooks/index.js +1 -1
- package/dist/index.cjs +178 -174
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +22 -22
- package/dist/styles.css +1 -1
- package/dist/tailwind-preset.cjs +4 -4
- package/dist/tailwind-preset.js +1 -1
- package/dist/{types-BoTeTPdH.d.ts → types-9vK_YdEb.d.ts} +12 -1
- package/dist/{types-DyIB9HYT.d.cts → types-DZDroUW8.d.cts} +12 -1
- package/dist/{useAnchoredPosition-C7PNglzD.d.cts → useAnchoredPosition-CKwLSQW8.d.cts} +10 -3
- package/dist/{useAnchoredPosition-C7PNglzD.d.ts → useAnchoredPosition-CKwLSQW8.d.ts} +10 -3
- package/package.json +5 -2
- package/dist/chunk-AESFOMSH.js.map +0 -1
- package/dist/chunk-BOOJDRJO.js.map +0 -1
- package/dist/chunk-BOW7ZGI2.cjs.map +0 -1
- package/dist/chunk-L6D4CKLV.cjs.map +0 -1
- package/dist/chunk-LZU7YBXG.js.map +0 -1
- package/dist/chunk-MYFZYUPR.cjs.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { inputVariants } from './chunk-3IMM2PM4.js';
|
|
2
2
|
import { useEscapeKey } from './chunk-T4ME7QCT.js';
|
|
3
3
|
import { useClickOutside } from './chunk-62ZOA6PX.js';
|
|
4
|
-
import { useAnchoredPosition } from './chunk-
|
|
4
|
+
import { useAnchoredPosition } from './chunk-WSNMQQ4P.js';
|
|
5
5
|
import { cn } from './chunk-TQONQSJO.js';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
8
|
+
import { ChevronRight } from 'lucide-react';
|
|
8
9
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
9
10
|
|
|
10
11
|
var placementOffset = 8;
|
|
@@ -116,6 +117,20 @@ function filterDropdownChildren(children, query) {
|
|
|
116
117
|
].filter(Boolean).join(" ").toLowerCase();
|
|
117
118
|
return searchText.includes(normalizedQuery) ? child : null;
|
|
118
119
|
}
|
|
120
|
+
if (isDropdownElement(child, DropdownSubmenu)) {
|
|
121
|
+
const searchText = [
|
|
122
|
+
getNodeText(child.props.label),
|
|
123
|
+
child.props.searchText
|
|
124
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
125
|
+
if (searchText.includes(normalizedQuery)) {
|
|
126
|
+
return child;
|
|
127
|
+
}
|
|
128
|
+
const submenuChildren = filterDropdownChildren(
|
|
129
|
+
child.props.children,
|
|
130
|
+
normalizedQuery
|
|
131
|
+
);
|
|
132
|
+
return hasVisibleDropdownContent(submenuChildren) ? React.cloneElement(child, void 0, submenuChildren) : null;
|
|
133
|
+
}
|
|
119
134
|
if (isDropdownElement(child, DropdownContent)) {
|
|
120
135
|
const contentChildren = filterDropdownChildren(
|
|
121
136
|
child.props.children,
|
|
@@ -180,6 +195,7 @@ function Dropdown({
|
|
|
180
195
|
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);
|
|
181
196
|
const [uncontrolledSelectedValues, setUncontrolledSelectedValues] = React.useState(defaultSelectedValues);
|
|
182
197
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
198
|
+
const [extraOutsideRefs, setExtraOutsideRefs] = React.useState([]);
|
|
183
199
|
const containerRef = React.useRef(null);
|
|
184
200
|
const searchInputRef = React.useRef(null);
|
|
185
201
|
const menuId = React.useId();
|
|
@@ -224,13 +240,21 @@ function Dropdown({
|
|
|
224
240
|
},
|
|
225
241
|
[multiSelect, selectedValues, setSelectedValues]
|
|
226
242
|
);
|
|
243
|
+
const registerOutsideRef = React.useCallback(
|
|
244
|
+
(ref) => {
|
|
245
|
+
setExtraOutsideRefs((prev) => [...prev, ref]);
|
|
246
|
+
return () => setExtraOutsideRefs((prev) => prev.filter((r) => r !== ref));
|
|
247
|
+
},
|
|
248
|
+
[]
|
|
249
|
+
);
|
|
227
250
|
const dropdownContext = React.useMemo(
|
|
228
251
|
() => ({
|
|
229
252
|
multiSelect,
|
|
230
253
|
selectedValues,
|
|
231
|
-
toggleSelectedValue
|
|
254
|
+
toggleSelectedValue,
|
|
255
|
+
registerOutsideRef
|
|
232
256
|
}),
|
|
233
|
-
[multiSelect, selectedValues, toggleSelectedValue]
|
|
257
|
+
[multiSelect, selectedValues, toggleSelectedValue, registerOutsideRef]
|
|
234
258
|
);
|
|
235
259
|
useEscapeKey(handleClose, isOpen);
|
|
236
260
|
const { anchorRef, floatingRef, style } = useAnchoredPosition({
|
|
@@ -240,8 +264,8 @@ function Dropdown({
|
|
|
240
264
|
matchMinWidth: width === "trigger"
|
|
241
265
|
});
|
|
242
266
|
const outsideRefs = React.useMemo(
|
|
243
|
-
() => [containerRef, floatingRef],
|
|
244
|
-
[floatingRef]
|
|
267
|
+
() => [containerRef, floatingRef, ...extraOutsideRefs],
|
|
268
|
+
[floatingRef, extraOutsideRefs]
|
|
245
269
|
);
|
|
246
270
|
useClickOutside(outsideRefs, handleClose, isOpen);
|
|
247
271
|
React.useEffect(() => {
|
|
@@ -574,6 +598,141 @@ var DropdownItem = React.forwardRef(
|
|
|
574
598
|
}
|
|
575
599
|
);
|
|
576
600
|
DropdownItem.displayName = "DropdownItem";
|
|
601
|
+
var submenuCloseDelay = 150;
|
|
602
|
+
function DropdownSubmenu({
|
|
603
|
+
label,
|
|
604
|
+
icon,
|
|
605
|
+
disabled = false,
|
|
606
|
+
className,
|
|
607
|
+
children
|
|
608
|
+
}) {
|
|
609
|
+
const [open, setOpen] = React.useState(false);
|
|
610
|
+
const menuId = React.useId();
|
|
611
|
+
const dropdownContext = React.useContext(DropdownContext);
|
|
612
|
+
const closeTimer = React.useRef(
|
|
613
|
+
void 0
|
|
614
|
+
);
|
|
615
|
+
const { anchorRef, floatingRef, style } = useAnchoredPosition({ open, placement: "right-start", offset: 4 });
|
|
616
|
+
const registerOutsideRef = dropdownContext?.registerOutsideRef;
|
|
617
|
+
React.useLayoutEffect(() => {
|
|
618
|
+
if (!open || !registerOutsideRef) return;
|
|
619
|
+
return registerOutsideRef(floatingRef);
|
|
620
|
+
}, [open, registerOutsideRef, floatingRef]);
|
|
621
|
+
React.useEffect(() => () => clearTimeout(closeTimer.current), []);
|
|
622
|
+
const cancelClose = () => clearTimeout(closeTimer.current);
|
|
623
|
+
const openNow = () => {
|
|
624
|
+
if (disabled) return;
|
|
625
|
+
cancelClose();
|
|
626
|
+
setOpen(true);
|
|
627
|
+
};
|
|
628
|
+
const scheduleClose = () => {
|
|
629
|
+
cancelClose();
|
|
630
|
+
closeTimer.current = setTimeout(() => setOpen(false), submenuCloseDelay);
|
|
631
|
+
};
|
|
632
|
+
const closeAndRefocus = () => {
|
|
633
|
+
cancelClose();
|
|
634
|
+
setOpen(false);
|
|
635
|
+
anchorRef.current?.focus();
|
|
636
|
+
};
|
|
637
|
+
const focusFirstItem = () => {
|
|
638
|
+
requestAnimationFrame(() => {
|
|
639
|
+
floatingRef.current?.querySelector('[data-slot="dropdown-item"]')?.focus();
|
|
640
|
+
});
|
|
641
|
+
};
|
|
642
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
643
|
+
/* @__PURE__ */ jsxs(
|
|
644
|
+
"button",
|
|
645
|
+
{
|
|
646
|
+
ref: anchorRef,
|
|
647
|
+
type: "button",
|
|
648
|
+
role: "menuitem",
|
|
649
|
+
disabled,
|
|
650
|
+
"aria-haspopup": "menu",
|
|
651
|
+
"aria-expanded": open,
|
|
652
|
+
"aria-controls": open ? menuId : void 0,
|
|
653
|
+
"data-slot": "dropdown-submenu-trigger",
|
|
654
|
+
className: cn(
|
|
655
|
+
"flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm",
|
|
656
|
+
"transition-colors duration-150",
|
|
657
|
+
"focus:outline-none",
|
|
658
|
+
"text-neutral-700 dark:text-neutral-300",
|
|
659
|
+
"hover:bg-neutral-100 dark:hover:bg-neutral-700",
|
|
660
|
+
"focus:bg-neutral-100 dark:focus:bg-neutral-700",
|
|
661
|
+
open && "bg-neutral-100 dark:bg-neutral-700",
|
|
662
|
+
className
|
|
663
|
+
),
|
|
664
|
+
onPointerEnter: (event) => {
|
|
665
|
+
if (event.pointerType === "mouse") openNow();
|
|
666
|
+
},
|
|
667
|
+
onPointerLeave: (event) => {
|
|
668
|
+
if (event.pointerType === "mouse") scheduleClose();
|
|
669
|
+
},
|
|
670
|
+
onClick: (event) => {
|
|
671
|
+
openNow();
|
|
672
|
+
if (event.detail === 0) focusFirstItem();
|
|
673
|
+
},
|
|
674
|
+
onKeyDown: (event) => {
|
|
675
|
+
if (event.key === "ArrowRight") {
|
|
676
|
+
event.preventDefault();
|
|
677
|
+
openNow();
|
|
678
|
+
focusFirstItem();
|
|
679
|
+
} else if (open && (event.key === "ArrowLeft" || event.key === "Escape")) {
|
|
680
|
+
event.preventDefault();
|
|
681
|
+
event.stopPropagation();
|
|
682
|
+
closeAndRefocus();
|
|
683
|
+
}
|
|
684
|
+
},
|
|
685
|
+
children: [
|
|
686
|
+
icon && /* @__PURE__ */ jsx("span", { className: "h-4 w-4 shrink-0", "data-slot": "dropdown-item-icon", children: icon }),
|
|
687
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 font-medium", "data-slot": "dropdown-item-label", children: label }),
|
|
688
|
+
/* @__PURE__ */ jsx(
|
|
689
|
+
ChevronRight,
|
|
690
|
+
{
|
|
691
|
+
size: 16,
|
|
692
|
+
"aria-hidden": "true",
|
|
693
|
+
className: "shrink-0 text-neutral-400"
|
|
694
|
+
}
|
|
695
|
+
)
|
|
696
|
+
]
|
|
697
|
+
}
|
|
698
|
+
),
|
|
699
|
+
open && createPortal(
|
|
700
|
+
/* @__PURE__ */ jsx(
|
|
701
|
+
"div",
|
|
702
|
+
{
|
|
703
|
+
ref: floatingRef,
|
|
704
|
+
style,
|
|
705
|
+
id: menuId,
|
|
706
|
+
role: "menu",
|
|
707
|
+
tabIndex: -1,
|
|
708
|
+
"data-slot": "dropdown-submenu",
|
|
709
|
+
className: cn(
|
|
710
|
+
// min() keeps the preferred width from beating the hook's
|
|
711
|
+
// maxWidth viewport clamp on very narrow screens.
|
|
712
|
+
"flex min-w-[min(10rem,calc(100vw-1rem))] flex-col overflow-hidden",
|
|
713
|
+
"rounded-xl border border-neutral-200 bg-white shadow-lg",
|
|
714
|
+
"dark:border-neutral-700 dark:bg-neutral-800",
|
|
715
|
+
"animate-in fade-in zoom-in-95 duration-100"
|
|
716
|
+
),
|
|
717
|
+
onPointerEnter: cancelClose,
|
|
718
|
+
onPointerLeave: (event) => {
|
|
719
|
+
if (event.pointerType === "mouse") scheduleClose();
|
|
720
|
+
},
|
|
721
|
+
onKeyDown: (event) => {
|
|
722
|
+
if (event.key === "ArrowLeft" || event.key === "Escape") {
|
|
723
|
+
event.preventDefault();
|
|
724
|
+
event.stopPropagation();
|
|
725
|
+
closeAndRefocus();
|
|
726
|
+
}
|
|
727
|
+
},
|
|
728
|
+
children: /* @__PURE__ */ jsx("div", { className: "min-h-0 overflow-y-auto", children })
|
|
729
|
+
}
|
|
730
|
+
),
|
|
731
|
+
document.body
|
|
732
|
+
)
|
|
733
|
+
] });
|
|
734
|
+
}
|
|
735
|
+
DropdownSubmenu.displayName = "DropdownSubmenu";
|
|
577
736
|
function DropdownSeparator({ className }) {
|
|
578
737
|
return /* @__PURE__ */ jsx(
|
|
579
738
|
"hr",
|
|
@@ -606,6 +765,6 @@ function DropdownLabel({
|
|
|
606
765
|
}
|
|
607
766
|
DropdownLabel.displayName = "DropdownLabel";
|
|
608
767
|
|
|
609
|
-
export { Dropdown, DropdownContent, DropdownHeader, DropdownItem, DropdownLabel, DropdownSeparator };
|
|
610
|
-
//# sourceMappingURL=chunk-
|
|
611
|
-
//# sourceMappingURL=chunk-
|
|
768
|
+
export { Dropdown, DropdownContent, DropdownHeader, DropdownItem, DropdownLabel, DropdownSeparator, DropdownSubmenu };
|
|
769
|
+
//# sourceMappingURL=chunk-AHUYW673.js.map
|
|
770
|
+
//# sourceMappingURL=chunk-AHUYW673.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/components/Dropdown/Dropdown.tsx"],"names":["Fragment","ChevronRightIcon"],"mappings":"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","file":"chunk-AHUYW673.js","sourcesContent":["import * as React from 'react';\nimport { createPortal } from 'react-dom';\nimport { ChevronRight as ChevronRightIcon } from 'lucide-react';\nimport { cn } from '../../utils/cn';\nimport { useClickOutside } from '../../hooks/useClickOutside';\nimport { useEscapeKey } from '../../hooks/useEscapeKey';\nimport {\n useAnchoredPosition,\n type AnchoredPlacement,\n} from '../../hooks/useAnchoredPosition';\nimport { inputVariants } from '../Input';\n\nexport type DropdownPlacement = AnchoredPlacement;\n\nexport interface DropdownProps {\n /** The trigger element (usually a button) */\n trigger: React.ReactElement<{\n onClick?: () => void;\n disabled?: boolean;\n 'aria-haspopup'?: string;\n 'aria-expanded'?: boolean;\n 'aria-controls'?: string;\n }>;\n /** Dropdown content */\n children: React.ReactNode;\n /** Controlled open state */\n open?: boolean;\n /** Callback when open state changes */\n onOpenChange?: (open: boolean) => void;\n /** Placement of the dropdown */\n placement?: DropdownPlacement;\n /** Additional class name for the dropdown menu */\n className?: string;\n /** Width of the dropdown menu */\n width?: 'auto' | 'trigger' | number;\n /** Whether the dropdown is disabled */\n disabled?: boolean;\n /** Whether to render a search field at the top of the dropdown */\n searchable?: boolean;\n /** Placeholder text for the search input */\n searchPlaceholder?: string;\n /** Accessible label for the search input */\n searchAriaLabel?: string;\n /** Content to render when no items match the search query */\n searchEmptyState?: React.ReactNode;\n /** Whether dropdown items support multi-select checkboxes */\n multiSelect?: boolean;\n /** Selected item values for controlled multi-select dropdowns */\n selectedValues?: string[];\n /** Initial selected item values for uncontrolled multi-select dropdowns */\n defaultSelectedValues?: string[];\n /** Callback fired when selected values change in multi-select mode */\n onSelectedValuesChange?: (values: string[]) => void;\n /** Whether to render a select-all control for multi-select dropdowns */\n showSelectAll?: boolean;\n /** Label for the select-all control */\n selectAllLabel?: React.ReactNode;\n}\n\nconst placementOffset = 8; // matches the previous mt-2/mb-2 gap\n\ninterface DropdownContextValue {\n multiSelect: boolean;\n selectedValues: string[];\n toggleSelectedValue: (value: string) => void;\n /**\n * Registers a portaled descendant (submenu panel) with the root dropdown's\n * click-outside detection so clicks inside it don't close the menu.\n * Returns an unregister function.\n */\n registerOutsideRef: (ref: React.RefObject<HTMLElement | null>) => () => void;\n}\n\nconst DropdownContext = React.createContext<DropdownContextValue | null>(null);\n\nfunction getNodeText(node: React.ReactNode): string {\n if (typeof node === 'string' || typeof node === 'number') {\n return String(node);\n }\n\n if (Array.isArray(node)) {\n return node.map(getNodeText).join(' ');\n }\n\n if (React.isValidElement<{ children?: React.ReactNode }>(node)) {\n return getNodeText(node.props.children);\n }\n\n return '';\n}\n\nfunction isDropdownElement<P>(\n node: React.ReactNode,\n component: React.JSXElementConstructor<P>\n): node is React.ReactElement<P> {\n return React.isValidElement(node) && node.type === component;\n}\n\nfunction hasVisibleDropdownContent(node: React.ReactNode): boolean {\n if (node == null || typeof node === 'boolean') {\n return false;\n }\n\n if (Array.isArray(node)) {\n return node.some(hasVisibleDropdownContent);\n }\n\n if (!React.isValidElement<{ children?: React.ReactNode }>(node)) {\n if (typeof node === 'string') {\n return node.trim().length > 0;\n }\n\n return true;\n }\n\n if (node.type === React.Fragment) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n if (\n node.type === DropdownSeparator ||\n node.type === DropdownLabel ||\n node.type === DropdownHeader\n ) {\n return false;\n }\n\n if (node.type === DropdownContent) {\n return React.Children.toArray(node.props.children).some(\n hasVisibleDropdownContent\n );\n }\n\n return true;\n}\n\nfunction normalizeDropdownSiblings(\n children: React.ReactNode[]\n): React.ReactNode[] {\n const hasContentBefore = (index: number) => {\n for (let current = index - 1; current >= 0; current -= 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n const hasContentAfter = (index: number) => {\n for (let current = index + 1; current < children.length; current += 1) {\n const child = children[current];\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return false;\n }\n\n if (hasVisibleDropdownContent(child)) {\n return true;\n }\n }\n\n return false;\n };\n\n return children.filter((child, index) => {\n if (isDropdownElement(child, DropdownSeparator)) {\n return hasContentBefore(index) && hasContentAfter(index);\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return hasContentAfter(index);\n }\n\n return true;\n });\n}\n\nfunction filterDropdownChildren(\n children: React.ReactNode,\n query: string\n): React.ReactNode[] {\n const normalizedQuery = query.trim().toLowerCase();\n\n if (!normalizedQuery) {\n return React.Children.toArray(children);\n }\n\n const filteredChildren = React.Children.toArray(children)\n .map((child) => {\n if (!React.isValidElement<{ children?: React.ReactNode }>(child)) {\n if (typeof child === 'string' || typeof child === 'number') {\n return String(child).toLowerCase().includes(normalizedQuery)\n ? child\n : null;\n }\n\n return null;\n }\n\n if (child.type === React.Fragment) {\n const fragmentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return fragmentChildren.length > 0\n ? React.cloneElement(child, undefined, fragmentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownHeader)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n const searchText = [\n getNodeText(child.props.children),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n return searchText.includes(normalizedQuery) ? child : null;\n }\n\n if (isDropdownElement(child, DropdownSubmenu)) {\n const searchText = [\n getNodeText(child.props.label),\n child.props.searchText,\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n // Keep the whole submenu when its label matches; otherwise filter its\n // items and keep it only when something inside still matches.\n if (searchText.includes(normalizedQuery)) {\n return child;\n }\n\n const submenuChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(submenuChildren)\n ? React.cloneElement(child, undefined, submenuChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownContent)) {\n const contentChildren = filterDropdownChildren(\n child.props.children,\n normalizedQuery\n );\n\n return hasVisibleDropdownContent(contentChildren)\n ? React.cloneElement(child, undefined, contentChildren)\n : null;\n }\n\n if (isDropdownElement(child, DropdownSeparator)) {\n return child;\n }\n\n if (isDropdownElement(child, DropdownLabel)) {\n return child;\n }\n\n const nestedChildren = child.props.children;\n\n if (nestedChildren === undefined) {\n return child;\n }\n\n const filteredNestedChildren = filterDropdownChildren(\n nestedChildren,\n normalizedQuery\n );\n\n return filteredNestedChildren.length > 0\n ? React.cloneElement(child, undefined, filteredNestedChildren)\n : null;\n })\n .filter((child) => child !== null);\n\n return normalizeDropdownSiblings(filteredChildren);\n}\n\nfunction getSelectableValues(children: React.ReactNode): string[] {\n return React.Children.toArray(children).flatMap((child) => {\n if (\n !React.isValidElement<{ children?: React.ReactNode; value?: unknown }>(\n child\n )\n ) {\n return [];\n }\n\n if (child.type === React.Fragment || child.type === DropdownContent) {\n return getSelectableValues(child.props.children);\n }\n\n if (isDropdownElement(child, DropdownItem)) {\n return typeof child.props.value === 'string' ? [child.props.value] : [];\n }\n\n return child.props.children !== undefined\n ? getSelectableValues(child.props.children)\n : [];\n });\n}\n\n/**\n * An accessible dropdown menu component.\n *\n * @example\n * ```tsx\n * <Dropdown\n * trigger={<Button>Options</Button>}\n * >\n * <DropdownItem onClick={() => console.log('Edit')}>Edit</DropdownItem>\n * <DropdownItem onClick={() => console.log('Delete')} variant=\"danger\">Delete</DropdownItem>\n * </Dropdown>\n * ```\n */\nfunction Dropdown({\n trigger,\n children,\n open: controlledOpen,\n onOpenChange,\n placement = 'bottom-start',\n className,\n width = 'auto',\n disabled = false,\n searchable = false,\n searchPlaceholder = 'Search...',\n searchAriaLabel = 'Search dropdown items',\n searchEmptyState = 'No results found',\n multiSelect = false,\n selectedValues: controlledSelectedValues,\n defaultSelectedValues = [],\n onSelectedValuesChange,\n showSelectAll = false,\n selectAllLabel = 'Select all',\n}: DropdownProps) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(false);\n const [uncontrolledSelectedValues, setUncontrolledSelectedValues] =\n React.useState(defaultSelectedValues);\n const [searchQuery, setSearchQuery] = React.useState('');\n const [extraOutsideRefs, setExtraOutsideRefs] = React.useState<\n ReadonlyArray<React.RefObject<HTMLElement | null>>\n >([]);\n const containerRef = React.useRef<HTMLDivElement>(null);\n const searchInputRef = React.useRef<HTMLInputElement>(null);\n const menuId = React.useId();\n\n const isControlled = controlledOpen !== undefined;\n const isSelectedValuesControlled = controlledSelectedValues !== undefined;\n const isOpen = isControlled ? controlledOpen : uncontrolledOpen;\n const selectedValues = isSelectedValuesControlled\n ? controlledSelectedValues\n : uncontrolledSelectedValues;\n\n const setOpen = React.useCallback(\n (value: boolean) => {\n if (!isControlled) {\n setUncontrolledOpen(value);\n }\n onOpenChange?.(value);\n },\n [isControlled, onOpenChange]\n );\n\n const handleToggle = React.useCallback(() => {\n if (!disabled) {\n setOpen(!isOpen);\n }\n }, [disabled, isOpen, setOpen]);\n\n const handleClose = React.useCallback(() => {\n setOpen(false);\n }, [setOpen]);\n\n const setSelectedValues = React.useCallback(\n (values: string[]) => {\n if (!isSelectedValuesControlled) {\n setUncontrolledSelectedValues(values);\n }\n onSelectedValuesChange?.(values);\n },\n [isSelectedValuesControlled, onSelectedValuesChange]\n );\n\n const toggleSelectedValue = React.useCallback(\n (value: string) => {\n if (!multiSelect) {\n return;\n }\n\n setSelectedValues(\n selectedValues.includes(value)\n ? selectedValues.filter((selectedValue) => selectedValue !== value)\n : [...selectedValues, value]\n );\n },\n [multiSelect, selectedValues, setSelectedValues]\n );\n\n const registerOutsideRef = React.useCallback(\n (ref: React.RefObject<HTMLElement | null>) => {\n setExtraOutsideRefs((prev) => [...prev, ref]);\n return () => setExtraOutsideRefs((prev) => prev.filter((r) => r !== ref));\n },\n []\n );\n\n const dropdownContext = React.useMemo<DropdownContextValue>(\n () => ({\n multiSelect,\n selectedValues,\n toggleSelectedValue,\n registerOutsideRef,\n }),\n [multiSelect, selectedValues, toggleSelectedValue, registerOutsideRef]\n );\n\n useEscapeKey(handleClose, isOpen);\n\n // Portal + fixed positioning so the menu escapes overflow-hidden ancestors.\n const { anchorRef, floatingRef, style } = useAnchoredPosition<\n HTMLDivElement,\n HTMLDivElement\n >({\n open: isOpen,\n placement,\n offset: placementOffset,\n matchMinWidth: width === 'trigger',\n });\n\n const outsideRefs = React.useMemo(\n () => [containerRef, floatingRef, ...extraOutsideRefs],\n [floatingRef, extraOutsideRefs]\n );\n useClickOutside(outsideRefs, handleClose, isOpen);\n\n React.useEffect(() => {\n if (!isOpen) {\n setSearchQuery('');\n return;\n }\n\n if (searchable) {\n requestAnimationFrame(() => searchInputRef.current?.focus());\n }\n }, [isOpen, searchable]);\n\n // Clone trigger to add event handlers\n const triggerElement = React.cloneElement(trigger, {\n onClick: handleToggle,\n 'aria-haspopup': 'menu',\n 'aria-expanded': isOpen,\n 'aria-controls': isOpen ? menuId : undefined,\n disabled: disabled || trigger.props.disabled,\n });\n\n const widthStyle = typeof width === 'number' ? { width: `${width}px` } : {};\n\n const filteredChildren = React.useMemo(\n () => filterDropdownChildren(children, searchQuery),\n [children, searchQuery]\n );\n const visibleSelectableValues = React.useMemo(\n () => getSelectableValues(searchable ? filteredChildren : children),\n [children, filteredChildren, searchable]\n );\n const hasSearchResults = React.useMemo(\n () => hasVisibleDropdownContent(filteredChildren),\n [filteredChildren]\n );\n const allVisibleSelected =\n visibleSelectableValues.length > 0 &&\n visibleSelectableValues.every((value) => selectedValues.includes(value));\n const someVisibleSelected = visibleSelectableValues.some((value) =>\n selectedValues.includes(value)\n );\n\n const handleSelectAll = React.useCallback(() => {\n if (!multiSelect || visibleSelectableValues.length === 0) {\n return;\n }\n\n const visibleValueSet = new Set(visibleSelectableValues);\n\n setSelectedValues(\n allVisibleSelected\n ? selectedValues.filter((value) => !visibleValueSet.has(value))\n : Array.from(new Set([...selectedValues, ...visibleSelectableValues]))\n );\n }, [\n allVisibleSelected,\n multiSelect,\n selectedValues,\n setSelectedValues,\n visibleSelectableValues,\n ]);\n\n return (\n <DropdownContext.Provider value={dropdownContext}>\n <div\n ref={(node) => {\n containerRef.current = node;\n anchorRef.current = node;\n }}\n className=\"relative inline-flex\"\n >\n {triggerElement}\n {isOpen &&\n createPortal(\n <div\n ref={floatingRef}\n style={{ ...style, ...widthStyle }}\n data-slot=\"dropdown-menu\"\n className={cn(\n 'flex min-w-[12rem] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n 'animate-in fade-in zoom-in-95 duration-100',\n className\n )}\n >\n {searchable && (\n <div\n className=\"shrink-0 border-b border-neutral-200 p-2 dark:border-neutral-700\"\n data-slot=\"dropdown-search\"\n >\n <input\n ref={searchInputRef}\n type=\"search\"\n value={searchQuery}\n onChange={(event) => setSearchQuery(event.target.value)}\n placeholder={searchPlaceholder}\n aria-label={searchAriaLabel}\n aria-controls={menuId}\n aria-autocomplete=\"list\"\n data-slot=\"dropdown-search-input\"\n className={cn(\n inputVariants({ size: 'sm' }),\n 'text-sm',\n 'dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-100'\n )}\n />\n </div>\n )}\n <div id={menuId} role=\"menu\" className=\"min-h-0 overflow-y-auto\">\n {multiSelect &&\n showSelectAll &&\n visibleSelectableValues.length > 0 && (\n <>\n <div className=\"p-2\" data-slot=\"dropdown-select-all\">\n <DropdownItem\n checked={allVisibleSelected}\n indeterminate={\n !allVisibleSelected && someVisibleSelected\n }\n onClick={handleSelectAll}\n >\n {selectAllLabel}\n </DropdownItem>\n </div>\n <DropdownSeparator />\n </>\n )}\n {searchable ? (\n hasSearchResults ? (\n filteredChildren\n ) : (\n <div\n className=\"text-muted-foreground px-3 py-4 text-center text-sm\"\n data-slot=\"dropdown-empty\"\n >\n {searchEmptyState}\n </div>\n )\n ) : (\n children\n )}\n </div>\n </div>,\n document.body\n )}\n </div>\n </DropdownContext.Provider>\n );\n}\n\nDropdown.displayName = 'Dropdown';\n\n// ============================================================================\n// Dropdown Header Component\n// ============================================================================\n\nexport interface DropdownHeaderProps extends Omit<\n React.HTMLAttributes<HTMLDivElement>,\n 'title'\n> {\n /** Avatar element or image */\n avatar?: React.ReactNode;\n /** Primary text (e.g., user name) */\n title: React.ReactNode;\n /** Secondary text (e.g., email) */\n subtitle?: React.ReactNode;\n}\n\n/**\n * A header section for dropdown menus, typically used for user info.\n *\n * @example\n * ```tsx\n * <DropdownHeader\n * avatar={<Avatar name=\"John Doe\" />}\n * title=\"John Doe\"\n * subtitle=\"john@example.com\"\n * />\n * ```\n */\nconst DropdownHeader = React.forwardRef<HTMLDivElement, DropdownHeaderProps>(\n ({ className, avatar, title, subtitle, children, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-header\"\n className={cn(\n 'border-b border-neutral-200 p-4 dark:border-neutral-700',\n className\n )}\n {...props}\n >\n <div\n className=\"flex items-center gap-3\"\n data-slot=\"dropdown-header-row\"\n >\n {avatar}\n <div className=\"min-w-0 flex-1\">\n <p\n className=\"truncate text-sm font-semibold text-neutral-900 dark:text-white\"\n data-slot=\"dropdown-header-title\"\n >\n {title}\n </p>\n {subtitle && (\n <p\n className=\"text-muted-foreground truncate text-xs\"\n data-slot=\"dropdown-header-subtitle\"\n >\n {subtitle}\n </p>\n )}\n </div>\n </div>\n {children}\n </div>\n );\n }\n);\n\nDropdownHeader.displayName = 'DropdownHeader';\n\n// ============================================================================\n// Dropdown Content Component\n// ============================================================================\n\nexport type DropdownContentProps = React.HTMLAttributes<HTMLDivElement>;\n\n/**\n * A container for dropdown menu items with proper padding.\n */\nconst DropdownContent = React.forwardRef<HTMLDivElement, DropdownContentProps>(\n ({ className, ...props }, ref) => {\n return (\n <div\n ref={ref}\n data-slot=\"dropdown-content\"\n className={cn('p-2', className)}\n {...props}\n />\n );\n }\n);\n\nDropdownContent.displayName = 'DropdownContent';\n\n// ============================================================================\n// Dropdown Item Component\n// ============================================================================\n\nexport interface DropdownItemProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Danger variant for destructive actions */\n variant?: 'default' | 'danger';\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Checked state for multi-select items */\n checked?: boolean;\n /** Indeterminate state for multi-select items */\n indeterminate?: boolean;\n /** Callback fired when a multi-select item changes */\n onCheckedChange?: (checked: boolean) => void;\n}\n\nfunction DropdownItemCheckbox({\n checked,\n indeterminate = false,\n}: {\n checked: boolean;\n indeterminate?: boolean;\n}) {\n return (\n <span\n aria-hidden=\"true\"\n data-slot=\"dropdown-checkbox\"\n className={cn(\n 'flex h-4 w-4 shrink-0 items-center justify-center rounded border-2 transition-colors duration-150',\n checked || indeterminate\n ? 'border-primary-500 bg-primary-800 text-white'\n : 'border-input bg-background text-transparent'\n )}\n >\n {indeterminate ? (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M4 8h8\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n />\n </svg>\n ) : (\n <svg\n aria-hidden=\"true\"\n className=\"h-3 w-3\"\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n >\n <path\n d=\"M3.5 8.5 6.5 11.5 12.5 4.5\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n />\n </svg>\n )}\n </span>\n );\n}\n\n/**\n * An item within a Dropdown menu.\n */\nconst DropdownItem = React.forwardRef<HTMLButtonElement, DropdownItemProps>(\n (\n {\n className,\n icon,\n variant = 'default',\n children,\n searchText,\n checked,\n indeterminate = false,\n onCheckedChange,\n onClick,\n value,\n disabled,\n ...props\n },\n ref\n ) => {\n const dropdownContext = React.useContext(DropdownContext);\n const itemValue = typeof value === 'string' ? value : undefined;\n const contextSelectedValues = dropdownContext?.selectedValues ?? [];\n const isMultiSelectItem =\n (dropdownContext?.multiSelect === true && itemValue !== undefined) ||\n checked !== undefined ||\n indeterminate;\n const isChecked =\n checked ??\n (isMultiSelectItem\n ? itemValue !== undefined && contextSelectedValues.includes(itemValue)\n : false);\n\n const handleClick = React.useCallback(\n (event: React.MouseEvent<HTMLButtonElement>) => {\n if (\n dropdownContext &&\n isMultiSelectItem &&\n itemValue !== undefined &&\n !disabled\n ) {\n dropdownContext.toggleSelectedValue(itemValue);\n onCheckedChange?.(!isChecked);\n }\n\n onClick?.(event);\n },\n [\n disabled,\n dropdownContext,\n isChecked,\n isMultiSelectItem,\n itemValue,\n onCheckedChange,\n onClick,\n ]\n );\n\n return (\n <button\n ref={ref}\n type=\"button\"\n role={isMultiSelectItem ? 'menuitemcheckbox' : 'menuitem'}\n aria-checked={\n isMultiSelectItem ? (indeterminate ? 'mixed' : isChecked) : undefined\n }\n disabled={disabled}\n data-slot=\"dropdown-item\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-left text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n variant === 'default' && [\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n ],\n variant === 'danger' && [\n 'text-red-600 dark:text-red-400',\n 'hover:bg-red-50 dark:hover:bg-red-900/20',\n 'focus:bg-red-50 dark:focus:bg-red-900/20',\n ],\n className\n )}\n data-search-text={searchText}\n onClick={handleClick}\n value={value}\n {...props}\n >\n {isMultiSelectItem && (\n <DropdownItemCheckbox\n checked={isChecked}\n indeterminate={indeterminate}\n />\n )}\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"font-medium\" data-slot=\"dropdown-item-label\">\n {children}\n </span>\n </button>\n );\n }\n);\n\nDropdownItem.displayName = 'DropdownItem';\n\n// ============================================================================\n// Dropdown Submenu Component\n// ============================================================================\n\nexport interface DropdownSubmenuProps {\n /** The parent item's label */\n label: React.ReactNode;\n /** Icon to display before the label */\n icon?: React.ReactNode;\n /** Whether the submenu trigger is disabled */\n disabled?: boolean;\n /** Optional text used when filtering searchable dropdown items */\n searchText?: string;\n /** Additional class name for the submenu trigger item */\n className?: string;\n /** Submenu items */\n children: React.ReactNode;\n}\n\n/** Delay before a hover-opened submenu closes, allowing diagonal travel. */\nconst submenuCloseDelay = 150;\n\n/**\n * A dropdown item that opens a nested flyout menu.\n *\n * Opens on hover or click, and via ArrowRight/Enter/Space from the keyboard;\n * ArrowLeft or Escape closes just the submenu (Escape is stopped so the root\n * menu stays open) and returns focus to the trigger.\n *\n * @example\n * ```tsx\n * <Dropdown trigger={<Button>Options</Button>}>\n * <DropdownItem onClick={copy}>Copy</DropdownItem>\n * <DropdownSubmenu label=\"Copy as\">\n * <DropdownItem onClick={copyMarkdown}>Markdown</DropdownItem>\n * <DropdownItem onClick={copyPlain}>Plain text</DropdownItem>\n * </DropdownSubmenu>\n * </Dropdown>\n * ```\n */\nfunction DropdownSubmenu({\n label,\n icon,\n disabled = false,\n className,\n children,\n}: DropdownSubmenuProps) {\n const [open, setOpen] = React.useState(false);\n const menuId = React.useId();\n const dropdownContext = React.useContext(DropdownContext);\n const closeTimer = React.useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined\n );\n\n const { anchorRef, floatingRef, style } = useAnchoredPosition<\n HTMLButtonElement,\n HTMLDivElement\n >({ open, placement: 'right-start', offset: 4 });\n\n // Let the root dropdown treat clicks inside the portaled flyout as \"inside\"\n // so they don't dismiss the whole menu. Layout effect so the registration\n // flushes before the browser can deliver the next mousedown/touchstart —\n // a passive effect could lose a fast open-then-click race.\n const registerOutsideRef = dropdownContext?.registerOutsideRef;\n React.useLayoutEffect(() => {\n if (!open || !registerOutsideRef) return;\n return registerOutsideRef(floatingRef);\n }, [open, registerOutsideRef, floatingRef]);\n\n React.useEffect(() => () => clearTimeout(closeTimer.current), []);\n\n const cancelClose = () => clearTimeout(closeTimer.current);\n const openNow = () => {\n if (disabled) return;\n cancelClose();\n setOpen(true);\n };\n const scheduleClose = () => {\n cancelClose();\n closeTimer.current = setTimeout(() => setOpen(false), submenuCloseDelay);\n };\n const closeAndRefocus = () => {\n cancelClose();\n setOpen(false);\n anchorRef.current?.focus();\n };\n\n const focusFirstItem = () => {\n // The flyout positions in a layout effect; wait a frame so it's measurable\n // and visible before moving focus.\n requestAnimationFrame(() => {\n floatingRef.current\n ?.querySelector<HTMLElement>('[data-slot=\"dropdown-item\"]')\n ?.focus();\n });\n };\n\n return (\n <>\n <button\n ref={anchorRef}\n type=\"button\"\n role=\"menuitem\"\n disabled={disabled}\n aria-haspopup=\"menu\"\n aria-expanded={open}\n aria-controls={open ? menuId : undefined}\n data-slot=\"dropdown-submenu-trigger\"\n className={cn(\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2 text-start text-sm',\n 'transition-colors duration-150',\n 'focus:outline-none',\n 'text-neutral-700 dark:text-neutral-300',\n 'hover:bg-neutral-100 dark:hover:bg-neutral-700',\n 'focus:bg-neutral-100 dark:focus:bg-neutral-700',\n open && 'bg-neutral-100 dark:bg-neutral-700',\n className\n )}\n onPointerEnter={(event) => {\n // Hover-open is a mouse affordance; touch taps go through onClick so\n // the flyout doesn't open-then-toggle on the same tap.\n if (event.pointerType === 'mouse') openNow();\n }}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onClick={(event) => {\n openNow();\n // Keyboard activation (Enter/Space fire click with detail 0) moves\n // focus into the flyout; pointer clicks leave focus on the trigger.\n if (event.detail === 0) focusFirstItem();\n }}\n onKeyDown={(event) => {\n if (event.key === 'ArrowRight') {\n event.preventDefault();\n openNow();\n focusFirstItem();\n } else if (\n open &&\n (event.key === 'ArrowLeft' || event.key === 'Escape')\n ) {\n event.preventDefault();\n // Keep the root menu open: stop Escape before it reaches the\n // document-level listener that closes the whole dropdown.\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n {icon && (\n <span className=\"h-4 w-4 shrink-0\" data-slot=\"dropdown-item-icon\">\n {icon}\n </span>\n )}\n <span className=\"flex-1 font-medium\" data-slot=\"dropdown-item-label\">\n {label}\n </span>\n <ChevronRightIcon\n size={16}\n aria-hidden=\"true\"\n className=\"shrink-0 text-neutral-400\"\n />\n </button>\n {open &&\n createPortal(\n <div\n ref={floatingRef}\n style={style}\n id={menuId}\n role=\"menu\"\n // Programmatically focusable (a11y: interactive role); focus lands\n // on the menu items themselves.\n tabIndex={-1}\n data-slot=\"dropdown-submenu\"\n className={cn(\n // min() keeps the preferred width from beating the hook's\n // maxWidth viewport clamp on very narrow screens.\n 'flex min-w-[min(10rem,calc(100vw-1rem))] flex-col overflow-hidden',\n 'rounded-xl border border-neutral-200 bg-white shadow-lg',\n 'dark:border-neutral-700 dark:bg-neutral-800',\n 'animate-in fade-in zoom-in-95 duration-100'\n )}\n onPointerEnter={cancelClose}\n onPointerLeave={(event) => {\n if (event.pointerType === 'mouse') scheduleClose();\n }}\n onKeyDown={(event) => {\n if (event.key === 'ArrowLeft' || event.key === 'Escape') {\n event.preventDefault();\n event.stopPropagation();\n closeAndRefocus();\n }\n }}\n >\n <div className=\"min-h-0 overflow-y-auto\">{children}</div>\n </div>,\n document.body\n )}\n </>\n );\n}\n\nDropdownSubmenu.displayName = 'DropdownSubmenu';\n\n// ============================================================================\n// Dropdown Separator Component\n// ============================================================================\n\n/**\n * A separator between dropdown items.\n */\nfunction DropdownSeparator({ className }: { className?: string }) {\n return (\n <hr\n data-slot=\"dropdown-separator\"\n className={cn(\n 'border-t border-neutral-200 dark:border-neutral-700',\n className\n )}\n />\n );\n}\n\nDropdownSeparator.displayName = 'DropdownSeparator';\n\n// ============================================================================\n// Dropdown Label Component\n// ============================================================================\n\n/**\n * A label/header for a group of dropdown items.\n */\nfunction DropdownLabel({\n className,\n children,\n}: {\n className?: string;\n children: React.ReactNode;\n}) {\n return (\n <div\n data-slot=\"dropdown-label\"\n className={cn(\n 'px-3 py-1.5 text-xs font-semibold tracking-wider uppercase',\n 'text-muted-foreground',\n className\n )}\n >\n {children}\n </div>\n );\n}\n\nDropdownLabel.displayName = 'DropdownLabel';\n\nexport {\n Dropdown,\n DropdownHeader,\n DropdownContent,\n DropdownItem,\n DropdownSubmenu,\n DropdownSeparator,\n DropdownLabel,\n};\n"]}
|
|
@@ -49,7 +49,7 @@ function useAnchoredPosition({
|
|
|
49
49
|
const floatingRef = React__namespace.useRef(null);
|
|
50
50
|
const [style, setStyle] = React__namespace.useState(HIDDEN_STYLE);
|
|
51
51
|
const [actualSide, setActualSide] = React__namespace.useState(
|
|
52
|
-
placement.startsWith("top") ? "top" : "bottom"
|
|
52
|
+
placement.startsWith("top") ? "top" : placement.startsWith("left") ? "left" : placement.startsWith("right") ? "right" : "bottom"
|
|
53
53
|
);
|
|
54
54
|
const update = React__namespace.useCallback(() => {
|
|
55
55
|
const anchor = anchorRef.current;
|
|
@@ -82,6 +82,41 @@ function useAnchoredPosition({
|
|
|
82
82
|
const floatingWidth = matchWidth ? rect.width : Math.max(floating.offsetWidth, matchMinWidth ? rect.width : 0);
|
|
83
83
|
const availableWidth = Math.max(rightLimit - leftLimit, 0);
|
|
84
84
|
const positionedWidth = Math.min(floatingWidth, availableWidth);
|
|
85
|
+
if (placement.startsWith("left") || placement.startsWith("right")) {
|
|
86
|
+
const contentWidth = floatingWidth;
|
|
87
|
+
const spaceRight = rightLimit - rect.right - offset;
|
|
88
|
+
const spaceLeft = rect.left - leftLimit - offset;
|
|
89
|
+
const preferLeft = placement.startsWith("left");
|
|
90
|
+
let hSide = preferLeft ? "left" : "right";
|
|
91
|
+
if (allowFlip && preferLeft) {
|
|
92
|
+
hSide = spaceLeft < contentWidth && spaceRight > spaceLeft ? "right" : "left";
|
|
93
|
+
} else if (allowFlip) {
|
|
94
|
+
hSide = spaceRight < contentWidth && spaceLeft > spaceRight ? "left" : "right";
|
|
95
|
+
}
|
|
96
|
+
const sideWidth = Math.max(hSide === "left" ? spaceLeft : spaceRight, 0);
|
|
97
|
+
const boundaryHeight = Math.max(bottomLimit - topLimit, 0);
|
|
98
|
+
const positionedHeight = Math.min(contentHeight, boundaryHeight);
|
|
99
|
+
const alignV = placement.endsWith("-start") ? "top" : placement.endsWith("-end") ? "bottom" : "center";
|
|
100
|
+
let top = alignV === "top" ? rect.top : alignV === "bottom" ? rect.bottom - positionedHeight : rect.top + rect.height / 2 - positionedHeight / 2;
|
|
101
|
+
top = Math.min(
|
|
102
|
+
Math.max(top, topLimit),
|
|
103
|
+
Math.max(bottomLimit - positionedHeight, topLimit)
|
|
104
|
+
);
|
|
105
|
+
setActualSide(hSide);
|
|
106
|
+
setStyle({
|
|
107
|
+
position: "fixed",
|
|
108
|
+
top,
|
|
109
|
+
// Anchor the edge nearest the trigger so the flyout grows away from it.
|
|
110
|
+
...hSide === "left" ? { right: viewportWidth - rect.left + offset } : { left: rect.right + offset },
|
|
111
|
+
...matchWidth ? { width: rect.width } : {},
|
|
112
|
+
...matchMinWidth ? { minWidth: rect.width } : {},
|
|
113
|
+
maxWidth: sideWidth,
|
|
114
|
+
maxHeight: Math.min(boundaryHeight, maxHeight ?? Infinity),
|
|
115
|
+
zIndex: 9999,
|
|
116
|
+
transition: "none"
|
|
117
|
+
});
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
85
120
|
const spaceBelow = bottomLimit - rect.bottom - offset;
|
|
86
121
|
const spaceAbove = rect.top - topLimit - offset;
|
|
87
122
|
const preferTop = placement.startsWith("top");
|
|
@@ -159,5 +194,5 @@ function useAnchoredPosition({
|
|
|
159
194
|
}
|
|
160
195
|
|
|
161
196
|
exports.useAnchoredPosition = useAnchoredPosition;
|
|
162
|
-
//# sourceMappingURL=chunk-
|
|
163
|
-
//# sourceMappingURL=chunk-
|
|
197
|
+
//# sourceMappingURL=chunk-AOHJILLU.cjs.map
|
|
198
|
+
//# sourceMappingURL=chunk-AOHJILLU.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/hooks/useAnchoredPosition.ts"],"names":["React"],"mappings":"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","file":"chunk-AOHJILLU.cjs","sourcesContent":["'use client';\n\nimport * as React from 'react';\n\nexport type AnchoredPlacement =\n | 'bottom-start'\n | 'bottom-end'\n | 'bottom'\n | 'top-start'\n | 'top-end'\n | 'top'\n | 'right-start'\n | 'right-end'\n | 'right'\n | 'left-start'\n | 'left-end'\n | 'left';\n\nexport type AnchoredSide = 'top' | 'bottom' | 'left' | 'right';\n\nexport interface UseAnchoredPositionOptions {\n /** Whether the floating element is currently shown */\n open: boolean;\n /** Preferred placement relative to the anchor (flips when out of space) */\n placement?: AnchoredPlacement;\n /** Gap between the anchor and the floating element, in px */\n offset?: number;\n /** Force the floating element to the anchor's width */\n matchWidth?: boolean;\n /** Use the anchor's width as the floating element's minimum width */\n matchMinWidth?: boolean;\n /** Minimum distance from the viewport edges, in px */\n viewportPadding?: number;\n /** Flip to the opposite vertical side when the preferred side is cramped */\n allowFlip?: boolean;\n /** Optional element whose visible rectangle also constrains the popup */\n boundaryRef?: React.RefObject<HTMLElement | null>;\n /**\n * Additional cap on the floating element's height, in px. The height is\n * always clamped to the available viewport space; this only lowers that\n * limit further (omitting it does not remove the viewport constraint).\n */\n maxHeight?: number;\n}\n\nexport interface UseAnchoredPositionReturn<\n TAnchor extends HTMLElement,\n TFloating extends HTMLElement,\n> {\n /** Attach to the element the popup is anchored to (trigger/input) */\n anchorRef: React.RefObject<TAnchor | null>;\n /** Attach to the floating element (menu/listbox/panel) */\n floatingRef: React.RefObject<TFloating | null>;\n /** Fixed-position style for the floating element — spread onto it */\n style: React.CSSProperties;\n /**\n * Side of the anchor in use after flipping.\n *\n * Widened from `'top' | 'bottom'` to {@link AnchoredSide} in 0.8.0 alongside\n * the new horizontal (`left*` / `right*`) placements — consumers that\n * annotate this as `'top' | 'bottom'` need to widen their annotation.\n */\n actualSide: AnchoredSide;\n /** Recompute the position (e.g. after async content loads) */\n update: () => void;\n}\n\nconst HIDDEN_STYLE: React.CSSProperties = {\n position: 'fixed',\n top: 0,\n left: 0,\n visibility: 'hidden',\n zIndex: 9999,\n // Never let `transition-*` utilities animate top/left from the hidden\n // (0,0) mount position to the computed one (keyframe animations like\n // `animate-in` are unaffected).\n transition: 'none',\n};\n\n/**\n * Positions a floating element (dropdown menu, autocomplete listbox,\n * date-picker calendar, …) relative to an anchor using `position: fixed`,\n * so it is never clipped by `overflow: hidden` ancestors.\n *\n * Render the floating element through `createPortal(..., document.body)`\n * and spread the returned `style` onto it. The hook:\n * - flips vertically when there is not enough space on the preferred side\n * - clamps horizontally to the viewport or optional boundary element\n * - constrains `maxHeight` to the available space (add `overflow-auto`)\n * - tracks scroll, resize, and anchor/content size changes while open\n *\n * @example\n * ```tsx\n * const { anchorRef, floatingRef, style } = useAnchoredPosition<\n * HTMLButtonElement,\n * HTMLDivElement\n * >({ open, placement: 'bottom-start' });\n *\n * <button ref={anchorRef} onClick={() => setOpen(!open)}>Open</button>\n * {open &&\n * createPortal(\n * <div ref={floatingRef} style={style} className=\"overflow-auto …\">…</div>,\n * document.body\n * )}\n * ```\n */\nexport function useAnchoredPosition<\n TAnchor extends HTMLElement = HTMLElement,\n TFloating extends HTMLElement = HTMLElement,\n>({\n open,\n placement = 'bottom-start',\n offset = 4,\n matchWidth = false,\n matchMinWidth = false,\n viewportPadding = 8,\n allowFlip = true,\n boundaryRef,\n maxHeight,\n}: UseAnchoredPositionOptions): UseAnchoredPositionReturn<TAnchor, TFloating> {\n const anchorRef = React.useRef<TAnchor | null>(null);\n const floatingRef = React.useRef<TFloating | null>(null);\n const [style, setStyle] = React.useState<React.CSSProperties>(HIDDEN_STYLE);\n const [actualSide, setActualSide] = React.useState<AnchoredSide>(\n placement.startsWith('top')\n ? 'top'\n : placement.startsWith('left')\n ? 'left'\n : placement.startsWith('right')\n ? 'right'\n : 'bottom'\n );\n\n const update = React.useCallback(() => {\n const anchor = anchorRef.current;\n const floating = floatingRef.current;\n if (!anchor || !floating) return;\n\n const rect = anchor.getBoundingClientRect();\n const viewportWidth = window.innerWidth;\n const viewportHeight = window.innerHeight;\n const boundaryRect = boundaryRef?.current?.getBoundingClientRect();\n const bounds = boundaryRect ?? {\n top: 0,\n right: viewportWidth,\n bottom: viewportHeight,\n left: 0,\n };\n const leftLimit = Math.max(bounds.left + viewportPadding, viewportPadding);\n const rightLimit = Math.min(\n bounds.right - viewportPadding,\n viewportWidth - viewportPadding\n );\n const topLimit = Math.max(bounds.top + viewportPadding, viewportPadding);\n const bottomLimit = Math.min(\n bounds.bottom - viewportPadding,\n viewportHeight - viewportPadding\n );\n\n // Natural content size (scrollHeight so a previously applied maxHeight\n // doesn't skew the flip decision).\n const contentHeight = Math.min(\n floating.scrollHeight,\n maxHeight ?? Infinity\n );\n // With matchMinWidth the rendered width is at least the anchor's width,\n // even if offsetWidth was measured before minWidth applied.\n const floatingWidth = matchWidth\n ? rect.width\n : Math.max(floating.offsetWidth, matchMinWidth ? rect.width : 0);\n const availableWidth = Math.max(rightLimit - leftLimit, 0);\n const positionedWidth = Math.min(floatingWidth, availableWidth);\n\n // --- Horizontal-axis placements (left/right flyouts, e.g. submenus) -----\n // The floating element sits beside the anchor: flip horizontally when the\n // preferred side is cramped, align vertically (-start = top edges,\n // -end = bottom edges, bare = centered), and clamp to the boundary.\n if (placement.startsWith('left') || placement.startsWith('right')) {\n // Use floatingWidth (not raw offsetWidth) so matchWidth/matchMinWidth\n // factor into the flip decision, same as the vertical branch.\n const contentWidth = floatingWidth;\n const spaceRight = rightLimit - rect.right - offset;\n const spaceLeft = rect.left - leftLimit - offset;\n const preferLeft = placement.startsWith('left');\n let hSide: 'left' | 'right' = preferLeft ? 'left' : 'right';\n if (allowFlip && preferLeft) {\n hSide =\n spaceLeft < contentWidth && spaceRight > spaceLeft ? 'right' : 'left';\n } else if (allowFlip) {\n hSide =\n spaceRight < contentWidth && spaceLeft > spaceRight\n ? 'left'\n : 'right';\n }\n const sideWidth = Math.max(hSide === 'left' ? spaceLeft : spaceRight, 0);\n\n const boundaryHeight = Math.max(bottomLimit - topLimit, 0);\n const positionedHeight = Math.min(contentHeight, boundaryHeight);\n const alignV = placement.endsWith('-start')\n ? 'top'\n : placement.endsWith('-end')\n ? 'bottom'\n : 'center';\n let top =\n alignV === 'top'\n ? rect.top\n : alignV === 'bottom'\n ? rect.bottom - positionedHeight\n : rect.top + rect.height / 2 - positionedHeight / 2;\n top = Math.min(\n Math.max(top, topLimit),\n Math.max(bottomLimit - positionedHeight, topLimit)\n );\n\n setActualSide(hSide);\n setStyle({\n position: 'fixed',\n top,\n // Anchor the edge nearest the trigger so the flyout grows away from it.\n ...(hSide === 'left'\n ? { right: viewportWidth - rect.left + offset }\n : { left: rect.right + offset }),\n ...(matchWidth ? { width: rect.width } : {}),\n ...(matchMinWidth ? { minWidth: rect.width } : {}),\n maxWidth: sideWidth,\n maxHeight: Math.min(boundaryHeight, maxHeight ?? Infinity),\n zIndex: 9999,\n transition: 'none',\n });\n return;\n }\n\n // --- Vertical: preferred side, flip when out of space -------------------\n const spaceBelow = bottomLimit - rect.bottom - offset;\n const spaceAbove = rect.top - topLimit - offset;\n const preferTop = placement.startsWith('top');\n let side: 'top' | 'bottom' = preferTop ? 'top' : 'bottom';\n if (allowFlip && preferTop) {\n side =\n spaceAbove < contentHeight && spaceBelow > spaceAbove\n ? 'bottom'\n : 'top';\n } else if (allowFlip) {\n side =\n spaceBelow < contentHeight && spaceAbove > spaceBelow\n ? 'top'\n : 'bottom';\n }\n const availableHeight = Math.max(\n side === 'top' ? spaceAbove : spaceBelow,\n 0\n );\n\n // --- Horizontal: -start aligns left edges, -end aligns right edges ------\n const align = placement.endsWith('-start')\n ? 'left'\n : placement.endsWith('-end')\n ? 'right'\n : 'center';\n let left =\n align === 'left'\n ? rect.left\n : align === 'right'\n ? rect.right - positionedWidth\n : rect.left + rect.width / 2 - positionedWidth / 2;\n left = Math.min(\n Math.max(left, leftLimit),\n Math.max(rightLimit - positionedWidth, leftLimit)\n );\n\n setActualSide(side);\n setStyle({\n position: 'fixed',\n left,\n ...(side === 'top'\n ? { bottom: viewportHeight - rect.top + offset }\n : { top: rect.bottom + offset }),\n ...(matchWidth ? { width: rect.width } : {}),\n ...(matchMinWidth ? { minWidth: rect.width } : {}),\n maxWidth: availableWidth,\n maxHeight: Math.min(availableHeight, maxHeight ?? Infinity),\n zIndex: 9999,\n transition: 'none',\n });\n }, [\n matchMinWidth,\n matchWidth,\n maxHeight,\n offset,\n placement,\n viewportPadding,\n allowFlip,\n boundaryRef,\n ]);\n\n // Position synchronously before paint when opening / re-rendering open.\n React.useLayoutEffect(() => {\n if (open) {\n update();\n } else {\n setStyle(HIDDEN_STYLE);\n }\n }, [open, update]);\n\n // Track scroll/resize and anchor/content size changes while open.\n React.useEffect(() => {\n if (!open) return;\n\n // Coalesce bursts (scroll/resize fire per event) into one layout\n // read + state update per frame.\n let frame = 0;\n const scheduleUpdate = () => {\n if (frame) return;\n frame = window.requestAnimationFrame(() => {\n frame = 0;\n update();\n });\n };\n\n window.addEventListener('scroll', scheduleUpdate, true);\n window.addEventListener('resize', scheduleUpdate);\n\n let resizeObserver: globalThis.ResizeObserver | undefined;\n if (typeof globalThis.ResizeObserver !== 'undefined') {\n resizeObserver = new globalThis.ResizeObserver(scheduleUpdate);\n if (anchorRef.current) resizeObserver.observe(anchorRef.current);\n if (floatingRef.current) resizeObserver.observe(floatingRef.current);\n }\n\n return () => {\n if (frame) window.cancelAnimationFrame(frame);\n window.removeEventListener('scroll', scheduleUpdate, true);\n window.removeEventListener('resize', scheduleUpdate);\n resizeObserver?.disconnect();\n };\n }, [open, update]);\n\n return { anchorRef, floatingRef, style, actualSide, update };\n}\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RequiredMark } from './chunk-3IMM2PM4.js';
|
|
2
2
|
import { useEscapeKey } from './chunk-T4ME7QCT.js';
|
|
3
3
|
import { useClickOutside } from './chunk-62ZOA6PX.js';
|
|
4
|
-
import { useAnchoredPosition } from './chunk-
|
|
4
|
+
import { useAnchoredPosition } from './chunk-WSNMQQ4P.js';
|
|
5
5
|
import { cn } from './chunk-TQONQSJO.js';
|
|
6
6
|
import * as React from 'react';
|
|
7
7
|
import { createPortal } from 'react-dom';
|
|
@@ -658,5 +658,5 @@ function CheckIcon({ className }) {
|
|
|
658
658
|
}
|
|
659
659
|
|
|
660
660
|
export { Select, selectTriggerVariants };
|
|
661
|
-
//# sourceMappingURL=chunk-
|
|
662
|
-
//# sourceMappingURL=chunk-
|
|
661
|
+
//# sourceMappingURL=chunk-ATOWMVZH.js.map
|
|
662
|
+
//# sourceMappingURL=chunk-ATOWMVZH.js.map
|