@saas-ui/forms 3.0.0-alpha.8 → 3.0.0-next.0

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.mjs CHANGED
@@ -1,9 +1,10 @@
1
1
  'use client'
2
2
 
3
3
  // src/create-form.tsx
4
- import { forwardRef as forwardRef7, useMemo as useMemo2 } from "react";
4
+ import { forwardRef as forwardRef7, useMemo as useMemo3 } from "react";
5
5
 
6
6
  // src/default-fields.tsx
7
+ import { useMemo } from "react";
7
8
  import {
8
9
  Input,
9
10
  Stack,
@@ -29,7 +30,7 @@ import { callAll, mergeRefs, splitProps as splitProps2 } from "@saas-ui/core/uti
29
30
  import { Controller } from "react-hook-form";
30
31
 
31
32
  // src/base-field.tsx
32
- import { Box, Field } from "@chakra-ui/react";
33
+ import { Field } from "@chakra-ui/react";
33
34
  import { splitProps } from "@saas-ui/core/utils";
34
35
  import { get } from "react-hook-form";
35
36
 
@@ -69,35 +70,38 @@ var isTouched = (name, formState) => {
69
70
  return get(formState.touchedFields, name);
70
71
  };
71
72
  var useBaseField = (props) => {
72
- const [fieldProps] = splitProps(props, ["name", "label", "help", "hideLabel"]);
73
- const [controlProps] = splitProps(props, [
74
- // 'id',
75
- // 'orientation',
76
- // 'disabled',
77
- // 'invalid',
78
- // 'readOnly',
79
- // 'required',
73
+ const [fieldProps, rootProps] = splitProps(props, [
74
+ "name",
75
+ "label",
76
+ "help",
77
+ "hideLabel",
78
+ "placeholder",
79
+ "rules",
80
+ "type",
81
+ "children"
80
82
  ]);
81
83
  const { formState } = useFormContext();
82
84
  const error = getError(fieldProps.name, formState);
83
85
  const touched = isTouched(fieldProps.name, formState);
84
86
  return {
85
87
  ...fieldProps,
86
- controlProps,
88
+ rootProps,
87
89
  error,
88
90
  touched
89
91
  };
90
92
  };
91
93
  var BaseField = (props) => {
92
- const { label, help, hideLabel, error } = useBaseField(props);
94
+ const { rootProps, label, hideLabel, help, error } = useBaseField(props);
93
95
  const isInvalid = !!error;
94
- return /* @__PURE__ */ jsxs(Field.Root, { invalid: isInvalid, ...props, children: [
95
- label && !hideLabel ? /* @__PURE__ */ jsx2(Field.Label, { children: label }) : null,
96
- /* @__PURE__ */ jsxs(Box, { width: "full", children: [
97
- props.children,
98
- help && !(error == null ? void 0 : error.message) ? /* @__PURE__ */ jsx2(Field.HelperText, { children: help }) : null,
99
- (error == null ? void 0 : error.message) && /* @__PURE__ */ jsx2(Field.ErrorText, { children: error == null ? void 0 : error.message })
100
- ] })
96
+ return /* @__PURE__ */ jsxs(Field.Root, { invalid: isInvalid, ...rootProps, children: [
97
+ label && !hideLabel ? /* @__PURE__ */ jsxs(Field.Label, { children: [
98
+ label,
99
+ " ",
100
+ /* @__PURE__ */ jsx2(Field.RequiredIndicator, {})
101
+ ] }) : null,
102
+ props.children,
103
+ help && !(error == null ? void 0 : error.message) ? /* @__PURE__ */ jsx2(Field.HelperText, { children: help }) : null,
104
+ (error == null ? void 0 : error.message) && /* @__PURE__ */ jsx2(Field.ErrorText, { children: error == null ? void 0 : error.message })
101
105
  ] });
102
106
  };
103
107
  BaseField.displayName = "BaseField";
@@ -123,37 +127,34 @@ import { jsx as jsx4 } from "react/jsx-runtime";
123
127
  var _createField = (InputComponent, { displayName, hideLabel, getBaseField: getBaseFieldProp }) => {
124
128
  const Field3 = forwardRef((props, ref) => {
125
129
  var _a;
126
- const { id, name, label, isRequired, rules } = props;
130
+ const { id, label, required, rules } = props;
127
131
  const inputRules = {
128
- required: isRequired,
132
+ required,
129
133
  ...rules
130
134
  };
131
135
  const fieldContext = useFieldsContext();
132
136
  const getBaseField = (_a = fieldContext == null ? void 0 : fieldContext.getBaseField) != null ? _a : getBaseFieldProp;
133
- const { extraProps, BaseField: BaseField2 } = React3.useMemo(
137
+ const { props: extraProps, Component } = React3.useMemo(
134
138
  () => getBaseField(),
135
139
  [getBaseField]
136
140
  );
137
- const [, inputProps] = splitProps2(
141
+ const rootProps = {
142
+ name: props.name,
143
+ label: props.label,
144
+ disabled: props.disabled,
145
+ invalid: props.invalid,
146
+ readOnly: props.readOnly,
147
+ required: props.required
148
+ };
149
+ const [baseFieldProps, inputProps] = splitProps2(
138
150
  props,
139
- [
140
- "children",
141
- "name",
142
- "label",
143
- "required",
144
- "disabled",
145
- "invalid",
146
- "readOnly",
147
- "help",
148
- "hideLabel"
149
- ].concat(extraProps)
151
+ ["orientation", "help", "hideLabel"].concat(extraProps)
150
152
  );
151
- return /* @__PURE__ */ jsx4(BaseField2, { name, hideLabel, ...props, children: /* @__PURE__ */ jsx4(
153
+ return /* @__PURE__ */ jsx4(Component, { ...rootProps, ...baseFieldProps, children: /* @__PURE__ */ jsx4(
152
154
  InputComponent,
153
155
  {
154
156
  ref,
155
157
  id,
156
- name,
157
158
  label: hideLabel ? label : void 0,
158
159
  ...inputProps,
159
160
  rules: inputRules
@@ -219,8 +220,8 @@ var createField = (component, options) => {
219
220
  displayName: `${(_a = component.displayName) != null ? _a : "Custom"}Field`,
220
221
  hideLabel: options == null ? void 0 : options.hideLabel,
221
222
  getBaseField: () => ({
222
- extraProps: [],
223
- BaseField
223
+ props: [],
224
+ Component: BaseField
224
225
  })
225
226
  });
226
227
  return Field3;
@@ -230,7 +231,15 @@ var createField = (component, options) => {
230
231
  import { jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
231
232
  var InputField = createField(
232
233
  ({ type = "text", startElement, endElement, size, ...rest }, ref) => {
233
- return /* @__PURE__ */ jsx5(InputGroup, { startElement, endElement, children: /* @__PURE__ */ jsx5(Input, { type, size, ...rest, ref }) });
234
+ return /* @__PURE__ */ jsx5(
235
+ InputGroup,
236
+ {
237
+ startElement,
238
+ endElement,
239
+ width: "full",
240
+ children: /* @__PURE__ */ jsx5(Input, { type, size, ...rest, ref })
241
+ }
242
+ );
234
243
  }
235
244
  );
236
245
  var NumberInputField = createField((props, ref) => /* @__PURE__ */ jsx5(NumberInput, { ...props, ref }), {
@@ -254,22 +263,28 @@ var SelectField = createField(
254
263
  options,
255
264
  placeholder,
256
265
  onChange,
257
- onValueChange,
258
266
  onBlur,
267
+ multiple = false,
268
+ value: valueProp,
259
269
  ...rest
260
270
  } = props;
261
- const collection = createListCollection({
262
- items: options
263
- });
271
+ const collection = useMemo(
272
+ () => createListCollection({
273
+ items: options
274
+ }),
275
+ [options]
276
+ );
277
+ const value = multiple ? [...valueProp != null ? valueProp : []] : valueProp ? [valueProp] : [];
264
278
  return /* @__PURE__ */ jsxs2(
265
279
  Select.Root,
266
280
  {
267
281
  ref,
268
282
  collection,
269
283
  onValueChange: (details) => {
270
- onChange(details.value);
284
+ onChange(multiple ? details.value : details.value[0]);
271
285
  },
272
286
  onInteractOutside: () => onBlur(),
287
+ value,
273
288
  ...rest,
274
289
  children: [
275
290
  /* @__PURE__ */ jsx5(Select.Trigger, { ...triggerProps, children: /* @__PURE__ */ jsx5(Select.ValueText, { placeholder }) }),
@@ -376,7 +391,7 @@ var objectFieldResolver = (schema) => {
376
391
  };
377
392
 
378
393
  // src/form.tsx
379
- import React10, { forwardRef as forwardRef6 } from "react";
394
+ import React11, { forwardRef as forwardRef6 } from "react";
380
395
  import { chakra as chakra2 } from "@chakra-ui/react";
381
396
  import { cx as cx2, runIfFn } from "@saas-ui/core/utils";
382
397
  import {
@@ -384,7 +399,7 @@ import {
384
399
  } from "react-hook-form";
385
400
 
386
401
  // src/array-field.tsx
387
- import React6, { forwardRef as forwardRef3 } from "react";
402
+ import React7, { forwardRef as forwardRef3 } from "react";
388
403
  import { Button, chakra } from "@chakra-ui/react";
389
404
  import { MinusIcon, PlusIcon } from "@saas-ui/react/icons";
390
405
 
@@ -397,9 +412,9 @@ import {
397
412
  import { cx } from "@saas-ui/core/utils";
398
413
  import { jsx as jsx6 } from "react/jsx-runtime";
399
414
  var FormLayout = forwardRef2(
400
- ({ children, rowGap = 4, ...props }, ref) => {
415
+ ({ children, gap = 4, ...props }, ref) => {
401
416
  const recipe = useRecipe({
402
- key: "formLayout"
417
+ key: "suiFormLayout"
403
418
  });
404
419
  const [variantProps, gridProps] = recipe.splitVariantProps(props);
405
420
  const styles = recipe(variantProps);
@@ -411,7 +426,7 @@ var FormLayout = forwardRef2(
411
426
  className: cx("sui-form-layout", props.className),
412
427
  css: [
413
428
  {
414
- rowGap
429
+ gap
415
430
  },
416
431
  styles,
417
432
  props.css
@@ -424,7 +439,7 @@ var FormLayout = forwardRef2(
424
439
  FormLayout.displayName = "FormLayout";
425
440
 
426
441
  // src/use-array-field.tsx
427
- import * as React4 from "react";
442
+ import * as React5 from "react";
428
443
  import { createContext as createContext2 } from "@saas-ui/core/utils";
429
444
  import {
430
445
  useFieldArray
@@ -459,7 +474,7 @@ var useArrayField = ({
459
474
  var useArrayFieldRow = ({ index }) => {
460
475
  const { clearErrors } = useFormContext();
461
476
  const { name, remove, fields } = useArrayFieldContext();
462
- React4.useEffect(() => {
477
+ React5.useEffect(() => {
463
478
  clearErrors(name);
464
479
  }, []);
465
480
  return {
@@ -467,7 +482,7 @@ var useArrayFieldRow = ({ index }) => {
467
482
  isFirst: index === 0,
468
483
  isLast: index === fields.length - 1,
469
484
  name: `${name}.${index}`,
470
- remove: React4.useCallback(() => {
485
+ remove: React5.useCallback(() => {
471
486
  clearErrors(name);
472
487
  remove(index);
473
488
  }, [index])
@@ -494,17 +509,17 @@ var useArrayFieldAddButton = () => {
494
509
  };
495
510
 
496
511
  // src/utils.ts
497
- import * as React5 from "react";
512
+ import * as React6 from "react";
498
513
  var mapNestedFields = (name, children) => {
499
- return React5.Children.map(children, (child) => {
500
- if (React5.isValidElement(child) && child.props.name) {
514
+ return React6.Children.map(children, (child) => {
515
+ if (React6.isValidElement(child) && child.props.name) {
501
516
  let childName = child.props.name;
502
517
  if (childName.includes(".")) {
503
518
  childName = childName.replace(/^.*\.(.*)/, "$1");
504
519
  } else if (childName.includes(".$")) {
505
520
  childName = childName.replace(/^.*\.\$(.*)/, "$1");
506
521
  }
507
- return React5.cloneElement(child, {
522
+ return React6.cloneElement(child, {
508
523
  ...child.props,
509
524
  name: `${name}.${childName}`
510
525
  });
@@ -585,7 +600,7 @@ var ArrayFieldRows = ({
585
600
  return children(fields);
586
601
  };
587
602
  ArrayFieldRows.displayName = "ArrayFieldRows";
588
- var ArrayFieldContainer = React6.forwardRef(
603
+ var ArrayFieldContainer = React7.forwardRef(
589
604
  ({
590
605
  name,
591
606
  defaultValue,
@@ -603,14 +618,14 @@ var ArrayFieldContainer = React6.forwardRef(
603
618
  min: min || (overrides == null ? void 0 : overrides.min),
604
619
  max: max || (overrides == null ? void 0 : overrides.max)
605
620
  });
606
- React6.useImperativeHandle(ref, () => context, [ref, context]);
621
+ React7.useImperativeHandle(ref, () => context, [ref, context]);
607
622
  return /* @__PURE__ */ jsx7(ArrayFieldProvider, { value: context, children: /* @__PURE__ */ jsx7(BaseField, { name, ...fieldProps, ...overrides, children }) });
608
623
  }
609
624
  );
610
625
  ArrayFieldContainer.displayName = "ArrayFieldContainer";
611
626
 
612
627
  // src/display-if.tsx
613
- import * as React7 from "react";
628
+ import * as React8 from "react";
614
629
  import {
615
630
  useWatch
616
631
  } from "react-hook-form";
@@ -623,8 +638,8 @@ var DisplayIf = ({
623
638
  condition = (value) => !!value,
624
639
  onToggle
625
640
  }) => {
626
- const initializedRef = React7.useRef(false);
627
- const matchesRef = React7.useRef(false);
641
+ const initializedRef = React8.useRef(false);
642
+ const matchesRef = React8.useRef(false);
628
643
  const value = useWatch({
629
644
  name,
630
645
  defaultValue,
@@ -633,7 +648,7 @@ var DisplayIf = ({
633
648
  });
634
649
  const context = useFormContext();
635
650
  const matches = condition(value, context);
636
- React7.useEffect(() => {
651
+ React8.useEffect(() => {
637
652
  if (!initializedRef.current) {
638
653
  initializedRef.current = true;
639
654
  return;
@@ -647,10 +662,10 @@ var DisplayIf = ({
647
662
  DisplayIf.displayName = "DisplayIf";
648
663
 
649
664
  // src/field.tsx
650
- import * as React8 from "react";
665
+ import * as React9 from "react";
651
666
  import { jsx as jsx8 } from "react/jsx-runtime";
652
667
  var defaultInputType = "text";
653
- var Field2 = React8.forwardRef(
668
+ var Field2 = React9.forwardRef(
654
669
  (props, ref) => {
655
670
  const { type = defaultInputType, name } = props;
656
671
  const overrides = useFieldProps(name);
@@ -660,7 +675,7 @@ var Field2 = React8.forwardRef(
660
675
  );
661
676
 
662
677
  // src/fields.tsx
663
- import * as React9 from "react";
678
+ import * as React10 from "react";
664
679
 
665
680
  // src/object-field.tsx
666
681
  import { Field as FieldPrimivite } from "@chakra-ui/react";
@@ -713,10 +728,10 @@ var AutoFields = ({
713
728
  const context = useFormContext();
714
729
  const schema = schemaProp || context.schema;
715
730
  const fieldResolver = fieldResolverProp || context.fieldResolver;
716
- const resolver = React9.useMemo(() => fieldResolver, [schema, fieldResolver]);
717
- const fields = React9.useMemo(() => resolver == null ? void 0 : resolver.getFields(), [resolver]);
731
+ const resolver = React10.useMemo(() => fieldResolver, [schema, fieldResolver]);
732
+ const fields = React10.useMemo(() => resolver == null ? void 0 : resolver.getFields(), [resolver]);
718
733
  const form = useFormContext();
719
- React9.useEffect(() => {
734
+ React10.useEffect(() => {
720
735
  var _a;
721
736
  if (focusFirstField && ((_a = fields == null ? void 0 : fields[0]) == null ? void 0 : _a.name)) {
722
737
  form.setFocus(fields[0].name);
@@ -834,8 +849,8 @@ var Form = forwardRef6(
834
849
  };
835
850
  const methods = useForm(form);
836
851
  const { handleSubmit } = methods;
837
- React10.useImperativeHandle(formRef, () => methods, [formRef, methods]);
838
- React10.useEffect(() => {
852
+ React11.useImperativeHandle(formRef, () => methods, [formRef, methods]);
853
+ React11.useEffect(() => {
839
854
  let subscription;
840
855
  if (onChange) {
841
856
  subscription = methods.watch(onChange);
@@ -894,7 +909,7 @@ function createForm({
894
909
  fieldResolver: fieldResolverProp,
895
910
  ...rest
896
911
  } = props;
897
- const fieldsContext = useMemo2(
912
+ const fieldsContext = useMemo3(
898
913
  () => ({
899
914
  fields: { ...defaultFieldTypes, ...fields },
900
915
  getBaseField
@@ -917,17 +932,65 @@ function createForm({
917
932
  return DefaultForm;
918
933
  }
919
934
 
935
+ // src/use-form.tsx
936
+ import { forwardRef as forwardRef8 } from "react";
937
+ import { chakra as chakra3 } from "@chakra-ui/react";
938
+ import { zodResolver } from "@hookform/resolvers/zod";
939
+ import { cx as cx3 } from "@saas-ui/core/utils";
940
+ import {
941
+ useForm as useHookForm
942
+ } from "react-hook-form";
943
+ import { jsx as jsx14 } from "react/jsx-runtime";
944
+ function useForm2(props = {}) {
945
+ const form = useHookForm(props);
946
+ const FormComponent = forwardRef8(
947
+ function FormComponent2(props2, ref) {
948
+ return /* @__PURE__ */ jsx14(Form2, { ...props2, form, ref });
949
+ }
950
+ );
951
+ return {
952
+ ...form,
953
+ Form: FormComponent,
954
+ Field: Field2,
955
+ DisplayIf,
956
+ ArrayField,
957
+ ObjectField
958
+ };
959
+ }
960
+ var Form2 = forwardRef8(
961
+ function Form3(props, ref) {
962
+ const { children, form, onSubmit, onError, ...rest } = props;
963
+ return /* @__PURE__ */ jsx14(FormProvider, { ...form, children: /* @__PURE__ */ jsx14(
964
+ chakra3.form,
965
+ {
966
+ ref,
967
+ onSubmit: form.handleSubmit(onSubmit, onError),
968
+ ...rest,
969
+ className: cx3("sui-form", props.className),
970
+ children: props.children
971
+ }
972
+ ) });
973
+ }
974
+ );
975
+ function useZodForm(props) {
976
+ const { schema, ...rest } = props;
977
+ return useForm2({
978
+ resolver: zodResolver(schema),
979
+ ...rest
980
+ });
981
+ }
982
+
920
983
  // src/display-field.tsx
921
984
  import { Field as FieldPrimivite2, Text } from "@chakra-ui/react";
922
- import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
985
+ import { jsx as jsx15, jsxs as jsxs6 } from "react/jsx-runtime";
923
986
  var DisplayField = ({
924
987
  name,
925
988
  label,
926
989
  ...props
927
990
  }) => {
928
991
  return /* @__PURE__ */ jsxs6(FieldPrimivite2.Root, { ...props, children: [
929
- label ? /* @__PURE__ */ jsx14(FieldPrimivite2.Label, { htmlFor: name, children: label }) : null,
930
- /* @__PURE__ */ jsx14(Text, { fontSize: "md", children: /* @__PURE__ */ jsx14(FormValue, { name }) })
992
+ label ? /* @__PURE__ */ jsx15(FieldPrimivite2.Label, { htmlFor: name, children: label }) : null,
993
+ /* @__PURE__ */ jsx15(Text, { fontSize: "md", children: /* @__PURE__ */ jsx15(FormValue, { name }) })
931
994
  ] });
932
995
  };
933
996
  DisplayField.displayName = "DisplayField";
@@ -956,12 +1019,11 @@ import {
956
1019
  appendErrors,
957
1020
  useController,
958
1021
  useFieldArray as useFieldArray2,
959
- useForm as useForm2,
960
1022
  useFormState,
961
1023
  useWatch as useWatch3,
962
1024
  Controller as Controller2
963
1025
  } from "react-hook-form";
964
- var Form2 = createForm();
1026
+ var Form4 = createForm();
965
1027
  export {
966
1028
  ArrayField,
967
1029
  ArrayFieldAddButton,
@@ -981,7 +1043,7 @@ export {
981
1043
  DisplayIf,
982
1044
  Field2 as Field,
983
1045
  FieldsProvider,
984
- Form2 as Form,
1046
+ Form4 as Form,
985
1047
  FormLayout,
986
1048
  FormLegend,
987
1049
  FormProvider,
@@ -1009,6 +1071,7 @@ export {
1009
1071
  useForm2 as useForm,
1010
1072
  useFormContext,
1011
1073
  useFormState,
1012
- useWatch3 as useWatch
1074
+ useWatch3 as useWatch,
1075
+ useZodForm
1013
1076
  };
1014
1077
  //# sourceMappingURL=index.mjs.map