@edux-design/forms 0.0.5 → 0.0.7

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 CHANGED
@@ -29,11 +29,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
29
29
  // src/index.js
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
+ Checkbox: () => Checkbox,
33
+ Combobox: () => ComboboxRoot,
34
+ ComboboxOption: () => Option,
32
35
  Feedback: () => Feedback,
33
36
  Field: () => Field,
34
37
  Input: () => Input,
35
38
  Label: () => Label,
39
+ Option: () => Option,
36
40
  Radio: () => Radio,
41
+ Switch: () => Switch,
37
42
  Textarea: () => Textarea
38
43
  });
39
44
  module.exports = __toCommonJS(index_exports);
@@ -58,6 +63,13 @@ var FieldProvider = ({ children }) => {
58
63
  if (!id) return;
59
64
  setDescribedByIds((prev) => prev.filter((x) => x !== id));
60
65
  }, []);
66
+ const getPartId = (0, import_react.useCallback)(
67
+ (part) => {
68
+ if (!part) return baseId;
69
+ return `${baseId}-${part}`;
70
+ },
71
+ [baseId]
72
+ );
61
73
  const value = (0, import_react.useMemo)(
62
74
  () => ({
63
75
  labelHTMLForId: baseId,
@@ -65,9 +77,17 @@ var FieldProvider = ({ children }) => {
65
77
  setType,
66
78
  describedByIds,
67
79
  registerDescription,
68
- unregisterDescription
80
+ unregisterDescription,
81
+ getPartId
69
82
  }),
70
- [baseId, type, describedByIds, registerDescription, unregisterDescription]
83
+ [
84
+ baseId,
85
+ type,
86
+ describedByIds,
87
+ registerDescription,
88
+ unregisterDescription,
89
+ getPartId
90
+ ]
71
91
  );
72
92
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(FieldContext.Provider, { value, children });
73
93
  };
@@ -208,9 +228,16 @@ var import_react5 = __toESM(require("react"));
208
228
  var import_utils2 = require("@edux-design/utils");
209
229
  var import_icons2 = require("@edux-design/icons");
210
230
  var import_jsx_runtime4 = require("react/jsx-runtime");
211
- var Field = ({ children }) => {
231
+ var Field = ({
232
+ children,
233
+ orientation = "vertical",
234
+ className
235
+ }) => {
236
+ const orientationClasses = orientation === "horizontal" ? "flex-row items-center gap-6" : "flex-col items-start gap-8";
212
237
  const FIELD_GROUP_WRAPPER_STYLES = (0, import_utils2.cx)(
213
- "flex flex-col items-start relative gap-8"
238
+ "flex relative",
239
+ orientationClasses,
240
+ className
214
241
  );
215
242
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(FieldProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: FIELD_GROUP_WRAPPER_STYLES, children }) });
216
243
  };
@@ -285,12 +312,376 @@ function Radio() {
285
312
  ] });
286
313
  }
287
314
 
288
- // src/elements/Textarea.jsx
315
+ // src/elements/Checkbox.jsx
289
316
  var import_react7 = __toESM(require("react"));
290
317
  var import_utils4 = require("@edux-design/utils");
291
318
  var import_icons3 = require("@edux-design/icons");
292
319
  var import_jsx_runtime6 = require("react/jsx-runtime");
293
- var Textarea = (0, import_react7.forwardRef)(
320
+ var VARIANT_INTENTS = {
321
+ primary: {
322
+ baseBorder: "border-border-base",
323
+ baseBg: "bg-bg-base",
324
+ hoverBorder: "peer-hover:border-border-primary-base",
325
+ activeBorder: "peer-active:border-border-primary-emphasis",
326
+ activeBg: "peer-active:bg-bg-primary-subtle",
327
+ peerSelectedBorder: "peer-checked:border-border-primary-base",
328
+ peerSelectedBg: "peer-checked:bg-bg-primary-base",
329
+ selectedBorder: "border-border-primary-base",
330
+ selectedBg: "bg-bg-primary-base",
331
+ iconColor: "text-white"
332
+ },
333
+ success: {
334
+ baseBorder: "border-border-success-base",
335
+ baseBg: "bg-bg-base",
336
+ hoverBorder: "peer-hover:border-border-success-emphasis",
337
+ activeBorder: "peer-active:border-border-success-emphasis",
338
+ activeBg: "peer-active:bg-bg-success-subtle",
339
+ peerSelectedBorder: "peer-checked:border-border-success-base",
340
+ peerSelectedBg: "peer-checked:bg-bg-success-base",
341
+ selectedBorder: "border-border-success-base",
342
+ selectedBg: "bg-bg-success-base",
343
+ iconColor: "text-white"
344
+ },
345
+ corrective: {
346
+ baseBorder: "border-border-corrective-base",
347
+ baseBg: "bg-bg-base",
348
+ hoverBorder: "peer-hover:border-border-corrective-emphasis",
349
+ activeBorder: "peer-active:border-border-corrective-emphasis",
350
+ activeBg: "peer-active:bg-bg-corrective-subtle",
351
+ peerSelectedBorder: "peer-checked:border-border-corrective-base",
352
+ peerSelectedBg: "peer-checked:bg-bg-corrective-base",
353
+ selectedBorder: "border-border-corrective-base",
354
+ selectedBg: "bg-bg-corrective-base",
355
+ iconColor: "text-fg-base"
356
+ },
357
+ error: {
358
+ baseBorder: "border-border-danger-base",
359
+ baseBg: "bg-bg-base",
360
+ hoverBorder: "peer-hover:border-border-danger-emphasis",
361
+ activeBorder: "peer-active:border-border-danger-emphasis",
362
+ activeBg: "peer-active:bg-bg-danger-subtle",
363
+ peerSelectedBorder: "peer-checked:border-border-danger-base",
364
+ peerSelectedBg: "peer-checked:bg-bg-danger-base",
365
+ selectedBorder: "border-border-danger-base",
366
+ selectedBg: "bg-bg-danger-base",
367
+ iconColor: "text-white"
368
+ },
369
+ inactive: {
370
+ baseBorder: "border-border-subtle",
371
+ baseBg: "bg-bg-inactive",
372
+ hoverBorder: null,
373
+ activeBorder: null,
374
+ activeBg: null,
375
+ peerSelectedBorder: null,
376
+ peerSelectedBg: null,
377
+ selectedBorder: "border-border-subtle",
378
+ selectedBg: "bg-bg-inactive",
379
+ iconColor: "text-fg-inactive"
380
+ }
381
+ };
382
+ var Checkbox = (0, import_react7.forwardRef)(
383
+ ({
384
+ className,
385
+ indeterminate = false,
386
+ variant = "primary",
387
+ disabled,
388
+ id: providedId,
389
+ ...rest
390
+ }, ref) => {
391
+ const {
392
+ ["aria-describedby"]: ariaDescribedByProp,
393
+ ["aria-checked"]: ariaCheckedProp,
394
+ ...inputProps
395
+ } = rest;
396
+ const {
397
+ labelHTMLForId,
398
+ describedByIds = []
399
+ } = useFieldContext();
400
+ const resolvedId = providedId ?? labelHTMLForId;
401
+ const intent = VARIANT_INTENTS[variant] ?? VARIANT_INTENTS.primary;
402
+ const derivedDisabled = Boolean(disabled);
403
+ const isInactiveVariant = variant === "inactive";
404
+ const isDisabled = derivedDisabled || isInactiveVariant;
405
+ const describedByTokens = [
406
+ ...describedByIds,
407
+ ...ariaDescribedByProp ? ariaDescribedByProp.split(" ") : []
408
+ ].filter(Boolean);
409
+ const describedBy = describedByTokens.length ? describedByTokens.join(" ") : void 0;
410
+ const ariaChecked = indeterminate ? "mixed" : ariaCheckedProp;
411
+ const inputRef = (0, import_react7.useRef)(null);
412
+ const setRefs = (0, import_react7.useCallback)(
413
+ (node) => {
414
+ inputRef.current = node;
415
+ if (typeof ref === "function") {
416
+ ref(node);
417
+ } else if (ref) {
418
+ ref.current = node;
419
+ }
420
+ },
421
+ [ref]
422
+ );
423
+ (0, import_react7.useEffect)(() => {
424
+ if (inputRef.current) {
425
+ inputRef.current.indeterminate = indeterminate;
426
+ }
427
+ }, [indeterminate]);
428
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
429
+ "div",
430
+ {
431
+ className: (0, import_utils4.cx)(
432
+ "relative inline-flex h-[28px] w-[28px] items-center justify-center",
433
+ className
434
+ ),
435
+ children: [
436
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
437
+ "input",
438
+ {
439
+ id: resolvedId,
440
+ ref: setRefs,
441
+ type: "checkbox",
442
+ className: (0, import_utils4.cx)(
443
+ "peer absolute inset-0 h-full w-full cursor-pointer appearance-none rounded-md bg-transparent",
444
+ "focus:shadow-focus focus-visible:shadow-focus focus:outline-none focus-visible:outline-none",
445
+ isDisabled && "cursor-not-allowed"
446
+ ),
447
+ "aria-checked": ariaChecked,
448
+ "aria-describedby": describedBy,
449
+ "aria-disabled": isDisabled ? "true" : void 0,
450
+ "aria-invalid": variant === "error" ? "true" : void 0,
451
+ disabled: isDisabled,
452
+ ...inputProps
453
+ }
454
+ ),
455
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
456
+ "span",
457
+ {
458
+ "data-slot": "checkbox-control",
459
+ "aria-hidden": "true",
460
+ className: (0, import_utils4.cx)(
461
+ "flex h-full w-full items-center justify-center rounded-md border-2 transition-all duration-200 ease-in-out",
462
+ "peer-focus-visible:shadow-focus",
463
+ "peer-disabled:border-border-subtle peer-disabled:bg-bg-inactive peer-disabled:text-fg-inactive",
464
+ intent.baseBg,
465
+ intent.baseBorder,
466
+ !isDisabled && intent.hoverBorder,
467
+ !isDisabled && intent.activeBorder,
468
+ !isDisabled && intent.activeBg,
469
+ intent.peerSelectedBorder,
470
+ intent.peerSelectedBg,
471
+ indeterminate && intent.selectedBorder,
472
+ indeterminate && intent.selectedBg
473
+ )
474
+ }
475
+ ),
476
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
477
+ import_icons3.Check,
478
+ {
479
+ "aria-hidden": "true",
480
+ className: (0, import_utils4.cx)(
481
+ "pointer-events-none absolute left-1/2 top-1/2 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 transition-opacity duration-150",
482
+ intent.iconColor,
483
+ "peer-disabled:text-fg-inactive",
484
+ indeterminate ? "opacity-0" : "opacity-0 peer-checked:opacity-100"
485
+ )
486
+ }
487
+ ),
488
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
489
+ import_icons3.Indeterminate,
490
+ {
491
+ "aria-hidden": "true",
492
+ className: (0, import_utils4.cx)(
493
+ "pointer-events-none absolute left-1/2 top-1/2 h-3.5 w-3.5 -translate-x-1/2 -translate-y-1/2 transition-opacity duration-150",
494
+ intent.iconColor,
495
+ "peer-disabled:text-fg-inactive",
496
+ indeterminate ? "opacity-100" : "opacity-0"
497
+ )
498
+ }
499
+ )
500
+ ]
501
+ }
502
+ );
503
+ }
504
+ );
505
+ Checkbox.displayName = "Checkbox";
506
+
507
+ // src/elements/Switch.jsx
508
+ var import_react8 = __toESM(require("react"));
509
+ var import_utils5 = require("@edux-design/utils");
510
+ var import_icons4 = require("@edux-design/icons");
511
+ var import_jsx_runtime7 = require("react/jsx-runtime");
512
+ var SWITCH_INTENTS = {
513
+ primary: {
514
+ trackBase: "bg-bg-subtle border-2 border-border-base",
515
+ trackChecked: "peer-checked:bg-bg-primary-subtle peer-checked:border-border-primary-base",
516
+ trackHover: "peer-hover:border-border-primary-base",
517
+ trackActive: "peer-active:border-border-primary-emphasis peer-active:bg-bg-primary-subtle",
518
+ thumbBase: "bg-fg-inactive border-border-base text-bg-emphasis",
519
+ thumbChecked: "peer-checked:bg-bg-primary-base peer-checked:border-border-primary-base peer-checked:text-white",
520
+ thumbHover: "peer-hover:border-border-primary-base",
521
+ thumbActive: "peer-active:border-border-primary-emphasis",
522
+ offIcon: "text-white",
523
+ onIcon: "text-white"
524
+ },
525
+ success: {
526
+ trackBase: "bg-bg-subtle border-2 border-border-success-base",
527
+ trackChecked: "peer-checked:bg-bg-success-subtle peer-checked:border-border-success-base",
528
+ trackHover: "peer-hover:border-border-success-emphasis",
529
+ trackActive: "peer-active:border-border-success-emphasis peer-active:bg-bg-success-subtle",
530
+ thumbBase: "bg-bg-success-subtle border-border-success-base text-fg-success-base",
531
+ thumbChecked: "peer-checked:bg-bg-success-base peer-checked:border-border-success-base peer-checked:text-white",
532
+ thumbHover: "peer-hover:border-border-success-emphasis",
533
+ thumbActive: "peer-active:border-border-success-emphasis",
534
+ offIcon: "text-fg-success-base",
535
+ onIcon: "text-white"
536
+ },
537
+ corrective: {
538
+ trackBase: "bg-bg-corrective-subtle border-2 border-border-corrective-base",
539
+ trackChecked: "peer-checked:bg-bg-corrective-subtle peer-checked:border-border-corrective-base",
540
+ trackHover: "peer-hover:border-border-corrective-emphasis",
541
+ trackActive: "peer-active:border-border-corrective-emphasis peer-active:bg-bg-corrective-subtle",
542
+ thumbBase: "bg-bg-corrective-base border-border-corrective-base text-fg-base",
543
+ thumbChecked: "peer-checked:bg-bg-corrective-base peer-checked:border-border-corrective-base peer-checked:text-fg-base",
544
+ thumbHover: "peer-hover:border-border-corrective-emphasis",
545
+ thumbActive: "peer-active:border-border-corrective-emphasis",
546
+ offIcon: "text-white",
547
+ onIcon: "text-white"
548
+ },
549
+ error: {
550
+ trackBase: "bg-bg-danger-subtle border-2 border-border-danger-base",
551
+ trackChecked: "peer-checked:bg-bg-danger-subtle peer-checked:border-border-danger-base",
552
+ trackHover: "peer-hover:border-border-danger-emphasis",
553
+ trackActive: "peer-active:border-border-danger-emphasis peer-active:bg-bg-danger-subtle",
554
+ thumbBase: "bg-white border-border-danger-base text-fg-danger-base",
555
+ thumbChecked: "peer-checked:bg-bg-danger-base peer-checked:border-border-danger-base peer-checked:text-white",
556
+ thumbHover: "peer-hover:border-border-danger-emphasis",
557
+ thumbActive: "peer-active:border-border-danger-emphasis",
558
+ offIcon: "text-fg-danger-base",
559
+ onIcon: "text-white"
560
+ },
561
+ inactive: {
562
+ trackBase: "bg-bg-inactive border-2 border-border-subtle",
563
+ trackChecked: "peer-checked:bg-bg-inactive peer-checked:border-border-subtle",
564
+ trackHover: null,
565
+ trackActive: null,
566
+ thumbBase: "bg-bg-inactive border-border-subtle text-fg-inactive",
567
+ thumbChecked: "peer-checked:bg-bg-inactive peer-checked:border-border-subtle peer-checked:text-fg-inactive",
568
+ thumbHover: null,
569
+ thumbActive: null,
570
+ offIcon: "text-fg-inactive",
571
+ onIcon: "text-fg-inactive"
572
+ }
573
+ };
574
+ var Switch = (0, import_react8.forwardRef)(
575
+ ({
576
+ className,
577
+ variant = "primary",
578
+ disabled,
579
+ id: providedId,
580
+ checked,
581
+ onChange,
582
+ ...rest
583
+ }, ref) => {
584
+ const { ["aria-describedby"]: ariaDescribedByProp, ...inputProps } = rest;
585
+ const { labelHTMLForId, describedByIds = [] } = useFieldContext();
586
+ const resolvedId = providedId ?? labelHTMLForId;
587
+ const describedByTokens = [
588
+ ...describedByIds,
589
+ ...ariaDescribedByProp ? ariaDescribedByProp.split(" ") : []
590
+ ].filter(Boolean);
591
+ const ariaDescribedBy = describedByTokens.length > 0 ? describedByTokens.join(" ") : void 0;
592
+ const intent = SWITCH_INTENTS[variant] ?? SWITCH_INTENTS.primary;
593
+ const derivedDisabled = Boolean(disabled);
594
+ const isInactiveVariant = variant === "inactive";
595
+ const isDisabled = derivedDisabled || isInactiveVariant;
596
+ const [unControlledChecked, setUnControlledChecked] = (0, import_react8.useState)(false);
597
+ const isOn = checked ?? unControlledChecked;
598
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
599
+ "div",
600
+ {
601
+ className: (0, import_utils5.cx)(
602
+ "relative flex h-[28px] w-[46px] items-center justify-center",
603
+ className
604
+ ),
605
+ children: [
606
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
607
+ "input",
608
+ {
609
+ id: resolvedId,
610
+ ref,
611
+ onChange: onChange ? onChange : () => setUnControlledChecked(!unControlledChecked),
612
+ checked: checked ? checked : unControlledChecked,
613
+ type: "checkbox",
614
+ role: "switch",
615
+ className: (0, import_utils5.cx)(
616
+ "peer absolute inset-0 z-10 h-full w-full cursor-pointer appearance-none rounded-full opacity-0",
617
+ "focus:shadow-focus focus-visible:shadow-focus focus:outline-none focus-visible:outline-none",
618
+ isDisabled && "cursor-not-allowed"
619
+ ),
620
+ "aria-describedby": ariaDescribedBy,
621
+ "aria-invalid": variant === "error" ? "true" : void 0,
622
+ "aria-disabled": isDisabled ? "true" : void 0,
623
+ disabled: isDisabled,
624
+ ...inputProps
625
+ }
626
+ ),
627
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
628
+ "span",
629
+ {
630
+ "aria-hidden": "true",
631
+ "data-slot": "switch-track",
632
+ className: (0, import_utils5.cx)(
633
+ "pointer-events-none absolute inset-0 rounded-full border-1 transition-all duration-200 ease-out",
634
+ "peer-focus-visible:shadow-focus",
635
+ "peer-disabled:border-border-subtle peer-disabled:bg-bg-inactive",
636
+ intent.trackBase,
637
+ intent.trackChecked,
638
+ !isDisabled && intent.trackHover,
639
+ !isDisabled && intent.trackActive
640
+ )
641
+ }
642
+ ),
643
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
644
+ "span",
645
+ {
646
+ "data-slot": "switch-thumb",
647
+ "aria-hidden": "true",
648
+ className: (0, import_utils5.cx)(
649
+ "pointer-events-none absolute left-[5px] top-[5px] flex h-[18px] w-[18px] items-center justify-center rounded-full transition-all duration-200 ease-out transform-gpu",
650
+ "peer-disabled:border-border-subtle peer-disabled:bg-bg-inactive",
651
+ intent.thumbBase,
652
+ intent.thumbChecked,
653
+ !isDisabled && intent.thumbHover,
654
+ !isDisabled && intent.thumbActive,
655
+ "peer-checked:translate-x-[19px]"
656
+ ),
657
+ children: !isOn ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
658
+ import_icons4.Close,
659
+ {
660
+ "aria-hidden": "true",
661
+ className: (0, import_utils5.cx)("absolute duration-150", intent.offIcon)
662
+ }
663
+ ) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
664
+ import_icons4.Check,
665
+ {
666
+ "aria-hidden": "true",
667
+ className: (0, import_utils5.cx)("absolute duration-150", intent.onIcon)
668
+ }
669
+ )
670
+ }
671
+ )
672
+ ]
673
+ }
674
+ );
675
+ }
676
+ );
677
+ Switch.displayName = "Switch";
678
+
679
+ // src/elements/Textarea.jsx
680
+ var import_react9 = __toESM(require("react"));
681
+ var import_utils6 = require("@edux-design/utils");
682
+ var import_icons5 = require("@edux-design/icons");
683
+ var import_jsx_runtime8 = require("react/jsx-runtime");
684
+ var Textarea = (0, import_react9.forwardRef)(
294
685
  ({
295
686
  children,
296
687
  validation,
@@ -312,7 +703,7 @@ var Textarea = (0, import_react7.forwardRef)(
312
703
  success: "border-border-success-base",
313
704
  inactive: "border-border-subtle bg-bg-subtle"
314
705
  };
315
- const TEXTAREA_STYLES = (0, import_utils4.cx)(
706
+ const TEXTAREA_STYLES = (0, import_utils6.cx)(
316
707
  defaults,
317
708
  fonts,
318
709
  variants[variant],
@@ -320,8 +711,8 @@ var Textarea = (0, import_react7.forwardRef)(
320
711
  clearable && endIcon && "pr-10",
321
712
  clearable && !endIcon && "pr-5"
322
713
  );
323
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { className: "w-full relative flex items-start", children: [
324
- startIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
714
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)("div", { className: "w-full relative flex items-start", children: [
715
+ startIcon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
325
716
  "span",
326
717
  {
327
718
  className: "absolute left-3 top-3 flex items-center pointer-events-none text-fg-subtle",
@@ -329,7 +720,7 @@ var Textarea = (0, import_react7.forwardRef)(
329
720
  children: startIcon
330
721
  }
331
722
  ),
332
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
723
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
333
724
  "textarea",
334
725
  {
335
726
  id: labelHTMLForId,
@@ -342,7 +733,7 @@ var Textarea = (0, import_react7.forwardRef)(
342
733
  ...props
343
734
  }
344
735
  ),
345
- clearable && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
736
+ clearable && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
346
737
  "button",
347
738
  {
348
739
  type: "button",
@@ -351,20 +742,20 @@ var Textarea = (0, import_react7.forwardRef)(
351
742
  var _a;
352
743
  return (_a = props.onChange) == null ? void 0 : _a.call(props, { target: { value: "" } });
353
744
  },
354
- className: (0, import_utils4.cx)(
745
+ className: (0, import_utils6.cx)(
355
746
  clearable && hasValue && endIcon ? "right-9" : "right-3",
356
747
  "absolute top-3 flex items-center p-1 rounded-full outline-none",
357
748
  "transition-all duration-300 ease-in-out",
358
749
  hasValue ? "opacity-100 scale-100" : "opacity-0 scale-90 pointer-events-none",
359
750
  "focus:shadow-focus"
360
751
  ),
361
- children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_icons3.Close, { "aria-hidden": "true", className: "text-fg-subtle" })
752
+ children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons5.Close, { "aria-hidden": "true", className: "text-fg-subtle" })
362
753
  }
363
754
  ),
364
- endIcon && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
755
+ endIcon && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
365
756
  "span",
366
757
  {
367
- className: (0, import_utils4.cx)(
758
+ className: (0, import_utils6.cx)(
368
759
  "absolute flex items-center right-3 top-3 text-fg-subtle"
369
760
  ),
370
761
  "aria-hidden": typeof endIcon === "string" ? void 0 : "true",
@@ -374,12 +765,551 @@ var Textarea = (0, import_react7.forwardRef)(
374
765
  ] });
375
766
  }
376
767
  );
768
+
769
+ // src/elements/Combobox.jsx
770
+ var import_react10 = __toESM(require("react"));
771
+ var import_utils7 = require("@edux-design/utils");
772
+ var import_popovers = require("@edux-design/popovers");
773
+ var import_chips = require("@edux-design/chips");
774
+ var import_icons6 = require("@edux-design/icons");
775
+ var import_jsx_runtime9 = require("react/jsx-runtime");
776
+ var OPTION_COMPONENT_NAME = "ComboboxOption";
777
+ var MENU_ITEM_STYLES = (0, import_utils7.cx)(
778
+ "flex items-center px-32 py-8 cursor-pointer min-w-[100px]",
779
+ "transition-colors duration-200 ease-in-out w-full text-sm",
780
+ "focus:bg-bg-focus focus:outline-none hover:underline hover:bg-bg-primary-subtle"
781
+ );
782
+ var getOptionLabel = (child) => {
783
+ if (!(child == null ? void 0 : child.props)) return "";
784
+ if (typeof child.props.label === "string") {
785
+ return child.props.label;
786
+ }
787
+ if (typeof child.props.children === "string") {
788
+ return child.props.children;
789
+ }
790
+ if (typeof child.props.value === "string") {
791
+ return child.props.value;
792
+ }
793
+ return "";
794
+ };
795
+ var defaultFilter = (option, query) => {
796
+ var _a;
797
+ const normalisedLabel = ((_a = option.label) == null ? void 0 : _a.toString().toLowerCase()) ?? "";
798
+ return normalisedLabel.includes(query.trim().toLowerCase());
799
+ };
800
+ var ComboboxRoot = (0, import_react10.forwardRef)(
801
+ ({
802
+ children,
803
+ value,
804
+ defaultValue = null,
805
+ onValueChange,
806
+ placeholder = "Select an option",
807
+ disabled = false,
808
+ autoComplete = false,
809
+ multiSelect = false,
810
+ emptyState = "No options found",
811
+ filterFunction = defaultFilter,
812
+ selectOnly = false,
813
+ wrapperClassName,
814
+ contentClassName,
815
+ listClassName,
816
+ optionClassName,
817
+ ...inputProps
818
+ }, ref) => {
819
+ const {
820
+ labelHTMLForId,
821
+ describedByIds = [],
822
+ getPartId
823
+ } = useFieldContext();
824
+ const optionElements = (0, import_react10.useMemo)(
825
+ () => import_react10.default.Children.toArray(children).filter(
826
+ (child) => {
827
+ var _a;
828
+ return import_react10.default.isValidElement(child) && ((_a = child.type) == null ? void 0 : _a.displayName) === OPTION_COMPONENT_NAME;
829
+ }
830
+ ),
831
+ [children]
832
+ );
833
+ const normalisedOptions = (0, import_react10.useMemo)(
834
+ () => optionElements.map((child) => {
835
+ if (child.props.value === void 0 || child.props.value === null) {
836
+ return null;
837
+ }
838
+ return {
839
+ value: child.props.value,
840
+ label: getOptionLabel(child),
841
+ disabled: Boolean(child.props.disabled),
842
+ element: child
843
+ };
844
+ }).filter(Boolean),
845
+ [optionElements]
846
+ );
847
+ const isMultiSelectEnabled = Boolean(multiSelect);
848
+ const isControlled = value !== void 0;
849
+ const [internalValue, setInternalValue] = (0, import_react10.useState)(() => {
850
+ if (isMultiSelectEnabled) {
851
+ if (Array.isArray(defaultValue)) return defaultValue;
852
+ if (defaultValue === null || defaultValue === void 0) {
853
+ return [];
854
+ }
855
+ return [defaultValue];
856
+ }
857
+ return defaultValue ?? null;
858
+ });
859
+ const resolvedValue = isControlled ? value : internalValue;
860
+ const singleSelectedValue = !isMultiSelectEnabled ? resolvedValue ?? null : null;
861
+ const multiSelectedValues = isMultiSelectEnabled ? Array.isArray(resolvedValue) ? resolvedValue : resolvedValue === null || resolvedValue === void 0 ? [] : [resolvedValue] : [];
862
+ const selectedOption = (0, import_react10.useMemo)(() => {
863
+ if (isMultiSelectEnabled) return null;
864
+ return normalisedOptions.find(
865
+ (option) => option.value === singleSelectedValue
866
+ ) ?? null;
867
+ }, [isMultiSelectEnabled, normalisedOptions, singleSelectedValue]);
868
+ const multiSelectedOptions = (0, import_react10.useMemo)(() => {
869
+ if (!isMultiSelectEnabled) return [];
870
+ return normalisedOptions.filter(
871
+ (option) => multiSelectedValues.includes(option.value)
872
+ );
873
+ }, [isMultiSelectEnabled, normalisedOptions, multiSelectedValues]);
874
+ const selectionSummary = isMultiSelectEnabled ? multiSelectedOptions.map((option) => option.label).join(", ") : (selectedOption == null ? void 0 : selectedOption.label) ?? "";
875
+ const shouldFilter = !selectOnly && (autoComplete || isMultiSelectEnabled);
876
+ const [open, setOpen] = (0, import_react10.useState)(false);
877
+ const [inputValue, setInputValue] = (0, import_react10.useState)(
878
+ () => isMultiSelectEnabled && shouldFilter ? "" : selectionSummary
879
+ );
880
+ const [isUserTyping, setIsUserTyping] = (0, import_react10.useState)(false);
881
+ const [activeIndex, setActiveIndex] = (0, import_react10.useState)(-1);
882
+ const fallbackListboxId = (0, import_react10.useId)();
883
+ const listboxId = getPartId ? getPartId("listbox") : fallbackListboxId;
884
+ const anchorRef = (0, import_react10.useRef)(null);
885
+ const inputRef = (0, import_react10.useRef)(null);
886
+ const mergedRef = (0, import_react10.useCallback)(
887
+ (node) => {
888
+ inputRef.current = node;
889
+ if (typeof ref === "function") {
890
+ ref(node);
891
+ } else if (ref) {
892
+ ref.current = node;
893
+ }
894
+ },
895
+ [ref]
896
+ );
897
+ (0, import_react10.useEffect)(() => {
898
+ if (!isMultiSelectEnabled && !open) {
899
+ setInputValue((selectedOption == null ? void 0 : selectedOption.label) ?? "");
900
+ }
901
+ }, [isMultiSelectEnabled, open, selectedOption]);
902
+ const filteredOptions = (0, import_react10.useMemo)(() => {
903
+ const query = inputValue.trim();
904
+ if (!shouldFilter || !query) {
905
+ return normalisedOptions;
906
+ }
907
+ return normalisedOptions.filter(
908
+ (option) => filterFunction(option, query)
909
+ );
910
+ }, [normalisedOptions, filterFunction, inputValue, shouldFilter]);
911
+ (0, import_react10.useEffect)(() => {
912
+ if (!open) {
913
+ setActiveIndex(-1);
914
+ return;
915
+ }
916
+ if (!filteredOptions.length) {
917
+ setActiveIndex(-1);
918
+ return;
919
+ }
920
+ if (!isMultiSelectEnabled) {
921
+ const selectedIndex = filteredOptions.findIndex(
922
+ (option) => option.value === singleSelectedValue
923
+ );
924
+ setActiveIndex(selectedIndex >= 0 ? selectedIndex : 0);
925
+ return;
926
+ }
927
+ setActiveIndex((prev) => prev >= 0 ? prev : 0);
928
+ }, [open, filteredOptions, singleSelectedValue, isMultiSelectEnabled]);
929
+ const [contentWidth, setContentWidth] = (0, import_react10.useState)(0);
930
+ (0, import_react10.useLayoutEffect)(() => {
931
+ if (anchorRef.current) {
932
+ setContentWidth(anchorRef.current.offsetWidth);
933
+ }
934
+ }, [open]);
935
+ const emitChange = (0, import_react10.useCallback)(
936
+ (nextValue, option) => {
937
+ if (!isControlled) {
938
+ setInternalValue(nextValue);
939
+ }
940
+ onValueChange == null ? void 0 : onValueChange(nextValue, option);
941
+ },
942
+ [isControlled, onValueChange]
943
+ );
944
+ const selectOption = (0, import_react10.useCallback)(
945
+ (option) => {
946
+ if (!option || option.disabled) return;
947
+ if (isMultiSelectEnabled) {
948
+ const exists = multiSelectedValues.includes(option.value);
949
+ const nextValues = exists ? multiSelectedValues.filter((value2) => value2 !== option.value) : [...multiSelectedValues, option.value];
950
+ emitChange(nextValues, option);
951
+ if (shouldFilter) {
952
+ setInputValue("");
953
+ setIsUserTyping(false);
954
+ }
955
+ return;
956
+ }
957
+ emitChange(option.value, option);
958
+ setInputValue(option.label);
959
+ setOpen(false);
960
+ },
961
+ [emitChange, isMultiSelectEnabled, multiSelectedValues, shouldFilter]
962
+ );
963
+ const {
964
+ onFocus: userOnFocus,
965
+ onBlur: userOnBlur,
966
+ onKeyDown: userOnKeyDown,
967
+ onChange: userOnInputChange,
968
+ onMouseDown: userOnMouseDown,
969
+ ...restInputProps
970
+ } = inputProps;
971
+ const handleInputChange = (event) => {
972
+ if (disabled) return;
973
+ if (selectOnly) {
974
+ setOpen(true);
975
+ userOnInputChange == null ? void 0 : userOnInputChange(event);
976
+ return;
977
+ }
978
+ if (isMultiSelectEnabled && shouldFilter) {
979
+ setIsUserTyping(true);
980
+ }
981
+ setOpen(true);
982
+ setInputValue(event.target.value);
983
+ userOnInputChange == null ? void 0 : userOnInputChange(event);
984
+ };
985
+ const handleFocus = (event) => {
986
+ if (disabled) return;
987
+ setOpen(true);
988
+ if (isMultiSelectEnabled && autoComplete && !selectOnly) {
989
+ setIsUserTyping(true);
990
+ }
991
+ userOnFocus == null ? void 0 : userOnFocus(event);
992
+ };
993
+ const handleBlur = (event) => {
994
+ setIsUserTyping(false);
995
+ if (isMultiSelectEnabled) {
996
+ setInputValue("");
997
+ }
998
+ userOnBlur == null ? void 0 : userOnBlur(event);
999
+ };
1000
+ const handleKeyDown = (event) => {
1001
+ if (disabled) {
1002
+ userOnKeyDown == null ? void 0 : userOnKeyDown(event);
1003
+ return;
1004
+ }
1005
+ if (event.key === "ArrowDown") {
1006
+ event.preventDefault();
1007
+ setOpen(true);
1008
+ setActiveIndex((prev) => {
1009
+ if (!filteredOptions.length) return -1;
1010
+ const next = prev + 1;
1011
+ return next >= filteredOptions.length ? filteredOptions.length - 1 : next;
1012
+ });
1013
+ } else if (event.key === "ArrowUp") {
1014
+ event.preventDefault();
1015
+ setOpen(true);
1016
+ setActiveIndex((prev) => {
1017
+ if (!filteredOptions.length) return -1;
1018
+ const next = prev <= 0 ? 0 : prev - 1;
1019
+ return next;
1020
+ });
1021
+ } else if (event.key === "Enter") {
1022
+ if (open && activeIndex >= 0 && filteredOptions[activeIndex]) {
1023
+ event.preventDefault();
1024
+ selectOption(filteredOptions[activeIndex]);
1025
+ }
1026
+ } else if (event.key === "Escape") {
1027
+ event.preventDefault();
1028
+ setOpen(false);
1029
+ } else if (event.key === "Tab") {
1030
+ setOpen(false);
1031
+ }
1032
+ userOnKeyDown == null ? void 0 : userOnKeyDown(event);
1033
+ };
1034
+ const handleInputMouseDown = (event) => {
1035
+ if (disabled) {
1036
+ userOnMouseDown == null ? void 0 : userOnMouseDown(event);
1037
+ return;
1038
+ }
1039
+ setOpen(true);
1040
+ userOnMouseDown == null ? void 0 : userOnMouseDown(event);
1041
+ };
1042
+ const handleChevronMouseDown = (event) => {
1043
+ var _a;
1044
+ event.preventDefault();
1045
+ if (disabled) return;
1046
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
1047
+ setOpen((prev) => !prev);
1048
+ };
1049
+ const handleSingleAnchorMouseDown = (event) => {
1050
+ var _a;
1051
+ if (disabled || isMultiSelectEnabled) return;
1052
+ if (!open) {
1053
+ setOpen(true);
1054
+ }
1055
+ if (selectOnly) {
1056
+ event.preventDefault();
1057
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
1058
+ }
1059
+ };
1060
+ const handleOpenChange = (nextOpen) => {
1061
+ if (disabled) return;
1062
+ setOpen(nextOpen);
1063
+ };
1064
+ const activeDescendant = open && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : void 0;
1065
+ const describedBy = describedByIds.length ? describedByIds.join(" ") : void 0;
1066
+ const selectionSummaryForDisplay = selectionSummary || "";
1067
+ const inputDisplayValue = isMultiSelectEnabled ? inputValue : inputValue || selectionSummaryForDisplay;
1068
+ const comboboxInputProps = {
1069
+ role: "combobox",
1070
+ "aria-expanded": open,
1071
+ "aria-controls": listboxId,
1072
+ "aria-activedescendant": activeDescendant,
1073
+ "aria-autocomplete": shouldFilter ? "list" : "none",
1074
+ "aria-disabled": disabled || void 0,
1075
+ "aria-describedby": describedBy,
1076
+ "aria-readonly": selectOnly ? "true" : void 0
1077
+ };
1078
+ const listboxAriaProps = isMultiSelectEnabled ? { "aria-multiselectable": "true" } : {};
1079
+ const handleMultiContainerClick = () => {
1080
+ var _a;
1081
+ if (disabled) return;
1082
+ setOpen(true);
1083
+ (_a = inputRef.current) == null ? void 0 : _a.focus();
1084
+ };
1085
+ const selectedChips = isMultiSelectEnabled && multiSelectedOptions.length > 0 ? multiSelectedOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1086
+ import_chips.Chip,
1087
+ {
1088
+ label: option.label,
1089
+ size: "small",
1090
+ onRemove: () => selectOption(option),
1091
+ removeLabel: `Remove ${option.label}`,
1092
+ disabled: disabled || option.disabled,
1093
+ "data-slot": "combobox-selected-chip",
1094
+ className: "max-w-full"
1095
+ },
1096
+ option.value
1097
+ )) : null;
1098
+ console.log(inputDisplayValue);
1099
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_popovers.Popover, { open, onOpenChange: handleOpenChange, children: [
1100
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(import_popovers.PopoverAnchor, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1101
+ "div",
1102
+ {
1103
+ ref: anchorRef,
1104
+ className: (0, import_utils7.cx)("w-full", wrapperClassName),
1105
+ onMouseDown: isMultiSelectEnabled ? void 0 : handleSingleAnchorMouseDown,
1106
+ children: isMultiSelectEnabled ? /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1107
+ "div",
1108
+ {
1109
+ className: (0, import_utils7.cx)(
1110
+ "w-full min-h-[44px] border-2 rounded-md bg-white px-4 py-2 flex items-center gap-3 cursor-text",
1111
+ "border-border-base hover:border-border-primary-base focus-within:border-border-primary-base focus-within:shadow-focus",
1112
+ disabled && "bg-bg-inactive text-fg-inactive cursor-not-allowed border-border-subtle"
1113
+ ),
1114
+ onClick: handleMultiContainerClick,
1115
+ children: [
1116
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("div", { className: "flex flex-1 flex-wrap items-center gap-2", children: [
1117
+ selectedChips,
1118
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1119
+ "input",
1120
+ {
1121
+ ref: mergedRef,
1122
+ className: (0, import_utils7.cx)(
1123
+ "flex-1 basis-[140px] min-w-[120px] border-none bg-transparent outline-none text-base leading-tight py-1 pl-5",
1124
+ disabled && "cursor-not-allowed text-fg-inactive"
1125
+ ),
1126
+ value: inputDisplayValue,
1127
+ disabled,
1128
+ readOnly: selectOnly,
1129
+ autoComplete: "off",
1130
+ placeholder: multiSelectedOptions.length === 0 ? placeholder : "",
1131
+ onChange: handleInputChange,
1132
+ onFocus: handleFocus,
1133
+ onBlur: handleBlur,
1134
+ onKeyDown: handleKeyDown,
1135
+ ...comboboxInputProps,
1136
+ ...restInputProps
1137
+ }
1138
+ )
1139
+ ] }),
1140
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1141
+ "button",
1142
+ {
1143
+ type: "button",
1144
+ "aria-label": open ? "Collapse options" : "Expand options",
1145
+ onMouseDown: handleChevronMouseDown,
1146
+ className: "flex items-center justify-center rounded-full text-fg-subtle hover:text-fg-primary-base focus-visible:shadow-focus focus-visible:outline-none transition-colors mr-3",
1147
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1148
+ import_icons6.Chevron,
1149
+ {
1150
+ "aria-hidden": "true",
1151
+ className: (0, import_utils7.cx)(
1152
+ "transition-transform duration-200 rotate-90",
1153
+ open && "rotate-270"
1154
+ )
1155
+ }
1156
+ )
1157
+ }
1158
+ )
1159
+ ]
1160
+ }
1161
+ ) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1162
+ Input,
1163
+ {
1164
+ ref: mergedRef,
1165
+ placeholder,
1166
+ value: inputDisplayValue,
1167
+ disabled,
1168
+ readOnly: selectOnly,
1169
+ autoComplete: "off",
1170
+ onChange: handleInputChange,
1171
+ onFocus: handleFocus,
1172
+ onBlur: handleBlur,
1173
+ onKeyDown: handleKeyDown,
1174
+ onMouseDown: handleInputMouseDown,
1175
+ endIcon: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1176
+ "button",
1177
+ {
1178
+ type: "button",
1179
+ "aria-label": open ? "Collapse options" : "Expand options",
1180
+ onMouseDown: handleChevronMouseDown,
1181
+ className: "flex items-center justify-center rounded-full text-fg-subtle hover:text-fg-primary-base focus-visible:shadow-focus focus-visible:outline-none transition-colors",
1182
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1183
+ import_icons6.Chevron,
1184
+ {
1185
+ "aria-hidden": "true",
1186
+ className: (0, import_utils7.cx)(
1187
+ "transition-transform duration-200 rotate-90",
1188
+ open && "rotate-270"
1189
+ )
1190
+ }
1191
+ )
1192
+ }
1193
+ ),
1194
+ ...comboboxInputProps,
1195
+ ...restInputProps
1196
+ }
1197
+ )
1198
+ }
1199
+ ) }),
1200
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1201
+ import_popovers.PopoverContent,
1202
+ {
1203
+ side: "bottom",
1204
+ align: "start",
1205
+ sideOffset: 4,
1206
+ avoidCollisions: true,
1207
+ forceMount: true,
1208
+ trapFocus: false,
1209
+ disableOutsidePointerEvents: false,
1210
+ onOpenAutoFocus: (event) => event.preventDefault(),
1211
+ className: (0, import_utils7.cx)(
1212
+ "rounded-md border border-bg-base bg-white shadow-lg p-0 mt-1 max-h-60 overflow-auto",
1213
+ contentClassName
1214
+ ),
1215
+ style: { width: contentWidth || void 0 },
1216
+ "data-testid": "combobox-popover",
1217
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1218
+ "ul",
1219
+ {
1220
+ id: listboxId,
1221
+ role: "listbox",
1222
+ "aria-labelledby": labelHTMLForId,
1223
+ className: (0, import_utils7.cx)("py-1", listClassName),
1224
+ ...listboxAriaProps,
1225
+ children: filteredOptions.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1226
+ "li",
1227
+ {
1228
+ role: "presentation",
1229
+ className: "px-32 py-8 text-sm text-fg-subtle",
1230
+ children: emptyState
1231
+ }
1232
+ ) : filteredOptions.map((option, index) => {
1233
+ const optionId = `${listboxId}-option-${index}`;
1234
+ const isActive = index === activeIndex;
1235
+ const isSelected = isMultiSelectEnabled ? multiSelectedValues.includes(option.value) : option.value === singleSelectedValue;
1236
+ const mergedClassName = (0, import_utils7.cx)(
1237
+ MENU_ITEM_STYLES,
1238
+ isActive && "bg-bg-subtle text-fg-base",
1239
+ isSelected && "font-medium",
1240
+ option.disabled && "opacity-50 cursor-not-allowed",
1241
+ optionClassName,
1242
+ option.element.props.className
1243
+ );
1244
+ const originalOnClick = option.element.props.onClick;
1245
+ const originalOnMouseDown = option.element.props.onMouseDown;
1246
+ const optionContent = option.element.props.children ?? option.label;
1247
+ const checkboxIndicator = isMultiSelectEnabled && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1248
+ "span",
1249
+ {
1250
+ "data-slot": "combobox-option-checkbox",
1251
+ className: "pointer-events-none select-none shrink-0",
1252
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1253
+ Checkbox,
1254
+ {
1255
+ id: `${optionId}-checkbox`,
1256
+ checked: isSelected,
1257
+ readOnly: true,
1258
+ tabIndex: -1,
1259
+ "aria-hidden": "true",
1260
+ disabled: option.disabled
1261
+ }
1262
+ )
1263
+ }
1264
+ );
1265
+ return import_react10.default.cloneElement(option.element, {
1266
+ key: option.element.key ?? option.value ?? optionId,
1267
+ id: optionId,
1268
+ role: "option",
1269
+ "aria-selected": isSelected,
1270
+ "aria-disabled": option.disabled || void 0,
1271
+ tabIndex: -1,
1272
+ className: mergedClassName,
1273
+ onMouseDown: (event) => {
1274
+ event.preventDefault();
1275
+ originalOnMouseDown == null ? void 0 : originalOnMouseDown(event);
1276
+ },
1277
+ onClick: (event) => {
1278
+ originalOnClick == null ? void 0 : originalOnClick(event);
1279
+ if (event.defaultPrevented) return;
1280
+ selectOption(option);
1281
+ },
1282
+ children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("span", { className: "flex w-full items-center justify-between gap-8", children: [
1283
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", { className: "truncate", children: optionContent }),
1284
+ checkboxIndicator
1285
+ ] })
1286
+ });
1287
+ })
1288
+ }
1289
+ )
1290
+ }
1291
+ )
1292
+ ] });
1293
+ }
1294
+ );
1295
+ ComboboxRoot.displayName = "Combobox";
1296
+ var ComboboxOption = (0, import_react10.forwardRef)(function ComboboxOption2({ children, label, ...props }, ref) {
1297
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { ref, ...props, children: children ?? label });
1298
+ });
1299
+ ComboboxOption.displayName = OPTION_COMPONENT_NAME;
1300
+ ComboboxRoot.Option = ComboboxOption;
1301
+ var Option = ComboboxOption;
377
1302
  // Annotate the CommonJS export names for ESM import in node:
378
1303
  0 && (module.exports = {
1304
+ Checkbox,
1305
+ Combobox,
1306
+ ComboboxOption,
379
1307
  Feedback,
380
1308
  Field,
381
1309
  Input,
382
1310
  Label,
1311
+ Option,
383
1312
  Radio,
1313
+ Switch,
384
1314
  Textarea
385
1315
  });