@invana/forms 0.0.12 → 0.0.14

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
@@ -1,4 +1,4 @@
1
- import { cn, Accordion, AccordionItem, AccordionTrigger, AccordionContent, Separator, Button } from '@invana/ui';
1
+ import { cn, Accordion, AccordionItem, AccordionTrigger, Badge, AccordionContent, Card, CardContent, Separator, Button } from '@invana/ui';
2
2
  import * as React2 from 'react';
3
3
  import { useMemo } from 'react';
4
4
  import { Slot } from '@radix-ui/react-slot';
@@ -6,12 +6,12 @@ import { useFormContext, Controller, FormProvider } from 'react-hook-form';
6
6
  import * as LabelPrimitive from '@radix-ui/react-label';
7
7
  import { cva } from 'class-variance-authority';
8
8
  import { jsx, jsxs } from 'react/jsx-runtime';
9
- import { EyeOff, Eye, ChevronDown, ChevronUp, Check, Circle } from 'lucide-react';
9
+ import { EyeOff, Eye, Check, Circle, ChevronDown, ChevronUp } from 'lucide-react';
10
10
  import * as SwitchPrimitives from '@radix-ui/react-switch';
11
- import * as SelectPrimitive from '@radix-ui/react-select';
12
- import * as SliderPrimitive from '@radix-ui/react-slider';
13
11
  import * as CheckboxPrimitive from '@radix-ui/react-checkbox';
14
12
  import * as RadioGroupPrimitive from '@radix-ui/react-radio-group';
13
+ import * as SelectPrimitive from '@radix-ui/react-select';
14
+ import * as SliderPrimitive from '@radix-ui/react-slider';
15
15
 
16
16
  // src/form-field.tsx
17
17
  var labelVariants = cva(
@@ -208,6 +208,51 @@ var Switch = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
208
208
  }
209
209
  ));
210
210
  Switch.displayName = SwitchPrimitives.Root.displayName;
211
+ var Checkbox = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
212
+ CheckboxPrimitive.Root,
213
+ {
214
+ ref,
215
+ className: cn(
216
+ "peer h-4 w-4 shrink-0 rounded-md border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
217
+ className
218
+ ),
219
+ ...props,
220
+ children: /* @__PURE__ */ jsx(
221
+ CheckboxPrimitive.Indicator,
222
+ {
223
+ className: cn("flex items-center justify-center text-current"),
224
+ children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
225
+ }
226
+ )
227
+ }
228
+ ));
229
+ Checkbox.displayName = CheckboxPrimitive.Root.displayName;
230
+ var RadioGroup = React2.forwardRef(({ className, ...props }, ref) => {
231
+ return /* @__PURE__ */ jsx(
232
+ RadioGroupPrimitive.Root,
233
+ {
234
+ className: cn("grid gap-2", className),
235
+ ...props,
236
+ ref
237
+ }
238
+ );
239
+ });
240
+ RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
241
+ var RadioGroupItem = React2.forwardRef(({ className, ...props }, ref) => {
242
+ return /* @__PURE__ */ jsx(
243
+ RadioGroupPrimitive.Item,
244
+ {
245
+ ref,
246
+ className: cn(
247
+ "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
248
+ className
249
+ ),
250
+ ...props,
251
+ children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
252
+ }
253
+ );
254
+ });
255
+ RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
211
256
  var Select = SelectPrimitive.Root;
212
257
  var SelectGroup = SelectPrimitive.Group;
213
258
  var SelectValue = SelectPrimitive.Value;
@@ -462,18 +507,86 @@ var IconInput = ({ value, onChange }) => {
462
507
  ] });
463
508
  };
464
509
  var SIZE = {
465
- sm: { input: "h-8 text-sm", select: "h-8", label: "text-xs", desc: "text-xs" },
466
- md: { input: "", select: "", label: "", desc: "" }
510
+ xs: {
511
+ input: "h-9",
512
+ select: "h-9",
513
+ textarea: "",
514
+ label: "text-base",
515
+ desc: "text-base",
516
+ gap: "gap-x-3 gap-y-2.5",
517
+ section: "space-y-3",
518
+ outer: "space-y-4",
519
+ stack: "space-y-2",
520
+ sideGap: "gap-x-2",
521
+ trigger: "py-1.5 text-base",
522
+ switch: "scale-90 origin-right",
523
+ check: "h-4 w-4",
524
+ radio: "h-4 w-4"
525
+ },
526
+ sm: {
527
+ input: "h-9",
528
+ select: "h-9",
529
+ textarea: "",
530
+ label: "text-base",
531
+ desc: "text-base",
532
+ gap: "gap-x-3 gap-y-2",
533
+ section: "space-y-3",
534
+ outer: "space-y-4",
535
+ stack: "space-y-1.5",
536
+ sideGap: "gap-x-2",
537
+ trigger: "py-1.5 text-base",
538
+ switch: "scale-90 origin-right",
539
+ check: "h-4 w-4",
540
+ radio: "h-4 w-4"
541
+ },
542
+ md: {
543
+ input: "",
544
+ select: "",
545
+ textarea: "",
546
+ label: "text-base",
547
+ desc: "text-base",
548
+ gap: "gap-4",
549
+ section: "space-y-4",
550
+ outer: "space-y-6",
551
+ stack: "space-y-2",
552
+ sideGap: "gap-2",
553
+ trigger: "py-1.5 text-base",
554
+ switch: "",
555
+ check: "h-4 w-4",
556
+ radio: "h-4 w-4"
557
+ }
467
558
  };
468
- function itemClasses(labelPosition, className) {
559
+ function itemClasses(labelPosition, size, className) {
469
560
  return cn(
470
- labelPosition === "side" && "grid grid-cols-3 items-center gap-2",
471
- labelPosition === "top" && "space-y-2",
561
+ labelPosition === "side" && cn("grid grid-cols-3 items-center", SIZE[size].sideGap),
562
+ labelPosition === "top" && SIZE[size].stack,
472
563
  className
473
564
  );
474
565
  }
475
- function inputWrapper(labelPosition) {
476
- return cn(labelPosition === "side" && "col-span-2", "space-y-1");
566
+ function inputWrapper(labelPosition, size) {
567
+ return cn(labelPosition === "side" && "col-span-2", SIZE[size].stack);
568
+ }
569
+ function StatusPill({ badge }) {
570
+ return /* @__PURE__ */ jsx(
571
+ Badge,
572
+ {
573
+ variant: badge.variant ?? "secondary",
574
+ className: "rounded-full px-1.5 py-0 text-base font-medium",
575
+ children: badge.label
576
+ }
577
+ );
578
+ }
579
+ function FieldLabel({
580
+ label,
581
+ badge,
582
+ size,
583
+ className
584
+ }) {
585
+ if (!label && !badge) return null;
586
+ return /* @__PURE__ */ jsxs(FormLabel, { className: cn(SIZE[size].label, className), children: [
587
+ label,
588
+ badge && /* @__PURE__ */ jsx(StatusPill, { badge })
589
+ ] });
477
590
  }
478
591
  var InputField = ({
479
592
  label,
@@ -483,10 +596,12 @@ var InputField = ({
483
596
  onChange,
484
597
  labelPosition = "side",
485
598
  size = "sm",
599
+ labelClassName,
600
+ badge,
486
601
  className
487
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
488
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
489
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
602
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
603
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
604
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
490
605
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
491
606
  Input,
492
607
  {
@@ -508,10 +623,12 @@ var PasswordField = ({
508
623
  onChange,
509
624
  labelPosition = "side",
510
625
  size = "sm",
626
+ labelClassName,
627
+ badge,
511
628
  className
512
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
513
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
514
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
629
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
630
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
631
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
515
632
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
516
633
  PasswordInput,
517
634
  {
@@ -534,14 +651,16 @@ var TextareaField = ({
534
651
  rows,
535
652
  labelPosition = "side",
536
653
  size = "sm",
654
+ labelClassName,
655
+ badge,
537
656
  className
538
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
539
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
540
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
657
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
658
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
659
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
541
660
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
542
661
  Textarea,
543
662
  {
544
- className: size === "sm" ? "text-sm" : void 0,
663
+ className: SIZE[size].textarea || void 0,
545
664
  rows,
546
665
  placeholder,
547
666
  value: value ?? "",
@@ -561,10 +680,12 @@ var SelectField = ({
561
680
  placeholder = "Select type",
562
681
  labelPosition = "side",
563
682
  size = "sm",
683
+ labelClassName,
684
+ badge,
564
685
  className
565
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
566
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
567
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
686
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
687
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
688
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
568
689
  /* @__PURE__ */ jsxs(Select, { value: value ?? "", onValueChange: onChange, children: [
569
690
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(SelectTrigger, { className: SIZE[size].select, children: /* @__PURE__ */ jsx(SelectValue, { placeholder }) }) }),
570
691
  /* @__PURE__ */ jsx(SelectContent, { children: options.map((o) => /* @__PURE__ */ jsx(SelectItem, { value: o.value, children: o.label }, o.value)) })
@@ -579,25 +700,160 @@ var BooleanField = ({
579
700
  value,
580
701
  onChange,
581
702
  labelPosition = "side",
582
- size = "sm"
703
+ size = "sm",
704
+ control = "switch",
705
+ labelClassName,
706
+ badge,
707
+ className,
708
+ boxed = false
583
709
  }) => {
710
+ const boxClass = boxed ? "rounded-md border p-2" : "";
711
+ if (control === "checkbox") {
712
+ return /* @__PURE__ */ jsxs(FormItem, { className: cn("flex items-center gap-2 space-y-0", className), children: [
713
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
714
+ Checkbox,
715
+ {
716
+ className: SIZE[size].check,
717
+ checked: !!value,
718
+ onCheckedChange: onChange
719
+ }
720
+ ) }),
721
+ /* @__PURE__ */ jsx(
722
+ FieldLabel,
723
+ {
724
+ label,
725
+ badge,
726
+ size,
727
+ className: cn(
728
+ "!mt-0 cursor-pointer font-normal leading-none",
729
+ labelClassName
730
+ )
731
+ }
732
+ )
733
+ ] });
734
+ }
584
735
  if (labelPosition === "side") {
585
- return /* @__PURE__ */ jsxs(FormItem, { className: "flex items-center justify-between rounded-md border p-2", children: [
736
+ return /* @__PURE__ */ jsxs(FormItem, { className: cn("flex items-center justify-between", boxClass), children: [
586
737
  /* @__PURE__ */ jsxs("div", { children: [
587
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
738
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
588
739
  description && /* @__PURE__ */ jsx(FormDescription, { className: SIZE[size].desc, children: description })
589
740
  ] }),
590
- /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Switch, { checked: !!value, onCheckedChange: onChange }) })
741
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
742
+ Switch,
743
+ {
744
+ className: SIZE[size].switch || void 0,
745
+ checked: !!value,
746
+ onCheckedChange: onChange
747
+ }
748
+ ) })
591
749
  ] });
592
750
  }
593
- return /* @__PURE__ */ jsxs(FormItem, { className: "space-y-2", children: [
594
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
595
- /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between rounded-md border p-2", children: [
596
- /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(Switch, { checked: !!value, onCheckedChange: onChange }) }),
751
+ return /* @__PURE__ */ jsxs(FormItem, { className: SIZE[size].stack, children: [
752
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
753
+ /* @__PURE__ */ jsxs("div", { className: cn("flex items-center justify-between", boxClass), children: [
754
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
755
+ Switch,
756
+ {
757
+ className: SIZE[size].switch || void 0,
758
+ checked: !!value,
759
+ onCheckedChange: onChange
760
+ }
761
+ ) }),
597
762
  description && /* @__PURE__ */ jsx(FormDescription, { className: cn("ml-2", SIZE[size].desc), children: description })
598
763
  ] })
599
764
  ] });
600
765
  };
766
+ var RadioField = ({
767
+ label,
768
+ description,
769
+ options = [],
770
+ value,
771
+ onChange,
772
+ labelPosition = "side",
773
+ size = "sm",
774
+ orientation = "vertical",
775
+ labelClassName,
776
+ badge,
777
+ className
778
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
779
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
780
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
781
+ /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
782
+ RadioGroup,
783
+ {
784
+ value: value ?? "",
785
+ onValueChange: onChange,
786
+ className: orientation === "horizontal" ? "flex flex-row items-center gap-x-4" : cn("flex flex-col", SIZE[size].stack),
787
+ children: options.map((o) => /* @__PURE__ */ jsxs(
788
+ "label",
789
+ {
790
+ className: "flex cursor-pointer items-center gap-2",
791
+ children: [
792
+ /* @__PURE__ */ jsx(
793
+ RadioGroupItem,
794
+ {
795
+ value: o.value,
796
+ className: cn("shrink-0", SIZE[size].radio)
797
+ }
798
+ ),
799
+ /* @__PURE__ */ jsx("span", { className: cn("leading-none", SIZE[size].label), children: o.label })
800
+ ]
801
+ },
802
+ o.value
803
+ ))
804
+ }
805
+ ) }),
806
+ description && /* @__PURE__ */ jsx(FormDescription, { className: SIZE[size].desc, children: description }),
807
+ /* @__PURE__ */ jsx(FormMessage, { className: SIZE[size].desc })
808
+ ] })
809
+ ] });
810
+ var CheckboxGroupField = ({
811
+ label,
812
+ description,
813
+ options = [],
814
+ value,
815
+ onChange,
816
+ labelPosition = "side",
817
+ size = "sm",
818
+ orientation = "vertical",
819
+ labelClassName,
820
+ badge,
821
+ className
822
+ }) => {
823
+ const selected = Array.isArray(value) ? value : [];
824
+ const toggle = (v, checked) => onChange?.(checked ? [...selected, v] : selected.filter((x) => x !== v));
825
+ return /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
826
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
827
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
828
+ /* @__PURE__ */ jsx(
829
+ "div",
830
+ {
831
+ className: orientation === "horizontal" ? "flex flex-row items-center gap-x-4" : cn("flex flex-col", SIZE[size].stack),
832
+ children: options.map((o) => /* @__PURE__ */ jsxs(
833
+ "label",
834
+ {
835
+ className: "flex cursor-pointer items-center gap-2",
836
+ children: [
837
+ /* @__PURE__ */ jsx(
838
+ Checkbox,
839
+ {
840
+ className: cn("shrink-0", SIZE[size].check),
841
+ checked: selected.includes(o.value),
842
+ onCheckedChange: (c) => toggle(o.value, c === true)
843
+ }
844
+ ),
845
+ /* @__PURE__ */ jsx("span", { className: cn("leading-none", SIZE[size].label), children: o.label })
846
+ ]
847
+ },
848
+ o.value
849
+ ))
850
+ }
851
+ ),
852
+ description && /* @__PURE__ */ jsx(FormDescription, { className: SIZE[size].desc, children: description }),
853
+ /* @__PURE__ */ jsx(FormMessage, { className: SIZE[size].desc })
854
+ ] })
855
+ ] });
856
+ };
601
857
  var ColorField = ({
602
858
  label,
603
859
  description,
@@ -607,10 +863,12 @@ var ColorField = ({
607
863
  defaultValue,
608
864
  labelPosition = "side",
609
865
  size = "sm",
866
+ labelClassName,
867
+ badge,
610
868
  className
611
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
612
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
613
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
869
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
870
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
871
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
614
872
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
615
873
  ColorSwatches,
616
874
  {
@@ -634,10 +892,12 @@ var NumberField = ({
634
892
  step,
635
893
  labelPosition = "side",
636
894
  size = "sm",
895
+ labelClassName,
896
+ badge,
637
897
  className
638
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
639
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
640
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
898
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
899
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
900
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
641
901
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(
642
902
  SliderNumber,
643
903
  {
@@ -659,10 +919,12 @@ var IconField = ({
659
919
  onChange,
660
920
  labelPosition = "side",
661
921
  size = "sm",
922
+ labelClassName,
923
+ badge,
662
924
  className
663
- }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, className), children: [
664
- label && /* @__PURE__ */ jsx(FormLabel, { className: SIZE[size].label, children: label }),
665
- /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition), children: [
925
+ }) => /* @__PURE__ */ jsxs(FormItem, { className: itemClasses(labelPosition, size, className), children: [
926
+ /* @__PURE__ */ jsx(FieldLabel, { label, badge, size, className: labelClassName }),
927
+ /* @__PURE__ */ jsxs("div", { className: inputWrapper(labelPosition, size), children: [
666
928
  /* @__PURE__ */ jsx(FormControl, { children: /* @__PURE__ */ jsx(IconInput, { value, onChange }) }),
667
929
  description && /* @__PURE__ */ jsx(FormDescription, { className: SIZE[size].desc, children: description }),
668
930
  /* @__PURE__ */ jsx(FormMessage, { className: SIZE[size].desc })
@@ -673,6 +935,8 @@ var Field = {
673
935
  Password: PasswordField,
674
936
  Textarea: TextareaField,
675
937
  Boolean: BooleanField,
938
+ Radio: RadioField,
939
+ CheckboxGroup: CheckboxGroupField,
676
940
  Color: ColorField,
677
941
  Number: NumberField,
678
942
  Select: SelectField,
@@ -699,6 +963,11 @@ function renderField(field, parentName, control, labelPosition, size) {
699
963
  presetColors: field.presetColors,
700
964
  defaultValue: field.defaultValue,
701
965
  rows: field.rows,
966
+ control: field.control,
967
+ orientation: field.orientation,
968
+ boxed: field.boxed,
969
+ labelClassName: field.labelClassName,
970
+ badge: field.badge,
702
971
  labelPosition,
703
972
  size,
704
973
  value: rhf.value,
@@ -715,6 +984,10 @@ function renderField(field, parentName, control, labelPosition, size) {
715
984
  );
716
985
  case "boolean":
717
986
  return /* @__PURE__ */ jsx(BooleanField, { ...common });
987
+ case "radio":
988
+ return /* @__PURE__ */ jsx(RadioField, { ...common });
989
+ case "checkbox":
990
+ return /* @__PURE__ */ jsx(CheckboxGroupField, { ...common });
718
991
  case "color":
719
992
  return /* @__PURE__ */ jsx(ColorField, { ...common });
720
993
  case "number":
@@ -752,7 +1025,8 @@ function renderGrid(fields, parentName, control, labelPosition, size, columns, k
752
1025
  "div",
753
1026
  {
754
1027
  className: cn(
755
- "grid grid-cols-1 gap-4",
1028
+ "grid grid-cols-1",
1029
+ SIZE[size].gap,
756
1030
  customCols ? "md:[grid-template-columns:repeat(var(--ff-cols),minmax(0,1fr))]" : "md:grid-cols-2"
757
1031
  ),
758
1032
  style: customCols ? { "--ff-cols": columns } : void 0,
@@ -782,7 +1056,7 @@ function renderRows(fields, rowConfig, parentName, control, labelPosition, size,
782
1056
  const used = new Set(rowConfig.flatMap((r) => r.fields));
783
1057
  const unassigned = fields.filter((f) => !used.has(f.name));
784
1058
  const byName = new Map(fields.map((f) => [f.name, f]));
785
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1059
+ return /* @__PURE__ */ jsxs("div", { className: SIZE[size].section, children: [
786
1060
  rowConfig.map((row) => {
787
1061
  const rowFields = row.fields.map((n) => byName.get(n)).filter((f) => !!f);
788
1062
  if (rowFields.length === 0) return null;
@@ -812,6 +1086,7 @@ var ObjectField = ({
812
1086
  name,
813
1087
  fields,
814
1088
  rowConfig,
1089
+ groupConfig,
815
1090
  labelPosition = "side",
816
1091
  size = "sm",
817
1092
  columns = 2
@@ -824,8 +1099,11 @@ var ObjectField = ({
824
1099
  const ungrouped = grouped["_ungrouped"] ?? [];
825
1100
  delete grouped["_ungrouped"];
826
1101
  const groupedEntries = Object.entries(grouped);
827
- return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
828
- ungrouped.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-4", children: renderRows(
1102
+ const groupConfigById = new Map(
1103
+ (groupConfig ?? []).map((g) => [g.id, g])
1104
+ );
1105
+ return /* @__PURE__ */ jsxs("div", { className: SIZE[size].outer, children: [
1106
+ ungrouped.length > 0 && /* @__PURE__ */ jsx("div", { className: SIZE[size].section, children: renderRows(
829
1107
  ungrouped,
830
1108
  rowConfig,
831
1109
  name,
@@ -839,22 +1117,42 @@ var ObjectField = ({
839
1117
  {
840
1118
  type: "multiple",
841
1119
  defaultValue: groupedEntries.map(([k]) => k),
842
- className: "w-full space-y-2",
843
- children: groupedEntries.map(([group, gFields]) => /* @__PURE__ */ jsxs(AccordionItem, { value: group, className: "rounded-md border", children: [
844
- /* @__PURE__ */ jsxs(AccordionTrigger, { className: "px-3 text-sm font-medium hover:no-underline", children: [
845
- humanize(group),
846
- " Settings"
847
- ] }),
848
- /* @__PURE__ */ jsx(AccordionContent, { className: "px-3 pb-3", children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children: renderRows(
849
- gFields,
850
- rowConfig,
851
- name,
852
- control,
853
- labelPosition,
854
- size,
855
- columns
856
- ) }) })
857
- ] }, group))
1120
+ className: "w-full",
1121
+ children: groupedEntries.map(([group, gFields]) => {
1122
+ const gc = groupConfigById.get(group);
1123
+ return /* @__PURE__ */ jsxs(AccordionItem, { value: group, className: "border-b", children: [
1124
+ /* @__PURE__ */ jsx(
1125
+ AccordionTrigger,
1126
+ {
1127
+ className: cn(
1128
+ "font-semibold uppercase tracking-wide text-muted-foreground hover:no-underline",
1129
+ SIZE[size].trigger
1130
+ ),
1131
+ children: /* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
1132
+ gc?.label ?? humanize(group),
1133
+ (gc?.showCount ?? true) && /* @__PURE__ */ jsx(
1134
+ Badge,
1135
+ {
1136
+ variant: "secondary",
1137
+ className: "rounded-full px-1.5 py-0 text-base font-normal tabular-nums",
1138
+ children: gFields.length
1139
+ }
1140
+ ),
1141
+ gc?.badges?.map((b, i) => /* @__PURE__ */ jsx(StatusPill, { badge: b }, i))
1142
+ ] })
1143
+ }
1144
+ ),
1145
+ /* @__PURE__ */ jsx(AccordionContent, { className: "pb-3 pt-1", children: /* @__PURE__ */ jsx("div", { className: SIZE[size].section, children: renderRows(
1146
+ gFields,
1147
+ rowConfig,
1148
+ name,
1149
+ control,
1150
+ labelPosition,
1151
+ size,
1152
+ columns
1153
+ ) }) })
1154
+ ] }, group);
1155
+ })
858
1156
  }
859
1157
  )
860
1158
  ] });
@@ -865,56 +1163,35 @@ var FormField2 = Object.assign(FormField, {
865
1163
  Password: PasswordField,
866
1164
  Textarea: TextareaField,
867
1165
  Boolean: BooleanField,
1166
+ Radio: RadioField,
1167
+ CheckboxGroup: CheckboxGroupField,
868
1168
  Color: ColorField,
869
1169
  Number: NumberField,
870
1170
  Select: SelectField,
871
1171
  Icon: IconField
872
1172
  });
873
- var Checkbox = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
874
- CheckboxPrimitive.Root,
875
- {
876
- ref,
877
- className: cn(
878
- "peer h-4 w-4 shrink-0 rounded-md border border-primary shadow focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=checked]:text-primary-foreground",
879
- className
880
- ),
881
- ...props,
882
- children: /* @__PURE__ */ jsx(
883
- CheckboxPrimitive.Indicator,
884
- {
885
- className: cn("flex items-center justify-center text-current"),
886
- children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
887
- }
888
- )
889
- }
890
- ));
891
- Checkbox.displayName = CheckboxPrimitive.Root.displayName;
892
- var RadioGroup = React2.forwardRef(({ className, ...props }, ref) => {
893
- return /* @__PURE__ */ jsx(
894
- RadioGroupPrimitive.Root,
895
- {
896
- className: cn("grid gap-2", className),
897
- ...props,
898
- ref
899
- }
900
- );
901
- });
902
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
903
- var RadioGroupItem = React2.forwardRef(({ className, ...props }, ref) => {
904
- return /* @__PURE__ */ jsx(
905
- RadioGroupPrimitive.Item,
1173
+ function SettingsPanel({
1174
+ form,
1175
+ title,
1176
+ className,
1177
+ contentClassName,
1178
+ children,
1179
+ ...objectField
1180
+ }) {
1181
+ return /* @__PURE__ */ jsx(Card, { className, children: /* @__PURE__ */ jsxs(
1182
+ CardContent,
906
1183
  {
907
- ref,
908
- className: cn(
909
- "aspect-square h-4 w-4 rounded-full border border-primary text-primary ring-offset-background focus:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
910
- className
911
- ),
912
- ...props,
913
- children: /* @__PURE__ */ jsx(RadioGroupPrimitive.Indicator, { className: "flex items-center justify-center", children: /* @__PURE__ */ jsx(Circle, { className: "h-2.5 w-2.5 fill-current text-current" }) })
1184
+ className: cn("max-h-[80vh] overflow-y-auto p-4", contentClassName),
1185
+ children: [
1186
+ title && /* @__PURE__ */ jsx("h2", { className: "mb-3 text-base font-semibold uppercase tracking-wide text-muted-foreground", children: title }),
1187
+ /* @__PURE__ */ jsxs(Form, { ...form, children: [
1188
+ /* @__PURE__ */ jsx(ObjectField, { control: form.control, ...objectField }),
1189
+ children
1190
+ ] })
1191
+ ]
914
1192
  }
915
- );
916
- });
917
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
1193
+ ) });
1194
+ }
918
1195
  function FieldSet({ className, ...props }) {
919
1196
  return /* @__PURE__ */ jsx(
920
1197
  "fieldset",
@@ -998,7 +1275,7 @@ function FieldContent({ className, ...props }) {
998
1275
  }
999
1276
  );
1000
1277
  }
1001
- function FieldLabel({
1278
+ function FieldLabel2({
1002
1279
  className,
1003
1280
  ...props
1004
1281
  }) {
@@ -1248,6 +1525,6 @@ function InputGroupTextarea({
1248
1525
  );
1249
1526
  }
1250
1527
 
1251
- export { BooleanField, Checkbox, ColorField, ColorSwatches, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField2 as FormField, FormItem, FormLabel, FormMessage, IconField, IconInput, Input, InputField, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, NumberField, ObjectField, PasswordField, PasswordInput, RadioGroup, RadioGroupItem, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Slider, SliderNumber, Switch, Textarea, TextareaField, useFormField };
1528
+ export { BooleanField, Checkbox, CheckboxGroupField, ColorField, ColorSwatches, Field, FieldContent, FieldDescription, FieldError, FieldGroup, FieldLabel2 as FieldLabel, FieldLegend, FieldSeparator, FieldSet, FieldTitle, Form, FormControl, FormDescription, FormField2 as FormField, FormItem, FormLabel, FormMessage, IconField, IconInput, Input, InputField, InputGroup, InputGroupAddon, InputGroupButton, InputGroupInput, InputGroupText, InputGroupTextarea, Label, NumberField, ObjectField, PasswordField, PasswordInput, RadioField, RadioGroup, RadioGroupItem, Select, SelectContent, SelectField, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SettingsPanel, Slider, SliderNumber, Switch, Textarea, TextareaField, useFormField };
1252
1529
  //# sourceMappingURL=index.js.map
1253
1530
  //# sourceMappingURL=index.js.map