@invana/forms 0.0.11 → 0.0.13

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,
@@ -681,11 +945,6 @@ var Field = {
681
945
  function humanize(name) {
682
946
  return name.replace(/([A-Z])/g, " $1").replace(/^./, (c) => c.toUpperCase()).trim();
683
947
  }
684
- function chunk(arr, size) {
685
- const out = [];
686
- for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
687
- return out;
688
- }
689
948
  function renderField(field, parentName, control, labelPosition, size) {
690
949
  return /* @__PURE__ */ jsx(
691
950
  FormField,
@@ -704,6 +963,11 @@ function renderField(field, parentName, control, labelPosition, size) {
704
963
  presetColors: field.presetColors,
705
964
  defaultValue: field.defaultValue,
706
965
  rows: field.rows,
966
+ control: field.control,
967
+ orientation: field.orientation,
968
+ boxed: field.boxed,
969
+ labelClassName: field.labelClassName,
970
+ badge: field.badge,
707
971
  labelPosition,
708
972
  size,
709
973
  value: rhf.value,
@@ -720,6 +984,10 @@ function renderField(field, parentName, control, labelPosition, size) {
720
984
  );
721
985
  case "boolean":
722
986
  return /* @__PURE__ */ jsx(BooleanField, { ...common });
987
+ case "radio":
988
+ return /* @__PURE__ */ jsx(RadioField, { ...common });
989
+ case "checkbox":
990
+ return /* @__PURE__ */ jsx(CheckboxGroupField, { ...common });
723
991
  case "color":
724
992
  return /* @__PURE__ */ jsx(ColorField, { ...common });
725
993
  case "number":
@@ -751,26 +1019,66 @@ function renderField(field, parentName, control, labelPosition, size) {
751
1019
  field.name
752
1020
  );
753
1021
  }
754
- function renderRows(fields, rowConfig, parentName, control, labelPosition, size) {
1022
+ function renderGrid(fields, parentName, control, labelPosition, size, columns, key) {
1023
+ const customCols = columns !== 2;
1024
+ return /* @__PURE__ */ jsx(
1025
+ "div",
1026
+ {
1027
+ className: cn(
1028
+ "grid grid-cols-1",
1029
+ SIZE[size].gap,
1030
+ customCols ? "md:[grid-template-columns:repeat(var(--ff-cols),minmax(0,1fr))]" : "md:grid-cols-2"
1031
+ ),
1032
+ style: customCols ? { "--ff-cols": columns } : void 0,
1033
+ children: fields.map((f) => {
1034
+ const span = f.colSpan && f.colSpan > 1 ? f.colSpan : void 0;
1035
+ return /* @__PURE__ */ jsx(
1036
+ "div",
1037
+ {
1038
+ className: cn(
1039
+ span && "md:[grid-column:span_var(--ff-span)/span_var(--ff-span)]",
1040
+ f.className
1041
+ ),
1042
+ style: span ? { "--ff-span": span } : void 0,
1043
+ children: renderField(f, parentName, control, labelPosition, size)
1044
+ },
1045
+ f.name
1046
+ );
1047
+ })
1048
+ },
1049
+ key
1050
+ );
1051
+ }
1052
+ function renderRows(fields, rowConfig, parentName, control, labelPosition, size, columns) {
755
1053
  if (!rowConfig || rowConfig.length === 0) {
756
- return /* @__PURE__ */ jsx("div", { className: "grid gap-4", children: chunk(fields, 2).map((row, i) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: row.map((f) => renderField(f, parentName, control, labelPosition, size)) }, i)) });
1054
+ return renderGrid(fields, parentName, control, labelPosition, size, columns);
757
1055
  }
758
1056
  const used = new Set(rowConfig.flatMap((r) => r.fields));
759
1057
  const unassigned = fields.filter((f) => !used.has(f.name));
760
1058
  const byName = new Map(fields.map((f) => [f.name, f]));
761
- return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
1059
+ return /* @__PURE__ */ jsxs("div", { className: SIZE[size].section, children: [
762
1060
  rowConfig.map((row) => {
763
1061
  const rowFields = row.fields.map((n) => byName.get(n)).filter((f) => !!f);
764
- return chunk(rowFields, 2).map((cnk, idx) => /* @__PURE__ */ jsx(
765
- "div",
766
- {
767
- className: "grid grid-cols-1 gap-4 md:grid-cols-2",
768
- children: cnk.map((f) => renderField(f, parentName, control, labelPosition, size))
769
- },
770
- `${row.id}-${idx}`
771
- ));
1062
+ if (rowFields.length === 0) return null;
1063
+ return renderGrid(
1064
+ rowFields,
1065
+ parentName,
1066
+ control,
1067
+ labelPosition,
1068
+ size,
1069
+ columns,
1070
+ row.id
1071
+ );
772
1072
  }),
773
- unassigned.length > 0 && /* @__PURE__ */ jsx("div", { className: "grid gap-4", children: chunk(unassigned, 2).map((row, i) => /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: row.map((f) => renderField(f, parentName, control, labelPosition, size)) }, `u-${i}`)) })
1073
+ unassigned.length > 0 && renderGrid(
1074
+ unassigned,
1075
+ parentName,
1076
+ control,
1077
+ labelPosition,
1078
+ size,
1079
+ columns,
1080
+ "_unassigned"
1081
+ )
774
1082
  ] });
775
1083
  }
776
1084
  var ObjectField = ({
@@ -778,8 +1086,10 @@ var ObjectField = ({
778
1086
  name,
779
1087
  fields,
780
1088
  rowConfig,
1089
+ groupConfig,
781
1090
  labelPosition = "side",
782
- size = "sm"
1091
+ size = "sm",
1092
+ columns = 2
783
1093
  }) => {
784
1094
  const grouped = fields.reduce((acc, f) => {
785
1095
  const key = f.group ?? "_ungrouped";
@@ -789,21 +1099,60 @@ var ObjectField = ({
789
1099
  const ungrouped = grouped["_ungrouped"] ?? [];
790
1100
  delete grouped["_ungrouped"];
791
1101
  const groupedEntries = Object.entries(grouped);
792
- return /* @__PURE__ */ jsxs("div", { className: "space-y-6", children: [
793
- ungrouped.length > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-4", children: renderRows(ungrouped, rowConfig, name, control, labelPosition, size) }),
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(
1107
+ ungrouped,
1108
+ rowConfig,
1109
+ name,
1110
+ control,
1111
+ labelPosition,
1112
+ size,
1113
+ columns
1114
+ ) }),
794
1115
  groupedEntries.length > 0 && /* @__PURE__ */ jsx(
795
1116
  Accordion,
796
1117
  {
797
1118
  type: "multiple",
798
1119
  defaultValue: groupedEntries.map(([k]) => k),
799
- className: "w-full space-y-2",
800
- children: groupedEntries.map(([group, gFields]) => /* @__PURE__ */ jsxs(AccordionItem, { value: group, className: "rounded-md border", children: [
801
- /* @__PURE__ */ jsxs(AccordionTrigger, { className: "px-3 text-sm font-medium hover:no-underline", children: [
802
- humanize(group),
803
- " Settings"
804
- ] }),
805
- /* @__PURE__ */ jsx(AccordionContent, { className: "px-3 pb-3", children: /* @__PURE__ */ jsx("div", { className: "space-y-4", children: renderRows(gFields, rowConfig, name, control, labelPosition, size) }) })
806
- ] }, 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
+ })
807
1156
  }
808
1157
  )
809
1158
  ] });
@@ -814,56 +1163,35 @@ var FormField2 = Object.assign(FormField, {
814
1163
  Password: PasswordField,
815
1164
  Textarea: TextareaField,
816
1165
  Boolean: BooleanField,
1166
+ Radio: RadioField,
1167
+ CheckboxGroup: CheckboxGroupField,
817
1168
  Color: ColorField,
818
1169
  Number: NumberField,
819
1170
  Select: SelectField,
820
1171
  Icon: IconField
821
1172
  });
822
- var Checkbox = React2.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
823
- CheckboxPrimitive.Root,
824
- {
825
- ref,
826
- className: cn(
827
- "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",
828
- className
829
- ),
830
- ...props,
831
- children: /* @__PURE__ */ jsx(
832
- CheckboxPrimitive.Indicator,
833
- {
834
- className: cn("flex items-center justify-center text-current"),
835
- children: /* @__PURE__ */ jsx(Check, { className: "h-4 w-4" })
836
- }
837
- )
838
- }
839
- ));
840
- Checkbox.displayName = CheckboxPrimitive.Root.displayName;
841
- var RadioGroup = React2.forwardRef(({ className, ...props }, ref) => {
842
- return /* @__PURE__ */ jsx(
843
- RadioGroupPrimitive.Root,
844
- {
845
- className: cn("grid gap-2", className),
846
- ...props,
847
- ref
848
- }
849
- );
850
- });
851
- RadioGroup.displayName = RadioGroupPrimitive.Root.displayName;
852
- var RadioGroupItem = React2.forwardRef(({ className, ...props }, ref) => {
853
- return /* @__PURE__ */ jsx(
854
- 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,
855
1183
  {
856
- ref,
857
- className: cn(
858
- "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",
859
- className
860
- ),
861
- ...props,
862
- 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
+ ]
863
1192
  }
864
- );
865
- });
866
- RadioGroupItem.displayName = RadioGroupPrimitive.Item.displayName;
1193
+ ) });
1194
+ }
867
1195
  function FieldSet({ className, ...props }) {
868
1196
  return /* @__PURE__ */ jsx(
869
1197
  "fieldset",
@@ -947,7 +1275,7 @@ function FieldContent({ className, ...props }) {
947
1275
  }
948
1276
  );
949
1277
  }
950
- function FieldLabel({
1278
+ function FieldLabel2({
951
1279
  className,
952
1280
  ...props
953
1281
  }) {
@@ -1197,6 +1525,6 @@ function InputGroupTextarea({
1197
1525
  );
1198
1526
  }
1199
1527
 
1200
- 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 };
1201
1529
  //# sourceMappingURL=index.js.map
1202
1530
  //# sourceMappingURL=index.js.map