@reopt-ai/opt-ui-primitives 1.4.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/dist/index.js ADDED
@@ -0,0 +1,5013 @@
1
+ "use client";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ var __objRest = (source, exclude) => {
22
+ var target = {};
23
+ for (var prop in source)
24
+ if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
25
+ target[prop] = source[prop];
26
+ if (source != null && __getOwnPropSymbols)
27
+ for (var prop of __getOwnPropSymbols(source)) {
28
+ if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
29
+ target[prop] = source[prop];
30
+ }
31
+ return target;
32
+ };
33
+
34
+ // src/hooks/use-controllable-state.ts
35
+ import { useState, useCallback } from "react";
36
+ function useControllableState(defaultValue, controlledValue, onChange) {
37
+ const [uncontrolledValue, setUncontrolledValue] = useState(defaultValue);
38
+ const isControlled = controlledValue !== void 0;
39
+ const value = isControlled ? controlledValue : uncontrolledValue;
40
+ const setValue = useCallback(
41
+ (newValue) => {
42
+ if (!isControlled) {
43
+ setUncontrolledValue(newValue);
44
+ }
45
+ onChange == null ? void 0 : onChange(newValue);
46
+ },
47
+ [isControlled, onChange]
48
+ );
49
+ return [value, setValue];
50
+ }
51
+
52
+ // src/hooks/use-enter-leave.ts
53
+ import { useRef, useEffect, useState as useState2 } from "react";
54
+ function useEnterLeave(open, options) {
55
+ var _a;
56
+ const animated = (_a = options == null ? void 0 : options.animated) != null ? _a : true;
57
+ const ref = useRef(null);
58
+ const [mounted, setMounted] = useState2(open);
59
+ const [state, setState] = useState2(open ? "entered" : "idle");
60
+ const rafRef = useRef(0);
61
+ useEffect(() => {
62
+ if (open) {
63
+ setMounted(true);
64
+ if (!animated) {
65
+ setState("entered");
66
+ return;
67
+ }
68
+ setState("entering");
69
+ rafRef.current = requestAnimationFrame(() => {
70
+ rafRef.current = requestAnimationFrame(() => {
71
+ setState("entered");
72
+ });
73
+ });
74
+ } else {
75
+ if (!animated) {
76
+ setState("idle");
77
+ setMounted(false);
78
+ return;
79
+ }
80
+ setState(
81
+ (prev) => prev === "entered" || prev === "entering" ? "leaving" : prev
82
+ );
83
+ }
84
+ return () => {
85
+ if (rafRef.current) cancelAnimationFrame(rafRef.current);
86
+ };
87
+ }, [open, animated]);
88
+ useEffect(() => {
89
+ if (state !== "leaving") return;
90
+ let cancelled = false;
91
+ const finish = () => {
92
+ if (cancelled) return;
93
+ setState("idle");
94
+ setMounted(false);
95
+ };
96
+ const el = ref.current;
97
+ if (!el || typeof el.getAnimations !== "function") {
98
+ const raf2 = requestAnimationFrame(finish);
99
+ return () => {
100
+ cancelled = true;
101
+ cancelAnimationFrame(raf2);
102
+ };
103
+ }
104
+ const raf = requestAnimationFrame(() => {
105
+ if (cancelled) return;
106
+ const animations = el.getAnimations();
107
+ if (animations.length === 0) {
108
+ finish();
109
+ return;
110
+ }
111
+ Promise.all(
112
+ animations.map((animation) => animation.finished.catch(() => {
113
+ }))
114
+ ).then(finish);
115
+ });
116
+ return () => {
117
+ cancelled = true;
118
+ cancelAnimationFrame(raf);
119
+ };
120
+ }, [state]);
121
+ const dataAttributes = {};
122
+ if (state === "entering" || state === "entered") {
123
+ dataAttributes["data-enter"] = "";
124
+ }
125
+ if (state === "leaving") {
126
+ dataAttributes["data-leave"] = "";
127
+ }
128
+ return {
129
+ ref,
130
+ mounted,
131
+ dataAttributes,
132
+ state
133
+ };
134
+ }
135
+
136
+ // src/hooks/use-focus-visible.ts
137
+ import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
138
+ var hadKeyboardEvent = true;
139
+ var listenerCount = 0;
140
+ function handleKeyDown(e) {
141
+ if (e.metaKey || e.altKey || e.ctrlKey) return;
142
+ hadKeyboardEvent = true;
143
+ }
144
+ function handlePointerDown() {
145
+ hadKeyboardEvent = false;
146
+ }
147
+ function addGlobalListeners() {
148
+ if (listenerCount === 0 && typeof document !== "undefined") {
149
+ document.addEventListener("keydown", handleKeyDown, true);
150
+ document.addEventListener("pointerdown", handlePointerDown, true);
151
+ document.addEventListener("mousedown", handlePointerDown, true);
152
+ document.addEventListener("touchstart", handlePointerDown, true);
153
+ }
154
+ listenerCount += 1;
155
+ }
156
+ function removeGlobalListeners() {
157
+ listenerCount = Math.max(0, listenerCount - 1);
158
+ if (listenerCount === 0 && typeof document !== "undefined") {
159
+ document.removeEventListener("keydown", handleKeyDown, true);
160
+ document.removeEventListener("pointerdown", handlePointerDown, true);
161
+ document.removeEventListener("mousedown", handlePointerDown, true);
162
+ document.removeEventListener("touchstart", handlePointerDown, true);
163
+ }
164
+ }
165
+ function useFocusVisible() {
166
+ useEffect2(() => {
167
+ addGlobalListeners();
168
+ return removeGlobalListeners;
169
+ }, []);
170
+ const onFocus = useCallback2((e) => {
171
+ if (hadKeyboardEvent) {
172
+ e.currentTarget.setAttribute("data-focus-visible", "");
173
+ }
174
+ }, []);
175
+ const onBlur = useCallback2((e) => {
176
+ e.currentTarget.removeAttribute("data-focus-visible");
177
+ }, []);
178
+ return {
179
+ focusVisibleProps: {
180
+ onFocus,
181
+ onBlur
182
+ }
183
+ };
184
+ }
185
+
186
+ // src/hooks/use-roving-tabindex.ts
187
+ import { useCallback as useCallback3, useRef as useRef2, useState as useState3, useEffect as useEffect3 } from "react";
188
+ function useRovingTabindex(options = {}) {
189
+ const {
190
+ orientation = "horizontal",
191
+ loop = false,
192
+ rtl = false,
193
+ columns
194
+ } = options;
195
+ const itemsRef = useRef2([]);
196
+ const [activeId, setActiveId] = useState3(null);
197
+ const containerRef = useRef2(null);
198
+ const seededRef = useRef2(false);
199
+ const getEnabledItems = useCallback3(() => {
200
+ return itemsRef.current.filter((item) => !item.disabled);
201
+ }, []);
202
+ const register = useCallback3(
203
+ (id, element, disabled) => {
204
+ var _a, _b;
205
+ const existing = itemsRef.current.findIndex((item) => item.id === id);
206
+ const activeBecameDisabled = existing >= 0 && id === activeId && !!disabled;
207
+ if (existing >= 0) {
208
+ itemsRef.current[existing] = { id, element, disabled };
209
+ } else {
210
+ itemsRef.current.push({ id, element, disabled });
211
+ }
212
+ if (activeId === null && !seededRef.current && !disabled) {
213
+ seededRef.current = true;
214
+ setActiveId(id);
215
+ } else if (activeBecameDisabled) {
216
+ const next = (_b = (_a = itemsRef.current.find((item) => !item.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
217
+ if (next === null) seededRef.current = false;
218
+ setActiveId(next);
219
+ }
220
+ },
221
+ [activeId]
222
+ );
223
+ const unregister = useCallback3(
224
+ (id) => {
225
+ var _a, _b;
226
+ itemsRef.current = itemsRef.current.filter((item) => item.id !== id);
227
+ if (activeId === id) {
228
+ const next = (_b = (_a = getEnabledItems()[0]) == null ? void 0 : _a.id) != null ? _b : null;
229
+ if (next === null) seededRef.current = false;
230
+ setActiveId(next);
231
+ }
232
+ },
233
+ [activeId, getEnabledItems]
234
+ );
235
+ const moveTo = useCallback3((id) => {
236
+ setActiveId(id);
237
+ const item = itemsRef.current.find((i) => i.id === id);
238
+ item == null ? void 0 : item.element.focus();
239
+ }, []);
240
+ const moveByOffset = useCallback3(
241
+ (offset2) => {
242
+ const enabled = getEnabledItems();
243
+ if (enabled.length === 0) return;
244
+ const currentIndex = enabled.findIndex((item) => item.id === activeId);
245
+ let nextIndex = currentIndex + offset2;
246
+ if (loop) {
247
+ nextIndex = (nextIndex % enabled.length + enabled.length) % enabled.length;
248
+ } else {
249
+ nextIndex = Math.max(0, Math.min(enabled.length - 1, nextIndex));
250
+ }
251
+ moveTo(enabled[nextIndex].id);
252
+ },
253
+ [activeId, getEnabledItems, loop, moveTo]
254
+ );
255
+ const onKeyDown = useCallback3(
256
+ (e) => {
257
+ const grid = columns !== void 0 && columns > 0;
258
+ const horizontal = grid || orientation === "horizontal" || orientation === "both";
259
+ const vertical = grid || orientation === "vertical" || orientation === "both";
260
+ const rowOffset = grid ? columns : 1;
261
+ if (vertical && e.key === "ArrowDown") {
262
+ e.preventDefault();
263
+ moveByOffset(rowOffset);
264
+ } else if (vertical && e.key === "ArrowUp") {
265
+ e.preventDefault();
266
+ moveByOffset(-rowOffset);
267
+ } else if (horizontal && e.key === "ArrowRight") {
268
+ e.preventDefault();
269
+ moveByOffset(rtl ? -1 : 1);
270
+ } else if (horizontal && e.key === "ArrowLeft") {
271
+ e.preventDefault();
272
+ moveByOffset(rtl ? 1 : -1);
273
+ } else if (e.key === "Home") {
274
+ e.preventDefault();
275
+ const enabled = getEnabledItems();
276
+ if (enabled.length > 0) moveTo(enabled[0].id);
277
+ } else if (e.key === "End") {
278
+ e.preventDefault();
279
+ const enabled = getEnabledItems();
280
+ if (enabled.length > 0) moveTo(enabled[enabled.length - 1].id);
281
+ }
282
+ },
283
+ [orientation, rtl, columns, moveByOffset, getEnabledItems, moveTo]
284
+ );
285
+ useEffect3(() => {
286
+ for (const item of itemsRef.current) {
287
+ if (item.id === activeId) {
288
+ item.element.setAttribute("data-active-item", "");
289
+ } else {
290
+ item.element.removeAttribute("data-active-item");
291
+ }
292
+ }
293
+ }, [activeId]);
294
+ return {
295
+ containerRef,
296
+ containerProps: {
297
+ ref: containerRef,
298
+ onKeyDown
299
+ },
300
+ activeId,
301
+ register,
302
+ unregister,
303
+ moveTo,
304
+ getTabIndex: (id) => id === activeId ? 0 : -1
305
+ };
306
+ }
307
+
308
+ // src/hooks/use-floating.ts
309
+ import {
310
+ useFloating as useFloatingUI,
311
+ useDismiss,
312
+ autoUpdate,
313
+ offset,
314
+ flip as flipMiddleware,
315
+ shift as shiftMiddleware,
316
+ size as sizeMiddleware,
317
+ hide as hideMiddleware
318
+ } from "@floating-ui/react";
319
+ import {
320
+ useCallback as useCallback4,
321
+ useEffect as useEffect4,
322
+ useMemo,
323
+ useRef as useRef3,
324
+ useState as useState4
325
+ } from "react";
326
+
327
+ // src/internal/state-attrs.ts
328
+ function getStateAttributesProps(attrs) {
329
+ const result = {};
330
+ for (const key in attrs) {
331
+ if (!Object.prototype.hasOwnProperty.call(attrs, key)) continue;
332
+ const value = attrs[key];
333
+ if (value === false || value == null || value === "") continue;
334
+ result[key] = value === true ? "" : String(value);
335
+ }
336
+ return result;
337
+ }
338
+
339
+ // src/hooks/use-floating.ts
340
+ function useFloating(options = {}) {
341
+ var _a, _b, _c, _d, _e, _f;
342
+ const {
343
+ placement = "bottom-start",
344
+ strategy = "absolute",
345
+ gutter,
346
+ sideOffset,
347
+ alignOffset,
348
+ sameWidth = false,
349
+ flip = true,
350
+ lazyFlip = false,
351
+ shift = 8,
352
+ overflowPadding = 12,
353
+ open = false,
354
+ onOpenChange,
355
+ dismiss
356
+ } = options;
357
+ const onOpenChangeRef = useRef3(onOpenChange);
358
+ onOpenChangeRef.current = onOpenChange;
359
+ const handleOpenChange = useCallback4(
360
+ (next, _event, reason) => {
361
+ var _a2;
362
+ (_a2 = onOpenChangeRef.current) == null ? void 0 : _a2.call(onOpenChangeRef, next, reason);
363
+ },
364
+ []
365
+ );
366
+ const sideOffsetRef = useRef3(void 0);
367
+ sideOffsetRef.current = (_a = sideOffset != null ? sideOffset : gutter) != null ? _a : 4;
368
+ const alignOffsetRef = useRef3(void 0);
369
+ alignOffsetRef.current = alignOffset;
370
+ const middleware = useMemo(() => {
371
+ const m = [];
372
+ m.push(
373
+ offset((state) => {
374
+ const args = {
375
+ rects: state.rects,
376
+ placement: state.placement
377
+ };
378
+ const so = sideOffsetRef.current;
379
+ const ao = alignOffsetRef.current;
380
+ return {
381
+ mainAxis: typeof so === "function" ? so(args) : so,
382
+ alignmentAxis: ao == null ? void 0 : typeof ao === "function" ? ao(args) : ao
383
+ };
384
+ })
385
+ );
386
+ if (flip) m.push(flipMiddleware({ padding: overflowPadding }));
387
+ if (shift) {
388
+ const shiftPadding = typeof shift === "number" ? shift : 8;
389
+ m.push(shiftMiddleware({ padding: shiftPadding }));
390
+ }
391
+ m.push(
392
+ sizeMiddleware({
393
+ padding: overflowPadding,
394
+ apply({ rects, elements, availableWidth, availableHeight }) {
395
+ const dpr = typeof window !== "undefined" && window.devicePixelRatio || 1;
396
+ const roundByDpr = (v) => Math.round(v * dpr) / dpr;
397
+ const styles = {
398
+ "--opt-available-width": `${Math.max(0, Math.round(availableWidth))}px`,
399
+ "--opt-available-height": `${Math.max(0, Math.round(availableHeight))}px`,
400
+ "--opt-anchor-width": `${roundByDpr(rects.reference.width)}px`,
401
+ "--opt-anchor-height": `${roundByDpr(rects.reference.height)}px`
402
+ };
403
+ if (sameWidth)
404
+ styles.width = `${roundByDpr(rects.reference.width)}px`;
405
+ Object.assign(elements.floating.style, styles);
406
+ }
407
+ })
408
+ );
409
+ m.push(hideMiddleware({ padding: overflowPadding }));
410
+ return m;
411
+ }, [flip, shift, sameWidth, overflowPadding]);
412
+ const [lockedPlacement, setLockedPlacement] = useState4(
413
+ null
414
+ );
415
+ const effectivePlacement = lazyFlip && lockedPlacement ? lockedPlacement : placement;
416
+ const floating = useFloatingUI({
417
+ placement: effectivePlacement,
418
+ strategy,
419
+ middleware,
420
+ whileElementsMounted: open ? autoUpdate : void 0,
421
+ open,
422
+ onOpenChange: handleOpenChange
423
+ });
424
+ const dismissConfig = typeof dismiss === "object" ? dismiss : {};
425
+ useDismiss(floating.context, {
426
+ enabled: dismiss !== void 0 && dismiss !== false,
427
+ outsidePress: (_b = dismissConfig.outsidePress) != null ? _b : true,
428
+ escapeKey: (_c = dismissConfig.escapeKey) != null ? _c : true,
429
+ ancestorScroll: (_d = dismissConfig.ancestorScroll) != null ? _d : false
430
+ });
431
+ const isPositioned = floating.isPositioned;
432
+ useEffect4(() => {
433
+ if (!open) {
434
+ setLockedPlacement(null);
435
+ }
436
+ }, [open]);
437
+ useEffect4(() => {
438
+ if (open && lazyFlip && isPositioned && lockedPlacement === null) {
439
+ setLockedPlacement(floating.placement);
440
+ }
441
+ }, [open, lazyFlip, isPositioned, floating.placement, lockedPlacement]);
442
+ const [side, alignPart] = floating.placement.split("-");
443
+ const align = alignPart != null ? alignPart : "center";
444
+ const anchorHidden = (_f = (_e = floating.middlewareData.hide) == null ? void 0 : _e.referenceHidden) != null ? _f : false;
445
+ return {
446
+ refs: floating.refs,
447
+ floatingStyles: floating.floatingStyles,
448
+ placement: floating.placement,
449
+ side,
450
+ align,
451
+ isPositioned,
452
+ anchorHidden,
453
+ context: floating.context,
454
+ getReferenceProps: () => ({
455
+ ref: floating.refs.setReference
456
+ }),
457
+ getFloatingProps: () => ({
458
+ ref: floating.refs.setFloating,
459
+ style: __spreadValues(__spreadValues({
460
+ // Seed the available-space caps so first-frame CSS
461
+ // (max-height: var(--opt-available-height)) resolves before the size
462
+ // middleware runs — the imperative apply() then refines these.
463
+ "--opt-available-width": "100vw",
464
+ "--opt-available-height": "100vh"
465
+ }, floating.floatingStyles), isPositioned ? null : { opacity: 0 })
466
+ }),
467
+ /**
468
+ * `data-open`/`data-closed`/`data-side`/`data-align`/`data-anchor-hidden`
469
+ * for the positioner. Additive — spread onto the panel alongside existing
470
+ * data attributes so Core can target open state, resolved side, and anchor
471
+ * visibility with CSS only.
472
+ */
473
+ getPositionerStateProps: (isOpen) => getStateAttributesProps({
474
+ "data-open": isOpen,
475
+ "data-closed": !isOpen,
476
+ "data-side": side,
477
+ "data-align": align,
478
+ "data-anchor-hidden": anchorHidden
479
+ })
480
+ };
481
+ }
482
+
483
+ // src/hooks/use-id.ts
484
+ import { useId as useReactId } from "react";
485
+ function useId(providedId) {
486
+ const generatedId = useReactId();
487
+ return providedId != null ? providedId : generatedId;
488
+ }
489
+
490
+ // src/hooks/use-focusable-when-disabled.ts
491
+ function useFocusableWhenDisabled({
492
+ disabled = false,
493
+ focusableWhenDisabled = false,
494
+ isNativeButton = true,
495
+ tabIndex
496
+ }) {
497
+ const inert = disabled && focusableWhenDisabled;
498
+ return {
499
+ // Emit native `disabled` only when NOT keeping the element focusable.
500
+ disabled: isNativeButton ? disabled && !focusableWhenDisabled : void 0,
501
+ "aria-disabled": inert ? true : void 0,
502
+ // Native buttons are focusable by default; a non-native element needs an
503
+ // explicit tabIndex to remain reachable while disabled.
504
+ tabIndex: !isNativeButton && inert ? tabIndex != null ? tabIndex : 0 : tabIndex
505
+ };
506
+ }
507
+
508
+ // src/hooks/use-scroll-into-view.ts
509
+ import { useEffect as useEffect5 } from "react";
510
+ function useScrollActiveDescendantIntoView(activeId) {
511
+ useEffect5(() => {
512
+ if (!activeId) return;
513
+ const el = document.getElementById(activeId);
514
+ if (el && typeof el.scrollIntoView === "function") {
515
+ el.scrollIntoView({ block: "nearest", inline: "nearest" });
516
+ }
517
+ }, [activeId]);
518
+ }
519
+
520
+ // src/primitives/disclosure.tsx
521
+ import {
522
+ createContext,
523
+ useContext,
524
+ useCallback as useCallback5,
525
+ useRef as useRef4,
526
+ useEffect as useEffect6
527
+ } from "react";
528
+ import { jsx } from "react/jsx-runtime";
529
+ var DisclosureContext = createContext(null);
530
+ function useDisclosureContext() {
531
+ const ctx = useContext(DisclosureContext);
532
+ if (!ctx)
533
+ throw new Error("Disclosure components must be used within DisclosureRoot");
534
+ return ctx;
535
+ }
536
+ function DisclosureRoot({
537
+ children,
538
+ open: controlledOpen,
539
+ defaultOpen = false,
540
+ onOpenChange,
541
+ setOpen: setOpenDeprecated,
542
+ animated = true
543
+ }) {
544
+ const [open, setOpen] = useControllableState(
545
+ defaultOpen,
546
+ controlledOpen,
547
+ onOpenChange != null ? onOpenChange : setOpenDeprecated
548
+ );
549
+ const baseId = useId();
550
+ const contentId = `${baseId}-content`;
551
+ const triggerId = `${baseId}-trigger`;
552
+ return /* @__PURE__ */ jsx(
553
+ DisclosureContext.Provider,
554
+ {
555
+ value: { open, setOpen, contentId, triggerId, animated },
556
+ children
557
+ }
558
+ );
559
+ }
560
+ function DisclosureTrigger(_a) {
561
+ var _b = _a, {
562
+ onClick
563
+ } = _b, props = __objRest(_b, [
564
+ "onClick"
565
+ ]);
566
+ const { open, setOpen, contentId, triggerId } = useDisclosureContext();
567
+ const handleClick = useCallback5(
568
+ (e) => {
569
+ setOpen(!open);
570
+ onClick == null ? void 0 : onClick(e);
571
+ },
572
+ [open, setOpen, onClick]
573
+ );
574
+ return /* @__PURE__ */ jsx(
575
+ "button",
576
+ __spreadValues({
577
+ type: "button",
578
+ id: triggerId,
579
+ "aria-expanded": open,
580
+ "aria-controls": contentId,
581
+ onClick: handleClick
582
+ }, props)
583
+ );
584
+ }
585
+ function DisclosureContent(_a) {
586
+ var _b = _a, {
587
+ hiddenUntilFound = false,
588
+ style
589
+ } = _b, props = __objRest(_b, [
590
+ "hiddenUntilFound",
591
+ "style"
592
+ ]);
593
+ const { open, setOpen, contentId, triggerId, animated } = useDisclosureContext();
594
+ const { ref, mounted, dataAttributes } = useEnterLeave(open, {
595
+ animated: animated && !hiddenUntilFound
596
+ });
597
+ const innerRef = useRef4(null);
598
+ useEffect6(() => {
599
+ if (innerRef.current) {
600
+ ref.current = innerRef.current;
601
+ }
602
+ }, [ref]);
603
+ useEffect6(() => {
604
+ const el = innerRef.current;
605
+ if (!el || !hiddenUntilFound) return;
606
+ const onBeforeMatch = () => setOpen(true);
607
+ el.addEventListener("beforematch", onBeforeMatch);
608
+ return () => el.removeEventListener("beforematch", onBeforeMatch);
609
+ }, [hiddenUntilFound, setOpen]);
610
+ useEffect6(() => {
611
+ const el = innerRef.current;
612
+ if (!el || !hiddenUntilFound) return;
613
+ if (open) el.removeAttribute("hidden");
614
+ else el.setAttribute("hidden", "until-found");
615
+ }, [open, hiddenUntilFound]);
616
+ if (hiddenUntilFound) {
617
+ return /* @__PURE__ */ jsx(
618
+ "div",
619
+ __spreadValues({
620
+ ref: innerRef,
621
+ id: contentId,
622
+ role: "region",
623
+ "aria-labelledby": triggerId,
624
+ "data-state": open ? "open" : "closed",
625
+ style
626
+ }, props)
627
+ );
628
+ }
629
+ if (!mounted) return null;
630
+ return /* @__PURE__ */ jsx(
631
+ "div",
632
+ __spreadValues(__spreadValues({
633
+ ref: innerRef,
634
+ id: contentId,
635
+ role: "region",
636
+ "aria-labelledby": triggerId,
637
+ style
638
+ }, dataAttributes), props)
639
+ );
640
+ }
641
+
642
+ // src/primitives/button.tsx
643
+ import { forwardRef, useCallback as useCallback6 } from "react";
644
+ import { jsx as jsx2 } from "react/jsx-runtime";
645
+ var Button = forwardRef(
646
+ (_a, ref) => {
647
+ var _b = _a, {
648
+ type = "button",
649
+ clickOnEnter,
650
+ clickOnSpace,
651
+ focusableWhenDisabled = false,
652
+ disabled = false,
653
+ onKeyDown,
654
+ onClick
655
+ } = _b, props = __objRest(_b, [
656
+ "type",
657
+ "clickOnEnter",
658
+ "clickOnSpace",
659
+ "focusableWhenDisabled",
660
+ "disabled",
661
+ "onKeyDown",
662
+ "onClick"
663
+ ]);
664
+ const focusableProps = useFocusableWhenDisabled({
665
+ disabled,
666
+ focusableWhenDisabled
667
+ });
668
+ const inert = disabled && focusableWhenDisabled;
669
+ const handleKeyDown2 = useCallback6(
670
+ (e) => {
671
+ if (inert) {
672
+ if (e.key === "Enter" || e.key === " ") {
673
+ e.preventDefault();
674
+ return;
675
+ }
676
+ } else {
677
+ if (clickOnEnter === false && e.key === "Enter") {
678
+ e.preventDefault();
679
+ }
680
+ if (clickOnSpace === false && e.key === " ") {
681
+ e.preventDefault();
682
+ }
683
+ }
684
+ onKeyDown == null ? void 0 : onKeyDown(e);
685
+ },
686
+ [inert, clickOnEnter, clickOnSpace, onKeyDown]
687
+ );
688
+ const handleClick = useCallback6(
689
+ (e) => {
690
+ if (inert) {
691
+ e.preventDefault();
692
+ e.stopPropagation();
693
+ return;
694
+ }
695
+ onClick == null ? void 0 : onClick(e);
696
+ },
697
+ [inert, onClick]
698
+ );
699
+ const needsKeyHandler = inert || clickOnEnter === false || clickOnSpace === false;
700
+ return /* @__PURE__ */ jsx2(
701
+ "button",
702
+ __spreadProps(__spreadValues(__spreadValues({
703
+ ref,
704
+ type
705
+ }, focusableProps), props), {
706
+ onKeyDown: needsKeyHandler ? handleKeyDown2 : onKeyDown,
707
+ onClick: handleClick
708
+ })
709
+ );
710
+ }
711
+ );
712
+ Button.displayName = "Button";
713
+
714
+ // src/primitives/dialog.tsx
715
+ import {
716
+ createContext as createContext2,
717
+ useContext as useContext2,
718
+ useCallback as useCallback7,
719
+ useRef as useRef5,
720
+ useEffect as useEffect7,
721
+ forwardRef as forwardRef2
722
+ } from "react";
723
+ import { jsx as jsx3 } from "react/jsx-runtime";
724
+ var DialogContext = createContext2(null);
725
+ function useDialogContext() {
726
+ const ctx = useContext2(DialogContext);
727
+ if (!ctx) throw new Error("Dialog components must be used within DialogRoot");
728
+ return ctx;
729
+ }
730
+ function useDialogClose() {
731
+ const { setOpen } = useDialogContext();
732
+ return () => setOpen(false);
733
+ }
734
+ function DialogRoot({
735
+ children,
736
+ open: controlledOpen,
737
+ defaultOpen = false,
738
+ onOpenChange,
739
+ setOpen: setOpenDeprecated,
740
+ animated = true
741
+ }) {
742
+ const [open, setOpen] = useControllableState(
743
+ defaultOpen,
744
+ controlledOpen,
745
+ onOpenChange != null ? onOpenChange : setOpenDeprecated
746
+ );
747
+ const baseId = useId();
748
+ const headingId = `${baseId}-heading`;
749
+ const descriptionId = `${baseId}-description`;
750
+ const dialogRef = useRef5(null);
751
+ return /* @__PURE__ */ jsx3(
752
+ DialogContext.Provider,
753
+ {
754
+ value: { open, setOpen, headingId, descriptionId, animated, dialogRef },
755
+ children
756
+ }
757
+ );
758
+ }
759
+ var DialogDisclosure = forwardRef2((_a, ref) => {
760
+ var _b = _a, { onClick } = _b, props = __objRest(_b, ["onClick"]);
761
+ const { setOpen } = useDialogContext();
762
+ const handleClick = useCallback7(
763
+ (e) => {
764
+ setOpen(true);
765
+ onClick == null ? void 0 : onClick(e);
766
+ },
767
+ [setOpen, onClick]
768
+ );
769
+ return /* @__PURE__ */ jsx3("button", __spreadValues({ ref, type: "button", onClick: handleClick }, props));
770
+ });
771
+ DialogDisclosure.displayName = "DialogDisclosure";
772
+ var DialogPanel = forwardRef2(
773
+ (_a, forwardedRef) => {
774
+ var _b = _a, {
775
+ backdrop: _backdrop,
776
+ dismissOnBackdrop = true,
777
+ dismissOnEscape = true,
778
+ children,
779
+ onClick
780
+ } = _b, props = __objRest(_b, [
781
+ "backdrop",
782
+ "dismissOnBackdrop",
783
+ "dismissOnEscape",
784
+ "children",
785
+ "onClick"
786
+ ]);
787
+ const { open, setOpen, headingId, descriptionId, animated, dialogRef } = useDialogContext();
788
+ const {
789
+ ref: enterLeaveRef,
790
+ mounted,
791
+ dataAttributes
792
+ } = useEnterLeave(open, { animated });
793
+ const lastFocusedRef = useRef5(null);
794
+ const wasMountedRef = useRef5(false);
795
+ useEffect7(() => {
796
+ const dialog = dialogRef.current;
797
+ if (!dialog) return;
798
+ if (mounted && !dialog.open) {
799
+ lastFocusedRef.current = document.activeElement;
800
+ dialog.showModal();
801
+ }
802
+ }, [mounted, dialogRef]);
803
+ useEffect7(() => {
804
+ var _a2;
805
+ if (mounted) {
806
+ wasMountedRef.current = true;
807
+ } else if (wasMountedRef.current) {
808
+ wasMountedRef.current = false;
809
+ (_a2 = lastFocusedRef.current) == null ? void 0 : _a2.focus();
810
+ lastFocusedRef.current = null;
811
+ }
812
+ }, [mounted]);
813
+ const mergedRef = useCallback7(
814
+ (node) => {
815
+ dialogRef.current = node;
816
+ enterLeaveRef.current = node;
817
+ if (typeof forwardedRef === "function") forwardedRef(node);
818
+ else if (forwardedRef) forwardedRef.current = node;
819
+ },
820
+ [dialogRef, enterLeaveRef, forwardedRef]
821
+ );
822
+ useEffect7(() => {
823
+ const dialog = dialogRef.current;
824
+ if (!dialog) return;
825
+ const handleCancel = (e) => {
826
+ e.preventDefault();
827
+ if (dismissOnEscape) setOpen(false);
828
+ };
829
+ dialog.addEventListener("cancel", handleCancel);
830
+ return () => dialog.removeEventListener("cancel", handleCancel);
831
+ }, [dialogRef, setOpen, dismissOnEscape]);
832
+ const handleClick = useCallback7(
833
+ (e) => {
834
+ if (dismissOnBackdrop && e.target === e.currentTarget) {
835
+ setOpen(false);
836
+ }
837
+ onClick == null ? void 0 : onClick(e);
838
+ },
839
+ [setOpen, onClick, dismissOnBackdrop]
840
+ );
841
+ if (!mounted) return null;
842
+ return /* @__PURE__ */ jsx3(
843
+ "dialog",
844
+ __spreadProps(__spreadValues(__spreadValues({
845
+ ref: mergedRef,
846
+ "aria-labelledby": headingId,
847
+ "aria-describedby": descriptionId,
848
+ onClick: handleClick
849
+ }, dataAttributes), props), {
850
+ children
851
+ })
852
+ );
853
+ }
854
+ );
855
+ DialogPanel.displayName = "DialogPanel";
856
+ var AlertDialogPanel = forwardRef2(function AlertDialogPanel2(props, ref) {
857
+ return /* @__PURE__ */ jsx3(
858
+ DialogPanel,
859
+ __spreadValues({
860
+ ref,
861
+ role: "alertdialog",
862
+ dismissOnBackdrop: false,
863
+ dismissOnEscape: false
864
+ }, props)
865
+ );
866
+ });
867
+ function DialogHeading(props) {
868
+ const { headingId } = useDialogContext();
869
+ return /* @__PURE__ */ jsx3("h2", __spreadValues({ id: headingId }, props));
870
+ }
871
+ function DialogDescription(props) {
872
+ const { descriptionId } = useDialogContext();
873
+ return /* @__PURE__ */ jsx3("p", __spreadValues({ id: descriptionId }, props));
874
+ }
875
+ var DialogDismiss = forwardRef2(
876
+ (_a, ref) => {
877
+ var _b = _a, { onClick } = _b, props = __objRest(_b, ["onClick"]);
878
+ const { setOpen } = useDialogContext();
879
+ const handleClick = useCallback7(
880
+ (e) => {
881
+ setOpen(false);
882
+ onClick == null ? void 0 : onClick(e);
883
+ },
884
+ [setOpen, onClick]
885
+ );
886
+ return /* @__PURE__ */ jsx3("button", __spreadValues({ ref, type: "button", onClick: handleClick }, props));
887
+ }
888
+ );
889
+ DialogDismiss.displayName = "DialogDismiss";
890
+
891
+ // src/primitives/tabs.tsx
892
+ import {
893
+ createContext as createContext3,
894
+ useContext as useContext3,
895
+ useCallback as useCallback8,
896
+ useRef as useRef6,
897
+ useLayoutEffect
898
+ } from "react";
899
+ import { jsx as jsx4 } from "react/jsx-runtime";
900
+ function nextEnabledTabId(tabs, currentId, delta) {
901
+ const enabled = tabs.filter((t) => !t.disabled);
902
+ if (enabled.length === 0) return null;
903
+ const idx = enabled.findIndex((t) => t.id === currentId);
904
+ if (idx < 0) return enabled[0].id;
905
+ const n = enabled.length;
906
+ const next = ((idx + delta) % n + n) % n;
907
+ return enabled[next].id;
908
+ }
909
+ var TabsContext = createContext3(null);
910
+ function useTabsContext() {
911
+ const ctx = useContext3(TabsContext);
912
+ if (!ctx) throw new Error("Tabs components must be used within TabsRoot");
913
+ return ctx;
914
+ }
915
+ function TabsRoot({
916
+ children,
917
+ selectedId: controlledId,
918
+ defaultSelectedId = "",
919
+ onSelectedIdChange,
920
+ setSelectedId: setSelectedIdDeprecated,
921
+ orientation = "horizontal"
922
+ }) {
923
+ const [selectedId, setSelectedId] = useControllableState(
924
+ defaultSelectedId,
925
+ controlledId,
926
+ onSelectedIdChange != null ? onSelectedIdChange : setSelectedIdDeprecated
927
+ );
928
+ const baseId = useId();
929
+ const tabs = useRef6([]);
930
+ const registerTab = useCallback8((id, disabled) => {
931
+ const existing = tabs.current.findIndex((t) => t.id === id);
932
+ if (existing >= 0) tabs.current[existing] = { id, disabled };
933
+ else tabs.current.push({ id, disabled });
934
+ }, []);
935
+ const unregisterTab = useCallback8((id) => {
936
+ tabs.current = tabs.current.filter((t) => t.id !== id);
937
+ }, []);
938
+ useLayoutEffect(() => {
939
+ if (!selectedId) {
940
+ const first = tabs.current.find((t) => !t.disabled);
941
+ if (first) setSelectedId(first.id);
942
+ }
943
+ }, [selectedId, setSelectedId]);
944
+ return /* @__PURE__ */ jsx4(
945
+ TabsContext.Provider,
946
+ {
947
+ value: {
948
+ selectedId,
949
+ setSelectedId,
950
+ baseId,
951
+ orientation,
952
+ registerTab,
953
+ unregisterTab,
954
+ tabs
955
+ },
956
+ children
957
+ }
958
+ );
959
+ }
960
+ function TabList(_a) {
961
+ var _b = _a, {
962
+ role = "tablist",
963
+ onKeyDown
964
+ } = _b, props = __objRest(_b, [
965
+ "role",
966
+ "onKeyDown"
967
+ ]);
968
+ const { selectedId, setSelectedId, tabs, orientation } = useTabsContext();
969
+ const handleKeyDown2 = useCallback8(
970
+ (e) => {
971
+ var _a2, _b2, _c, _d, _e;
972
+ const prevKey = orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
973
+ const nextKey = orientation === "vertical" ? "ArrowDown" : "ArrowRight";
974
+ let nextId = null;
975
+ if (e.key === nextKey) {
976
+ e.preventDefault();
977
+ nextId = nextEnabledTabId(tabs.current, selectedId, 1);
978
+ } else if (e.key === prevKey) {
979
+ e.preventDefault();
980
+ nextId = nextEnabledTabId(tabs.current, selectedId, -1);
981
+ } else if (e.key === "Home") {
982
+ e.preventDefault();
983
+ nextId = (_b2 = (_a2 = tabs.current.find((t) => !t.disabled)) == null ? void 0 : _a2.id) != null ? _b2 : null;
984
+ } else if (e.key === "End") {
985
+ e.preventDefault();
986
+ nextId = (_d = (_c = [...tabs.current].reverse().find((t) => !t.disabled)) == null ? void 0 : _c.id) != null ? _d : null;
987
+ }
988
+ if (nextId) {
989
+ setSelectedId(nextId);
990
+ (_e = document.getElementById(`${nextId}-tab`)) == null ? void 0 : _e.focus();
991
+ }
992
+ onKeyDown == null ? void 0 : onKeyDown(e);
993
+ },
994
+ [selectedId, setSelectedId, tabs, orientation, onKeyDown]
995
+ );
996
+ return /* @__PURE__ */ jsx4(
997
+ "div",
998
+ __spreadValues({
999
+ role,
1000
+ "aria-orientation": orientation,
1001
+ onKeyDown: handleKeyDown2
1002
+ }, props)
1003
+ );
1004
+ }
1005
+ function Tab(_a) {
1006
+ var _b = _a, { id, disabled, onClick } = _b, props = __objRest(_b, ["id", "disabled", "onClick"]);
1007
+ const { selectedId, setSelectedId, registerTab, unregisterTab } = useTabsContext();
1008
+ const isSelected = selectedId === id;
1009
+ useLayoutEffect(() => {
1010
+ registerTab(id, disabled);
1011
+ return () => unregisterTab(id);
1012
+ }, [id, disabled, registerTab, unregisterTab]);
1013
+ const handleClick = useCallback8(
1014
+ (e) => {
1015
+ if (!disabled) setSelectedId(id);
1016
+ onClick == null ? void 0 : onClick(e);
1017
+ },
1018
+ [id, disabled, setSelectedId, onClick]
1019
+ );
1020
+ return /* @__PURE__ */ jsx4(
1021
+ "button",
1022
+ __spreadValues({
1023
+ type: "button",
1024
+ role: "tab",
1025
+ id: `${id}-tab`,
1026
+ "aria-selected": isSelected,
1027
+ "aria-controls": isSelected ? `${id}-panel` : void 0,
1028
+ tabIndex: isSelected ? 0 : -1,
1029
+ disabled,
1030
+ "data-active-item": isSelected ? "" : void 0,
1031
+ onClick: handleClick
1032
+ }, props)
1033
+ );
1034
+ }
1035
+ function TabPanel(_a) {
1036
+ var _b = _a, { tabId } = _b, props = __objRest(_b, ["tabId"]);
1037
+ const { selectedId } = useTabsContext();
1038
+ const isSelected = selectedId === tabId;
1039
+ if (!isSelected) return null;
1040
+ return /* @__PURE__ */ jsx4(
1041
+ "div",
1042
+ __spreadValues({
1043
+ role: "tabpanel",
1044
+ id: `${tabId}-panel`,
1045
+ "aria-labelledby": `${tabId}-tab`,
1046
+ tabIndex: 0
1047
+ }, props)
1048
+ );
1049
+ }
1050
+
1051
+ // src/primitives/radio-group.tsx
1052
+ import {
1053
+ createContext as createContext4,
1054
+ useContext as useContext4,
1055
+ useCallback as useCallback9,
1056
+ forwardRef as forwardRef3,
1057
+ useId as useReactId2
1058
+ } from "react";
1059
+ import { jsx as jsx5 } from "react/jsx-runtime";
1060
+ var RadioGroupContext = createContext4(null);
1061
+ function useRadioGroupContext() {
1062
+ return useContext4(RadioGroupContext);
1063
+ }
1064
+ function RadioGroupRoot(_a) {
1065
+ var _b = _a, {
1066
+ children,
1067
+ name: providedName,
1068
+ value: controlledValue,
1069
+ defaultValue = "",
1070
+ onValueChange,
1071
+ onChange,
1072
+ disabled = false,
1073
+ orientation = "vertical"
1074
+ } = _b, props = __objRest(_b, [
1075
+ "children",
1076
+ "name",
1077
+ "value",
1078
+ "defaultValue",
1079
+ "onValueChange",
1080
+ "onChange",
1081
+ "disabled",
1082
+ "orientation"
1083
+ ]);
1084
+ const [value, setValue] = useControllableState(
1085
+ defaultValue,
1086
+ controlledValue,
1087
+ onValueChange != null ? onValueChange : onChange
1088
+ );
1089
+ const generatedName = useReactId2().replace(/:/g, "");
1090
+ const name = providedName != null ? providedName : `radio-group-${generatedName}`;
1091
+ return /* @__PURE__ */ jsx5(
1092
+ RadioGroupContext.Provider,
1093
+ {
1094
+ value: { name, value, setValue, disabled, orientation },
1095
+ children: /* @__PURE__ */ jsx5("div", __spreadProps(__spreadValues({ role: "radiogroup", "aria-orientation": orientation }, props), { children }))
1096
+ }
1097
+ );
1098
+ }
1099
+ var Radio = forwardRef3(
1100
+ (_a, ref) => {
1101
+ var _b = _a, { value, disabled: itemDisabled, className } = _b, props = __objRest(_b, ["value", "disabled", "className"]);
1102
+ const group = useRadioGroupContext();
1103
+ if (!group) throw new Error("Radio must be used within RadioGroupRoot");
1104
+ const {
1105
+ name,
1106
+ value: groupValue,
1107
+ setValue,
1108
+ disabled: groupDisabled
1109
+ } = group;
1110
+ const isDisabled = itemDisabled != null ? itemDisabled : groupDisabled;
1111
+ const isChecked = groupValue === value;
1112
+ const handleChange = useCallback9(() => {
1113
+ if (!isDisabled) setValue(value);
1114
+ }, [isDisabled, setValue, value]);
1115
+ return /* @__PURE__ */ jsx5(
1116
+ "input",
1117
+ __spreadValues({
1118
+ ref,
1119
+ type: "radio",
1120
+ name,
1121
+ value,
1122
+ checked: isChecked,
1123
+ disabled: isDisabled,
1124
+ onChange: handleChange,
1125
+ className
1126
+ }, props)
1127
+ );
1128
+ }
1129
+ );
1130
+ Radio.displayName = "Radio";
1131
+
1132
+ // src/primitives/tooltip.tsx
1133
+ import React, {
1134
+ createContext as createContext5,
1135
+ useContext as useContext5,
1136
+ useCallback as useCallback10,
1137
+ useRef as useRef7,
1138
+ useEffect as useEffect8,
1139
+ useState as useState5,
1140
+ forwardRef as forwardRef4
1141
+ } from "react";
1142
+
1143
+ // src/internal/merge-props.ts
1144
+ var EVENT_HANDLER = /^on[A-Z]/;
1145
+ function mergeProps(...parts) {
1146
+ const result = {};
1147
+ for (const part of parts) {
1148
+ if (!part) continue;
1149
+ for (const key in part) {
1150
+ if (!Object.prototype.hasOwnProperty.call(part, key)) continue;
1151
+ const value = part[key];
1152
+ const existing = result[key];
1153
+ if (EVENT_HANDLER.test(key) && typeof value === "function" && typeof existing === "function") {
1154
+ const a = existing;
1155
+ const b = value;
1156
+ result[key] = (...args) => {
1157
+ a(...args);
1158
+ return b(...args);
1159
+ };
1160
+ } else if (key === "className") {
1161
+ const merged = [existing, value].filter(Boolean).join(" ");
1162
+ result[key] = merged || void 0;
1163
+ } else if (key === "style" && existing && typeof existing === "object" && value && typeof value === "object") {
1164
+ result[key] = __spreadValues(__spreadValues({}, existing), value);
1165
+ } else {
1166
+ result[key] = value;
1167
+ }
1168
+ }
1169
+ }
1170
+ return result;
1171
+ }
1172
+ function mergeRefs(...refs) {
1173
+ return (value) => {
1174
+ for (const ref of refs) {
1175
+ if (typeof ref === "function") {
1176
+ ref(value);
1177
+ } else if (ref != null) {
1178
+ ref.current = value;
1179
+ }
1180
+ }
1181
+ };
1182
+ }
1183
+
1184
+ // src/internal/overlay-portal.tsx
1185
+ import { FloatingPortal } from "@floating-ui/react";
1186
+ import { Fragment, jsx as jsx6 } from "react/jsx-runtime";
1187
+ function OverlayPortal({
1188
+ portal,
1189
+ portalRoot,
1190
+ children
1191
+ }) {
1192
+ if (!portal) return /* @__PURE__ */ jsx6(Fragment, { children });
1193
+ if (typeof portalRoot === "string") {
1194
+ return /* @__PURE__ */ jsx6(FloatingPortal, { id: portalRoot, children });
1195
+ }
1196
+ return /* @__PURE__ */ jsx6(FloatingPortal, { root: portalRoot != null ? portalRoot : void 0, children });
1197
+ }
1198
+
1199
+ // src/primitives/tooltip.tsx
1200
+ import { jsx as jsx7 } from "react/jsx-runtime";
1201
+ function mergeAriaDescribedBy(...values) {
1202
+ const ids = values.flatMap(
1203
+ (value) => typeof value === "string" ? value.trim().split(/\s+/) : []
1204
+ );
1205
+ const uniqueIds = [...new Set(ids.filter(Boolean))];
1206
+ return uniqueIds.length > 0 ? uniqueIds.join(" ") : void 0;
1207
+ }
1208
+ var TooltipContext = createContext5(null);
1209
+ function useTooltipContext() {
1210
+ const ctx = useContext5(TooltipContext);
1211
+ if (!ctx)
1212
+ throw new Error("Tooltip components must be used within TooltipProvider");
1213
+ return ctx;
1214
+ }
1215
+ function TooltipProvider({
1216
+ children,
1217
+ timeout,
1218
+ showTimeout = 700,
1219
+ hideTimeout = 300,
1220
+ placement = "top",
1221
+ animated = true,
1222
+ portal = false,
1223
+ portalRoot = null
1224
+ }) {
1225
+ const [open, setOpen] = useState5(false);
1226
+ const tooltipId = useId();
1227
+ const showDelay = timeout != null ? timeout : showTimeout;
1228
+ const showTimerRef = useRef7(void 0);
1229
+ const hideTimerRef = useRef7(void 0);
1230
+ const { getReferenceProps: getFloatRefProps, getFloatingProps } = useFloating(
1231
+ {
1232
+ placement,
1233
+ gutter: 8,
1234
+ open
1235
+ }
1236
+ );
1237
+ const show = useCallback10(() => {
1238
+ clearTimeout(hideTimerRef.current);
1239
+ showTimerRef.current = setTimeout(() => setOpen(true), showDelay);
1240
+ }, [showDelay]);
1241
+ const hide = useCallback10(() => {
1242
+ clearTimeout(showTimerRef.current);
1243
+ hideTimerRef.current = setTimeout(() => setOpen(false), hideTimeout);
1244
+ }, [hideTimeout]);
1245
+ useEffect8(() => {
1246
+ return () => {
1247
+ clearTimeout(showTimerRef.current);
1248
+ clearTimeout(hideTimerRef.current);
1249
+ };
1250
+ }, []);
1251
+ useEffect8(() => {
1252
+ if (!open) return;
1253
+ const handler = (e) => {
1254
+ if (e.key === "Escape") {
1255
+ clearTimeout(showTimerRef.current);
1256
+ clearTimeout(hideTimerRef.current);
1257
+ setOpen(false);
1258
+ }
1259
+ };
1260
+ document.addEventListener("keydown", handler);
1261
+ return () => document.removeEventListener("keydown", handler);
1262
+ }, [open]);
1263
+ const getReferenceProps = useCallback10(() => {
1264
+ return __spreadProps(__spreadValues({}, getFloatRefProps()), {
1265
+ "aria-describedby": open ? tooltipId : void 0,
1266
+ onMouseEnter: show,
1267
+ onMouseLeave: hide,
1268
+ onFocus: show,
1269
+ onBlur: hide
1270
+ });
1271
+ }, [getFloatRefProps, open, tooltipId, show, hide]);
1272
+ return /* @__PURE__ */ jsx7(
1273
+ TooltipContext.Provider,
1274
+ {
1275
+ value: {
1276
+ open,
1277
+ setOpen,
1278
+ tooltipId,
1279
+ show,
1280
+ hide,
1281
+ animated,
1282
+ portal,
1283
+ portalRoot,
1284
+ getReferenceProps,
1285
+ getFloatingProps
1286
+ },
1287
+ children
1288
+ }
1289
+ );
1290
+ }
1291
+ var TooltipAnchor = forwardRef4(
1292
+ (_a, ref) => {
1293
+ var _b = _a, { children, render, "aria-describedby": ariaDescribedBy } = _b, props = __objRest(_b, ["children", "render", "aria-describedby"]);
1294
+ const { getReferenceProps } = useTooltipContext();
1295
+ const _a2 = getReferenceProps(), {
1296
+ ref: referenceRef,
1297
+ "aria-describedby": referenceDescribedBy
1298
+ } = _a2, referenceProps = __objRest(_a2, [
1299
+ "ref",
1300
+ "aria-describedby"
1301
+ ]);
1302
+ if (render) {
1303
+ const renderProps = render.props;
1304
+ const renderRef = renderProps.ref;
1305
+ const mergedProps2 = mergeProps(renderProps, props, referenceProps);
1306
+ return React.cloneElement(render, __spreadProps(__spreadValues({}, mergedProps2), {
1307
+ "aria-describedby": mergeAriaDescribedBy(
1308
+ renderProps["aria-describedby"],
1309
+ ariaDescribedBy,
1310
+ referenceDescribedBy
1311
+ ),
1312
+ ref: mergeRefs(renderRef, ref, referenceRef)
1313
+ }));
1314
+ }
1315
+ const mergedProps = mergeProps(props, referenceProps);
1316
+ return /* @__PURE__ */ jsx7(
1317
+ "div",
1318
+ __spreadProps(__spreadValues({
1319
+ ref: mergeRefs(
1320
+ ref,
1321
+ referenceRef
1322
+ )
1323
+ }, mergedProps), {
1324
+ "aria-describedby": mergeAriaDescribedBy(
1325
+ ariaDescribedBy,
1326
+ referenceDescribedBy
1327
+ ),
1328
+ children
1329
+ })
1330
+ );
1331
+ }
1332
+ );
1333
+ TooltipAnchor.displayName = "TooltipAnchor";
1334
+ function Tooltip(_a) {
1335
+ var _b = _a, {
1336
+ children,
1337
+ onMouseEnter,
1338
+ onMouseLeave
1339
+ } = _b, props = __objRest(_b, [
1340
+ "children",
1341
+ "onMouseEnter",
1342
+ "onMouseLeave"
1343
+ ]);
1344
+ const {
1345
+ open,
1346
+ tooltipId,
1347
+ show,
1348
+ hide,
1349
+ animated,
1350
+ portal,
1351
+ portalRoot,
1352
+ getFloatingProps
1353
+ } = useTooltipContext();
1354
+ const { mounted, dataAttributes, ref } = useEnterLeave(open, { animated });
1355
+ const floatingProps = getFloatingProps();
1356
+ if (!mounted) return null;
1357
+ const node = /* @__PURE__ */ jsx7(
1358
+ "div",
1359
+ __spreadProps(__spreadValues(__spreadValues({
1360
+ ref: (n) => {
1361
+ ref.current = n;
1362
+ if (floatingProps.ref && typeof floatingProps.ref === "function") {
1363
+ floatingProps.ref(n);
1364
+ }
1365
+ },
1366
+ id: tooltipId,
1367
+ role: "tooltip",
1368
+ style: floatingProps.style,
1369
+ onMouseEnter: (e) => {
1370
+ show();
1371
+ onMouseEnter == null ? void 0 : onMouseEnter(e);
1372
+ },
1373
+ onMouseLeave: (e) => {
1374
+ hide();
1375
+ onMouseLeave == null ? void 0 : onMouseLeave(e);
1376
+ }
1377
+ }, dataAttributes), props), {
1378
+ children
1379
+ })
1380
+ );
1381
+ return /* @__PURE__ */ jsx7(OverlayPortal, { portal, portalRoot, children: node });
1382
+ }
1383
+
1384
+ // src/primitives/popover.tsx
1385
+ import {
1386
+ createContext as createContext6,
1387
+ useContext as useContext6,
1388
+ useCallback as useCallback11,
1389
+ forwardRef as forwardRef5
1390
+ } from "react";
1391
+ import { FloatingFocusManager } from "@floating-ui/react";
1392
+ import { jsx as jsx8 } from "react/jsx-runtime";
1393
+ var PopoverContext = createContext6(null);
1394
+ function usePopoverContext() {
1395
+ const ctx = useContext6(PopoverContext);
1396
+ if (!ctx)
1397
+ throw new Error("Popover components must be used within PopoverRoot");
1398
+ return ctx;
1399
+ }
1400
+ function PopoverRoot({
1401
+ children,
1402
+ open: controlledOpen,
1403
+ defaultOpen = false,
1404
+ onOpenChange,
1405
+ setOpen: setOpenDeprecated,
1406
+ placement = "bottom-start",
1407
+ manageFocus = false,
1408
+ animated = true,
1409
+ portal = false,
1410
+ portalRoot = null
1411
+ }) {
1412
+ const [open, setOpen] = useControllableState(
1413
+ defaultOpen,
1414
+ controlledOpen,
1415
+ onOpenChange != null ? onOpenChange : setOpenDeprecated
1416
+ );
1417
+ const popoverId = useId();
1418
+ const {
1419
+ getReferenceProps,
1420
+ getFloatingProps,
1421
+ getPositionerStateProps,
1422
+ context
1423
+ } = useFloating({
1424
+ placement,
1425
+ gutter: 8,
1426
+ open,
1427
+ onOpenChange: setOpen,
1428
+ dismiss: true
1429
+ });
1430
+ return /* @__PURE__ */ jsx8(
1431
+ PopoverContext.Provider,
1432
+ {
1433
+ value: {
1434
+ open,
1435
+ setOpen,
1436
+ popoverId,
1437
+ manageFocus,
1438
+ animated,
1439
+ portal,
1440
+ portalRoot,
1441
+ getReferenceProps,
1442
+ getFloatingProps,
1443
+ getPositionerStateProps,
1444
+ context
1445
+ },
1446
+ children
1447
+ }
1448
+ );
1449
+ }
1450
+ var PopoverTrigger = forwardRef5((_a, ref) => {
1451
+ var _b = _a, { onClick } = _b, props = __objRest(_b, ["onClick"]);
1452
+ const { open, setOpen, popoverId, getReferenceProps } = usePopoverContext();
1453
+ const refProps = getReferenceProps();
1454
+ const handleClick = useCallback11(
1455
+ (e) => {
1456
+ setOpen(!open);
1457
+ onClick == null ? void 0 : onClick(e);
1458
+ },
1459
+ [open, setOpen, onClick]
1460
+ );
1461
+ return /* @__PURE__ */ jsx8(
1462
+ "button",
1463
+ __spreadValues({
1464
+ ref: (node) => {
1465
+ if (refProps.ref && typeof refProps.ref === "function") {
1466
+ refProps.ref(node);
1467
+ }
1468
+ if (typeof ref === "function") ref(node);
1469
+ else if (ref) ref.current = node;
1470
+ },
1471
+ type: "button",
1472
+ "aria-expanded": open,
1473
+ "aria-controls": open ? popoverId : void 0,
1474
+ "data-popover-trigger": popoverId,
1475
+ onClick: handleClick
1476
+ }, props)
1477
+ );
1478
+ });
1479
+ PopoverTrigger.displayName = "PopoverTrigger";
1480
+ function PopoverContent(_a) {
1481
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
1482
+ const {
1483
+ open,
1484
+ popoverId,
1485
+ manageFocus,
1486
+ animated,
1487
+ portal,
1488
+ portalRoot,
1489
+ getFloatingProps,
1490
+ getPositionerStateProps,
1491
+ context
1492
+ } = usePopoverContext();
1493
+ const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
1494
+ const floatingProps = getFloatingProps();
1495
+ if (!mounted) return null;
1496
+ const node = /* @__PURE__ */ jsx8(
1497
+ "div",
1498
+ __spreadProps(__spreadValues(__spreadValues(__spreadValues({
1499
+ ref: (n) => {
1500
+ ref.current = n;
1501
+ if (floatingProps.ref && typeof floatingProps.ref === "function") {
1502
+ floatingProps.ref(n);
1503
+ }
1504
+ },
1505
+ id: popoverId,
1506
+ "data-popover-id": popoverId,
1507
+ tabIndex: -1,
1508
+ style: floatingProps.style
1509
+ }, getPositionerStateProps(open)), dataAttributes), props), {
1510
+ children
1511
+ })
1512
+ );
1513
+ return /* @__PURE__ */ jsx8(OverlayPortal, { portal, portalRoot, children: manageFocus ? (
1514
+ // Non-modal focus management: move focus into the panel on open, place
1515
+ // tab guards for correct tab-out continuity (incl. the VoiceOver/WebKit
1516
+ // workaround), and return focus to the trigger on close.
1517
+ /* @__PURE__ */ jsx8(FloatingFocusManager, { context, modal: false, returnFocus: true, children: node })
1518
+ ) : node });
1519
+ }
1520
+ var PopoverClose = forwardRef5(
1521
+ (_a, ref) => {
1522
+ var _b = _a, { onClick } = _b, props = __objRest(_b, ["onClick"]);
1523
+ const { setOpen } = usePopoverContext();
1524
+ const handleClick = useCallback11(
1525
+ (e) => {
1526
+ setOpen(false);
1527
+ onClick == null ? void 0 : onClick(e);
1528
+ },
1529
+ [setOpen, onClick]
1530
+ );
1531
+ return /* @__PURE__ */ jsx8("button", __spreadValues({ ref, type: "button", onClick: handleClick }, props));
1532
+ }
1533
+ );
1534
+ PopoverClose.displayName = "PopoverClose";
1535
+
1536
+ // src/primitives/select.tsx
1537
+ import {
1538
+ createContext as createContext7,
1539
+ useContext as useContext7,
1540
+ useCallback as useCallback12,
1541
+ useEffect as useEffect9,
1542
+ useLayoutEffect as useLayoutEffect2,
1543
+ useMemo as useMemo2,
1544
+ useRef as useRef8,
1545
+ useState as useState6,
1546
+ forwardRef as forwardRef6
1547
+ } from "react";
1548
+ import { jsx as jsx9, jsxs } from "react/jsx-runtime";
1549
+ function firstEnabledId(items) {
1550
+ var _a, _b;
1551
+ return (_b = (_a = items.find((i) => !i.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
1552
+ }
1553
+ function moveActiveId(items, activeId, delta) {
1554
+ const enabled = items.filter((i) => !i.disabled);
1555
+ if (enabled.length === 0) return null;
1556
+ const idx = enabled.findIndex((i) => i.id === activeId);
1557
+ if (idx < 0) {
1558
+ return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
1559
+ }
1560
+ const next = Math.min(enabled.length - 1, Math.max(0, idx + delta));
1561
+ return enabled[next].id;
1562
+ }
1563
+ var SelectContext = createContext7(null);
1564
+ function useSelectContext() {
1565
+ const ctx = useContext7(SelectContext);
1566
+ if (!ctx) throw new Error("Select components must be used within SelectRoot");
1567
+ return ctx;
1568
+ }
1569
+ function SelectRoot({
1570
+ children,
1571
+ value: controlledValue,
1572
+ defaultValue,
1573
+ onValueChange,
1574
+ setValue: setValueDeprecated,
1575
+ multiple = false,
1576
+ name,
1577
+ open: controlledOpen,
1578
+ onOpenChange,
1579
+ setOpen: setOpenDeprecated,
1580
+ animated = true,
1581
+ portal = false,
1582
+ portalRoot = null
1583
+ }) {
1584
+ var _a;
1585
+ const normalizedDefault = defaultValue != null ? defaultValue : multiple ? [] : "";
1586
+ const [value, setValue] = useControllableState(
1587
+ normalizedDefault,
1588
+ controlledValue,
1589
+ onValueChange != null ? onValueChange : setValueDeprecated
1590
+ );
1591
+ const [open, setOpenState] = useState6(controlledOpen != null ? controlledOpen : false);
1592
+ const onOpenChangeCb = onOpenChange != null ? onOpenChange : setOpenDeprecated;
1593
+ const [activeId, setActiveId] = useState6(null);
1594
+ const selectId = useId();
1595
+ const listboxId = `${selectId}-listbox`;
1596
+ const items = useRef8([]);
1597
+ useEffect9(() => {
1598
+ if (controlledOpen !== void 0) setOpenState(controlledOpen);
1599
+ }, [controlledOpen]);
1600
+ const setOpen = useCallback12(
1601
+ (v) => {
1602
+ if (controlledOpen === void 0) setOpenState(v);
1603
+ onOpenChangeCb == null ? void 0 : onOpenChangeCb(v);
1604
+ if (!v) setActiveId(null);
1605
+ },
1606
+ [controlledOpen, onOpenChangeCb]
1607
+ );
1608
+ const selectedValues = useMemo2(
1609
+ () => Array.isArray(value) ? value : value === "" ? [] : [value],
1610
+ [value]
1611
+ );
1612
+ const isSelected = useCallback12(
1613
+ (v) => selectedValues.includes(v),
1614
+ [selectedValues]
1615
+ );
1616
+ const selectValue = useCallback12(
1617
+ (v) => {
1618
+ if (multiple) {
1619
+ const arr = Array.isArray(value) ? value : value ? [value] : [];
1620
+ setValue(arr.includes(v) ? arr.filter((x) => x !== v) : [...arr, v]);
1621
+ } else {
1622
+ setValue(v);
1623
+ setOpen(false);
1624
+ }
1625
+ },
1626
+ [multiple, value, setValue, setOpen]
1627
+ );
1628
+ const registerItem = useCallback12((entry) => {
1629
+ const list = items.current;
1630
+ const existing = list.findIndex((i) => i.id === entry.id);
1631
+ if (existing >= 0) list[existing] = entry;
1632
+ else list.push(entry);
1633
+ }, []);
1634
+ const unregisterItem = useCallback12((id) => {
1635
+ items.current = items.current.filter((i) => i.id !== id);
1636
+ }, []);
1637
+ const { getReferenceProps, getFloatingProps } = useFloating({
1638
+ placement: "bottom-start",
1639
+ gutter: 4,
1640
+ sameWidth: true,
1641
+ open,
1642
+ onOpenChange: setOpen,
1643
+ dismiss: { outsidePress: true, escapeKey: false }
1644
+ });
1645
+ return /* @__PURE__ */ jsxs(
1646
+ SelectContext.Provider,
1647
+ {
1648
+ value: {
1649
+ open,
1650
+ setOpen,
1651
+ value,
1652
+ selectedValues,
1653
+ multiple,
1654
+ isSelected,
1655
+ selectValue,
1656
+ activeId,
1657
+ setActiveId,
1658
+ selectId,
1659
+ listboxId,
1660
+ getReferenceProps,
1661
+ getFloatingProps,
1662
+ items,
1663
+ registerItem,
1664
+ unregisterItem,
1665
+ animated,
1666
+ portal,
1667
+ portalRoot
1668
+ },
1669
+ children: [
1670
+ children,
1671
+ name && (multiple ? selectedValues.map((v) => /* @__PURE__ */ jsx9("input", { type: "hidden", name, value: v }, v)) : /* @__PURE__ */ jsx9("input", { type: "hidden", name, value: (_a = selectedValues[0]) != null ? _a : "" }))
1672
+ ]
1673
+ }
1674
+ );
1675
+ }
1676
+ function SelectLabel(props) {
1677
+ const { selectId } = useSelectContext();
1678
+ return /* @__PURE__ */ jsx9("label", __spreadValues({ htmlFor: selectId }, props));
1679
+ }
1680
+ var SelectTrigger = forwardRef6(
1681
+ (_a, ref) => {
1682
+ var _b = _a, { onClick, onKeyDown, children } = _b, props = __objRest(_b, ["onClick", "onKeyDown", "children"]);
1683
+ var _a2;
1684
+ const {
1685
+ open,
1686
+ setOpen,
1687
+ selectedValues,
1688
+ multiple,
1689
+ selectValue,
1690
+ selectId,
1691
+ listboxId,
1692
+ getReferenceProps,
1693
+ items,
1694
+ activeId,
1695
+ setActiveId
1696
+ } = useSelectContext();
1697
+ const refProps = getReferenceProps();
1698
+ const typeahead = useRef8({
1699
+ buffer: "",
1700
+ timer: 0
1701
+ });
1702
+ const selectActive = useCallback12(() => {
1703
+ const item = items.current.find((i) => i.id === activeId);
1704
+ if (item && !item.disabled) {
1705
+ selectValue(item.value);
1706
+ }
1707
+ }, [items, activeId, selectValue]);
1708
+ const runTypeahead = useCallback12(
1709
+ (char) => {
1710
+ const t = typeahead.current;
1711
+ window.clearTimeout(t.timer);
1712
+ t.buffer += char.toLowerCase();
1713
+ t.timer = window.setTimeout(() => {
1714
+ t.buffer = "";
1715
+ }, 500);
1716
+ const match = items.current.filter((i) => !i.disabled).find(
1717
+ (i) => {
1718
+ var _a3, _b2;
1719
+ return (_b2 = (_a3 = document.getElementById(i.id)) == null ? void 0 : _a3.textContent) == null ? void 0 : _b2.trim().toLowerCase().startsWith(t.buffer);
1720
+ }
1721
+ );
1722
+ if (match) setActiveId(match.id);
1723
+ },
1724
+ [items, setActiveId]
1725
+ );
1726
+ const handleClick = useCallback12(
1727
+ (e) => {
1728
+ setOpen(!open);
1729
+ onClick == null ? void 0 : onClick(e);
1730
+ },
1731
+ [open, setOpen, onClick]
1732
+ );
1733
+ const handleKeyDown2 = useCallback12(
1734
+ (e) => {
1735
+ var _a3, _b2;
1736
+ switch (e.key) {
1737
+ case "ArrowDown":
1738
+ e.preventDefault();
1739
+ if (!open) setOpen(true);
1740
+ else setActiveId(moveActiveId(items.current, activeId, 1));
1741
+ break;
1742
+ case "ArrowUp":
1743
+ e.preventDefault();
1744
+ if (!open) setOpen(true);
1745
+ else setActiveId(moveActiveId(items.current, activeId, -1));
1746
+ break;
1747
+ case "Home":
1748
+ if (open) {
1749
+ e.preventDefault();
1750
+ setActiveId(firstEnabledId(items.current));
1751
+ }
1752
+ break;
1753
+ case "End":
1754
+ if (open) {
1755
+ e.preventDefault();
1756
+ const enabled = items.current.filter((i) => !i.disabled);
1757
+ setActiveId((_b2 = (_a3 = enabled[enabled.length - 1]) == null ? void 0 : _a3.id) != null ? _b2 : null);
1758
+ }
1759
+ break;
1760
+ case "Enter":
1761
+ case " ":
1762
+ e.preventDefault();
1763
+ if (open) selectActive();
1764
+ else setOpen(true);
1765
+ break;
1766
+ case "Escape":
1767
+ if (open) {
1768
+ e.preventDefault();
1769
+ setOpen(false);
1770
+ }
1771
+ break;
1772
+ default:
1773
+ if (open && e.key.length === 1 && e.key !== " " && !e.metaKey && !e.ctrlKey && !e.altKey && !e.nativeEvent.isComposing) {
1774
+ runTypeahead(e.key);
1775
+ }
1776
+ }
1777
+ onKeyDown == null ? void 0 : onKeyDown(e);
1778
+ },
1779
+ [
1780
+ open,
1781
+ items,
1782
+ activeId,
1783
+ setActiveId,
1784
+ setOpen,
1785
+ selectActive,
1786
+ runTypeahead,
1787
+ onKeyDown
1788
+ ]
1789
+ );
1790
+ return /* @__PURE__ */ jsx9(
1791
+ "button",
1792
+ __spreadProps(__spreadValues({
1793
+ ref: (node) => {
1794
+ if (refProps.ref && typeof refProps.ref === "function") {
1795
+ refProps.ref(node);
1796
+ }
1797
+ if (typeof ref === "function") ref(node);
1798
+ else if (ref) ref.current = node;
1799
+ },
1800
+ type: "button",
1801
+ id: selectId,
1802
+ role: "combobox",
1803
+ "aria-expanded": open,
1804
+ "aria-haspopup": "listbox",
1805
+ "aria-controls": open ? listboxId : void 0,
1806
+ "aria-activedescendant": open ? activeId != null ? activeId : void 0 : void 0,
1807
+ "data-select-trigger": selectId,
1808
+ onClick: handleClick,
1809
+ onKeyDown: handleKeyDown2
1810
+ }, props), {
1811
+ children: children != null ? children : multiple ? selectedValues.join(", ") : (_a2 = selectedValues[0]) != null ? _a2 : ""
1812
+ })
1813
+ );
1814
+ }
1815
+ );
1816
+ SelectTrigger.displayName = "SelectTrigger";
1817
+ function SelectPopover(_a) {
1818
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
1819
+ const {
1820
+ open,
1821
+ multiple,
1822
+ selectedValues,
1823
+ listboxId,
1824
+ selectId,
1825
+ getFloatingProps,
1826
+ items,
1827
+ activeId,
1828
+ setActiveId,
1829
+ animated,
1830
+ portal,
1831
+ portalRoot
1832
+ } = useSelectContext();
1833
+ const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
1834
+ const floatingProps = getFloatingProps();
1835
+ useLayoutEffect2(() => {
1836
+ if (mounted) {
1837
+ setActiveId((prev) => {
1838
+ var _a2;
1839
+ if (prev) return prev;
1840
+ const selected = items.current.find(
1841
+ (i) => selectedValues.includes(i.value)
1842
+ );
1843
+ return (_a2 = selected == null ? void 0 : selected.id) != null ? _a2 : firstEnabledId(items.current);
1844
+ });
1845
+ }
1846
+ }, [mounted, items, selectedValues, setActiveId]);
1847
+ useScrollActiveDescendantIntoView(activeId);
1848
+ if (!mounted) return null;
1849
+ const node = /* @__PURE__ */ jsx9(
1850
+ "div",
1851
+ __spreadProps(__spreadValues(__spreadValues({
1852
+ ref: (n) => {
1853
+ ref.current = n;
1854
+ if (floatingProps.ref && typeof floatingProps.ref === "function") {
1855
+ floatingProps.ref(n);
1856
+ }
1857
+ },
1858
+ id: listboxId,
1859
+ role: "listbox",
1860
+ "aria-multiselectable": multiple || void 0,
1861
+ "aria-activedescendant": activeId != null ? activeId : void 0,
1862
+ "data-select-id": selectId,
1863
+ style: floatingProps.style
1864
+ }, dataAttributes), props), {
1865
+ children
1866
+ })
1867
+ );
1868
+ return /* @__PURE__ */ jsx9(OverlayPortal, { portal, portalRoot, children: node });
1869
+ }
1870
+ function SelectItem(_a) {
1871
+ var _b = _a, {
1872
+ value: itemValue,
1873
+ disabled,
1874
+ onClick,
1875
+ children
1876
+ } = _b, props = __objRest(_b, [
1877
+ "value",
1878
+ "disabled",
1879
+ "onClick",
1880
+ "children"
1881
+ ]);
1882
+ const {
1883
+ isSelected: isValueSelected,
1884
+ selectValue,
1885
+ activeId,
1886
+ setActiveId,
1887
+ registerItem,
1888
+ unregisterItem
1889
+ } = useSelectContext();
1890
+ const itemId = useId();
1891
+ const isSelected = isValueSelected(itemValue);
1892
+ const isActive = activeId === itemId;
1893
+ useLayoutEffect2(() => {
1894
+ registerItem({ id: itemId, value: itemValue, disabled });
1895
+ return () => unregisterItem(itemId);
1896
+ }, [itemId, itemValue, disabled, registerItem, unregisterItem]);
1897
+ const handleClick = useCallback12(
1898
+ (e) => {
1899
+ if (!disabled) {
1900
+ selectValue(itemValue);
1901
+ }
1902
+ onClick == null ? void 0 : onClick(e);
1903
+ },
1904
+ [disabled, itemValue, selectValue, onClick]
1905
+ );
1906
+ return /* @__PURE__ */ jsx9(
1907
+ "div",
1908
+ __spreadProps(__spreadValues({
1909
+ id: itemId,
1910
+ role: "option",
1911
+ "aria-selected": isSelected,
1912
+ "aria-disabled": disabled || void 0,
1913
+ "data-active-item": isActive ? "" : void 0,
1914
+ "data-disabled": disabled ? "" : void 0,
1915
+ onClick: handleClick,
1916
+ onMouseEnter: () => {
1917
+ if (!disabled) setActiveId(itemId);
1918
+ }
1919
+ }, props), {
1920
+ children: children != null ? children : itemValue
1921
+ })
1922
+ );
1923
+ }
1924
+
1925
+ // src/primitives/combobox.tsx
1926
+ import {
1927
+ createContext as createContext8,
1928
+ useContext as useContext8,
1929
+ useCallback as useCallback13,
1930
+ useEffect as useEffect10,
1931
+ useLayoutEffect as useLayoutEffect3,
1932
+ useMemo as useMemo3,
1933
+ useRef as useRef9,
1934
+ useState as useState7,
1935
+ useSyncExternalStore,
1936
+ forwardRef as forwardRef7
1937
+ } from "react";
1938
+ import { jsx as jsx10 } from "react/jsx-runtime";
1939
+ function firstEnabledId2(items) {
1940
+ var _a, _b;
1941
+ return (_b = (_a = items.find((i) => !i.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
1942
+ }
1943
+ function moveActiveId2(items, activeId, delta) {
1944
+ const enabled = items.filter((i) => !i.disabled);
1945
+ if (enabled.length === 0) return null;
1946
+ const idx = enabled.findIndex((i) => i.id === activeId);
1947
+ if (idx < 0) {
1948
+ return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
1949
+ }
1950
+ const next = Math.min(enabled.length - 1, Math.max(0, idx + delta));
1951
+ return enabled[next].id;
1952
+ }
1953
+ function createComboboxStore(initial) {
1954
+ let state = initial;
1955
+ const listeners = /* @__PURE__ */ new Set();
1956
+ return {
1957
+ getState: () => state,
1958
+ setState: (partial) => {
1959
+ const next = __spreadValues(__spreadValues({}, state), partial);
1960
+ if (next.value === state.value && next.searchValue === state.searchValue && next.activeId === state.activeId && next.open === state.open) {
1961
+ return;
1962
+ }
1963
+ state = next;
1964
+ listeners.forEach((l) => l());
1965
+ },
1966
+ subscribe: (listener) => {
1967
+ listeners.add(listener);
1968
+ return () => {
1969
+ listeners.delete(listener);
1970
+ };
1971
+ }
1972
+ };
1973
+ }
1974
+ var ComboboxStoreContext = createContext8(
1975
+ null
1976
+ );
1977
+ function useComboboxStoreContext() {
1978
+ const ctx = useContext8(ComboboxStoreContext);
1979
+ if (!ctx)
1980
+ throw new Error("Combobox components must be used within ComboboxRoot");
1981
+ return ctx;
1982
+ }
1983
+ function useComboboxSelector(selector) {
1984
+ const { store } = useComboboxStoreContext();
1985
+ return useSyncExternalStore(
1986
+ store.subscribe,
1987
+ () => selector(store.getState()),
1988
+ () => selector(store.getState())
1989
+ );
1990
+ }
1991
+ var ComboboxFloatingContext = createContext8(null);
1992
+ function useComboboxFloating() {
1993
+ const ctx = useContext8(ComboboxFloatingContext);
1994
+ if (!ctx)
1995
+ throw new Error("Combobox components must be used within ComboboxRoot");
1996
+ return ctx;
1997
+ }
1998
+ function ComboboxRoot({
1999
+ children,
2000
+ value: controlledValue,
2001
+ defaultValue = "",
2002
+ onValueChange,
2003
+ setValue: setValueDeprecated,
2004
+ open: controlledOpen,
2005
+ onOpenChange,
2006
+ setOpen: setOpenDeprecated,
2007
+ animated = true,
2008
+ portal = false,
2009
+ portalRoot = null
2010
+ }) {
2011
+ const comboboxId = useId();
2012
+ const listboxId = `${comboboxId}-listbox`;
2013
+ const items = useRef9([]);
2014
+ const [store] = useState7(
2015
+ () => createComboboxStore({
2016
+ value: controlledValue != null ? controlledValue : defaultValue,
2017
+ searchValue: "",
2018
+ activeId: null,
2019
+ open: controlledOpen != null ? controlledOpen : false
2020
+ })
2021
+ );
2022
+ const propsRef = useRef9({
2023
+ controlledValue,
2024
+ controlledOpen,
2025
+ onValueChange: onValueChange != null ? onValueChange : setValueDeprecated,
2026
+ onOpenChange: onOpenChange != null ? onOpenChange : setOpenDeprecated
2027
+ });
2028
+ propsRef.current = {
2029
+ controlledValue,
2030
+ controlledOpen,
2031
+ onValueChange: onValueChange != null ? onValueChange : setValueDeprecated,
2032
+ onOpenChange: onOpenChange != null ? onOpenChange : setOpenDeprecated
2033
+ };
2034
+ useEffect10(() => {
2035
+ if (controlledValue !== void 0)
2036
+ store.setState({ value: controlledValue });
2037
+ }, [controlledValue, store]);
2038
+ useEffect10(() => {
2039
+ if (controlledOpen !== void 0) store.setState({ open: controlledOpen });
2040
+ }, [controlledOpen, store]);
2041
+ const actions = useMemo3(
2042
+ () => ({
2043
+ setValue: (v) => {
2044
+ var _a;
2045
+ const p = propsRef.current;
2046
+ if (p.controlledValue === void 0) store.setState({ value: v });
2047
+ (_a = p.onValueChange) == null ? void 0 : _a.call(p, v);
2048
+ },
2049
+ setOpen: (v) => {
2050
+ var _a;
2051
+ const p = propsRef.current;
2052
+ if (p.controlledOpen === void 0) store.setState({ open: v });
2053
+ (_a = p.onOpenChange) == null ? void 0 : _a.call(p, v);
2054
+ if (!v) store.setState({ activeId: null });
2055
+ },
2056
+ setSearchValue: (v) => store.setState({ searchValue: v }),
2057
+ setActiveId: (updater) => {
2058
+ const cur = store.getState().activeId;
2059
+ const next = typeof updater === "function" ? updater(cur) : updater;
2060
+ store.setState({ activeId: next });
2061
+ }
2062
+ }),
2063
+ [store]
2064
+ );
2065
+ const registerItem = useCallback13((entry) => {
2066
+ const list = items.current;
2067
+ const existing = list.findIndex((i) => i.id === entry.id);
2068
+ if (existing >= 0) list[existing] = entry;
2069
+ else list.push(entry);
2070
+ }, []);
2071
+ const unregisterItem = useCallback13((id) => {
2072
+ items.current = items.current.filter((i) => i.id !== id);
2073
+ }, []);
2074
+ const open = useSyncExternalStore(
2075
+ store.subscribe,
2076
+ () => store.getState().open,
2077
+ () => store.getState().open
2078
+ );
2079
+ const { getReferenceProps, getFloatingProps } = useFloating({
2080
+ placement: "bottom-start",
2081
+ gutter: 4,
2082
+ sameWidth: true,
2083
+ lazyFlip: true,
2084
+ open,
2085
+ onOpenChange: actions.setOpen,
2086
+ dismiss: { outsidePress: true, escapeKey: false }
2087
+ });
2088
+ const storeContext = useMemo3(
2089
+ () => ({
2090
+ store,
2091
+ actions,
2092
+ comboboxId,
2093
+ listboxId,
2094
+ items,
2095
+ registerItem,
2096
+ unregisterItem
2097
+ }),
2098
+ [store, actions, comboboxId, listboxId, registerItem, unregisterItem]
2099
+ );
2100
+ const floatingContext = useMemo3(
2101
+ () => ({
2102
+ getReferenceProps,
2103
+ getFloatingProps,
2104
+ animated,
2105
+ portal,
2106
+ portalRoot
2107
+ }),
2108
+ [getReferenceProps, getFloatingProps, animated, portal, portalRoot]
2109
+ );
2110
+ return /* @__PURE__ */ jsx10(ComboboxStoreContext.Provider, { value: storeContext, children: /* @__PURE__ */ jsx10(ComboboxFloatingContext.Provider, { value: floatingContext, children }) });
2111
+ }
2112
+ var ComboboxInput = forwardRef7(
2113
+ (_a, ref) => {
2114
+ var _b = _a, { onKeyDown } = _b, props = __objRest(_b, ["onKeyDown"]);
2115
+ const { actions, comboboxId, listboxId, items } = useComboboxStoreContext();
2116
+ const { getReferenceProps } = useComboboxFloating();
2117
+ const open = useComboboxSelector((s) => s.open);
2118
+ const searchValue = useComboboxSelector((s) => s.searchValue);
2119
+ const activeId = useComboboxSelector((s) => s.activeId);
2120
+ const refProps = getReferenceProps();
2121
+ useScrollActiveDescendantIntoView(activeId);
2122
+ const handleChange = useCallback13(
2123
+ (e) => {
2124
+ actions.setSearchValue(e.target.value);
2125
+ if (!open) actions.setOpen(true);
2126
+ actions.setActiveId(null);
2127
+ },
2128
+ [actions, open]
2129
+ );
2130
+ const selectActive = useCallback13(() => {
2131
+ const item = items.current.find((i) => i.id === activeId);
2132
+ if (item && !item.disabled) {
2133
+ actions.setValue(item.value);
2134
+ actions.setSearchValue(item.value);
2135
+ actions.setOpen(false);
2136
+ }
2137
+ }, [items, activeId, actions]);
2138
+ const handleKeyDown2 = useCallback13(
2139
+ (e) => {
2140
+ if (e.nativeEvent.isComposing) {
2141
+ onKeyDown == null ? void 0 : onKeyDown(e);
2142
+ return;
2143
+ }
2144
+ switch (e.key) {
2145
+ case "ArrowDown":
2146
+ e.preventDefault();
2147
+ if (!open) actions.setOpen(true);
2148
+ actions.setActiveId(moveActiveId2(items.current, activeId, 1));
2149
+ break;
2150
+ case "ArrowUp":
2151
+ e.preventDefault();
2152
+ if (!open) actions.setOpen(true);
2153
+ actions.setActiveId(moveActiveId2(items.current, activeId, -1));
2154
+ break;
2155
+ case "Enter":
2156
+ if (open && activeId) {
2157
+ e.preventDefault();
2158
+ selectActive();
2159
+ }
2160
+ break;
2161
+ case "Escape":
2162
+ if (open) {
2163
+ e.preventDefault();
2164
+ actions.setOpen(false);
2165
+ }
2166
+ break;
2167
+ }
2168
+ onKeyDown == null ? void 0 : onKeyDown(e);
2169
+ },
2170
+ [open, actions, activeId, items, selectActive, onKeyDown]
2171
+ );
2172
+ return /* @__PURE__ */ jsx10(
2173
+ "input",
2174
+ __spreadValues({
2175
+ ref: (node) => {
2176
+ if (refProps.ref && typeof refProps.ref === "function") {
2177
+ refProps.ref(node);
2178
+ }
2179
+ if (typeof ref === "function") ref(node);
2180
+ else if (ref) ref.current = node;
2181
+ },
2182
+ type: "text",
2183
+ role: "combobox",
2184
+ id: comboboxId,
2185
+ "aria-expanded": open,
2186
+ "aria-autocomplete": "list",
2187
+ "aria-controls": open ? listboxId : void 0,
2188
+ "aria-activedescendant": open ? activeId != null ? activeId : void 0 : void 0,
2189
+ "data-combobox-input": comboboxId,
2190
+ value: searchValue,
2191
+ onChange: handleChange,
2192
+ onKeyDown: handleKeyDown2
2193
+ }, props)
2194
+ );
2195
+ }
2196
+ );
2197
+ ComboboxInput.displayName = "ComboboxInput";
2198
+ function ComboboxPopover(_a) {
2199
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
2200
+ const { actions, comboboxId, listboxId, items } = useComboboxStoreContext();
2201
+ const { getFloatingProps, animated, portal, portalRoot } = useComboboxFloating();
2202
+ const open = useComboboxSelector((s) => s.open);
2203
+ const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
2204
+ const floatingProps = getFloatingProps();
2205
+ useLayoutEffect3(() => {
2206
+ if (mounted) {
2207
+ actions.setActiveId((prev) => prev != null ? prev : firstEnabledId2(items.current));
2208
+ }
2209
+ }, [mounted, items, actions]);
2210
+ if (!mounted) return null;
2211
+ const node = /* @__PURE__ */ jsx10(
2212
+ "div",
2213
+ __spreadProps(__spreadValues(__spreadValues({
2214
+ ref: (n) => {
2215
+ ref.current = n;
2216
+ if (floatingProps.ref && typeof floatingProps.ref === "function") {
2217
+ floatingProps.ref(n);
2218
+ }
2219
+ },
2220
+ id: listboxId,
2221
+ role: "listbox",
2222
+ "data-combobox-id": comboboxId,
2223
+ style: floatingProps.style
2224
+ }, dataAttributes), props), {
2225
+ children
2226
+ })
2227
+ );
2228
+ return /* @__PURE__ */ jsx10(OverlayPortal, { portal, portalRoot, children: node });
2229
+ }
2230
+ function ComboboxItem(_a) {
2231
+ var _b = _a, {
2232
+ value: itemValue,
2233
+ disabled,
2234
+ onClick,
2235
+ children
2236
+ } = _b, props = __objRest(_b, [
2237
+ "value",
2238
+ "disabled",
2239
+ "onClick",
2240
+ "children"
2241
+ ]);
2242
+ const { actions, registerItem, unregisterItem } = useComboboxStoreContext();
2243
+ const itemId = useId();
2244
+ const isSelected = useComboboxSelector((s) => s.value === itemValue);
2245
+ const isActive = useComboboxSelector((s) => s.activeId === itemId);
2246
+ useLayoutEffect3(() => {
2247
+ registerItem({ id: itemId, value: itemValue, disabled });
2248
+ return () => unregisterItem(itemId);
2249
+ }, [itemId, itemValue, disabled, registerItem, unregisterItem]);
2250
+ const handleClick = useCallback13(
2251
+ (e) => {
2252
+ if (!disabled) {
2253
+ actions.setValue(itemValue);
2254
+ actions.setSearchValue(itemValue);
2255
+ actions.setOpen(false);
2256
+ }
2257
+ onClick == null ? void 0 : onClick(e);
2258
+ },
2259
+ [disabled, itemValue, actions, onClick]
2260
+ );
2261
+ return /* @__PURE__ */ jsx10(
2262
+ "div",
2263
+ __spreadProps(__spreadValues({
2264
+ id: itemId,
2265
+ role: "option",
2266
+ "aria-selected": isSelected,
2267
+ "aria-disabled": disabled || void 0,
2268
+ "data-active-item": isActive ? "" : void 0,
2269
+ "data-disabled": disabled ? "" : void 0,
2270
+ onClick: handleClick,
2271
+ onMouseEnter: () => {
2272
+ if (!disabled) actions.setActiveId(itemId);
2273
+ }
2274
+ }, props), {
2275
+ children: children != null ? children : itemValue
2276
+ })
2277
+ );
2278
+ }
2279
+ var ComboboxGroupContext = createContext8(
2280
+ null
2281
+ );
2282
+ function ComboboxGroup(_a) {
2283
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
2284
+ const labelId = useId();
2285
+ return /* @__PURE__ */ jsx10(ComboboxGroupContext.Provider, { value: { labelId }, children: /* @__PURE__ */ jsx10("div", __spreadProps(__spreadValues({ role: "group", "aria-labelledby": labelId }, props), { children })) });
2286
+ }
2287
+ function ComboboxGroupLabel(props) {
2288
+ const ctx = useContext8(ComboboxGroupContext);
2289
+ return /* @__PURE__ */ jsx10("div", __spreadValues({ id: ctx == null ? void 0 : ctx.labelId }, props));
2290
+ }
2291
+
2292
+ // src/primitives/command.tsx
2293
+ import {
2294
+ createContext as createContext9,
2295
+ forwardRef as forwardRef8,
2296
+ useCallback as useCallback14,
2297
+ useContext as useContext9,
2298
+ useEffect as useEffect11,
2299
+ useLayoutEffect as useLayoutEffect4,
2300
+ useMemo as useMemo4,
2301
+ useRef as useRef10,
2302
+ useState as useState8
2303
+ } from "react";
2304
+ import { jsx as jsx11, jsxs as jsxs2 } from "react/jsx-runtime";
2305
+ var CommandContext = createContext9(null);
2306
+ function useCommandContext() {
2307
+ const ctx = useContext9(CommandContext);
2308
+ if (!ctx)
2309
+ throw new Error("Command components must be used within CommandRoot");
2310
+ return ctx;
2311
+ }
2312
+ function defaultFilter(value, search, keywords) {
2313
+ if (!search) return true;
2314
+ const needle = search.toLowerCase();
2315
+ if (value.toLowerCase().includes(needle)) return true;
2316
+ return keywords.some((k) => k.toLowerCase().includes(needle));
2317
+ }
2318
+ function CommandRoot(_a) {
2319
+ var _b = _a, {
2320
+ children,
2321
+ value: controlledValue,
2322
+ defaultValue = "",
2323
+ onValueChange,
2324
+ shouldFilter = true,
2325
+ filter = defaultFilter,
2326
+ onEscape
2327
+ } = _b, props = __objRest(_b, [
2328
+ "children",
2329
+ "value",
2330
+ "defaultValue",
2331
+ "onValueChange",
2332
+ "shouldFilter",
2333
+ "filter",
2334
+ "onEscape"
2335
+ ]);
2336
+ const [value, setValue] = useControllableState(
2337
+ defaultValue,
2338
+ controlledValue,
2339
+ onValueChange
2340
+ );
2341
+ const [search, setSearch] = useState8("");
2342
+ const [activeValue, setActiveValue] = useState8("");
2343
+ const itemsRef = useRef10(/* @__PURE__ */ new Map());
2344
+ const [version, setVersion] = useState8(0);
2345
+ const baseId = useId();
2346
+ const bumpVersion = useCallback14(() => setVersion((v) => v + 1), []);
2347
+ const visibleValues = useMemo4(() => {
2348
+ const result = [];
2349
+ for (const [, ref] of itemsRef.current) {
2350
+ const item = ref.current;
2351
+ if (!shouldFilter || filter(item.value, search, item.keywords)) {
2352
+ result.push(item.value);
2353
+ }
2354
+ }
2355
+ return result;
2356
+ }, [search, shouldFilter, filter, version]);
2357
+ useEffect11(() => {
2358
+ const enabled = visibleValues.filter((v) => {
2359
+ for (const [, ref] of itemsRef.current) {
2360
+ if (ref.current.value === v) return !ref.current.disabled;
2361
+ }
2362
+ return true;
2363
+ });
2364
+ if (enabled.length === 0) {
2365
+ if (activeValue) setActiveValue("");
2366
+ return;
2367
+ }
2368
+ if (!enabled.includes(activeValue) && enabled[0]) {
2369
+ setActiveValue(enabled[0]);
2370
+ }
2371
+ }, [visibleValues, activeValue]);
2372
+ const activeId = useMemo4(() => {
2373
+ for (const [id, ref] of itemsRef.current) {
2374
+ if (ref.current.value === activeValue) return id;
2375
+ }
2376
+ return void 0;
2377
+ }, [activeValue, version]);
2378
+ const ctx = useMemo4(
2379
+ () => ({
2380
+ search,
2381
+ setSearch,
2382
+ value,
2383
+ setValue,
2384
+ activeValue,
2385
+ setActiveValue,
2386
+ itemsRef,
2387
+ bumpVersion,
2388
+ shouldFilter,
2389
+ filter,
2390
+ visibleValues,
2391
+ activeId,
2392
+ onEscape,
2393
+ inputId: `${baseId}-input`,
2394
+ listId: `${baseId}-list`
2395
+ }),
2396
+ [
2397
+ search,
2398
+ value,
2399
+ setValue,
2400
+ activeValue,
2401
+ bumpVersion,
2402
+ shouldFilter,
2403
+ filter,
2404
+ visibleValues,
2405
+ activeId,
2406
+ onEscape,
2407
+ baseId
2408
+ ]
2409
+ );
2410
+ return /* @__PURE__ */ jsx11(CommandContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx11("div", __spreadProps(__spreadValues({ "data-slot": "command" }, props), { children })) });
2411
+ }
2412
+ var CommandInput = forwardRef8(
2413
+ function CommandInput2(_a, ref) {
2414
+ var _b = _a, { onKeyDown, onValueChange, value: controlledValue } = _b, props = __objRest(_b, ["onKeyDown", "onValueChange", "value"]);
2415
+ const ctx = useCommandContext();
2416
+ const value = controlledValue != null ? controlledValue : ctx.search;
2417
+ useScrollActiveDescendantIntoView(ctx.activeId);
2418
+ const navigableValues = useCallback14(() => {
2419
+ const disabled = /* @__PURE__ */ new Set();
2420
+ for (const [, r] of ctx.itemsRef.current) {
2421
+ if (r.current.disabled) disabled.add(r.current.value);
2422
+ }
2423
+ return ctx.visibleValues.filter((v) => !disabled.has(v));
2424
+ }, [ctx]);
2425
+ const handleKeyDown2 = useCallback14(
2426
+ (e) => {
2427
+ var _a2, _b2, _c;
2428
+ if (e.nativeEvent.isComposing) {
2429
+ onKeyDown == null ? void 0 : onKeyDown(e);
2430
+ return;
2431
+ }
2432
+ const vals = navigableValues();
2433
+ const idx = vals.indexOf(ctx.activeValue);
2434
+ switch (e.key) {
2435
+ case "ArrowDown": {
2436
+ e.preventDefault();
2437
+ const next = vals[Math.min(idx + 1, vals.length - 1)];
2438
+ if (next) ctx.setActiveValue(next);
2439
+ break;
2440
+ }
2441
+ case "ArrowUp": {
2442
+ e.preventDefault();
2443
+ const prev = vals[Math.max(idx - 1, 0)];
2444
+ if (prev) ctx.setActiveValue(prev);
2445
+ break;
2446
+ }
2447
+ case "Home": {
2448
+ if (vals[0]) {
2449
+ e.preventDefault();
2450
+ ctx.setActiveValue(vals[0]);
2451
+ }
2452
+ break;
2453
+ }
2454
+ case "End": {
2455
+ const last = vals[vals.length - 1];
2456
+ if (last) {
2457
+ e.preventDefault();
2458
+ ctx.setActiveValue(last);
2459
+ }
2460
+ break;
2461
+ }
2462
+ case "Enter": {
2463
+ if (ctx.activeValue && vals.includes(ctx.activeValue)) {
2464
+ e.preventDefault();
2465
+ ctx.setValue(ctx.activeValue);
2466
+ for (const [, r] of ctx.itemsRef.current) {
2467
+ if (r.current.value === ctx.activeValue) {
2468
+ (_b2 = (_a2 = r.current).onSelect) == null ? void 0 : _b2.call(_a2, ctx.activeValue);
2469
+ break;
2470
+ }
2471
+ }
2472
+ }
2473
+ break;
2474
+ }
2475
+ case "Escape": {
2476
+ (_c = ctx.onEscape) == null ? void 0 : _c.call(ctx);
2477
+ break;
2478
+ }
2479
+ }
2480
+ onKeyDown == null ? void 0 : onKeyDown(e);
2481
+ },
2482
+ [ctx, navigableValues, onKeyDown]
2483
+ );
2484
+ return /* @__PURE__ */ jsx11(
2485
+ "input",
2486
+ __spreadValues({
2487
+ ref,
2488
+ type: "text",
2489
+ role: "combobox",
2490
+ id: ctx.inputId,
2491
+ "aria-expanded": true,
2492
+ "aria-autocomplete": "list",
2493
+ "aria-controls": ctx.listId,
2494
+ "aria-activedescendant": ctx.activeId,
2495
+ autoCorrect: "off",
2496
+ autoComplete: "off",
2497
+ spellCheck: false,
2498
+ value,
2499
+ onChange: (e) => {
2500
+ ctx.setSearch(e.target.value);
2501
+ onValueChange == null ? void 0 : onValueChange(e.target.value);
2502
+ },
2503
+ onKeyDown: handleKeyDown2
2504
+ }, props)
2505
+ );
2506
+ }
2507
+ );
2508
+ function CommandList(_a) {
2509
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
2510
+ const ctx = useCommandContext();
2511
+ return /* @__PURE__ */ jsx11("div", __spreadProps(__spreadValues({ role: "listbox", id: ctx.listId, "data-slot": "command-list" }, props), { children }));
2512
+ }
2513
+ function CommandEmpty(_a) {
2514
+ var _b = _a, { children } = _b, props = __objRest(_b, ["children"]);
2515
+ const ctx = useCommandContext();
2516
+ if (ctx.visibleValues.length > 0) return null;
2517
+ return /* @__PURE__ */ jsx11("div", __spreadProps(__spreadValues({ role: "presentation", "data-slot": "command-empty" }, props), { children }));
2518
+ }
2519
+ function CommandGroup(_a) {
2520
+ var _b = _a, {
2521
+ heading,
2522
+ children
2523
+ } = _b, props = __objRest(_b, [
2524
+ "heading",
2525
+ "children"
2526
+ ]);
2527
+ const headingId = useId();
2528
+ const hasHeading = heading != null;
2529
+ return /* @__PURE__ */ jsxs2(
2530
+ "div",
2531
+ __spreadProps(__spreadValues({
2532
+ role: "group",
2533
+ "data-slot": "command-group",
2534
+ "aria-labelledby": hasHeading ? headingId : void 0
2535
+ }, props), {
2536
+ children: [
2537
+ hasHeading && /* @__PURE__ */ jsx11(
2538
+ "div",
2539
+ {
2540
+ id: headingId,
2541
+ "data-slot": "command-group-heading",
2542
+ role: "presentation",
2543
+ children: heading
2544
+ }
2545
+ ),
2546
+ /* @__PURE__ */ jsx11("div", { "data-slot": "command-group-items", children })
2547
+ ]
2548
+ })
2549
+ );
2550
+ }
2551
+ function CommandSeparator(props) {
2552
+ return /* @__PURE__ */ jsx11("div", __spreadValues({ role: "separator", "data-slot": "command-separator" }, props));
2553
+ }
2554
+ var CommandItem = forwardRef8(
2555
+ function CommandItem2(_a, ref) {
2556
+ var _b = _a, {
2557
+ value,
2558
+ keywords,
2559
+ disabled,
2560
+ onSelect,
2561
+ onClick,
2562
+ onMouseEnter,
2563
+ children
2564
+ } = _b, props = __objRest(_b, [
2565
+ "value",
2566
+ "keywords",
2567
+ "disabled",
2568
+ "onSelect",
2569
+ "onClick",
2570
+ "onMouseEnter",
2571
+ "children"
2572
+ ]);
2573
+ const ctx = useCommandContext();
2574
+ const itemId = useId();
2575
+ const metaRef = useRef10({
2576
+ value,
2577
+ keywords: keywords != null ? keywords : [],
2578
+ disabled: Boolean(disabled),
2579
+ onSelect
2580
+ });
2581
+ metaRef.current = {
2582
+ value,
2583
+ keywords: keywords != null ? keywords : [],
2584
+ disabled: Boolean(disabled),
2585
+ onSelect
2586
+ };
2587
+ const { itemsRef, bumpVersion } = ctx;
2588
+ useLayoutEffect4(() => {
2589
+ const map = itemsRef.current;
2590
+ map.set(itemId, metaRef);
2591
+ bumpVersion();
2592
+ return () => {
2593
+ map.delete(itemId);
2594
+ bumpVersion();
2595
+ };
2596
+ }, [itemId, itemsRef, bumpVersion]);
2597
+ useEffect11(() => {
2598
+ bumpVersion();
2599
+ }, [value, disabled, bumpVersion]);
2600
+ const visible = !ctx.shouldFilter || ctx.filter(value, ctx.search, keywords != null ? keywords : []);
2601
+ if (!visible) return null;
2602
+ const isActive = ctx.activeValue === value;
2603
+ return /* @__PURE__ */ jsx11(
2604
+ "div",
2605
+ __spreadProps(__spreadValues({
2606
+ ref,
2607
+ role: "option",
2608
+ id: itemId,
2609
+ "aria-selected": isActive || void 0,
2610
+ "aria-disabled": disabled || void 0,
2611
+ "data-active-item": isActive ? "" : void 0,
2612
+ "data-disabled": disabled ? "" : void 0,
2613
+ "data-value": value,
2614
+ "data-slot": "command-item",
2615
+ onClick: (e) => {
2616
+ if (disabled) return;
2617
+ ctx.setValue(value);
2618
+ onSelect == null ? void 0 : onSelect(value);
2619
+ onClick == null ? void 0 : onClick(e);
2620
+ },
2621
+ onMouseEnter: (e) => {
2622
+ if (!disabled) ctx.setActiveValue(value);
2623
+ onMouseEnter == null ? void 0 : onMouseEnter(e);
2624
+ }
2625
+ }, props), {
2626
+ children
2627
+ })
2628
+ );
2629
+ }
2630
+ );
2631
+ function useCommandState() {
2632
+ const { search, value, activeValue, visibleValues } = useCommandContext();
2633
+ return { search, value, activeValue, visibleValues };
2634
+ }
2635
+
2636
+ // src/primitives/menu.tsx
2637
+ import {
2638
+ createContext as createContext10,
2639
+ useContext as useContext10,
2640
+ useCallback as useCallback15,
2641
+ useEffect as useEffect12,
2642
+ useLayoutEffect as useLayoutEffect5,
2643
+ useRef as useRef11,
2644
+ useState as useState9,
2645
+ forwardRef as forwardRef9
2646
+ } from "react";
2647
+ import { jsx as jsx12 } from "react/jsx-runtime";
2648
+ function firstEnabledId3(items) {
2649
+ var _a, _b;
2650
+ return (_b = (_a = items.find((i) => !i.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
2651
+ }
2652
+ function moveActiveId3(items, activeId, delta) {
2653
+ const enabled = items.filter((i) => !i.disabled);
2654
+ if (enabled.length === 0) return null;
2655
+ const idx = enabled.findIndex((i) => i.id === activeId);
2656
+ if (idx < 0) {
2657
+ return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
2658
+ }
2659
+ const next = Math.min(enabled.length - 1, Math.max(0, idx + delta));
2660
+ return enabled[next].id;
2661
+ }
2662
+ var MenuContext = createContext10(null);
2663
+ function useMenuContext() {
2664
+ const ctx = useContext10(MenuContext);
2665
+ if (!ctx) throw new Error("Menu components must be used within MenuRoot");
2666
+ return ctx;
2667
+ }
2668
+ var MenubarContext = createContext10(null);
2669
+ function useMenubarContext() {
2670
+ return useContext10(MenubarContext);
2671
+ }
2672
+ function MenubarRoot({ children }) {
2673
+ const [activeMenuId, setActiveMenuId] = useState9(null);
2674
+ return /* @__PURE__ */ jsx12(MenubarContext.Provider, { value: { activeMenuId, setActiveMenuId }, children });
2675
+ }
2676
+ function MenubarContainer(_a) {
2677
+ var _b = _a, {
2678
+ onKeyDown
2679
+ } = _b, props = __objRest(_b, [
2680
+ "onKeyDown"
2681
+ ]);
2682
+ const handleKeyDown2 = useCallback15(
2683
+ (e) => {
2684
+ if (e.key === "ArrowLeft" || e.key === "ArrowRight" || e.key === "Home" || e.key === "End") {
2685
+ const triggers = Array.from(
2686
+ e.currentTarget.querySelectorAll('[role="menuitem"]')
2687
+ );
2688
+ if (triggers.length > 0) {
2689
+ const current = triggers.indexOf(
2690
+ document.activeElement
2691
+ );
2692
+ let next = current;
2693
+ if (e.key === "ArrowRight")
2694
+ next = current < 0 ? 0 : (current + 1) % triggers.length;
2695
+ else if (e.key === "ArrowLeft")
2696
+ next = current < 0 ? 0 : (current - 1 + triggers.length) % triggers.length;
2697
+ else if (e.key === "Home") next = 0;
2698
+ else if (e.key === "End") next = triggers.length - 1;
2699
+ if (triggers[next]) {
2700
+ e.preventDefault();
2701
+ triggers[next].focus();
2702
+ }
2703
+ }
2704
+ }
2705
+ onKeyDown == null ? void 0 : onKeyDown(e);
2706
+ },
2707
+ [onKeyDown]
2708
+ );
2709
+ return /* @__PURE__ */ jsx12("div", __spreadValues({ role: "menubar", onKeyDown: handleKeyDown2 }, props));
2710
+ }
2711
+ function MenuRoot({
2712
+ children,
2713
+ open: controlledOpen,
2714
+ onOpenChange,
2715
+ setOpen: setOpenDeprecated,
2716
+ animated = true,
2717
+ portal = false,
2718
+ portalRoot = null
2719
+ }) {
2720
+ const [open, setOpenState] = useState9(controlledOpen != null ? controlledOpen : false);
2721
+ const [activeId, setActiveId] = useState9(null);
2722
+ const menuId = useId();
2723
+ const triggerId = `${menuId}-trigger`;
2724
+ const items = useRef11([]);
2725
+ const onOpenChangeCb = onOpenChange != null ? onOpenChange : setOpenDeprecated;
2726
+ useEffect12(() => {
2727
+ if (controlledOpen !== void 0) setOpenState(controlledOpen);
2728
+ }, [controlledOpen]);
2729
+ const setOpen = useCallback15(
2730
+ (v) => {
2731
+ if (controlledOpen === void 0) setOpenState(v);
2732
+ onOpenChangeCb == null ? void 0 : onOpenChangeCb(v);
2733
+ if (!v) setActiveId(null);
2734
+ },
2735
+ [controlledOpen, onOpenChangeCb]
2736
+ );
2737
+ const focusTrigger = useCallback15(() => {
2738
+ var _a;
2739
+ (_a = document.getElementById(triggerId)) == null ? void 0 : _a.focus();
2740
+ }, [triggerId]);
2741
+ const { getReferenceProps, getFloatingProps } = useFloating({
2742
+ placement: "bottom-start",
2743
+ gutter: 8,
2744
+ open,
2745
+ onOpenChange: setOpen,
2746
+ dismiss: { outsidePress: true, escapeKey: false }
2747
+ });
2748
+ const registerItem = useCallback15((id, disabled) => {
2749
+ const list = items.current;
2750
+ const existing = list.findIndex((i) => i.id === id);
2751
+ if (existing >= 0) list[existing] = { id, disabled };
2752
+ else list.push({ id, disabled });
2753
+ }, []);
2754
+ const unregisterItem = useCallback15((id) => {
2755
+ items.current = items.current.filter((i) => i.id !== id);
2756
+ }, []);
2757
+ return /* @__PURE__ */ jsx12(
2758
+ MenuContext.Provider,
2759
+ {
2760
+ value: {
2761
+ open,
2762
+ setOpen,
2763
+ menuId,
2764
+ triggerId,
2765
+ getReferenceProps,
2766
+ getFloatingProps,
2767
+ activeId,
2768
+ setActiveId,
2769
+ items,
2770
+ registerItem,
2771
+ unregisterItem,
2772
+ focusTrigger,
2773
+ animated,
2774
+ portal,
2775
+ portalRoot
2776
+ },
2777
+ children
2778
+ }
2779
+ );
2780
+ }
2781
+ var MenuTrigger = forwardRef9(
2782
+ (_a, ref) => {
2783
+ var _b = _a, { onClick, onKeyDown, role } = _b, props = __objRest(_b, ["onClick", "onKeyDown", "role"]);
2784
+ const { open, setOpen, menuId, triggerId, getReferenceProps } = useMenuContext();
2785
+ const menubarCtx = useMenubarContext();
2786
+ const refProps = getReferenceProps();
2787
+ const handleClick = useCallback15(
2788
+ (e) => {
2789
+ setOpen(!open);
2790
+ onClick == null ? void 0 : onClick(e);
2791
+ },
2792
+ [open, setOpen, onClick]
2793
+ );
2794
+ const handleKeyDown2 = useCallback15(
2795
+ (e) => {
2796
+ if (e.key === "ArrowDown" || e.key === "Enter" || e.key === " ") {
2797
+ e.preventDefault();
2798
+ setOpen(true);
2799
+ }
2800
+ onKeyDown == null ? void 0 : onKeyDown(e);
2801
+ },
2802
+ [setOpen, onKeyDown]
2803
+ );
2804
+ return /* @__PURE__ */ jsx12(
2805
+ "button",
2806
+ __spreadValues({
2807
+ ref: (node) => {
2808
+ if (refProps.ref && typeof refProps.ref === "function") {
2809
+ refProps.ref(node);
2810
+ }
2811
+ if (typeof ref === "function") ref(node);
2812
+ else if (ref) ref.current = node;
2813
+ },
2814
+ type: "button",
2815
+ role: role != null ? role : menubarCtx ? "menuitem" : void 0,
2816
+ id: triggerId,
2817
+ "aria-expanded": open,
2818
+ "aria-haspopup": "menu",
2819
+ "aria-controls": open ? menuId : void 0,
2820
+ "data-menu-trigger": menuId,
2821
+ onClick: handleClick,
2822
+ onKeyDown: handleKeyDown2
2823
+ }, props)
2824
+ );
2825
+ }
2826
+ );
2827
+ MenuTrigger.displayName = "MenuTrigger";
2828
+ function MenuPopover(_a) {
2829
+ var _b = _a, {
2830
+ children,
2831
+ onKeyDown
2832
+ } = _b, props = __objRest(_b, [
2833
+ "children",
2834
+ "onKeyDown"
2835
+ ]);
2836
+ const {
2837
+ open,
2838
+ setOpen,
2839
+ menuId,
2840
+ triggerId,
2841
+ getFloatingProps,
2842
+ items,
2843
+ activeId,
2844
+ setActiveId,
2845
+ focusTrigger,
2846
+ animated,
2847
+ portal,
2848
+ portalRoot
2849
+ } = useMenuContext();
2850
+ const { ref, mounted, dataAttributes } = useEnterLeave(open, { animated });
2851
+ const floatingProps = getFloatingProps();
2852
+ const menuRef = useRef11(null);
2853
+ const typeahead = useRef11({
2854
+ buffer: "",
2855
+ timer: 0
2856
+ });
2857
+ const activate = useCallback15(() => {
2858
+ var _a2;
2859
+ if (activeId) (_a2 = document.getElementById(activeId)) == null ? void 0 : _a2.click();
2860
+ }, [activeId]);
2861
+ const runTypeahead = useCallback15(
2862
+ (char) => {
2863
+ const t = typeahead.current;
2864
+ window.clearTimeout(t.timer);
2865
+ t.buffer += char.toLowerCase();
2866
+ t.timer = window.setTimeout(() => {
2867
+ t.buffer = "";
2868
+ }, 500);
2869
+ const match = items.current.filter((i) => !i.disabled).find(
2870
+ (i) => {
2871
+ var _a2, _b2;
2872
+ return (_b2 = (_a2 = document.getElementById(i.id)) == null ? void 0 : _a2.textContent) == null ? void 0 : _b2.trim().toLowerCase().startsWith(t.buffer);
2873
+ }
2874
+ );
2875
+ if (match) setActiveId(match.id);
2876
+ },
2877
+ [items, setActiveId]
2878
+ );
2879
+ const handleKeyDown2 = useCallback15(
2880
+ (e) => {
2881
+ var _a2, _b2;
2882
+ switch (e.key) {
2883
+ case "ArrowDown":
2884
+ e.preventDefault();
2885
+ setActiveId(moveActiveId3(items.current, activeId, 1));
2886
+ break;
2887
+ case "ArrowUp":
2888
+ e.preventDefault();
2889
+ setActiveId(moveActiveId3(items.current, activeId, -1));
2890
+ break;
2891
+ case "Home":
2892
+ e.preventDefault();
2893
+ setActiveId(firstEnabledId3(items.current));
2894
+ break;
2895
+ case "End": {
2896
+ e.preventDefault();
2897
+ const enabled = items.current.filter((i) => !i.disabled);
2898
+ setActiveId((_b2 = (_a2 = enabled[enabled.length - 1]) == null ? void 0 : _a2.id) != null ? _b2 : null);
2899
+ break;
2900
+ }
2901
+ case "Enter":
2902
+ case " ":
2903
+ e.preventDefault();
2904
+ activate();
2905
+ break;
2906
+ case "Escape":
2907
+ e.preventDefault();
2908
+ setOpen(false);
2909
+ focusTrigger();
2910
+ break;
2911
+ case "Tab":
2912
+ setOpen(false);
2913
+ break;
2914
+ default:
2915
+ if (e.key.length === 1 && e.key !== " " && !e.metaKey && !e.ctrlKey && !e.altKey && !e.nativeEvent.isComposing) {
2916
+ runTypeahead(e.key);
2917
+ }
2918
+ }
2919
+ onKeyDown == null ? void 0 : onKeyDown(e);
2920
+ },
2921
+ [
2922
+ activeId,
2923
+ items,
2924
+ setActiveId,
2925
+ setOpen,
2926
+ focusTrigger,
2927
+ activate,
2928
+ runTypeahead,
2929
+ onKeyDown
2930
+ ]
2931
+ );
2932
+ useLayoutEffect5(() => {
2933
+ var _a2;
2934
+ if (mounted) {
2935
+ (_a2 = menuRef.current) == null ? void 0 : _a2.focus();
2936
+ setActiveId((prev) => prev != null ? prev : firstEnabledId3(items.current));
2937
+ }
2938
+ }, [mounted, items, setActiveId]);
2939
+ useScrollActiveDescendantIntoView(activeId);
2940
+ if (!mounted) return null;
2941
+ const node = /* @__PURE__ */ jsx12(
2942
+ "div",
2943
+ __spreadProps(__spreadValues(__spreadValues({
2944
+ ref: (n) => {
2945
+ menuRef.current = n;
2946
+ ref.current = n;
2947
+ if (floatingProps.ref && typeof floatingProps.ref === "function") {
2948
+ floatingProps.ref(n);
2949
+ }
2950
+ },
2951
+ id: menuId,
2952
+ role: "menu",
2953
+ "aria-labelledby": triggerId,
2954
+ "aria-activedescendant": activeId != null ? activeId : void 0,
2955
+ "data-menu-id": menuId,
2956
+ style: floatingProps.style,
2957
+ tabIndex: -1,
2958
+ onKeyDown: handleKeyDown2
2959
+ }, dataAttributes), props), {
2960
+ children
2961
+ })
2962
+ );
2963
+ return /* @__PURE__ */ jsx12(OverlayPortal, { portal, portalRoot, children: node });
2964
+ }
2965
+ function useMenuItemRegistration(disabled) {
2966
+ const { registerItem, unregisterItem, activeId } = useMenuContext();
2967
+ const itemId = useId();
2968
+ useLayoutEffect5(() => {
2969
+ registerItem(itemId, disabled);
2970
+ return () => unregisterItem(itemId);
2971
+ }, [itemId, disabled, registerItem, unregisterItem]);
2972
+ return { itemId, isActive: activeId === itemId };
2973
+ }
2974
+ function MenuItem(_a) {
2975
+ var _b = _a, {
2976
+ disabled,
2977
+ hideOnClick = true,
2978
+ onClick,
2979
+ children
2980
+ } = _b, props = __objRest(_b, [
2981
+ "disabled",
2982
+ "hideOnClick",
2983
+ "onClick",
2984
+ "children"
2985
+ ]);
2986
+ const { setOpen, focusTrigger } = useMenuContext();
2987
+ const { itemId, isActive } = useMenuItemRegistration(disabled);
2988
+ const handleClick = useCallback15(
2989
+ (e) => {
2990
+ if (disabled) return;
2991
+ onClick == null ? void 0 : onClick(e);
2992
+ if (hideOnClick) {
2993
+ setOpen(false);
2994
+ focusTrigger();
2995
+ }
2996
+ },
2997
+ [disabled, onClick, hideOnClick, setOpen, focusTrigger]
2998
+ );
2999
+ return /* @__PURE__ */ jsx12(
3000
+ "div",
3001
+ __spreadProps(__spreadValues({
3002
+ id: itemId,
3003
+ role: "menuitem",
3004
+ tabIndex: -1,
3005
+ "aria-disabled": disabled || void 0,
3006
+ "data-active-item": isActive ? "" : void 0,
3007
+ "data-disabled": disabled ? "" : void 0,
3008
+ onClick: handleClick
3009
+ }, props), {
3010
+ children
3011
+ })
3012
+ );
3013
+ }
3014
+ function MenuItemCheckbox(_a) {
3015
+ var _b = _a, {
3016
+ checked = false,
3017
+ onChange,
3018
+ disabled,
3019
+ onClick,
3020
+ children
3021
+ } = _b, props = __objRest(_b, [
3022
+ "checked",
3023
+ "onChange",
3024
+ "disabled",
3025
+ "onClick",
3026
+ "children"
3027
+ ]);
3028
+ const { itemId, isActive } = useMenuItemRegistration(disabled);
3029
+ const handleClick = useCallback15(
3030
+ (e) => {
3031
+ if (disabled) return;
3032
+ onChange == null ? void 0 : onChange(!checked);
3033
+ onClick == null ? void 0 : onClick(e);
3034
+ },
3035
+ [disabled, checked, onChange, onClick]
3036
+ );
3037
+ return /* @__PURE__ */ jsx12(
3038
+ "div",
3039
+ __spreadProps(__spreadValues({
3040
+ id: itemId,
3041
+ role: "menuitemcheckbox",
3042
+ "aria-checked": checked,
3043
+ "aria-disabled": disabled || void 0,
3044
+ "data-active-item": isActive ? "" : void 0,
3045
+ "data-disabled": disabled ? "" : void 0,
3046
+ tabIndex: -1,
3047
+ onClick: handleClick
3048
+ }, props), {
3049
+ children
3050
+ })
3051
+ );
3052
+ }
3053
+ function MenuItemRadio(_a) {
3054
+ var _b = _a, {
3055
+ checked = false,
3056
+ onChange,
3057
+ disabled,
3058
+ onClick,
3059
+ children
3060
+ } = _b, props = __objRest(_b, [
3061
+ "checked",
3062
+ "onChange",
3063
+ "disabled",
3064
+ "onClick",
3065
+ "children"
3066
+ ]);
3067
+ const { itemId, isActive } = useMenuItemRegistration(disabled);
3068
+ const handleClick = useCallback15(
3069
+ (e) => {
3070
+ if (disabled) return;
3071
+ onChange == null ? void 0 : onChange(!checked);
3072
+ onClick == null ? void 0 : onClick(e);
3073
+ },
3074
+ [disabled, checked, onChange, onClick]
3075
+ );
3076
+ return /* @__PURE__ */ jsx12(
3077
+ "div",
3078
+ __spreadProps(__spreadValues({
3079
+ id: itemId,
3080
+ role: "menuitemradio",
3081
+ "aria-checked": checked,
3082
+ "aria-disabled": disabled || void 0,
3083
+ "data-active-item": isActive ? "" : void 0,
3084
+ "data-disabled": disabled ? "" : void 0,
3085
+ tabIndex: -1,
3086
+ onClick: handleClick
3087
+ }, props), {
3088
+ children
3089
+ })
3090
+ );
3091
+ }
3092
+ function MenuSeparator(props) {
3093
+ return /* @__PURE__ */ jsx12("hr", __spreadValues({ role: "separator" }, props));
3094
+ }
3095
+ function MenuButtonArrow(props) {
3096
+ const { open } = useMenuContext();
3097
+ return /* @__PURE__ */ jsx12("span", __spreadProps(__spreadValues({ "aria-hidden": "true", "data-expanded": open ? "" : void 0 }, props), { children: "\u25BE" }));
3098
+ }
3099
+
3100
+ // src/primitives/toolbar.tsx
3101
+ import {
3102
+ createContext as createContext11,
3103
+ useContext as useContext11,
3104
+ useCallback as useCallback16,
3105
+ useRef as useRef12,
3106
+ useLayoutEffect as useLayoutEffect6,
3107
+ useState as useState10
3108
+ } from "react";
3109
+ import { jsx as jsx13 } from "react/jsx-runtime";
3110
+ function firstEnabledId4(items) {
3111
+ var _a, _b;
3112
+ return (_b = (_a = items.find((i) => !i.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
3113
+ }
3114
+ function moveActiveId4(items, activeId, delta) {
3115
+ const enabled = items.filter((i) => !i.disabled);
3116
+ if (enabled.length === 0) return null;
3117
+ const idx = enabled.findIndex((i) => i.id === activeId);
3118
+ if (idx < 0) {
3119
+ return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
3120
+ }
3121
+ const next = Math.min(enabled.length - 1, Math.max(0, idx + delta));
3122
+ return enabled[next].id;
3123
+ }
3124
+ var ToolbarContext = createContext11(null);
3125
+ function useToolbarContext() {
3126
+ const ctx = useContext11(ToolbarContext);
3127
+ if (!ctx)
3128
+ throw new Error("Toolbar components must be used within ToolbarRoot");
3129
+ return ctx;
3130
+ }
3131
+ function ToolbarRoot({
3132
+ children,
3133
+ orientation = "horizontal"
3134
+ }) {
3135
+ const [activeId, setActiveId] = useState10(null);
3136
+ const items = useRef12([]);
3137
+ const registerItem = useCallback16((entry) => {
3138
+ const list = items.current;
3139
+ const existing = list.findIndex((i) => i.id === entry.id);
3140
+ if (existing >= 0) list[existing] = entry;
3141
+ else list.push(entry);
3142
+ }, []);
3143
+ const unregisterItem = useCallback16((id) => {
3144
+ items.current = items.current.filter((i) => i.id !== id);
3145
+ setActiveId((prev) => prev === id ? firstEnabledId4(items.current) : prev);
3146
+ }, []);
3147
+ useLayoutEffect6(() => {
3148
+ setActiveId((prev) => prev != null ? prev : firstEnabledId4(items.current));
3149
+ }, [activeId]);
3150
+ return /* @__PURE__ */ jsx13(
3151
+ ToolbarContext.Provider,
3152
+ {
3153
+ value: {
3154
+ orientation,
3155
+ activeId,
3156
+ setActiveId,
3157
+ registerItem,
3158
+ unregisterItem,
3159
+ items
3160
+ },
3161
+ children
3162
+ }
3163
+ );
3164
+ }
3165
+ function ToolbarContainer(_a) {
3166
+ var _b = _a, {
3167
+ onKeyDown
3168
+ } = _b, props = __objRest(_b, [
3169
+ "onKeyDown"
3170
+ ]);
3171
+ const { orientation, activeId, setActiveId, items } = useToolbarContext();
3172
+ const focusActive = useCallback16(
3173
+ (id) => {
3174
+ var _a2, _b2;
3175
+ if (!id) return;
3176
+ (_b2 = (_a2 = items.current.find((i) => i.id === id)) == null ? void 0 : _a2.element) == null ? void 0 : _b2.focus();
3177
+ },
3178
+ [items]
3179
+ );
3180
+ const handleKeyDown2 = useCallback16(
3181
+ (e) => {
3182
+ var _a2, _b2;
3183
+ const prevKey = orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
3184
+ const nextKey = orientation === "vertical" ? "ArrowDown" : "ArrowRight";
3185
+ let nextId;
3186
+ if (e.key === nextKey) {
3187
+ e.preventDefault();
3188
+ nextId = moveActiveId4(items.current, activeId, 1);
3189
+ } else if (e.key === prevKey) {
3190
+ e.preventDefault();
3191
+ nextId = moveActiveId4(items.current, activeId, -1);
3192
+ } else if (e.key === "Home") {
3193
+ e.preventDefault();
3194
+ nextId = firstEnabledId4(items.current);
3195
+ } else if (e.key === "End") {
3196
+ e.preventDefault();
3197
+ const enabled = items.current.filter((i) => !i.disabled);
3198
+ nextId = (_b2 = (_a2 = enabled[enabled.length - 1]) == null ? void 0 : _a2.id) != null ? _b2 : null;
3199
+ }
3200
+ if (nextId) {
3201
+ setActiveId(nextId);
3202
+ focusActive(nextId);
3203
+ }
3204
+ onKeyDown == null ? void 0 : onKeyDown(e);
3205
+ },
3206
+ [orientation, activeId, setActiveId, items, focusActive, onKeyDown]
3207
+ );
3208
+ return /* @__PURE__ */ jsx13(
3209
+ "div",
3210
+ __spreadValues({
3211
+ role: "toolbar",
3212
+ "aria-orientation": orientation,
3213
+ onKeyDown: handleKeyDown2
3214
+ }, props)
3215
+ );
3216
+ }
3217
+ function ToolbarButton(_a) {
3218
+ var _b = _a, {
3219
+ disabled,
3220
+ onFocus
3221
+ } = _b, props = __objRest(_b, [
3222
+ "disabled",
3223
+ "onFocus"
3224
+ ]);
3225
+ const { registerItem, unregisterItem, activeId, setActiveId } = useToolbarContext();
3226
+ const itemId = useId();
3227
+ const buttonRef = useRef12(null);
3228
+ const isActive = activeId === itemId;
3229
+ useLayoutEffect6(() => {
3230
+ registerItem({ id: itemId, element: buttonRef.current, disabled });
3231
+ return () => unregisterItem(itemId);
3232
+ }, [itemId, disabled, registerItem, unregisterItem]);
3233
+ return /* @__PURE__ */ jsx13(
3234
+ "button",
3235
+ __spreadValues({
3236
+ ref: buttonRef,
3237
+ type: "button",
3238
+ disabled,
3239
+ tabIndex: isActive ? 0 : -1,
3240
+ onFocus: (e) => {
3241
+ if (!disabled) setActiveId(itemId);
3242
+ onFocus == null ? void 0 : onFocus(e);
3243
+ }
3244
+ }, props)
3245
+ );
3246
+ }
3247
+ function ToolbarSeparator(props) {
3248
+ return /* @__PURE__ */ jsx13("hr", __spreadValues({ role: "separator", "aria-orientation": "vertical" }, props));
3249
+ }
3250
+
3251
+ // src/primitives/composite.tsx
3252
+ import {
3253
+ createContext as createContext12,
3254
+ useContext as useContext12,
3255
+ useCallback as useCallback17,
3256
+ useRef as useRef13,
3257
+ useState as useState11,
3258
+ useEffect as useEffect13,
3259
+ cloneElement,
3260
+ isValidElement
3261
+ } from "react";
3262
+ import { jsx as jsx14 } from "react/jsx-runtime";
3263
+ function firstEnabledFrom(list, start, dir, loop) {
3264
+ const n = list.length;
3265
+ if (n === 0) return -1;
3266
+ let i = start;
3267
+ for (let guard = 0; guard <= n; guard++) {
3268
+ if (i >= 0 && i < n && !list[i].disabled) return i;
3269
+ i += dir;
3270
+ if (loop) i = (i % n + n) % n;
3271
+ else if (i < 0 || i >= n) return -1;
3272
+ }
3273
+ return -1;
3274
+ }
3275
+ var CompositeContext = createContext12(null);
3276
+ function useCompositeContext() {
3277
+ const ctx = useContext12(CompositeContext);
3278
+ if (!ctx)
3279
+ throw new Error(
3280
+ "Composite components must be used within CompositeProvider"
3281
+ );
3282
+ return ctx;
3283
+ }
3284
+ function CompositeProvider({
3285
+ children,
3286
+ focusLoop = false,
3287
+ focusWrap = false,
3288
+ orientation = "both",
3289
+ activeId: controlledActiveId,
3290
+ onActiveIdChange,
3291
+ setActiveId: setActiveIdDeprecated
3292
+ }) {
3293
+ const [internalActiveId, setInternalActiveId] = useState11(null);
3294
+ const items = useRef13([]);
3295
+ const onActiveIdChangeCb = onActiveIdChange != null ? onActiveIdChange : setActiveIdDeprecated;
3296
+ const activeId = controlledActiveId !== void 0 ? controlledActiveId : internalActiveId;
3297
+ const activeIdRef = useRef13(activeId);
3298
+ activeIdRef.current = activeId;
3299
+ const seededRef = useRef13(false);
3300
+ const setActiveId = useCallback17(
3301
+ (id) => {
3302
+ if (controlledActiveId === void 0) setInternalActiveId(id);
3303
+ onActiveIdChangeCb == null ? void 0 : onActiveIdChangeCb(id);
3304
+ },
3305
+ [controlledActiveId, onActiveIdChangeCb]
3306
+ );
3307
+ const registerItem = useCallback17(
3308
+ (id, element, row = 0, col = 0, disabled = false) => {
3309
+ const list = items.current;
3310
+ const existing = list.findIndex((i) => i.id === id);
3311
+ const activeBecameDisabled = existing >= 0 && id === activeIdRef.current && disabled;
3312
+ if (existing >= 0) {
3313
+ list[existing] = { id, element, row, col, disabled };
3314
+ } else {
3315
+ list.push({ id, element, row, col, disabled });
3316
+ }
3317
+ if (controlledActiveId !== void 0) return;
3318
+ if (activeIdRef.current === null && !seededRef.current && !disabled) {
3319
+ seededRef.current = true;
3320
+ activeIdRef.current = id;
3321
+ setActiveId(id);
3322
+ } else if (activeBecameDisabled) {
3323
+ const idx = firstEnabledFrom(list, 0, 1, false);
3324
+ const nextId = idx >= 0 ? list[idx].id : null;
3325
+ activeIdRef.current = nextId;
3326
+ if (nextId === null) {
3327
+ seededRef.current = false;
3328
+ setInternalActiveId(null);
3329
+ } else {
3330
+ setActiveId(nextId);
3331
+ }
3332
+ }
3333
+ },
3334
+ [controlledActiveId, setActiveId]
3335
+ );
3336
+ const unregisterItem = useCallback17(
3337
+ (id) => {
3338
+ items.current = items.current.filter((i) => i.id !== id);
3339
+ if (controlledActiveId === void 0) {
3340
+ setInternalActiveId((prev) => {
3341
+ if (prev !== id) return prev;
3342
+ const idx = firstEnabledFrom(items.current, 0, 1, false);
3343
+ const nextId = idx >= 0 ? items.current[idx].id : null;
3344
+ activeIdRef.current = nextId;
3345
+ if (nextId === null) seededRef.current = false;
3346
+ return nextId;
3347
+ });
3348
+ }
3349
+ },
3350
+ [controlledActiveId]
3351
+ );
3352
+ return /* @__PURE__ */ jsx14(
3353
+ CompositeContext.Provider,
3354
+ {
3355
+ value: {
3356
+ activeId,
3357
+ setActiveId,
3358
+ registerItem,
3359
+ unregisterItem,
3360
+ items,
3361
+ focusLoop,
3362
+ focusWrap,
3363
+ orientation
3364
+ },
3365
+ children
3366
+ }
3367
+ );
3368
+ }
3369
+ function Composite(_a) {
3370
+ var _b = _a, { onKeyDown, render } = _b, props = __objRest(_b, ["onKeyDown", "render"]);
3371
+ const { activeId, setActiveId, items, focusLoop, focusWrap, orientation } = useCompositeContext();
3372
+ const handleKeyDown2 = useCallback17(
3373
+ (e) => {
3374
+ var _a2, _b2, _c, _d;
3375
+ const list = items.current;
3376
+ const currentIndex = list.findIndex((i) => i.id === activeId);
3377
+ if (currentIndex < 0) return;
3378
+ let nextIndex = -1;
3379
+ const { row, col } = list[currentIndex];
3380
+ const isHorizontal = orientation !== "vertical";
3381
+ const isVertical = orientation !== "horizontal";
3382
+ const navigate = (offset2) => {
3383
+ const dir = offset2 >= 0 ? 1 : -1;
3384
+ let target = currentIndex + offset2;
3385
+ if (focusLoop) {
3386
+ target = (target % list.length + list.length) % list.length;
3387
+ } else if (focusWrap && (target < 0 || target >= list.length)) {
3388
+ return void 0;
3389
+ } else {
3390
+ target = Math.max(0, Math.min(list.length - 1, target));
3391
+ }
3392
+ const enabled = firstEnabledFrom(list, target, dir, focusLoop);
3393
+ return enabled >= 0 ? enabled : void 0;
3394
+ };
3395
+ const navigateRow = (dir) => {
3396
+ const sibling = list.find(
3397
+ (i) => i.col === col && i.row === row + dir && !i.disabled
3398
+ );
3399
+ if (sibling) return list.indexOf(sibling);
3400
+ return navigate(dir);
3401
+ };
3402
+ switch (e.key) {
3403
+ case "ArrowRight":
3404
+ if (!isHorizontal) break;
3405
+ e.preventDefault();
3406
+ nextIndex = (_a2 = navigate(1)) != null ? _a2 : currentIndex;
3407
+ break;
3408
+ case "ArrowLeft":
3409
+ if (!isHorizontal) break;
3410
+ e.preventDefault();
3411
+ nextIndex = (_b2 = navigate(-1)) != null ? _b2 : currentIndex;
3412
+ break;
3413
+ case "ArrowDown":
3414
+ if (!isVertical) break;
3415
+ e.preventDefault();
3416
+ nextIndex = (_c = navigateRow(1)) != null ? _c : currentIndex;
3417
+ break;
3418
+ case "ArrowUp":
3419
+ if (!isVertical) break;
3420
+ e.preventDefault();
3421
+ nextIndex = (_d = navigateRow(-1)) != null ? _d : currentIndex;
3422
+ break;
3423
+ case "Home":
3424
+ e.preventDefault();
3425
+ nextIndex = firstEnabledFrom(list, 0, 1, false);
3426
+ break;
3427
+ case "End":
3428
+ e.preventDefault();
3429
+ nextIndex = firstEnabledFrom(list, list.length - 1, -1, false);
3430
+ break;
3431
+ }
3432
+ if (nextIndex >= 0 && list[nextIndex]) {
3433
+ setActiveId(list[nextIndex].id);
3434
+ list[nextIndex].element.focus();
3435
+ }
3436
+ onKeyDown == null ? void 0 : onKeyDown(e);
3437
+ },
3438
+ [
3439
+ activeId,
3440
+ items,
3441
+ focusLoop,
3442
+ focusWrap,
3443
+ orientation,
3444
+ setActiveId,
3445
+ onKeyDown
3446
+ ]
3447
+ );
3448
+ if (render && isValidElement(render)) {
3449
+ const merged = mergeProps(
3450
+ render.props,
3451
+ { onKeyDown: handleKeyDown2 },
3452
+ props
3453
+ );
3454
+ return cloneElement(
3455
+ render,
3456
+ merged
3457
+ );
3458
+ }
3459
+ return /* @__PURE__ */ jsx14("div", __spreadValues({ onKeyDown: handleKeyDown2 }, props));
3460
+ }
3461
+ function CompositeRow(_a) {
3462
+ var _b = _a, { render } = _b, props = __objRest(_b, ["render"]);
3463
+ if (render && isValidElement(render)) {
3464
+ const merged = mergeProps(
3465
+ render.props,
3466
+ { role: "row" },
3467
+ props
3468
+ );
3469
+ return cloneElement(
3470
+ render,
3471
+ merged
3472
+ );
3473
+ }
3474
+ return /* @__PURE__ */ jsx14("div", __spreadValues({ role: "row" }, props));
3475
+ }
3476
+ function CompositeItem(_a) {
3477
+ var _b = _a, {
3478
+ id: providedId,
3479
+ row = 0,
3480
+ col = 0,
3481
+ disabled,
3482
+ render,
3483
+ onFocus
3484
+ } = _b, props = __objRest(_b, [
3485
+ "id",
3486
+ "row",
3487
+ "col",
3488
+ "disabled",
3489
+ "render",
3490
+ "onFocus"
3491
+ ]);
3492
+ const id = useId(providedId);
3493
+ const { activeId, setActiveId, registerItem, unregisterItem } = useCompositeContext();
3494
+ const ref = useRef13(null);
3495
+ const isActive = activeId === id;
3496
+ useEffect13(() => {
3497
+ if (ref.current) registerItem(id, ref.current, row, col, disabled);
3498
+ return () => unregisterItem(id);
3499
+ }, [id, row, col, disabled, registerItem, unregisterItem]);
3500
+ const sharedProps = __spreadValues({
3501
+ tabIndex: isActive && !disabled ? 0 : -1,
3502
+ "data-active-item": isActive ? "" : void 0,
3503
+ "aria-disabled": disabled || void 0,
3504
+ // Compose with any consumer-supplied onFocus (previously clobbered by the
3505
+ // spread of `...props`).
3506
+ onFocus: (e) => {
3507
+ if (!disabled) setActiveId(id);
3508
+ onFocus == null ? void 0 : onFocus(e);
3509
+ }
3510
+ }, props);
3511
+ if (render && isValidElement(render)) {
3512
+ const renderRef = render.props.ref;
3513
+ const merged = mergeProps(
3514
+ render.props,
3515
+ sharedProps
3516
+ );
3517
+ return cloneElement(render, __spreadProps(__spreadValues({}, merged), {
3518
+ ref: renderRef ? mergeRefs(ref, renderRef) : ref
3519
+ }));
3520
+ }
3521
+ return /* @__PURE__ */ jsx14(
3522
+ "button",
3523
+ __spreadProps(__spreadValues({
3524
+ type: "button",
3525
+ disabled
3526
+ }, sharedProps), {
3527
+ ref
3528
+ })
3529
+ );
3530
+ }
3531
+
3532
+ // src/primitives/separator.tsx
3533
+ import { forwardRef as forwardRef10 } from "react";
3534
+ import { jsx as jsx15 } from "react/jsx-runtime";
3535
+ var Separator = forwardRef10(
3536
+ function Separator2(_a, ref) {
3537
+ var _b = _a, { orientation = "horizontal", decorative = false } = _b, props = __objRest(_b, ["orientation", "decorative"]);
3538
+ const semanticProps = decorative ? { role: "none" } : { role: "separator", "aria-orientation": orientation };
3539
+ return /* @__PURE__ */ jsx15(
3540
+ "div",
3541
+ __spreadValues(__spreadValues({
3542
+ ref,
3543
+ "data-orientation": orientation
3544
+ }, semanticProps), props)
3545
+ );
3546
+ }
3547
+ );
3548
+
3549
+ // src/primitives/toggle.tsx
3550
+ import {
3551
+ createContext as createContext13,
3552
+ useCallback as useCallback18,
3553
+ useContext as useContext13,
3554
+ useLayoutEffect as useLayoutEffect7,
3555
+ useMemo as useMemo5,
3556
+ useRef as useRef14,
3557
+ useState as useState12
3558
+ } from "react";
3559
+ import { jsx as jsx16 } from "react/jsx-runtime";
3560
+ function firstEnabledId5(items) {
3561
+ var _a, _b;
3562
+ return (_b = (_a = items.find((i) => !i.disabled)) == null ? void 0 : _a.id) != null ? _b : null;
3563
+ }
3564
+ function moveActiveId5(items, activeId, delta) {
3565
+ const enabled = items.filter((i) => !i.disabled);
3566
+ if (enabled.length === 0) return null;
3567
+ const idx = enabled.findIndex((i) => i.id === activeId);
3568
+ if (idx < 0)
3569
+ return delta > 0 ? enabled[0].id : enabled[enabled.length - 1].id;
3570
+ const next = Math.min(enabled.length - 1, Math.max(0, idx + delta));
3571
+ return enabled[next].id;
3572
+ }
3573
+ var ToggleGroupContext = createContext13(null);
3574
+ function ToggleGroup(_a) {
3575
+ var _b = _a, {
3576
+ value: controlledValue,
3577
+ defaultValue,
3578
+ onValueChange,
3579
+ toggleMultiple = false,
3580
+ orientation = "horizontal",
3581
+ disabled = false,
3582
+ onKeyDown
3583
+ } = _b, props = __objRest(_b, [
3584
+ "value",
3585
+ "defaultValue",
3586
+ "onValueChange",
3587
+ "toggleMultiple",
3588
+ "orientation",
3589
+ "disabled",
3590
+ "onKeyDown"
3591
+ ]);
3592
+ const normalizedDefault = defaultValue != null ? defaultValue : toggleMultiple ? [] : "";
3593
+ const [value, setValue] = useControllableState(
3594
+ normalizedDefault,
3595
+ controlledValue,
3596
+ onValueChange
3597
+ );
3598
+ const selected = useMemo5(
3599
+ () => Array.isArray(value) ? value : value === "" ? [] : [value],
3600
+ [value]
3601
+ );
3602
+ const isPressed = useCallback18(
3603
+ (v) => selected.includes(v),
3604
+ [selected]
3605
+ );
3606
+ const toggle = useCallback18(
3607
+ (v) => {
3608
+ if (toggleMultiple) {
3609
+ const set = new Set(Array.isArray(value) ? value : []);
3610
+ if (set.has(v)) set.delete(v);
3611
+ else set.add(v);
3612
+ setValue([...set]);
3613
+ } else {
3614
+ const current = Array.isArray(value) ? value[0] : value;
3615
+ setValue(current === v ? "" : v);
3616
+ }
3617
+ },
3618
+ [toggleMultiple, value, setValue]
3619
+ );
3620
+ const [activeId, setActiveId] = useState12(null);
3621
+ const items = useRef14([]);
3622
+ const registerItem = useCallback18((entry) => {
3623
+ const list = items.current;
3624
+ const existing = list.findIndex((i) => i.id === entry.id);
3625
+ if (existing >= 0) list[existing] = entry;
3626
+ else list.push(entry);
3627
+ }, []);
3628
+ const unregisterItem = useCallback18((id) => {
3629
+ items.current = items.current.filter((i) => i.id !== id);
3630
+ setActiveId((prev) => prev === id ? firstEnabledId5(items.current) : prev);
3631
+ }, []);
3632
+ useLayoutEffect7(() => {
3633
+ setActiveId((prev) => prev != null ? prev : firstEnabledId5(items.current));
3634
+ }, [activeId]);
3635
+ const focusActive = useCallback18((id) => {
3636
+ var _a2, _b2;
3637
+ if (!id) return;
3638
+ (_b2 = (_a2 = items.current.find((i) => i.id === id)) == null ? void 0 : _a2.element) == null ? void 0 : _b2.focus();
3639
+ }, []);
3640
+ const handleKeyDown2 = useCallback18(
3641
+ (e) => {
3642
+ var _a2, _b2;
3643
+ const prevKey = orientation === "vertical" ? "ArrowUp" : "ArrowLeft";
3644
+ const nextKey = orientation === "vertical" ? "ArrowDown" : "ArrowRight";
3645
+ let nextId;
3646
+ if (e.key === nextKey) {
3647
+ e.preventDefault();
3648
+ nextId = moveActiveId5(items.current, activeId, 1);
3649
+ } else if (e.key === prevKey) {
3650
+ e.preventDefault();
3651
+ nextId = moveActiveId5(items.current, activeId, -1);
3652
+ } else if (e.key === "Home") {
3653
+ e.preventDefault();
3654
+ nextId = firstEnabledId5(items.current);
3655
+ } else if (e.key === "End") {
3656
+ e.preventDefault();
3657
+ const enabled = items.current.filter((i) => !i.disabled);
3658
+ nextId = (_b2 = (_a2 = enabled[enabled.length - 1]) == null ? void 0 : _a2.id) != null ? _b2 : null;
3659
+ }
3660
+ if (nextId) {
3661
+ setActiveId(nextId);
3662
+ focusActive(nextId);
3663
+ }
3664
+ onKeyDown == null ? void 0 : onKeyDown(e);
3665
+ },
3666
+ [orientation, activeId, focusActive, onKeyDown]
3667
+ );
3668
+ return /* @__PURE__ */ jsx16(
3669
+ ToggleGroupContext.Provider,
3670
+ {
3671
+ value: {
3672
+ isPressed,
3673
+ toggle,
3674
+ disabled,
3675
+ orientation,
3676
+ activeId,
3677
+ setActiveId,
3678
+ registerItem,
3679
+ unregisterItem,
3680
+ items
3681
+ },
3682
+ children: /* @__PURE__ */ jsx16("div", __spreadValues({ role: "group", onKeyDown: handleKeyDown2 }, props))
3683
+ }
3684
+ );
3685
+ }
3686
+ function Toggle(_a) {
3687
+ var _b = _a, {
3688
+ pressed: pressedProp,
3689
+ defaultPressed = false,
3690
+ onPressedChange,
3691
+ value,
3692
+ disabled,
3693
+ onClick,
3694
+ onFocus
3695
+ } = _b, props = __objRest(_b, [
3696
+ "pressed",
3697
+ "defaultPressed",
3698
+ "onPressedChange",
3699
+ "value",
3700
+ "disabled",
3701
+ "onClick",
3702
+ "onFocus"
3703
+ ]);
3704
+ const group = useContext13(ToggleGroupContext);
3705
+ const itemId = useId();
3706
+ const buttonRef = useRef14(null);
3707
+ const [standalonePressed, setStandalonePressed] = useControllableState(
3708
+ defaultPressed,
3709
+ pressedProp,
3710
+ onPressedChange
3711
+ );
3712
+ const inGroup = group !== null;
3713
+ const isDisabled = disabled || inGroup && group.disabled || false;
3714
+ useLayoutEffect7(() => {
3715
+ if (!inGroup) return void 0;
3716
+ group.registerItem({
3717
+ id: itemId,
3718
+ element: buttonRef.current,
3719
+ disabled: isDisabled
3720
+ });
3721
+ return () => group.unregisterItem(itemId);
3722
+ }, [inGroup, group, itemId, isDisabled]);
3723
+ const pressed = inGroup && value !== void 0 ? group.isPressed(value) : standalonePressed;
3724
+ const isActive = inGroup ? group.activeId === itemId : void 0;
3725
+ const handleClick = useCallback18(
3726
+ (e) => {
3727
+ if (inGroup) {
3728
+ if (value !== void 0) group.toggle(value);
3729
+ } else {
3730
+ setStandalonePressed(!standalonePressed);
3731
+ }
3732
+ onClick == null ? void 0 : onClick(e);
3733
+ },
3734
+ [inGroup, group, value, setStandalonePressed, standalonePressed, onClick]
3735
+ );
3736
+ return /* @__PURE__ */ jsx16(
3737
+ "button",
3738
+ __spreadValues({
3739
+ ref: buttonRef,
3740
+ type: "button",
3741
+ "aria-pressed": pressed,
3742
+ "data-pressed": pressed ? "" : void 0,
3743
+ disabled: isDisabled,
3744
+ tabIndex: inGroup ? isActive ? 0 : -1 : void 0,
3745
+ onClick: handleClick,
3746
+ onFocus: (e) => {
3747
+ if (inGroup && !isDisabled) group.setActiveId(itemId);
3748
+ onFocus == null ? void 0 : onFocus(e);
3749
+ }
3750
+ }, props)
3751
+ );
3752
+ }
3753
+
3754
+ // src/primitives/switch.tsx
3755
+ import { forwardRef as forwardRef11, useCallback as useCallback19 } from "react";
3756
+
3757
+ // src/internal/visually-hidden.ts
3758
+ var VISUALLY_HIDDEN = {
3759
+ position: "absolute",
3760
+ width: 1,
3761
+ height: 1,
3762
+ padding: 0,
3763
+ margin: -1,
3764
+ overflow: "hidden",
3765
+ clip: "rect(0 0 0 0)",
3766
+ whiteSpace: "nowrap",
3767
+ border: 0
3768
+ };
3769
+
3770
+ // src/primitives/switch.tsx
3771
+ import { Fragment as Fragment2, jsx as jsx17, jsxs as jsxs3 } from "react/jsx-runtime";
3772
+ var Switch = forwardRef11(
3773
+ function Switch2(_a, ref) {
3774
+ var _b = _a, {
3775
+ checked,
3776
+ defaultChecked = false,
3777
+ onCheckedChange,
3778
+ disabled = false,
3779
+ name,
3780
+ value = "on",
3781
+ required,
3782
+ onClick
3783
+ } = _b, props = __objRest(_b, [
3784
+ "checked",
3785
+ "defaultChecked",
3786
+ "onCheckedChange",
3787
+ "disabled",
3788
+ "name",
3789
+ "value",
3790
+ "required",
3791
+ "onClick"
3792
+ ]);
3793
+ const [on, setOn] = useControllableState(
3794
+ defaultChecked,
3795
+ checked,
3796
+ onCheckedChange
3797
+ );
3798
+ const handleClick = useCallback19(
3799
+ (e) => {
3800
+ if (disabled) return;
3801
+ setOn(!on);
3802
+ onClick == null ? void 0 : onClick(e);
3803
+ },
3804
+ [disabled, on, setOn, onClick]
3805
+ );
3806
+ return /* @__PURE__ */ jsxs3(Fragment2, { children: [
3807
+ /* @__PURE__ */ jsx17(
3808
+ "button",
3809
+ __spreadValues({
3810
+ ref,
3811
+ type: "button",
3812
+ role: "switch",
3813
+ "aria-checked": on,
3814
+ disabled,
3815
+ "data-state": on ? "checked" : "unchecked",
3816
+ "data-disabled": disabled ? "" : void 0,
3817
+ onClick: handleClick
3818
+ }, props)
3819
+ ),
3820
+ name != null && /* @__PURE__ */ jsx17(
3821
+ "input",
3822
+ {
3823
+ type: "checkbox",
3824
+ "aria-hidden": true,
3825
+ tabIndex: -1,
3826
+ name,
3827
+ value,
3828
+ checked: on,
3829
+ required,
3830
+ disabled,
3831
+ readOnly: true,
3832
+ style: VISUALLY_HIDDEN
3833
+ }
3834
+ )
3835
+ ] });
3836
+ }
3837
+ );
3838
+
3839
+ // src/primitives/checkbox.tsx
3840
+ import { forwardRef as forwardRef12, useCallback as useCallback20 } from "react";
3841
+ import { Fragment as Fragment3, jsx as jsx18, jsxs as jsxs4 } from "react/jsx-runtime";
3842
+ var Checkbox = forwardRef12(
3843
+ function Checkbox2(_a, ref) {
3844
+ var _b = _a, {
3845
+ checked,
3846
+ defaultChecked = false,
3847
+ indeterminate = false,
3848
+ onCheckedChange,
3849
+ disabled = false,
3850
+ name,
3851
+ value = "on",
3852
+ required,
3853
+ onClick,
3854
+ children
3855
+ } = _b, props = __objRest(_b, [
3856
+ "checked",
3857
+ "defaultChecked",
3858
+ "indeterminate",
3859
+ "onCheckedChange",
3860
+ "disabled",
3861
+ "name",
3862
+ "value",
3863
+ "required",
3864
+ "onClick",
3865
+ "children"
3866
+ ]);
3867
+ const [on, setOn] = useControllableState(
3868
+ defaultChecked,
3869
+ checked,
3870
+ onCheckedChange
3871
+ );
3872
+ const handleClick = useCallback20(
3873
+ (e) => {
3874
+ if (disabled) return;
3875
+ setOn(indeterminate ? true : !on);
3876
+ onClick == null ? void 0 : onClick(e);
3877
+ },
3878
+ [disabled, indeterminate, on, setOn, onClick]
3879
+ );
3880
+ return /* @__PURE__ */ jsxs4(Fragment3, { children: [
3881
+ /* @__PURE__ */ jsx18(
3882
+ "button",
3883
+ __spreadProps(__spreadValues({
3884
+ ref,
3885
+ type: "button",
3886
+ role: "checkbox",
3887
+ "aria-checked": indeterminate ? "mixed" : on,
3888
+ disabled,
3889
+ "data-state": indeterminate ? "indeterminate" : on ? "checked" : "unchecked",
3890
+ "data-disabled": disabled ? "" : void 0,
3891
+ onClick: handleClick
3892
+ }, props), {
3893
+ children
3894
+ })
3895
+ ),
3896
+ name != null && /* @__PURE__ */ jsx18(
3897
+ "input",
3898
+ {
3899
+ type: "checkbox",
3900
+ "aria-hidden": true,
3901
+ tabIndex: -1,
3902
+ name,
3903
+ value,
3904
+ checked: on,
3905
+ required,
3906
+ disabled,
3907
+ readOnly: true,
3908
+ style: VISUALLY_HIDDEN
3909
+ }
3910
+ )
3911
+ ] });
3912
+ }
3913
+ );
3914
+
3915
+ // src/primitives/progress.tsx
3916
+ import { forwardRef as forwardRef13 } from "react";
3917
+ import { jsx as jsx19 } from "react/jsx-runtime";
3918
+ function formatPercent(fraction) {
3919
+ return new Intl.NumberFormat(void 0, { style: "percent" }).format(
3920
+ fraction
3921
+ );
3922
+ }
3923
+ var Progress = forwardRef13(
3924
+ function Progress2(_a, ref) {
3925
+ var _b = _a, { value = null, min = 0, max = 100, getValueLabel } = _b, props = __objRest(_b, ["value", "min", "max", "getValueLabel"]);
3926
+ const indeterminate = value == null || Number.isNaN(value);
3927
+ const clamped = indeterminate ? null : Math.min(max, Math.max(min, value));
3928
+ const fraction = clamped == null || max === min ? 0 : (clamped - min) / (max - min);
3929
+ const valueText = clamped == null ? void 0 : getValueLabel ? getValueLabel(clamped, min, max) : formatPercent(fraction);
3930
+ return /* @__PURE__ */ jsx19(
3931
+ "div",
3932
+ __spreadValues({
3933
+ ref,
3934
+ role: "progressbar",
3935
+ "aria-valuemin": min,
3936
+ "aria-valuemax": max,
3937
+ "aria-valuenow": clamped != null ? clamped : void 0,
3938
+ "aria-valuetext": valueText,
3939
+ "data-state": indeterminate ? "indeterminate" : fraction >= 1 ? "complete" : "loading",
3940
+ "data-value": clamped != null ? clamped : void 0
3941
+ }, props)
3942
+ );
3943
+ }
3944
+ );
3945
+
3946
+ // src/primitives/meter.tsx
3947
+ import { forwardRef as forwardRef14 } from "react";
3948
+ import { jsx as jsx20 } from "react/jsx-runtime";
3949
+ function formatPercent2(fraction) {
3950
+ return new Intl.NumberFormat(void 0, { style: "percent" }).format(
3951
+ fraction
3952
+ );
3953
+ }
3954
+ var Meter = forwardRef14(function Meter2(_a, ref) {
3955
+ var _b = _a, { value, min = 0, max = 100, getValueLabel } = _b, props = __objRest(_b, ["value", "min", "max", "getValueLabel"]);
3956
+ const clamped = Math.min(max, Math.max(min, value));
3957
+ const fraction = max === min ? 0 : (clamped - min) / (max - min);
3958
+ const valueText = getValueLabel ? getValueLabel(clamped, min, max) : formatPercent2(fraction);
3959
+ return /* @__PURE__ */ jsx20(
3960
+ "div",
3961
+ __spreadValues({
3962
+ ref,
3963
+ role: "meter",
3964
+ "aria-valuemin": min,
3965
+ "aria-valuemax": max,
3966
+ "aria-valuenow": clamped,
3967
+ "aria-valuetext": valueText,
3968
+ "data-value": clamped
3969
+ }, props)
3970
+ );
3971
+ });
3972
+
3973
+ // src/primitives/accordion.tsx
3974
+ import {
3975
+ createContext as createContext14,
3976
+ useCallback as useCallback21,
3977
+ useContext as useContext14,
3978
+ useEffect as useEffect14,
3979
+ useRef as useRef15
3980
+ } from "react";
3981
+ import { jsx as jsx21 } from "react/jsx-runtime";
3982
+ var AccordionRootContext = createContext14(
3983
+ null
3984
+ );
3985
+ function useAccordionRoot() {
3986
+ const ctx = useContext14(AccordionRootContext);
3987
+ if (!ctx) {
3988
+ throw new Error("Accordion components must be used within AccordionRoot");
3989
+ }
3990
+ return ctx;
3991
+ }
3992
+ var AccordionItemContext = createContext14(
3993
+ null
3994
+ );
3995
+ function useAccordionItem() {
3996
+ const ctx = useContext14(AccordionItemContext);
3997
+ if (!ctx) {
3998
+ throw new Error(
3999
+ "AccordionTrigger/AccordionContent must be used within AccordionItem"
4000
+ );
4001
+ }
4002
+ return ctx;
4003
+ }
4004
+ function AccordionRoot({
4005
+ children,
4006
+ type = "single",
4007
+ value: controlledValue,
4008
+ defaultValue,
4009
+ onValueChange,
4010
+ collapsible = false,
4011
+ disabled = false,
4012
+ animated = true
4013
+ }) {
4014
+ const multiple = type === "multiple";
4015
+ const normalizedDefault = defaultValue != null ? defaultValue : multiple ? [] : null;
4016
+ const [value, setValue] = useControllableState(
4017
+ normalizedDefault,
4018
+ controlledValue,
4019
+ onValueChange
4020
+ );
4021
+ const isExpanded = useCallback21(
4022
+ (v) => Array.isArray(value) ? value.includes(v) : value === v,
4023
+ [value]
4024
+ );
4025
+ const toggle = useCallback21(
4026
+ (v) => {
4027
+ if (multiple) {
4028
+ const set = new Set(Array.isArray(value) ? value : []);
4029
+ if (set.has(v)) set.delete(v);
4030
+ else set.add(v);
4031
+ setValue([...set]);
4032
+ } else {
4033
+ const current = Array.isArray(value) ? value[0] : value;
4034
+ if (current === v) {
4035
+ if (collapsible) setValue(null);
4036
+ } else {
4037
+ setValue(v);
4038
+ }
4039
+ }
4040
+ },
4041
+ [multiple, value, collapsible, setValue]
4042
+ );
4043
+ return /* @__PURE__ */ jsx21(
4044
+ AccordionRootContext.Provider,
4045
+ {
4046
+ value: { isExpanded, toggle, disabled, animated },
4047
+ children
4048
+ }
4049
+ );
4050
+ }
4051
+ function AccordionItem(_a) {
4052
+ var _b = _a, {
4053
+ value,
4054
+ disabled = false
4055
+ } = _b, props = __objRest(_b, [
4056
+ "value",
4057
+ "disabled"
4058
+ ]);
4059
+ const root = useAccordionRoot();
4060
+ const baseId = useId();
4061
+ const itemDisabled = disabled || root.disabled;
4062
+ return /* @__PURE__ */ jsx21(
4063
+ AccordionItemContext.Provider,
4064
+ {
4065
+ value: {
4066
+ value,
4067
+ triggerId: `${baseId}-trigger`,
4068
+ contentId: `${baseId}-content`,
4069
+ disabled: itemDisabled
4070
+ },
4071
+ children: /* @__PURE__ */ jsx21("div", __spreadValues({ "data-state": root.isExpanded(value) ? "open" : "closed" }, props))
4072
+ }
4073
+ );
4074
+ }
4075
+ function AccordionTrigger(_a) {
4076
+ var _b = _a, {
4077
+ onClick,
4078
+ disabled
4079
+ } = _b, props = __objRest(_b, [
4080
+ "onClick",
4081
+ "disabled"
4082
+ ]);
4083
+ const root = useAccordionRoot();
4084
+ const item = useAccordionItem();
4085
+ const expanded = root.isExpanded(item.value);
4086
+ const isDisabled = disabled || item.disabled;
4087
+ const handleClick = useCallback21(
4088
+ (e) => {
4089
+ if (!isDisabled) root.toggle(item.value);
4090
+ onClick == null ? void 0 : onClick(e);
4091
+ },
4092
+ [isDisabled, root, item.value, onClick]
4093
+ );
4094
+ return /* @__PURE__ */ jsx21(
4095
+ "button",
4096
+ __spreadValues({
4097
+ type: "button",
4098
+ id: item.triggerId,
4099
+ "aria-expanded": expanded,
4100
+ "aria-controls": item.contentId,
4101
+ disabled: isDisabled,
4102
+ "data-state": expanded ? "open" : "closed",
4103
+ onClick: handleClick
4104
+ }, props)
4105
+ );
4106
+ }
4107
+ function AccordionContent(_a) {
4108
+ var _b = _a, { style } = _b, props = __objRest(_b, ["style"]);
4109
+ const root = useAccordionRoot();
4110
+ const item = useAccordionItem();
4111
+ const expanded = root.isExpanded(item.value);
4112
+ const { ref, mounted, dataAttributes } = useEnterLeave(expanded, {
4113
+ animated: root.animated
4114
+ });
4115
+ const innerRef = useRef15(null);
4116
+ useEffect14(() => {
4117
+ if (innerRef.current) {
4118
+ ref.current = innerRef.current;
4119
+ }
4120
+ }, [ref]);
4121
+ if (!mounted) return null;
4122
+ return /* @__PURE__ */ jsx21(
4123
+ "div",
4124
+ __spreadValues(__spreadValues({
4125
+ ref: innerRef,
4126
+ id: item.contentId,
4127
+ role: "region",
4128
+ "aria-labelledby": item.triggerId,
4129
+ style
4130
+ }, dataAttributes), props)
4131
+ );
4132
+ }
4133
+
4134
+ // src/form/form-store.ts
4135
+ import { useCallback as useCallback22, useRef as useRef16, useSyncExternalStore as useSyncExternalStore2 } from "react";
4136
+ function getByPath(obj, path) {
4137
+ return path.split(".").reduce((acc, key) => {
4138
+ if (acc == null || typeof acc !== "object") return void 0;
4139
+ return acc[key];
4140
+ }, obj);
4141
+ }
4142
+ function setByPath(obj, path, value) {
4143
+ const keys = path.split(".");
4144
+ const result = __spreadValues({}, obj);
4145
+ let current = result;
4146
+ for (let i = 0; i < keys.length - 1; i++) {
4147
+ const key = keys[i];
4148
+ const next = current[key];
4149
+ if (Array.isArray(next)) {
4150
+ current[key] = [...next];
4151
+ } else if (next && typeof next === "object") {
4152
+ current[key] = __spreadValues({}, next);
4153
+ } else {
4154
+ current[key] = {};
4155
+ }
4156
+ current = current[key];
4157
+ }
4158
+ current[keys[keys.length - 1]] = value;
4159
+ return result;
4160
+ }
4161
+ function deepEqual(a, b) {
4162
+ if (a === b) return true;
4163
+ if (a == null || b == null) return false;
4164
+ if (typeof a !== typeof b) return false;
4165
+ if (Array.isArray(a) && Array.isArray(b)) {
4166
+ if (a.length !== b.length) return false;
4167
+ return a.every((v, i) => deepEqual(v, b[i]));
4168
+ }
4169
+ if (typeof a === "object" && typeof b === "object") {
4170
+ const keysA = Object.keys(a);
4171
+ const keysB = Object.keys(b);
4172
+ if (keysA.length !== keysB.length) return false;
4173
+ return keysA.every(
4174
+ (k) => deepEqual(
4175
+ a[k],
4176
+ b[k]
4177
+ )
4178
+ );
4179
+ }
4180
+ return false;
4181
+ }
4182
+ function collectFieldPaths(value, prefix = "") {
4183
+ if (Array.isArray(value)) {
4184
+ if (value.length === 0) {
4185
+ return prefix ? [prefix] : [];
4186
+ }
4187
+ return value.flatMap(
4188
+ (item, index) => collectFieldPaths(item, prefix ? `${prefix}.${index}` : `${index}`)
4189
+ );
4190
+ }
4191
+ if (value && typeof value === "object") {
4192
+ const entries = Object.entries(value);
4193
+ if (entries.length === 0) {
4194
+ return prefix ? [prefix] : [];
4195
+ }
4196
+ return entries.flatMap(
4197
+ ([key, nestedValue]) => collectFieldPaths(nestedValue, prefix ? `${prefix}.${key}` : key)
4198
+ );
4199
+ }
4200
+ return prefix ? [prefix] : [];
4201
+ }
4202
+ function createFormStore(optionsRef) {
4203
+ function getOptions() {
4204
+ return optionsRef.current;
4205
+ }
4206
+ function getDefaultValues() {
4207
+ return __spreadValues({}, getOptions().defaultValues);
4208
+ }
4209
+ function getValidateOn() {
4210
+ var _a;
4211
+ return (_a = getOptions().validateOn) != null ? _a : "change";
4212
+ }
4213
+ let values = getDefaultValues();
4214
+ let validationErrors = {};
4215
+ let injectedErrors = {};
4216
+ let errors = {};
4217
+ let touched = /* @__PURE__ */ new Set();
4218
+ let submitting = false;
4219
+ let submitError = void 0;
4220
+ let validating = false;
4221
+ let version = 0;
4222
+ let submitToken = 0;
4223
+ const listeners = /* @__PURE__ */ new Set();
4224
+ const controls = /* @__PURE__ */ new Map();
4225
+ function notify() {
4226
+ version++;
4227
+ for (const l of listeners) l();
4228
+ }
4229
+ function focusFirstInvalid(errs) {
4230
+ for (const [name, getElement] of controls) {
4231
+ if (!errs[name]) continue;
4232
+ const el = getElement();
4233
+ if (!el) return;
4234
+ el.focus();
4235
+ if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) {
4236
+ try {
4237
+ el.select();
4238
+ } catch (e) {
4239
+ }
4240
+ }
4241
+ return;
4242
+ }
4243
+ }
4244
+ function recombineErrors() {
4245
+ errors = __spreadValues(__spreadValues({}, injectedErrors), validationErrors);
4246
+ }
4247
+ function runValidation() {
4248
+ var _a;
4249
+ const validate = getOptions().validate;
4250
+ if (!validate) {
4251
+ validationErrors = {};
4252
+ recombineErrors();
4253
+ return errors;
4254
+ }
4255
+ validating = true;
4256
+ try {
4257
+ validationErrors = (_a = validate(values)) != null ? _a : {};
4258
+ } finally {
4259
+ validating = false;
4260
+ }
4261
+ recombineErrors();
4262
+ return errors;
4263
+ }
4264
+ const store = {
4265
+ getValues: () => values,
4266
+ getValue: ((name) => getByPath(values, name)),
4267
+ setValue: ((name, value) => {
4268
+ values = setByPath(values, name, value);
4269
+ touched.add(name);
4270
+ if (name in injectedErrors) {
4271
+ delete injectedErrors[name];
4272
+ recombineErrors();
4273
+ }
4274
+ if (getValidateOn() === "change") {
4275
+ errors = runValidation();
4276
+ }
4277
+ notify();
4278
+ }),
4279
+ getErrors: () => __spreadValues({}, errors),
4280
+ getError: (name) => errors[name],
4281
+ setError: (name, error) => {
4282
+ if (error === void 0) {
4283
+ delete injectedErrors[name];
4284
+ } else {
4285
+ injectedErrors[name] = error;
4286
+ touched.add(name);
4287
+ }
4288
+ recombineErrors();
4289
+ if (!validating) {
4290
+ notify();
4291
+ }
4292
+ },
4293
+ getFieldTouched: (name) => touched.has(name),
4294
+ setFieldTouched: (name, isTouched) => {
4295
+ if (isTouched) {
4296
+ touched.add(name);
4297
+ if (getValidateOn() === "blur") {
4298
+ errors = runValidation();
4299
+ }
4300
+ } else {
4301
+ touched.delete(name);
4302
+ }
4303
+ notify();
4304
+ },
4305
+ isDirty: () => {
4306
+ const defaultValues = getDefaultValues();
4307
+ return !deepEqual(values, defaultValues);
4308
+ },
4309
+ isFieldDirty: (name) => {
4310
+ const defaultValues = getDefaultValues();
4311
+ return !deepEqual(
4312
+ getByPath(values, name),
4313
+ getByPath(defaultValues, name)
4314
+ );
4315
+ },
4316
+ validate: () => {
4317
+ errors = runValidation();
4318
+ for (const key of collectFieldPaths(values)) {
4319
+ touched.add(key);
4320
+ }
4321
+ for (const key of Object.keys(errors)) {
4322
+ touched.add(key);
4323
+ }
4324
+ notify();
4325
+ return errors;
4326
+ },
4327
+ reset: () => {
4328
+ values = getDefaultValues();
4329
+ validationErrors = {};
4330
+ injectedErrors = {};
4331
+ errors = {};
4332
+ touched = /* @__PURE__ */ new Set();
4333
+ submitting = false;
4334
+ submitError = void 0;
4335
+ submitToken += 1;
4336
+ notify();
4337
+ },
4338
+ resetField: (name) => {
4339
+ const defaultValues = getDefaultValues();
4340
+ const defaultVal = getByPath(defaultValues, name);
4341
+ values = setByPath(values, name, defaultVal);
4342
+ delete validationErrors[name];
4343
+ delete injectedErrors[name];
4344
+ recombineErrors();
4345
+ touched.delete(name);
4346
+ notify();
4347
+ },
4348
+ registerControl: (name, getElement) => {
4349
+ controls.set(name, getElement);
4350
+ return () => {
4351
+ if (controls.get(name) === getElement) controls.delete(name);
4352
+ };
4353
+ },
4354
+ submit: (e) => {
4355
+ var _a, _b, _c;
4356
+ (_a = e == null ? void 0 : e.preventDefault) == null ? void 0 : _a.call(e);
4357
+ if (submitting) return;
4358
+ submitError = void 0;
4359
+ const errs = store.validate();
4360
+ if (Object.keys(errs).length > 0) {
4361
+ focusFirstInvalid(errs);
4362
+ return;
4363
+ }
4364
+ const result = (_c = (_b = getOptions()).onSubmit) == null ? void 0 : _c.call(_b, values);
4365
+ if (result && typeof result === "object" && "then" in result) {
4366
+ const token = submitToken += 1;
4367
+ submitting = true;
4368
+ notify();
4369
+ result.then(
4370
+ () => {
4371
+ if (token !== submitToken) return;
4372
+ submitting = false;
4373
+ notify();
4374
+ },
4375
+ (err) => {
4376
+ if (token !== submitToken) return;
4377
+ submitting = false;
4378
+ submitError = err;
4379
+ notify();
4380
+ }
4381
+ );
4382
+ }
4383
+ },
4384
+ isSubmitting: () => submitting,
4385
+ getSubmitError: () => submitError,
4386
+ push: ((name, item) => {
4387
+ const arr = getByPath(values, name);
4388
+ const newArr = Array.isArray(arr) ? [...arr, item] : [item];
4389
+ values = setByPath(values, name, newArr);
4390
+ touched.add(name);
4391
+ if (getValidateOn() === "change") {
4392
+ errors = runValidation();
4393
+ }
4394
+ notify();
4395
+ }),
4396
+ remove: (name, index) => {
4397
+ const arr = getByPath(values, name);
4398
+ if (Array.isArray(arr)) {
4399
+ const newArr = arr.filter((_, i) => i !== index);
4400
+ values = setByPath(values, name, newArr);
4401
+ touched.add(name);
4402
+ if (getValidateOn() === "change") {
4403
+ errors = runValidation();
4404
+ }
4405
+ notify();
4406
+ }
4407
+ },
4408
+ subscribe: (listener) => {
4409
+ listeners.add(listener);
4410
+ return () => listeners.delete(listener);
4411
+ },
4412
+ getSnapshot: () => version
4413
+ };
4414
+ return store;
4415
+ }
4416
+ function useFormStore(options) {
4417
+ const optionsRef = useRef16(options);
4418
+ optionsRef.current = options;
4419
+ const storeRef = useRef16(void 0);
4420
+ if (!storeRef.current) {
4421
+ storeRef.current = createFormStore(optionsRef);
4422
+ }
4423
+ useSyncExternalStore2(
4424
+ storeRef.current.subscribe,
4425
+ storeRef.current.getSnapshot,
4426
+ storeRef.current.getSnapshot
4427
+ );
4428
+ return storeRef.current;
4429
+ }
4430
+ function useFieldValue(store, name) {
4431
+ const getSnapshot = useCallback22(
4432
+ () => store.getValue(name),
4433
+ [store, name]
4434
+ );
4435
+ useSyncExternalStore2(store.subscribe, getSnapshot, getSnapshot);
4436
+ return store.getValue(name);
4437
+ }
4438
+ var noopSubscribe = () => () => {
4439
+ };
4440
+ function useFieldValueMaybe(store, name) {
4441
+ const subscribe = useCallback22(
4442
+ (cb) => store ? store.subscribe(cb) : noopSubscribe(),
4443
+ [store]
4444
+ );
4445
+ const getSnapshot = useCallback22(
4446
+ () => store ? store.getValue(name) : void 0,
4447
+ [store, name]
4448
+ );
4449
+ return useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
4450
+ }
4451
+ function useStoreSubscription(store) {
4452
+ const subscribe = useCallback22(
4453
+ (cb) => store ? store.subscribe(cb) : noopSubscribe(),
4454
+ [store]
4455
+ );
4456
+ const getSnapshot = useCallback22(
4457
+ () => store ? store.getSnapshot() : 0,
4458
+ [store]
4459
+ );
4460
+ useSyncExternalStore2(subscribe, getSnapshot, getSnapshot);
4461
+ }
4462
+
4463
+ // src/form/form-context.tsx
4464
+ import { createContext as createContext15, useContext as useContext15 } from "react";
4465
+ import { jsx as jsx22 } from "react/jsx-runtime";
4466
+ var FormContext = createContext15(null);
4467
+ function FormProvider({
4468
+ store,
4469
+ children
4470
+ }) {
4471
+ return /* @__PURE__ */ jsx22(FormContext.Provider, { value: store, children });
4472
+ }
4473
+ function useFormContext() {
4474
+ return useContext15(FormContext);
4475
+ }
4476
+
4477
+ // src/form/form-primitives.tsx
4478
+ import {
4479
+ createContext as createContext16,
4480
+ forwardRef as forwardRef15,
4481
+ useCallback as useCallback23,
4482
+ useContext as useContext16,
4483
+ useEffect as useEffect15,
4484
+ useMemo as useMemo6,
4485
+ useRef as useRef17,
4486
+ useState as useState13
4487
+ } from "react";
4488
+ import { jsx as jsx23 } from "react/jsx-runtime";
4489
+ function useRegisterControl(form, name, forwardedRef) {
4490
+ const elRef = useRef17(null);
4491
+ useEffect15(() => {
4492
+ if (!form) return;
4493
+ return form.registerControl(name, () => elRef.current);
4494
+ }, [form, name]);
4495
+ return useMemo6(
4496
+ () => mergeRefs((node) => {
4497
+ elRef.current = node;
4498
+ }, forwardedRef),
4499
+ [forwardedRef]
4500
+ );
4501
+ }
4502
+ var FormFieldContext = createContext16(null);
4503
+ function useFormField() {
4504
+ return useContext16(FormFieldContext);
4505
+ }
4506
+ function composeDescribedBy(field, hasError, own) {
4507
+ const ids = [
4508
+ own,
4509
+ hasError && field ? field.errorId : null,
4510
+ (field == null ? void 0 : field.hasDescription) ? field.descriptionId : null
4511
+ ].filter(Boolean);
4512
+ return ids.length ? ids.join(" ") : void 0;
4513
+ }
4514
+ function FormRoot(_a) {
4515
+ var _b = _a, { onSubmit } = _b, props = __objRest(_b, ["onSubmit"]);
4516
+ const form = useFormContext();
4517
+ return /* @__PURE__ */ jsx23(
4518
+ "form",
4519
+ __spreadValues({
4520
+ onSubmit: (e) => {
4521
+ e.preventDefault();
4522
+ form == null ? void 0 : form.submit();
4523
+ onSubmit == null ? void 0 : onSubmit(e);
4524
+ }
4525
+ }, props)
4526
+ );
4527
+ }
4528
+ function FormField(_a) {
4529
+ var _b = _a, { name } = _b, props = __objRest(_b, ["name"]);
4530
+ const base = useId();
4531
+ const [hasDescription, setHasDescription] = useState13(false);
4532
+ const ctx = useMemo6(
4533
+ () => ({
4534
+ name,
4535
+ inputId: `${base}-input`,
4536
+ errorId: `${base}-error`,
4537
+ descriptionId: `${base}-description`,
4538
+ hasDescription,
4539
+ setHasDescription
4540
+ }),
4541
+ [name, base, hasDescription]
4542
+ );
4543
+ return /* @__PURE__ */ jsx23(FormFieldContext.Provider, { value: ctx, children: /* @__PURE__ */ jsx23("div", __spreadValues({}, props)) });
4544
+ }
4545
+ function FormLabel(_a) {
4546
+ var _b = _a, { htmlFor, name: _name } = _b, props = __objRest(_b, ["htmlFor", "name"]);
4547
+ const field = useFormField();
4548
+ return /* @__PURE__ */ jsx23("label", __spreadValues({ htmlFor: htmlFor != null ? htmlFor : field == null ? void 0 : field.inputId }, props));
4549
+ }
4550
+ var FormInput = forwardRef15(
4551
+ (_a, ref) => {
4552
+ var _b = _a, { name, id, onChange, "aria-describedby": ariaDescribedBy } = _b, props = __objRest(_b, ["name", "id", "onChange", "aria-describedby"]);
4553
+ var _a2;
4554
+ const form = useFormContext();
4555
+ const field = useFormField();
4556
+ const value = (_a2 = useFieldValueMaybe(form, name)) != null ? _a2 : "";
4557
+ const error = form == null ? void 0 : form.getError(name);
4558
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4559
+ const hasError = Boolean(error && touched);
4560
+ const setRef = useRegisterControl(form, name, ref);
4561
+ const handleChange = useCallback23(
4562
+ (e) => {
4563
+ const el = e.target;
4564
+ let next = el.value;
4565
+ if (el.type === "number" && el.value !== "") {
4566
+ next = Number.isNaN(el.valueAsNumber) ? el.value : el.valueAsNumber;
4567
+ }
4568
+ form == null ? void 0 : form.setValue(name, next);
4569
+ onChange == null ? void 0 : onChange(e);
4570
+ },
4571
+ [form, name, onChange]
4572
+ );
4573
+ return /* @__PURE__ */ jsx23(
4574
+ "input",
4575
+ __spreadValues({
4576
+ ref: setRef,
4577
+ id: id != null ? id : field == null ? void 0 : field.inputId,
4578
+ name,
4579
+ value,
4580
+ onChange: handleChange,
4581
+ onBlur: () => form == null ? void 0 : form.setFieldTouched(name, true),
4582
+ "aria-invalid": hasError || void 0,
4583
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
4584
+ }, props)
4585
+ );
4586
+ }
4587
+ );
4588
+ FormInput.displayName = "FormInput";
4589
+ var FormTextarea = forwardRef15(
4590
+ (_a, ref) => {
4591
+ var _b = _a, { name, id, onChange, "aria-describedby": ariaDescribedBy } = _b, props = __objRest(_b, ["name", "id", "onChange", "aria-describedby"]);
4592
+ var _a2;
4593
+ const form = useFormContext();
4594
+ const field = useFormField();
4595
+ const value = (_a2 = useFieldValueMaybe(form, name)) != null ? _a2 : "";
4596
+ const error = form == null ? void 0 : form.getError(name);
4597
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4598
+ const hasError = Boolean(error && touched);
4599
+ const setRef = useRegisterControl(form, name, ref);
4600
+ const handleChange = useCallback23(
4601
+ (e) => {
4602
+ form == null ? void 0 : form.setValue(name, e.target.value);
4603
+ onChange == null ? void 0 : onChange(e);
4604
+ },
4605
+ [form, name, onChange]
4606
+ );
4607
+ return /* @__PURE__ */ jsx23(
4608
+ "textarea",
4609
+ __spreadValues({
4610
+ ref: setRef,
4611
+ id: id != null ? id : field == null ? void 0 : field.inputId,
4612
+ name,
4613
+ value,
4614
+ onChange: handleChange,
4615
+ onBlur: () => form == null ? void 0 : form.setFieldTouched(name, true),
4616
+ "aria-invalid": hasError || void 0,
4617
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
4618
+ }, props)
4619
+ );
4620
+ }
4621
+ );
4622
+ FormTextarea.displayName = "FormTextarea";
4623
+ var FormSelect = forwardRef15(
4624
+ (_a, ref) => {
4625
+ var _b = _a, {
4626
+ name,
4627
+ id,
4628
+ onChange,
4629
+ "aria-describedby": ariaDescribedBy,
4630
+ children
4631
+ } = _b, props = __objRest(_b, [
4632
+ "name",
4633
+ "id",
4634
+ "onChange",
4635
+ "aria-describedby",
4636
+ "children"
4637
+ ]);
4638
+ var _a2;
4639
+ const form = useFormContext();
4640
+ const field = useFormField();
4641
+ const value = (_a2 = useFieldValueMaybe(form, name)) != null ? _a2 : "";
4642
+ const error = form == null ? void 0 : form.getError(name);
4643
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4644
+ const hasError = Boolean(error && touched);
4645
+ const setRef = useRegisterControl(form, name, ref);
4646
+ const handleChange = useCallback23(
4647
+ (e) => {
4648
+ form == null ? void 0 : form.setValue(name, e.target.value);
4649
+ onChange == null ? void 0 : onChange(e);
4650
+ },
4651
+ [form, name, onChange]
4652
+ );
4653
+ return /* @__PURE__ */ jsx23(
4654
+ "select",
4655
+ __spreadProps(__spreadValues({
4656
+ ref: setRef,
4657
+ id: id != null ? id : field == null ? void 0 : field.inputId,
4658
+ name,
4659
+ value,
4660
+ onChange: handleChange,
4661
+ onBlur: () => form == null ? void 0 : form.setFieldTouched(name, true),
4662
+ "aria-invalid": hasError || void 0,
4663
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
4664
+ }, props), {
4665
+ children
4666
+ })
4667
+ );
4668
+ }
4669
+ );
4670
+ FormSelect.displayName = "FormSelect";
4671
+ var FormSwitch = forwardRef15(
4672
+ (_a, ref) => {
4673
+ var _b = _a, { name, onClick, onBlur, "aria-describedby": ariaDescribedBy } = _b, props = __objRest(_b, ["name", "onClick", "onBlur", "aria-describedby"]);
4674
+ const form = useFormContext();
4675
+ const field = useFormField();
4676
+ const checked = Boolean(useFieldValueMaybe(form, name));
4677
+ const error = form == null ? void 0 : form.getError(name);
4678
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4679
+ const hasError = Boolean(error && touched);
4680
+ const handleClick = useCallback23(
4681
+ (e) => {
4682
+ form == null ? void 0 : form.setValue(name, !checked);
4683
+ onClick == null ? void 0 : onClick(e);
4684
+ },
4685
+ [form, name, checked, onClick]
4686
+ );
4687
+ return /* @__PURE__ */ jsx23(
4688
+ "button",
4689
+ __spreadValues({
4690
+ ref,
4691
+ type: "button",
4692
+ role: "switch",
4693
+ "aria-checked": checked,
4694
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy),
4695
+ onClick: handleClick,
4696
+ onBlur: (e) => {
4697
+ form == null ? void 0 : form.setFieldTouched(name, true);
4698
+ onBlur == null ? void 0 : onBlur(e);
4699
+ }
4700
+ }, props)
4701
+ );
4702
+ }
4703
+ );
4704
+ FormSwitch.displayName = "FormSwitch";
4705
+ var FormCheckbox = forwardRef15(
4706
+ (_a, ref) => {
4707
+ var _b = _a, {
4708
+ name,
4709
+ value,
4710
+ onChange,
4711
+ onBlur,
4712
+ "aria-describedby": ariaDescribedBy
4713
+ } = _b, props = __objRest(_b, [
4714
+ "name",
4715
+ "value",
4716
+ "onChange",
4717
+ "onBlur",
4718
+ "aria-describedby"
4719
+ ]);
4720
+ const form = useFormContext();
4721
+ const field = useFormField();
4722
+ const fieldValue = useFieldValueMaybe(form, name);
4723
+ const checked = value ? Array.isArray(fieldValue) && fieldValue.includes(value) : Boolean(fieldValue);
4724
+ const error = form == null ? void 0 : form.getError(name);
4725
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4726
+ const hasError = Boolean(error && touched);
4727
+ const handleChange = useCallback23(
4728
+ (e) => {
4729
+ if (value && Array.isArray(fieldValue)) {
4730
+ const newArr = e.target.checked ? [...fieldValue, value] : fieldValue.filter((v) => v !== value);
4731
+ form == null ? void 0 : form.setValue(name, newArr);
4732
+ } else if (value) {
4733
+ form == null ? void 0 : form.setValue(name, e.target.checked ? [value] : []);
4734
+ } else {
4735
+ form == null ? void 0 : form.setValue(name, e.target.checked);
4736
+ }
4737
+ onChange == null ? void 0 : onChange(e);
4738
+ },
4739
+ [form, name, value, fieldValue, onChange]
4740
+ );
4741
+ return /* @__PURE__ */ jsx23(
4742
+ "input",
4743
+ __spreadValues({
4744
+ ref,
4745
+ type: "checkbox",
4746
+ name,
4747
+ checked,
4748
+ onChange: handleChange,
4749
+ onBlur: (e) => {
4750
+ form == null ? void 0 : form.setFieldTouched(name, true);
4751
+ onBlur == null ? void 0 : onBlur(e);
4752
+ },
4753
+ "aria-invalid": hasError || void 0,
4754
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
4755
+ }, props)
4756
+ );
4757
+ }
4758
+ );
4759
+ FormCheckbox.displayName = "FormCheckbox";
4760
+ function FormRadioGroup(_a) {
4761
+ var _b = _a, { name: _name } = _b, props = __objRest(_b, ["name"]);
4762
+ return /* @__PURE__ */ jsx23("div", __spreadValues({ role: "radiogroup" }, props));
4763
+ }
4764
+ var FormRadio = forwardRef15(
4765
+ (_a, ref) => {
4766
+ var _b = _a, {
4767
+ name,
4768
+ value,
4769
+ onChange,
4770
+ onBlur,
4771
+ "aria-describedby": ariaDescribedBy
4772
+ } = _b, props = __objRest(_b, [
4773
+ "name",
4774
+ "value",
4775
+ "onChange",
4776
+ "onBlur",
4777
+ "aria-describedby"
4778
+ ]);
4779
+ const form = useFormContext();
4780
+ const field = useFormField();
4781
+ const fieldValue = useFieldValueMaybe(form, name);
4782
+ const checked = fieldValue === value;
4783
+ const error = form == null ? void 0 : form.getError(name);
4784
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4785
+ const hasError = Boolean(error && touched);
4786
+ const handleChange = useCallback23(
4787
+ (e) => {
4788
+ form == null ? void 0 : form.setValue(name, value);
4789
+ onChange == null ? void 0 : onChange(e);
4790
+ },
4791
+ [form, name, value, onChange]
4792
+ );
4793
+ return /* @__PURE__ */ jsx23(
4794
+ "input",
4795
+ __spreadValues({
4796
+ ref,
4797
+ type: "radio",
4798
+ name,
4799
+ value,
4800
+ checked,
4801
+ onChange: handleChange,
4802
+ onBlur: (e) => {
4803
+ form == null ? void 0 : form.setFieldTouched(name, true);
4804
+ onBlur == null ? void 0 : onBlur(e);
4805
+ },
4806
+ "aria-invalid": hasError || void 0,
4807
+ "aria-describedby": composeDescribedBy(field, hasError, ariaDescribedBy)
4808
+ }, props)
4809
+ );
4810
+ }
4811
+ );
4812
+ FormRadio.displayName = "FormRadio";
4813
+ function FormDescription(_a) {
4814
+ var _b = _a, {
4815
+ name: _name
4816
+ } = _b, props = __objRest(_b, [
4817
+ "name"
4818
+ ]);
4819
+ const field = useFormField();
4820
+ const setHasDescription = field == null ? void 0 : field.setHasDescription;
4821
+ useEffect15(() => {
4822
+ setHasDescription == null ? void 0 : setHasDescription(true);
4823
+ return () => setHasDescription == null ? void 0 : setHasDescription(false);
4824
+ }, [setHasDescription]);
4825
+ return /* @__PURE__ */ jsx23("p", __spreadValues({ id: field == null ? void 0 : field.descriptionId }, props));
4826
+ }
4827
+ function FormError(_a) {
4828
+ var _b = _a, { name, children } = _b, props = __objRest(_b, ["name", "children"]);
4829
+ const form = useFormContext();
4830
+ const field = useFormField();
4831
+ useStoreSubscription(form);
4832
+ const error = form == null ? void 0 : form.getError(name);
4833
+ const touched = form == null ? void 0 : form.getFieldTouched(name);
4834
+ if (!error || !touched) return null;
4835
+ return /* @__PURE__ */ jsx23("p", __spreadProps(__spreadValues({ id: field == null ? void 0 : field.errorId, role: "alert" }, props), { children: children != null ? children : error }));
4836
+ }
4837
+ var FormControl = FormInput;
4838
+ function FormSubmit(_a) {
4839
+ var _b = _a, {
4840
+ type = "submit",
4841
+ disabled
4842
+ } = _b, props = __objRest(_b, [
4843
+ "type",
4844
+ "disabled"
4845
+ ]);
4846
+ const form = useFormContext();
4847
+ useStoreSubscription(form);
4848
+ return /* @__PURE__ */ jsx23(
4849
+ "button",
4850
+ __spreadValues({
4851
+ type,
4852
+ disabled: disabled != null ? disabled : form == null ? void 0 : form.isSubmitting()
4853
+ }, props)
4854
+ );
4855
+ }
4856
+ function FormReset(_a) {
4857
+ var _b = _a, { onClick } = _b, props = __objRest(_b, ["onClick"]);
4858
+ const form = useFormContext();
4859
+ const handleClick = useCallback23(
4860
+ (e) => {
4861
+ form == null ? void 0 : form.reset();
4862
+ onClick == null ? void 0 : onClick(e);
4863
+ },
4864
+ [form, onClick]
4865
+ );
4866
+ return /* @__PURE__ */ jsx23("button", __spreadValues({ type: "button", onClick: handleClick }, props));
4867
+ }
4868
+ function FormPush(_a) {
4869
+ var _b = _a, { name, value, onClick } = _b, props = __objRest(_b, ["name", "value", "onClick"]);
4870
+ const form = useFormContext();
4871
+ const handleClick = useCallback23(
4872
+ (e) => {
4873
+ form == null ? void 0 : form.push(name, value);
4874
+ onClick == null ? void 0 : onClick(e);
4875
+ },
4876
+ [form, name, value, onClick]
4877
+ );
4878
+ return /* @__PURE__ */ jsx23("button", __spreadValues({ type: "button", onClick: handleClick }, props));
4879
+ }
4880
+ function FormRemove(_a) {
4881
+ var _b = _a, {
4882
+ name,
4883
+ index,
4884
+ onClick
4885
+ } = _b, props = __objRest(_b, [
4886
+ "name",
4887
+ "index",
4888
+ "onClick"
4889
+ ]);
4890
+ const form = useFormContext();
4891
+ const handleClick = useCallback23(
4892
+ (e) => {
4893
+ form == null ? void 0 : form.remove(name, index);
4894
+ onClick == null ? void 0 : onClick(e);
4895
+ },
4896
+ [form, name, index, onClick]
4897
+ );
4898
+ return /* @__PURE__ */ jsx23("button", __spreadValues({ type: "button", onClick: handleClick }, props));
4899
+ }
4900
+ function FormGroup(props) {
4901
+ return /* @__PURE__ */ jsx23("fieldset", __spreadValues({}, props));
4902
+ }
4903
+ function FormGroupLabel(props) {
4904
+ return /* @__PURE__ */ jsx23("legend", __spreadValues({}, props));
4905
+ }
4906
+ export {
4907
+ AccordionContent,
4908
+ AccordionItem,
4909
+ AccordionRoot,
4910
+ AccordionTrigger,
4911
+ AlertDialogPanel,
4912
+ Button,
4913
+ Checkbox,
4914
+ ComboboxGroup,
4915
+ ComboboxGroupLabel,
4916
+ ComboboxInput,
4917
+ ComboboxItem,
4918
+ ComboboxPopover,
4919
+ ComboboxRoot,
4920
+ CommandEmpty,
4921
+ CommandGroup,
4922
+ CommandInput,
4923
+ CommandItem,
4924
+ CommandList,
4925
+ CommandRoot,
4926
+ CommandSeparator,
4927
+ Composite,
4928
+ CompositeItem,
4929
+ CompositeProvider,
4930
+ CompositeRow,
4931
+ DialogDescription,
4932
+ DialogDisclosure,
4933
+ DialogDismiss,
4934
+ DialogHeading,
4935
+ DialogPanel,
4936
+ DialogRoot,
4937
+ DisclosureContent,
4938
+ DisclosureRoot,
4939
+ DisclosureTrigger,
4940
+ FormCheckbox,
4941
+ FormControl,
4942
+ FormDescription,
4943
+ FormError,
4944
+ FormField,
4945
+ FormGroup,
4946
+ FormGroupLabel,
4947
+ FormInput,
4948
+ FormLabel,
4949
+ FormProvider,
4950
+ FormPush,
4951
+ FormRadio,
4952
+ FormRadioGroup,
4953
+ FormRemove,
4954
+ FormReset,
4955
+ FormRoot,
4956
+ FormSelect,
4957
+ FormSubmit,
4958
+ FormSwitch,
4959
+ FormTextarea,
4960
+ MenuButtonArrow,
4961
+ MenuItem,
4962
+ MenuItemCheckbox,
4963
+ MenuItemRadio,
4964
+ MenuPopover,
4965
+ MenuRoot,
4966
+ MenuSeparator,
4967
+ MenuTrigger,
4968
+ MenubarContainer,
4969
+ MenubarRoot,
4970
+ Meter,
4971
+ PopoverClose,
4972
+ PopoverContent,
4973
+ PopoverRoot,
4974
+ PopoverTrigger,
4975
+ Progress,
4976
+ Radio,
4977
+ RadioGroupRoot,
4978
+ SelectItem,
4979
+ SelectLabel,
4980
+ SelectPopover,
4981
+ SelectRoot,
4982
+ SelectTrigger,
4983
+ Separator,
4984
+ Switch,
4985
+ Tab,
4986
+ TabList,
4987
+ TabPanel,
4988
+ TabsRoot,
4989
+ Toggle,
4990
+ ToggleGroup,
4991
+ ToolbarButton,
4992
+ ToolbarContainer,
4993
+ ToolbarRoot,
4994
+ ToolbarSeparator,
4995
+ Tooltip,
4996
+ TooltipAnchor,
4997
+ TooltipProvider,
4998
+ useCommandState,
4999
+ useControllableState,
5000
+ useDialogClose,
5001
+ useEnterLeave,
5002
+ useFieldValue,
5003
+ useFloating,
5004
+ useFocusVisible,
5005
+ useFocusableWhenDisabled,
5006
+ useFormContext,
5007
+ useFormStore,
5008
+ useId,
5009
+ useMenubarContext,
5010
+ useRadioGroupContext,
5011
+ useRovingTabindex,
5012
+ useScrollActiveDescendantIntoView
5013
+ };