@ultraviolet/form 2.13.3 → 2.13.5

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.
Files changed (60) hide show
  1. package/dist/components/CheckboxField/index.cjs +53 -0
  2. package/dist/components/CheckboxField/index.js +15 -32
  3. package/dist/components/CheckboxGroupField/index.cjs +75 -0
  4. package/dist/components/CheckboxGroupField/index.js +31 -48
  5. package/dist/components/DateField/index.cjs +74 -0
  6. package/dist/components/DateField/index.js +27 -42
  7. package/dist/components/Form/defaultErrors.cjs +22 -0
  8. package/dist/components/Form/index.cjs +72 -0
  9. package/dist/components/Form/index.js +25 -33
  10. package/dist/components/KeyValueField/index.cjs +51 -0
  11. package/dist/components/KeyValueField/index.js +14 -48
  12. package/dist/components/NumberInputField/index.cjs +56 -0
  13. package/dist/components/NumberInputField/index.js +17 -32
  14. package/dist/components/NumberInputFieldV2/index.cjs +63 -0
  15. package/dist/components/NumberInputFieldV2/index.js +17 -37
  16. package/dist/components/RadioField/index.cjs +49 -0
  17. package/dist/components/RadioField/index.js +15 -27
  18. package/dist/components/RadioGroupField/index.cjs +45 -0
  19. package/dist/components/RadioGroupField/index.js +12 -22
  20. package/dist/components/SelectInputField/index.cjs +102 -0
  21. package/dist/components/SelectInputField/index.js +41 -78
  22. package/dist/components/SelectInputFieldV2/index.cjs +70 -0
  23. package/dist/components/SelectInputFieldV2/index.js +16 -50
  24. package/dist/components/SelectableCardField/index.cjs +58 -0
  25. package/dist/components/SelectableCardField/index.js +20 -42
  26. package/dist/components/SelectableCardGroupField/index.cjs +56 -0
  27. package/dist/components/SelectableCardGroupField/index.js +20 -34
  28. package/dist/components/Submit/index.cjs +26 -0
  29. package/dist/components/Submit/index.js +5 -19
  30. package/dist/components/SubmitErrorAlert/index.cjs +14 -0
  31. package/dist/components/SubmitErrorAlert/index.js +6 -2
  32. package/dist/components/TagInputField/index.cjs +50 -0
  33. package/dist/components/TagInputField/index.js +12 -27
  34. package/dist/components/TextAreaField/index.cjs +70 -0
  35. package/dist/components/TextAreaField/index.js +22 -50
  36. package/dist/components/TextInputField/index.cjs +114 -0
  37. package/dist/components/TextInputField/index.js +31 -71
  38. package/dist/components/TextInputFieldV2/index.cjs +79 -0
  39. package/dist/components/TextInputFieldV2/index.js +22 -59
  40. package/dist/components/TimeField/index.cjs +66 -0
  41. package/dist/components/TimeField/index.js +17 -42
  42. package/dist/components/ToggleField/index.cjs +47 -0
  43. package/dist/components/ToggleField/index.js +10 -24
  44. package/dist/constants.cjs +4 -0
  45. package/dist/hooks/useField.cjs +30 -0
  46. package/dist/hooks/useField.js +10 -3
  47. package/dist/hooks/useFieldArray.cjs +32 -0
  48. package/dist/hooks/useFieldArray.js +13 -3
  49. package/dist/hooks/useForm.cjs +24 -0
  50. package/dist/hooks/useForm.js +6 -1
  51. package/dist/hooks/useFormState.cjs +22 -0
  52. package/dist/hooks/useFormState.js +3 -1
  53. package/dist/hooks/useOnFieldChange.cjs +21 -0
  54. package/dist/hooks/useOnFieldChange.js +5 -4
  55. package/dist/index.cjs +84 -0
  56. package/dist/providers/ErrorContext/index.cjs +33 -0
  57. package/dist/providers/ErrorContext/index.js +17 -20
  58. package/dist/validators/maxDate.cjs +4 -0
  59. package/dist/validators/minDate.cjs +4 -0
  60. package/package.json +20 -4
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
4
+ const ui = require("@ultraviolet/ui");
5
+ const reactHookForm = require("react-hook-form");
6
+ const index = require("../../providers/ErrorContext/index.cjs");
7
+ const CheckboxField = ({
8
+ id,
9
+ name,
10
+ label,
11
+ size,
12
+ progress,
13
+ disabled,
14
+ required,
15
+ className,
16
+ children,
17
+ onChange,
18
+ onBlur,
19
+ onFocus,
20
+ rules,
21
+ helper,
22
+ tooltip,
23
+ "data-testid": dataTestId,
24
+ shouldUnregister = false
25
+ }) => {
26
+ const {
27
+ getError
28
+ } = index.useErrors();
29
+ const {
30
+ field,
31
+ fieldState: {
32
+ error
33
+ }
34
+ } = reactHookForm.useController({
35
+ name,
36
+ disabled,
37
+ shouldUnregister,
38
+ rules: {
39
+ required,
40
+ ...rules
41
+ }
42
+ });
43
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.Checkbox, { id, name: field.name, onChange: (event) => {
44
+ field.onChange(event.target.checked);
45
+ onChange?.(event.target.checked);
46
+ }, onBlur: (event) => {
47
+ field.onBlur();
48
+ onBlur?.(event);
49
+ }, onFocus, size, progress, disabled: field.disabled, checked: !!field.value, error: getError({
50
+ label: label ?? ""
51
+ }, error), ref: field.ref, className, required, "data-testid": dataTestId, helper, tooltip, children });
52
+ };
53
+ exports.CheckboxField = CheckboxField;
@@ -21,10 +21,14 @@ const CheckboxField = ({
21
21
  "data-testid": dataTestId,
22
22
  shouldUnregister = false
23
23
  }) => {
24
- const { getError } = useErrors();
24
+ const {
25
+ getError
26
+ } = useErrors();
25
27
  const {
26
28
  field,
27
- fieldState: { error }
29
+ fieldState: {
30
+ error
31
+ }
28
32
  } = useController({
29
33
  name,
30
34
  disabled,
@@ -34,36 +38,15 @@ const CheckboxField = ({
34
38
  ...rules
35
39
  }
36
40
  });
37
- return /* @__PURE__ */ jsx(
38
- Checkbox,
39
- {
40
- id,
41
- name: field.name,
42
- onChange: (event) => {
43
- field.onChange(event.target.checked);
44
- onChange?.(
45
- event.target.checked
46
- );
47
- },
48
- onBlur: (event) => {
49
- field.onBlur();
50
- onBlur?.(event);
51
- },
52
- onFocus,
53
- size,
54
- progress,
55
- disabled: field.disabled,
56
- checked: !!field.value,
57
- error: getError({ label: label ?? "" }, error),
58
- ref: field.ref,
59
- className,
60
- required,
61
- "data-testid": dataTestId,
62
- helper,
63
- tooltip,
64
- children
65
- }
66
- );
41
+ return /* @__PURE__ */ jsx(Checkbox, { id, name: field.name, onChange: (event) => {
42
+ field.onChange(event.target.checked);
43
+ onChange?.(event.target.checked);
44
+ }, onBlur: (event) => {
45
+ field.onBlur();
46
+ onBlur?.(event);
47
+ }, onFocus, size, progress, disabled: field.disabled, checked: !!field.value, error: getError({
48
+ label: label ?? ""
49
+ }, error), ref: field.ref, className, required, "data-testid": dataTestId, helper, tooltip, children });
67
50
  };
68
51
  export {
69
52
  CheckboxField
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
4
+ const ui = require("@ultraviolet/ui");
5
+ const React = require("react");
6
+ const reactHookForm = require("react-hook-form");
7
+ const index = require("../../providers/ErrorContext/index.cjs");
8
+ const arraysContainSameValues = (array1, array2) => {
9
+ if (array1.length === 0) {
10
+ return false;
11
+ }
12
+ return array2.every((value) => array1.includes(value));
13
+ };
14
+ const CheckboxGroupField = ({
15
+ legend,
16
+ className,
17
+ helper,
18
+ direction,
19
+ children,
20
+ onChange,
21
+ label = "",
22
+ error: customError,
23
+ name,
24
+ required = false,
25
+ shouldUnregister = false,
26
+ rules
27
+ }) => {
28
+ const {
29
+ getError
30
+ } = index.useErrors();
31
+ const validate = React.useCallback((value) => {
32
+ const requiredChildren = React.Children.map(children, (child) => {
33
+ if (React.isValidElement(child)) {
34
+ if (child.props.required) {
35
+ return child.props.name;
36
+ }
37
+ return null;
38
+ }
39
+ return null;
40
+ })?.filter(Boolean) ?? [];
41
+ if (!required && arraysContainSameValues(value, requiredChildren)) {
42
+ return true;
43
+ }
44
+ if (value.length >= React.Children.count(children)) {
45
+ return true;
46
+ }
47
+ return false;
48
+ }, [children, required]);
49
+ const {
50
+ field,
51
+ fieldState: {
52
+ error
53
+ }
54
+ } = reactHookForm.useController({
55
+ name,
56
+ shouldUnregister,
57
+ rules: {
58
+ validate,
59
+ ...rules
60
+ }
61
+ });
62
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.CheckboxGroup, { legend, name, value: field.value, onChange: (event) => {
63
+ const fieldValue = field.value;
64
+ if (fieldValue?.includes(event.currentTarget.value)) {
65
+ field.onChange(fieldValue?.filter((currentValue) => currentValue !== event.currentTarget.value));
66
+ } else {
67
+ field.onChange([...field.value, event.currentTarget.value]);
68
+ }
69
+ onChange?.(event.currentTarget.value);
70
+ }, error: getError({
71
+ label
72
+ }, error) ?? customError, className, direction, helper, required, children });
73
+ };
74
+ CheckboxGroupField.Checkbox = ui.CheckboxGroup.Checkbox;
75
+ exports.CheckboxGroupField = CheckboxGroupField;
@@ -23,31 +23,32 @@ const CheckboxGroupField = ({
23
23
  shouldUnregister = false,
24
24
  rules
25
25
  }) => {
26
- const { getError } = useErrors();
27
- const validate = useCallback(
28
- (value) => {
29
- const requiredChildren = Children.map(children, (child) => {
30
- if (isValidElement(child)) {
31
- if (child.props.required) {
32
- return child.props.name;
33
- }
34
- return null;
26
+ const {
27
+ getError
28
+ } = useErrors();
29
+ const validate = useCallback((value) => {
30
+ const requiredChildren = Children.map(children, (child) => {
31
+ if (isValidElement(child)) {
32
+ if (child.props.required) {
33
+ return child.props.name;
35
34
  }
36
35
  return null;
37
- })?.filter(Boolean) ?? [];
38
- if (!required && arraysContainSameValues(value, requiredChildren)) {
39
- return true;
40
- }
41
- if (value.length >= Children.count(children)) {
42
- return true;
43
36
  }
44
- return false;
45
- },
46
- [children, required]
47
- );
37
+ return null;
38
+ })?.filter(Boolean) ?? [];
39
+ if (!required && arraysContainSameValues(value, requiredChildren)) {
40
+ return true;
41
+ }
42
+ if (value.length >= Children.count(children)) {
43
+ return true;
44
+ }
45
+ return false;
46
+ }, [children, required]);
48
47
  const {
49
48
  field,
50
- fieldState: { error }
49
+ fieldState: {
50
+ error
51
+ }
51
52
  } = useController({
52
53
  name,
53
54
  shouldUnregister,
@@ -56,35 +57,17 @@ const CheckboxGroupField = ({
56
57
  ...rules
57
58
  }
58
59
  });
59
- return /* @__PURE__ */ jsx(
60
- CheckboxGroup,
61
- {
62
- legend,
63
- name,
64
- value: field.value,
65
- onChange: (event) => {
66
- const fieldValue = field.value;
67
- if (fieldValue?.includes(event.currentTarget.value)) {
68
- field.onChange(
69
- fieldValue?.filter(
70
- (currentValue) => currentValue !== event.currentTarget.value
71
- )
72
- );
73
- } else {
74
- field.onChange([...field.value, event.currentTarget.value]);
75
- }
76
- onChange?.(
77
- event.currentTarget.value
78
- );
79
- },
80
- error: getError({ label }, error) ?? customError,
81
- className,
82
- direction,
83
- helper,
84
- required,
85
- children
60
+ return /* @__PURE__ */ jsx(CheckboxGroup, { legend, name, value: field.value, onChange: (event) => {
61
+ const fieldValue = field.value;
62
+ if (fieldValue?.includes(event.currentTarget.value)) {
63
+ field.onChange(fieldValue?.filter((currentValue) => currentValue !== event.currentTarget.value));
64
+ } else {
65
+ field.onChange([...field.value, event.currentTarget.value]);
86
66
  }
87
- );
67
+ onChange?.(event.currentTarget.value);
68
+ }, error: getError({
69
+ label
70
+ }, error) ?? customError, className, direction, helper, required, children });
88
71
  };
89
72
  CheckboxGroupField.Checkbox = CheckboxGroup.Checkbox;
90
73
  export {
@@ -0,0 +1,74 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
4
+ const ui = require("@ultraviolet/ui");
5
+ const reactHookForm = require("react-hook-form");
6
+ const maxDate = require("../../validators/maxDate.cjs");
7
+ const minDate = require("../../validators/minDate.cjs");
8
+ const index = require("../../providers/ErrorContext/index.cjs");
9
+ const parseDate = (value) => typeof value === "string" ? new Date(value) : value;
10
+ const isEmpty = (value) => typeof value === "string" ? value === "" : value === void 0;
11
+ const DateField = ({
12
+ required,
13
+ name,
14
+ label = "",
15
+ format,
16
+ locale,
17
+ maxDate: maxDate$1,
18
+ minDate: minDate$1,
19
+ disabled,
20
+ onChange,
21
+ onBlur,
22
+ onFocus,
23
+ rules,
24
+ autoFocus = false,
25
+ excludeDates,
26
+ selectsRange,
27
+ "data-testid": dataTestId,
28
+ shouldUnregister = false
29
+ }) => {
30
+ const {
31
+ getError
32
+ } = index.useErrors();
33
+ const {
34
+ field,
35
+ fieldState: {
36
+ error
37
+ }
38
+ } = reactHookForm.useController({
39
+ name,
40
+ shouldUnregister,
41
+ rules: {
42
+ ...rules,
43
+ validate: {
44
+ ...rules?.validate,
45
+ minDate: minDate.minDateValidator(minDate$1),
46
+ maxDate: maxDate.maxDateValidator(maxDate$1)
47
+ },
48
+ required
49
+ }
50
+ });
51
+ return /* @__PURE__ */ jsxRuntime.jsx(ui.DateInput, { name: field.name, label, value: field.value, format: format || ((value) => value ? parseDate(value).toLocaleDateString() : ""), locale, required, onChange: (val) => {
52
+ if (val && val instanceof Date) {
53
+ onChange?.(val);
54
+ const newDate = parseDate(val);
55
+ if (isEmpty(field.value)) {
56
+ field.onChange(newDate);
57
+ return;
58
+ }
59
+ const currentDate = parseDate(field.value);
60
+ newDate.setHours(currentDate.getHours(), currentDate.getMinutes());
61
+ field.onChange(newDate);
62
+ } else if (Array.isArray(val)) {
63
+ field.onChange(val);
64
+ }
65
+ }, onBlur: (e) => {
66
+ field.onBlur();
67
+ onBlur?.(e);
68
+ }, onFocus, maxDate: maxDate$1, minDate: minDate$1, error: getError({
69
+ minDate: minDate$1,
70
+ maxDate: maxDate$1,
71
+ label
72
+ }, error), disabled, autoFocus, excludeDates, selectsRange, "data-testid": dataTestId, startDate: selectsRange && Array.isArray(field.value) ? field.value[0] : void 0, endDate: selectsRange && Array.isArray(field.value) ? field.value[1] : void 0 });
73
+ };
74
+ exports.DateField = DateField;
@@ -25,10 +25,14 @@ const DateField = ({
25
25
  "data-testid": dataTestId,
26
26
  shouldUnregister = false
27
27
  }) => {
28
- const { getError } = useErrors();
28
+ const {
29
+ getError
30
+ } = useErrors();
29
31
  const {
30
32
  field,
31
- fieldState: { error }
33
+ fieldState: {
34
+ error
35
+ }
32
36
  } = useController({
33
37
  name,
34
38
  shouldUnregister,
@@ -42,47 +46,28 @@ const DateField = ({
42
46
  required
43
47
  }
44
48
  });
45
- return /* @__PURE__ */ jsx(
46
- DateInput,
47
- {
48
- name: field.name,
49
- label,
50
- value: field.value,
51
- format: format || ((value) => value ? parseDate(value).toLocaleDateString() : ""),
52
- locale,
53
- required,
54
- onChange: (val) => {
55
- if (val && val instanceof Date) {
56
- onChange?.(val);
57
- const newDate = parseDate(val);
58
- if (isEmpty(field.value)) {
59
- field.onChange(newDate);
60
- return;
61
- }
62
- const currentDate = parseDate(field.value);
63
- newDate.setHours(currentDate.getHours(), currentDate.getMinutes());
64
- field.onChange(newDate);
65
- } else if (Array.isArray(val)) {
66
- field.onChange(val);
67
- }
68
- },
69
- onBlur: (e) => {
70
- field.onBlur();
71
- onBlur?.(e);
72
- },
73
- onFocus,
74
- maxDate,
75
- minDate,
76
- error: getError({ minDate, maxDate, label }, error),
77
- disabled,
78
- autoFocus,
79
- excludeDates,
80
- selectsRange,
81
- "data-testid": dataTestId,
82
- startDate: selectsRange && Array.isArray(field.value) ? field.value[0] : void 0,
83
- endDate: selectsRange && Array.isArray(field.value) ? field.value[1] : void 0
49
+ return /* @__PURE__ */ jsx(DateInput, { name: field.name, label, value: field.value, format: format || ((value) => value ? parseDate(value).toLocaleDateString() : ""), locale, required, onChange: (val) => {
50
+ if (val && val instanceof Date) {
51
+ onChange?.(val);
52
+ const newDate = parseDate(val);
53
+ if (isEmpty(field.value)) {
54
+ field.onChange(newDate);
55
+ return;
56
+ }
57
+ const currentDate = parseDate(field.value);
58
+ newDate.setHours(currentDate.getHours(), currentDate.getMinutes());
59
+ field.onChange(newDate);
60
+ } else if (Array.isArray(val)) {
61
+ field.onChange(val);
84
62
  }
85
- );
63
+ }, onBlur: (e) => {
64
+ field.onBlur();
65
+ onBlur?.(e);
66
+ }, onFocus, maxDate, minDate, error: getError({
67
+ minDate,
68
+ maxDate,
69
+ label
70
+ }, error), disabled, autoFocus, excludeDates, selectsRange, "data-testid": dataTestId, startDate: selectsRange && Array.isArray(field.value) ? field.value[0] : void 0, endDate: selectsRange && Array.isArray(field.value) ? field.value[1] : void 0 });
86
71
  };
87
72
  export {
88
73
  DateField
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const defaultErrors = {
4
+ maxDate: () => "",
5
+ maxLength: () => "",
6
+ minLength: () => "",
7
+ max: () => "",
8
+ min: () => "",
9
+ required: () => "",
10
+ pattern: () => "",
11
+ deps: () => "",
12
+ value: () => "",
13
+ onBlur: () => "",
14
+ disabled: () => "",
15
+ onChange: () => "",
16
+ validate: () => "",
17
+ setValueAs: () => "",
18
+ valueAsDate: () => "",
19
+ valueAsNumber: () => "",
20
+ shouldUnregister: () => ""
21
+ };
22
+ exports.defaultErrors = defaultErrors;
@@ -0,0 +1,72 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
4
+ const React = require("react");
5
+ const reactHookForm = require("react-hook-form");
6
+ const constants = require("../../constants.cjs");
7
+ const defaultErrors = require("./defaultErrors.cjs");
8
+ const index = require("../../providers/ErrorContext/index.cjs");
9
+ const _interopDefaultCompat = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
10
+ const React__default = /* @__PURE__ */ _interopDefaultCompat(React);
11
+ const FormSubmitContext = React__default.default.createContext({});
12
+ const Form = ({
13
+ children,
14
+ methods: methodsProp,
15
+ initialValues,
16
+ errors,
17
+ onRawSubmit,
18
+ name
19
+ }) => {
20
+ const methodsHook = reactHookForm.useForm({
21
+ defaultValues: initialValues,
22
+ mode: "onChange"
23
+ });
24
+ const methods = !methodsProp ? methodsHook : methodsProp;
25
+ const handleSubmit = methods.handleSubmit(async (values) => {
26
+ const result = await onRawSubmit(values, {
27
+ reset: methods.reset,
28
+ resetFieldState: methods.resetField,
29
+ restart: () => methods.reset(initialValues),
30
+ change: methods.setValue
31
+ });
32
+ if (result === null) {
33
+ methods.setError("root.submit", {
34
+ type: "custom"
35
+ });
36
+ return;
37
+ }
38
+ if (result && typeof result !== "boolean" && typeof result !== "number") {
39
+ methods.setError("root.submit", {
40
+ type: "custom",
41
+ message: typeof result === "object" ? result[constants.FORM_ERROR] : result
42
+ });
43
+ }
44
+ });
45
+ const formSubmitContextValue = React.useMemo(() => ({
46
+ handleSubmit
47
+ }), [handleSubmit]);
48
+ return /* @__PURE__ */ jsxRuntime.jsx(reactHookForm.FormProvider, { ...methods, children: /* @__PURE__ */ jsxRuntime.jsx(FormSubmitContext.Provider, { value: formSubmitContextValue, children: /* @__PURE__ */ jsxRuntime.jsx(index.ErrorProvider, { errors: {
49
+ ...defaultErrors.defaultErrors,
50
+ ...errors
51
+ }, children: /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: async (e) => {
52
+ e.preventDefault();
53
+ e.stopPropagation();
54
+ await handleSubmit(e);
55
+ }, name, noValidate: true, children: typeof children === "function" ? children({
56
+ values: methods.watch(),
57
+ hasValidationErrors: !methods.formState.isValid,
58
+ errors: methods.formState.errors,
59
+ submitting: methods.formState.isSubmitting,
60
+ pristine: !methods.formState.isDirty,
61
+ handleSubmit,
62
+ submitError: !!methods.formState.errors?.root?.["submit"],
63
+ valid: methods.formState.isValid,
64
+ form: {
65
+ change: methods.setValue,
66
+ reset: methods.reset,
67
+ submit: handleSubmit
68
+ }
69
+ }) : children }) }) }) });
70
+ };
71
+ exports.Form = Form;
72
+ exports.FormSubmitContext = FormSubmitContext;
@@ -4,9 +4,7 @@ import { useForm, FormProvider } from "react-hook-form";
4
4
  import { FORM_ERROR } from "../../constants.js";
5
5
  import { defaultErrors } from "./defaultErrors.js";
6
6
  import { ErrorProvider } from "../../providers/ErrorContext/index.js";
7
- const FormSubmitContext = React.createContext(
8
- {}
9
- );
7
+ const FormSubmitContext = React.createContext({});
10
8
  const Form = ({
11
9
  children,
12
10
  methods: methodsProp,
@@ -40,37 +38,31 @@ const Form = ({
40
38
  });
41
39
  }
42
40
  });
43
- const formSubmitContextValue = useMemo(
44
- () => ({ handleSubmit }),
45
- [handleSubmit]
46
- );
47
- return /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx(FormSubmitContext.Provider, { value: formSubmitContextValue, children: /* @__PURE__ */ jsx(ErrorProvider, { errors: { ...defaultErrors, ...errors }, children: /* @__PURE__ */ jsx(
48
- "form",
49
- {
50
- onSubmit: async (e) => {
51
- e.preventDefault();
52
- e.stopPropagation();
53
- await handleSubmit(e);
54
- },
55
- name,
56
- noValidate: true,
57
- children: typeof children === "function" ? children({
58
- values: methods.watch(),
59
- hasValidationErrors: !methods.formState.isValid,
60
- errors: methods.formState.errors,
61
- submitting: methods.formState.isSubmitting,
62
- pristine: !methods.formState.isDirty,
63
- handleSubmit,
64
- submitError: !!methods.formState.errors?.root?.["submit"],
65
- valid: methods.formState.isValid,
66
- form: {
67
- change: methods.setValue,
68
- reset: methods.reset,
69
- submit: handleSubmit
70
- }
71
- }) : children
41
+ const formSubmitContextValue = useMemo(() => ({
42
+ handleSubmit
43
+ }), [handleSubmit]);
44
+ return /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx(FormSubmitContext.Provider, { value: formSubmitContextValue, children: /* @__PURE__ */ jsx(ErrorProvider, { errors: {
45
+ ...defaultErrors,
46
+ ...errors
47
+ }, children: /* @__PURE__ */ jsx("form", { onSubmit: async (e) => {
48
+ e.preventDefault();
49
+ e.stopPropagation();
50
+ await handleSubmit(e);
51
+ }, name, noValidate: true, children: typeof children === "function" ? children({
52
+ values: methods.watch(),
53
+ hasValidationErrors: !methods.formState.isValid,
54
+ errors: methods.formState.errors,
55
+ submitting: methods.formState.isSubmitting,
56
+ pristine: !methods.formState.isDirty,
57
+ handleSubmit,
58
+ submitError: !!methods.formState.errors?.root?.["submit"],
59
+ valid: methods.formState.isValid,
60
+ form: {
61
+ change: methods.setValue,
62
+ reset: methods.reset,
63
+ submit: handleSubmit
72
64
  }
73
- ) }) }) });
65
+ }) : children }) }) }) });
74
66
  };
75
67
  export {
76
68
  Form,
@@ -0,0 +1,51 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("@emotion/react/jsx-runtime");
4
+ const ui = require("@ultraviolet/ui");
5
+ const reactHookForm = require("react-hook-form");
6
+ const index = require("../TextInputFieldV2/index.cjs");
7
+ const KeyValueField = ({
8
+ name,
9
+ inputKey,
10
+ inputValue,
11
+ addButton,
12
+ maxSize = 100,
13
+ readonly = false,
14
+ control
15
+ }) => {
16
+ const {
17
+ fields,
18
+ append,
19
+ remove
20
+ } = reactHookForm.useFieldArray({
21
+ name,
22
+ control
23
+ });
24
+ const canAdd = fields.length !== void 0 && fields.length < maxSize;
25
+ const maxSizeReachedTooltip = addButton.maxSizeReachedTooltip ?? `Cannot add more than ${maxSize} elements`;
26
+ return /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { gap: 3, children: [
27
+ fields.length ? /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { gap: 3, children: fields.map((field, index$1) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Row, { templateColumns: "1fr 1fr auto", gap: 2, alignItems: "end", children: [
28
+ /* @__PURE__ */ jsxRuntime.jsx(index.TextInputField, { readOnly: readonly, required: inputKey.required, name: `${name}.${index$1}.key`, label: inputKey.label, regex: inputKey.regex }),
29
+ /* @__PURE__ */ jsxRuntime.jsx(index.TextInputField, { readOnly: readonly, required: inputValue.required, name: `${name}.${index$1}.value`, label: inputValue.label, placeholder: inputValue.placeholder, type: inputValue.type, autoComplete: "off", regex: inputValue.regex }),
30
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { disabled: readonly, "data-testid": `remove-button-${index$1}`, icon: "delete", variant: "outlined", sentiment: "danger", size: "large", onClick: () => remove(index$1) })
31
+ ] }, field.id)) }) : null,
32
+ /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { direction: "row", justifyContent: "flex-start", children: /* @__PURE__ */ jsxRuntime.jsx(
33
+ ui.Button,
34
+ {
35
+ "data-testid": "add-button",
36
+ icon: "plus",
37
+ variant: "filled",
38
+ sentiment: "neutral",
39
+ fullWidth: addButton.fullWidth,
40
+ disabled: !canAdd || readonly,
41
+ tooltip: !canAdd ? maxSizeReachedTooltip : addButton.tooltip,
42
+ onClick: () => append({
43
+ key: "",
44
+ value: ""
45
+ }),
46
+ children: addButton.name
47
+ }
48
+ ) })
49
+ ] });
50
+ };
51
+ exports.KeyValueField = KeyValueField;