@ultraviolet/form 2.13.2 → 2.13.4
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/components/CheckboxField/index.d.ts +10 -0
- package/dist/components/CheckboxField/index.js +17 -35
- package/dist/components/CheckboxGroupField/index.d.ts +32 -0
- package/dist/components/CheckboxGroupField/index.js +24 -35
- package/dist/components/DateField/index.d.ts +16 -0
- package/dist/components/DateField/index.js +33 -53
- package/dist/components/Form/defaultErrors.d.ts +2 -0
- package/dist/components/Form/defaultErrors.js +20 -19
- package/dist/components/Form/index.d.ts +69 -0
- package/dist/components/Form/index.js +41 -54
- package/dist/components/KeyValueField/index.d.ts +33 -0
- package/dist/components/KeyValueField/index.js +23 -56
- package/dist/components/NumberInputField/index.d.ts +13 -0
- package/dist/components/NumberInputField/index.js +18 -39
- package/dist/components/NumberInputFieldV2/index.d.ts +11 -0
- package/dist/components/NumberInputFieldV2/index.js +20 -46
- package/dist/components/RadioField/index.d.ts +12 -0
- package/dist/components/RadioField/index.js +18 -36
- package/dist/components/RadioGroupField/index.d.ts +28 -0
- package/dist/components/RadioGroupField/index.js +15 -26
- package/dist/components/SelectInputField/index.d.ts +82 -0
- package/dist/components/SelectInputField/index.js +31 -61
- package/dist/components/SelectInputFieldV2/index.d.ts +7 -0
- package/dist/components/SelectInputFieldV2/index.js +18 -52
- package/dist/components/SelectableCardField/index.d.ts +9 -0
- package/dist/components/SelectableCardField/index.js +24 -41
- package/dist/components/SelectableCardGroupField/index.d.ts +42 -0
- package/dist/components/SelectableCardGroupField/index.js +22 -35
- package/dist/components/Submit/index.d.ts +17 -0
- package/dist/components/Submit/index.js +9 -23
- package/dist/components/SubmitErrorAlert/index.d.ts +3 -0
- package/dist/components/SubmitErrorAlert/index.js +7 -11
- package/dist/components/TagInputField/index.d.ts +6 -0
- package/dist/components/TagInputField/index.js +14 -32
- package/dist/components/TextAreaField/index.d.ts +11 -0
- package/dist/components/TextAreaField/index.js +25 -52
- package/dist/components/TextInputField/index.d.ts +18 -0
- package/dist/components/TextInputField/index.js +37 -76
- package/dist/components/TextInputFieldV2/index.d.ts +12 -0
- package/dist/components/TextInputFieldV2/index.js +30 -66
- package/dist/components/TimeField/index.d.ts +9 -0
- package/dist/components/TimeField/index.js +23 -46
- package/dist/components/ToggleField/index.d.ts +10 -0
- package/dist/components/ToggleField/index.js +15 -28
- package/dist/components/ToggleGroupField/index.d.ts +26 -0
- package/dist/components/index.d.ts +22 -0
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +4 -3
- package/dist/hooks/index.d.ts +5 -0
- package/dist/hooks/useField.d.ts +34 -0
- package/dist/hooks/useField.js +4 -20
- package/dist/hooks/useFieldArray.d.ts +21 -0
- package/dist/hooks/useFieldArray.js +6 -9
- package/dist/hooks/useForm.d.ts +23 -0
- package/dist/hooks/useForm.js +7 -19
- package/dist/hooks/useFormState.d.ts +39 -0
- package/dist/hooks/useFormState.js +5 -20
- package/dist/hooks/useOnFieldChange.d.ts +3 -0
- package/dist/hooks/useOnFieldChange.js +6 -6
- package/dist/index.d.ts +7 -555
- package/dist/index.js +66 -29
- package/dist/mocks/index.d.ts +1 -0
- package/dist/mocks/mockErrors.d.ts +3 -0
- package/dist/providers/ErrorContext/index.d.ts +14 -0
- package/dist/providers/ErrorContext/index.js +11 -13
- package/dist/providers/index.d.ts +1 -0
- package/dist/types.d.ts +32 -0
- package/dist/validators/index.d.ts +5 -0
- package/dist/validators/maxDate.d.ts +1 -0
- package/dist/validators/maxDate.js +4 -3
- package/dist/validators/minDate.d.ts +1 -0
- package/dist/validators/minDate.js +4 -3
- package/package.json +12 -6
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { Checkbox } from '@ultraviolet/ui';
|
|
2
|
+
import type { ComponentProps, ReactNode } from 'react';
|
|
3
|
+
import type { FieldPath, FieldValues } from 'react-hook-form';
|
|
4
|
+
import type { BaseFieldProps } from '../../types';
|
|
5
|
+
type CheckboxFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> = Omit<BaseFieldProps<TFieldValues, TName>, 'value'> & Partial<Pick<ComponentProps<typeof Checkbox>, 'id' | 'disabled' | 'onBlur' | 'onFocus' | 'progress' | 'size' | 'data-testid' | 'helper' | 'tooltip'>> & {
|
|
6
|
+
className?: string;
|
|
7
|
+
children?: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
export declare const CheckboxField: <TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ id, name, label, size, progress, disabled, required, className, children, onChange, onBlur, onFocus, rules, helper, tooltip, "data-testid": dataTestId, shouldUnregister, }: CheckboxFieldProps<TFieldValues, TName>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useErrors } from
|
|
5
|
-
|
|
1
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { Checkbox } from "@ultraviolet/ui";
|
|
3
|
+
import { useController } from "react-hook-form";
|
|
4
|
+
import { useErrors } from "../../providers/ErrorContext/index.js";
|
|
6
5
|
const CheckboxField = ({
|
|
7
6
|
id,
|
|
8
7
|
name,
|
|
@@ -19,7 +18,7 @@ const CheckboxField = ({
|
|
|
19
18
|
rules,
|
|
20
19
|
helper,
|
|
21
20
|
tooltip,
|
|
22
|
-
|
|
21
|
+
"data-testid": dataTestId,
|
|
23
22
|
shouldUnregister = false
|
|
24
23
|
}) => {
|
|
25
24
|
const {
|
|
@@ -39,33 +38,16 @@ const CheckboxField = ({
|
|
|
39
38
|
...rules
|
|
40
39
|
}
|
|
41
40
|
});
|
|
42
|
-
return jsx(Checkbox, {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
size: size,
|
|
55
|
-
progress: progress,
|
|
56
|
-
disabled: field.disabled,
|
|
57
|
-
checked: !!field.value,
|
|
58
|
-
error: getError({
|
|
59
|
-
label: label ?? ''
|
|
60
|
-
}, error),
|
|
61
|
-
ref: field.ref,
|
|
62
|
-
className: className,
|
|
63
|
-
required: required,
|
|
64
|
-
"data-testid": dataTestId,
|
|
65
|
-
helper: helper,
|
|
66
|
-
tooltip: tooltip,
|
|
67
|
-
children: children
|
|
68
|
-
});
|
|
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 });
|
|
50
|
+
};
|
|
51
|
+
export {
|
|
52
|
+
CheckboxField
|
|
69
53
|
};
|
|
70
|
-
|
|
71
|
-
export { CheckboxField };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { CheckboxGroup } from '@ultraviolet/ui';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
import type { FieldPath, FieldValues } from 'react-hook-form';
|
|
4
|
+
import type { BaseFieldProps } from '../../types';
|
|
5
|
+
type CheckboxGroupFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> = BaseFieldProps<TFieldValues, TName> & Partial<Pick<ComponentProps<typeof CheckboxGroup>, 'className' | 'helper' | 'required' | 'direction' | 'children' | 'error' | 'legend'>> & Required<Pick<ComponentProps<typeof CheckboxGroup>, 'legend'>>;
|
|
6
|
+
export declare const CheckboxGroupField: {
|
|
7
|
+
<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ legend, className, helper, direction, children, onChange, label, error: customError, name, required, shouldUnregister, rules, }: CheckboxGroupFieldProps<TFieldValues, TName>): import("@emotion/react/jsx-runtime").JSX.Element;
|
|
8
|
+
Checkbox: ({ onFocus, onBlur, disabled, error, name, value, children, helper, className, autoFocus, "data-testid": dataTestId, required, }: Omit<({
|
|
9
|
+
error?: import("react").ReactNode;
|
|
10
|
+
size?: number | undefined;
|
|
11
|
+
progress?: boolean | undefined;
|
|
12
|
+
helper?: import("react").ReactNode;
|
|
13
|
+
disabled?: boolean | undefined;
|
|
14
|
+
checked?: boolean | "indeterminate" | undefined;
|
|
15
|
+
className?: string | undefined;
|
|
16
|
+
"data-visibility"?: string | undefined;
|
|
17
|
+
required?: boolean | undefined;
|
|
18
|
+
'data-testid'?: string | undefined;
|
|
19
|
+
tooltip?: string | undefined;
|
|
20
|
+
} & Pick<import("react").InputHTMLAttributes<HTMLInputElement>, "value" | "onChange" | "onBlur" | "name" | "onFocus" | "autoFocus" | "id" | "tabIndex"> & (({
|
|
21
|
+
"aria-label"?: undefined;
|
|
22
|
+
} & {
|
|
23
|
+
children: import("react").ReactNode;
|
|
24
|
+
}) | ({
|
|
25
|
+
children?: undefined;
|
|
26
|
+
} & {
|
|
27
|
+
'aria-label': string;
|
|
28
|
+
}))) & import("react").RefAttributes<HTMLInputElement>, "onChange" | "checked"> & {
|
|
29
|
+
value: string;
|
|
30
|
+
}) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
31
|
+
};
|
|
32
|
+
export {};
|
|
@@ -1,14 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useErrors } from
|
|
6
|
-
|
|
1
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { CheckboxGroup } from "@ultraviolet/ui";
|
|
3
|
+
import { useCallback, Children, isValidElement } from "react";
|
|
4
|
+
import { useController } from "react-hook-form";
|
|
5
|
+
import { useErrors } from "../../providers/ErrorContext/index.js";
|
|
7
6
|
const arraysContainSameValues = (array1, array2) => {
|
|
8
7
|
if (array1.length === 0) {
|
|
9
8
|
return false;
|
|
10
9
|
}
|
|
11
|
-
return array2.every(value => array1.includes(value));
|
|
10
|
+
return array2.every((value) => array1.includes(value));
|
|
12
11
|
};
|
|
13
12
|
const CheckboxGroupField = ({
|
|
14
13
|
legend,
|
|
@@ -17,7 +16,7 @@ const CheckboxGroupField = ({
|
|
|
17
16
|
direction,
|
|
18
17
|
children,
|
|
19
18
|
onChange,
|
|
20
|
-
label =
|
|
19
|
+
label = "",
|
|
21
20
|
error: customError,
|
|
22
21
|
name,
|
|
23
22
|
required = false,
|
|
@@ -27,9 +26,9 @@ const CheckboxGroupField = ({
|
|
|
27
26
|
const {
|
|
28
27
|
getError
|
|
29
28
|
} = useErrors();
|
|
30
|
-
const validate = useCallback(value => {
|
|
31
|
-
const requiredChildren = Children.map(children, child => {
|
|
32
|
-
if (
|
|
29
|
+
const validate = useCallback((value) => {
|
|
30
|
+
const requiredChildren = Children.map(children, (child) => {
|
|
31
|
+
if (isValidElement(child)) {
|
|
33
32
|
if (child.props.required) {
|
|
34
33
|
return child.props.name;
|
|
35
34
|
}
|
|
@@ -58,29 +57,19 @@ const CheckboxGroupField = ({
|
|
|
58
57
|
...rules
|
|
59
58
|
}
|
|
60
59
|
});
|
|
61
|
-
return jsx(CheckboxGroup, {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
onChange?.(event.currentTarget.value);
|
|
73
|
-
},
|
|
74
|
-
error: getError({
|
|
75
|
-
label
|
|
76
|
-
}, error) ?? customError,
|
|
77
|
-
className: className,
|
|
78
|
-
direction: direction,
|
|
79
|
-
helper: helper,
|
|
80
|
-
required: required,
|
|
81
|
-
children: children
|
|
82
|
-
});
|
|
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]);
|
|
66
|
+
}
|
|
67
|
+
onChange?.(event.currentTarget.value);
|
|
68
|
+
}, error: getError({
|
|
69
|
+
label
|
|
70
|
+
}, error) ?? customError, className, direction, helper, required, children });
|
|
83
71
|
};
|
|
84
72
|
CheckboxGroupField.Checkbox = CheckboxGroup.Checkbox;
|
|
85
|
-
|
|
86
|
-
|
|
73
|
+
export {
|
|
74
|
+
CheckboxGroupField
|
|
75
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { DateInput } from '@ultraviolet/ui';
|
|
2
|
+
import type { ComponentProps, FocusEvent } from 'react';
|
|
3
|
+
import type { FieldPath, FieldValues } from 'react-hook-form';
|
|
4
|
+
import type { BaseFieldProps } from '../../types';
|
|
5
|
+
type DateFieldProps<TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues>> = BaseFieldProps<TFieldValues, TName> & Omit<ComponentProps<typeof DateInput>, 'maxDate' | 'minDate' | 'disabled' | 'required' | 'locale' | 'name' | 'onChange' | 'onFocus' | 'onBlur' | 'autoFocus' | 'stardDate' | 'endDate'> & {
|
|
6
|
+
maxDate?: Date;
|
|
7
|
+
minDate?: Date;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
required?: boolean;
|
|
10
|
+
locale?: string;
|
|
11
|
+
onBlur?: (event: FocusEvent<HTMLElement>) => void;
|
|
12
|
+
onFocus?: (value: FocusEvent<HTMLElement>) => void;
|
|
13
|
+
autoFocus?: boolean;
|
|
14
|
+
};
|
|
15
|
+
export declare const DateField: <TFieldValues extends FieldValues, TName extends FieldPath<TFieldValues> = FieldPath<TFieldValues>>({ required, name, label, format, locale, maxDate, minDate, disabled, onChange, onBlur, onFocus, rules, autoFocus, excludeDates, selectsRange, "data-testid": dataTestId, shouldUnregister, }: DateFieldProps<TFieldValues, TName>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
16
|
+
export {};
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useErrors } from
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const isEmpty = value => typeof value === 'string' ? value === '' : value === undefined;
|
|
1
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import { DateInput } from "@ultraviolet/ui";
|
|
3
|
+
import { useController } from "react-hook-form";
|
|
4
|
+
import { maxDateValidator } from "../../validators/maxDate.js";
|
|
5
|
+
import { minDateValidator } from "../../validators/minDate.js";
|
|
6
|
+
import { useErrors } from "../../providers/ErrorContext/index.js";
|
|
7
|
+
const parseDate = (value) => typeof value === "string" ? new Date(value) : value;
|
|
8
|
+
const isEmpty = (value) => typeof value === "string" ? value === "" : value === void 0;
|
|
10
9
|
const DateField = ({
|
|
11
10
|
required,
|
|
12
11
|
name,
|
|
13
|
-
label =
|
|
12
|
+
label = "",
|
|
14
13
|
format,
|
|
15
14
|
locale,
|
|
16
15
|
maxDate,
|
|
@@ -23,7 +22,7 @@ const DateField = ({
|
|
|
23
22
|
autoFocus = false,
|
|
24
23
|
excludeDates,
|
|
25
24
|
selectsRange,
|
|
26
|
-
|
|
25
|
+
"data-testid": dataTestId,
|
|
27
26
|
shouldUnregister = false
|
|
28
27
|
}) => {
|
|
29
28
|
const {
|
|
@@ -47,48 +46,29 @@ const DateField = ({
|
|
|
47
46
|
required
|
|
48
47
|
}
|
|
49
48
|
});
|
|
50
|
-
return jsx(DateInput, {
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
locale: locale,
|
|
56
|
-
required: required,
|
|
57
|
-
onChange: val => {
|
|
58
|
-
if (val && val instanceof Date) {
|
|
59
|
-
onChange?.(val);
|
|
60
|
-
const newDate = parseDate(val);
|
|
61
|
-
if (isEmpty(field.value)) {
|
|
62
|
-
field.onChange(newDate);
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const currentDate = parseDate(field.value);
|
|
66
|
-
newDate.setHours(currentDate.getHours(), currentDate.getMinutes());
|
|
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)) {
|
|
67
54
|
field.onChange(newDate);
|
|
68
|
-
|
|
69
|
-
field.onChange(val);
|
|
55
|
+
return;
|
|
70
56
|
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
field.
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
"data-testid": dataTestId,
|
|
89
|
-
startDate: selectsRange && Array.isArray(field.value) ? field.value[0] : undefined,
|
|
90
|
-
endDate: selectsRange && Array.isArray(field.value) ? field.value[1] : undefined
|
|
91
|
-
});
|
|
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);
|
|
62
|
+
}
|
|
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 });
|
|
71
|
+
};
|
|
72
|
+
export {
|
|
73
|
+
DateField
|
|
92
74
|
};
|
|
93
|
-
|
|
94
|
-
export { DateField };
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
const defaultErrors = {
|
|
2
|
-
maxDate: () =>
|
|
3
|
-
maxLength: () =>
|
|
4
|
-
minLength: () =>
|
|
5
|
-
max: () =>
|
|
6
|
-
min: () =>
|
|
7
|
-
required: () =>
|
|
8
|
-
pattern: () =>
|
|
9
|
-
deps: () =>
|
|
10
|
-
value: () =>
|
|
11
|
-
onBlur: () =>
|
|
12
|
-
disabled: () =>
|
|
13
|
-
onChange: () =>
|
|
14
|
-
validate: () =>
|
|
15
|
-
setValueAs: () =>
|
|
16
|
-
valueAsDate: () =>
|
|
17
|
-
valueAsNumber: () =>
|
|
18
|
-
shouldUnregister: () =>
|
|
2
|
+
maxDate: () => "",
|
|
3
|
+
maxLength: () => "",
|
|
4
|
+
minLength: () => "",
|
|
5
|
+
max: () => "",
|
|
6
|
+
min: () => "",
|
|
7
|
+
required: () => "",
|
|
8
|
+
pattern: () => "",
|
|
9
|
+
deps: () => "",
|
|
10
|
+
value: () => "",
|
|
11
|
+
onBlur: () => "",
|
|
12
|
+
disabled: () => "",
|
|
13
|
+
onChange: () => "",
|
|
14
|
+
validate: () => "",
|
|
15
|
+
setValueAs: () => "",
|
|
16
|
+
valueAsDate: () => "",
|
|
17
|
+
valueAsNumber: () => "",
|
|
18
|
+
shouldUnregister: () => ""
|
|
19
|
+
};
|
|
20
|
+
export {
|
|
21
|
+
defaultErrors
|
|
19
22
|
};
|
|
20
|
-
|
|
21
|
-
export { defaultErrors };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import type { DefaultValues, FieldErrors, FieldValues, UseFormHandleSubmit, UseFormReturn } from 'react-hook-form';
|
|
4
|
+
import { FORM_ERROR } from '../../constants';
|
|
5
|
+
import type { FormErrors } from '../../types';
|
|
6
|
+
type Without<T, U> = {
|
|
7
|
+
[P in Exclude<keyof T, keyof U>]?: never;
|
|
8
|
+
};
|
|
9
|
+
type SingleXOR<T, U> = T | U extends object ? (Without<T, U> & U) | (Without<U, T> & T) : T | U;
|
|
10
|
+
export type XOR<T extends unknown[]> = T extends [infer Only] ? Only : T extends [infer A, infer B, ...infer Rest] ? XOR<[SingleXOR<A, B>, ...Rest]> : never;
|
|
11
|
+
type FormStateReturn<TFormValues extends FieldValues> = {
|
|
12
|
+
values: TFormValues;
|
|
13
|
+
hasValidationErrors: boolean;
|
|
14
|
+
errors: FieldErrors<TFormValues>;
|
|
15
|
+
submitting: boolean;
|
|
16
|
+
pristine: boolean;
|
|
17
|
+
handleSubmit: () => Promise<void>;
|
|
18
|
+
submitError: boolean;
|
|
19
|
+
valid: boolean;
|
|
20
|
+
form: {
|
|
21
|
+
change: UseFormReturn<TFormValues>['setValue'];
|
|
22
|
+
reset: UseFormReturn<TFormValues>['reset'];
|
|
23
|
+
submit: () => Promise<void>;
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
type OnRawSubmitReturn = {
|
|
27
|
+
[FORM_ERROR]?: string;
|
|
28
|
+
} | undefined | null | string | void | boolean | number;
|
|
29
|
+
type FormSubmitContextValue<TFieldValues extends FieldValues = FieldValues> = {
|
|
30
|
+
handleSubmit: ReturnType<UseFormHandleSubmit<TFieldValues>>;
|
|
31
|
+
};
|
|
32
|
+
export declare const FormSubmitContext: React.Context<FormSubmitContextValue<FieldValues>>;
|
|
33
|
+
export type FormProps<TFormValues extends FieldValues = FieldValues> = {
|
|
34
|
+
children?: ((props: FormStateReturn<TFormValues>) => ReactNode) | ReactNode;
|
|
35
|
+
errors: FormErrors;
|
|
36
|
+
name?: string;
|
|
37
|
+
onRawSubmit: (data: TFormValues, formState: {
|
|
38
|
+
reset: UseFormReturn<TFormValues>['reset'];
|
|
39
|
+
resetFieldState: UseFormReturn<TFormValues>['resetField'];
|
|
40
|
+
restart: () => void;
|
|
41
|
+
change: UseFormReturn<TFormValues>['setValue'];
|
|
42
|
+
}) => Promise<OnRawSubmitReturn> | OnRawSubmitReturn;
|
|
43
|
+
} & XOR<[
|
|
44
|
+
{
|
|
45
|
+
/**
|
|
46
|
+
* @deprecated Use the `methods` prop with [useForm](https://www.react-hook-form.com/api/useform/) instead.
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```tsx
|
|
50
|
+
* const methods = useForm({
|
|
51
|
+
* defaultValues,
|
|
52
|
+
* mode: 'onChange'
|
|
53
|
+
* })
|
|
54
|
+
*
|
|
55
|
+
* return (
|
|
56
|
+
* <Form methods={methods} onRawSubmit={handleSubmit} errors={formErrors}>
|
|
57
|
+
* // ...
|
|
58
|
+
* </Form>
|
|
59
|
+
* )
|
|
60
|
+
* ```
|
|
61
|
+
*/
|
|
62
|
+
initialValues?: DefaultValues<TFormValues>;
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
methods: UseFormReturn<TFormValues>;
|
|
66
|
+
}
|
|
67
|
+
]>;
|
|
68
|
+
export declare const Form: <TFormValues extends FieldValues>({ children, methods: methodsProp, initialValues, errors, onRawSubmit, name, }: FormProps<TFormValues>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
69
|
+
export {};
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { ErrorProvider } from
|
|
7
|
-
|
|
8
|
-
const FormSubmitContext = /*#__PURE__*/React.createContext({});
|
|
1
|
+
import { jsx } from "@emotion/react/jsx-runtime";
|
|
2
|
+
import React, { useMemo } from "react";
|
|
3
|
+
import { useForm, FormProvider } from "react-hook-form";
|
|
4
|
+
import { FORM_ERROR } from "../../constants.js";
|
|
5
|
+
import { defaultErrors } from "./defaultErrors.js";
|
|
6
|
+
import { ErrorProvider } from "../../providers/ErrorContext/index.js";
|
|
7
|
+
const FormSubmitContext = React.createContext({});
|
|
9
8
|
const Form = ({
|
|
10
9
|
children,
|
|
11
10
|
methods: methodsProp,
|
|
@@ -16,10 +15,10 @@ const Form = ({
|
|
|
16
15
|
}) => {
|
|
17
16
|
const methodsHook = useForm({
|
|
18
17
|
defaultValues: initialValues,
|
|
19
|
-
mode:
|
|
18
|
+
mode: "onChange"
|
|
20
19
|
});
|
|
21
20
|
const methods = !methodsProp ? methodsHook : methodsProp;
|
|
22
|
-
const handleSubmit = methods.handleSubmit(async values => {
|
|
21
|
+
const handleSubmit = methods.handleSubmit(async (values) => {
|
|
23
22
|
const result = await onRawSubmit(values, {
|
|
24
23
|
reset: methods.reset,
|
|
25
24
|
resetFieldState: methods.resetField,
|
|
@@ -27,57 +26,45 @@ const Form = ({
|
|
|
27
26
|
change: methods.setValue
|
|
28
27
|
});
|
|
29
28
|
if (result === null) {
|
|
30
|
-
methods.setError(
|
|
31
|
-
type:
|
|
29
|
+
methods.setError("root.submit", {
|
|
30
|
+
type: "custom"
|
|
32
31
|
});
|
|
33
32
|
return;
|
|
34
33
|
}
|
|
35
|
-
if (result && typeof result !==
|
|
36
|
-
methods.setError(
|
|
37
|
-
type:
|
|
38
|
-
message: typeof result ===
|
|
34
|
+
if (result && typeof result !== "boolean" && typeof result !== "number") {
|
|
35
|
+
methods.setError("root.submit", {
|
|
36
|
+
type: "custom",
|
|
37
|
+
message: typeof result === "object" ? result[FORM_ERROR] : result
|
|
39
38
|
});
|
|
40
39
|
}
|
|
41
40
|
});
|
|
42
41
|
const formSubmitContextValue = useMemo(() => ({
|
|
43
42
|
handleSubmit
|
|
44
43
|
}), [handleSubmit]);
|
|
45
|
-
return jsx(FormProvider, {
|
|
46
|
-
...
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
form: {
|
|
72
|
-
change: methods.setValue,
|
|
73
|
-
reset: methods.reset,
|
|
74
|
-
submit: handleSubmit
|
|
75
|
-
}
|
|
76
|
-
}) : children
|
|
77
|
-
})
|
|
78
|
-
})
|
|
79
|
-
})
|
|
80
|
-
});
|
|
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
|
|
64
|
+
}
|
|
65
|
+
}) : children }) }) }) });
|
|
66
|
+
};
|
|
67
|
+
export {
|
|
68
|
+
Form,
|
|
69
|
+
FormSubmitContext
|
|
81
70
|
};
|
|
82
|
-
|
|
83
|
-
export { Form, FormSubmitContext };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { Button } from '@ultraviolet/ui';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
3
|
+
import type { Control, FieldArrayPath, FieldValues } from 'react-hook-form';
|
|
4
|
+
import { TextInputField as TextInputFieldV2 } from '../TextInputFieldV2';
|
|
5
|
+
type InputKeyProps = {
|
|
6
|
+
label: ComponentProps<typeof TextInputFieldV2>['label'];
|
|
7
|
+
required?: ComponentProps<typeof TextInputFieldV2>['required'];
|
|
8
|
+
regex?: ComponentProps<typeof TextInputFieldV2>['regex'];
|
|
9
|
+
};
|
|
10
|
+
type InputValueProps = {
|
|
11
|
+
type?: ComponentProps<typeof TextInputFieldV2>['type'];
|
|
12
|
+
placeholder?: ComponentProps<typeof TextInputFieldV2>['placeholder'];
|
|
13
|
+
} & InputKeyProps;
|
|
14
|
+
type AddButtonProps = {
|
|
15
|
+
name: ComponentProps<typeof Button>['children'];
|
|
16
|
+
fullWidth?: ComponentProps<typeof Button>['fullWidth'];
|
|
17
|
+
tooltip?: string;
|
|
18
|
+
maxSizeReachedTooltip?: string;
|
|
19
|
+
};
|
|
20
|
+
type KeyValueFieldProps<TFieldValues extends FieldValues, TFieldArrayName extends FieldArrayPath<TFieldValues>> = {
|
|
21
|
+
name: TFieldArrayName;
|
|
22
|
+
inputKey: InputKeyProps;
|
|
23
|
+
inputValue: InputValueProps;
|
|
24
|
+
addButton: AddButtonProps;
|
|
25
|
+
maxSize?: number;
|
|
26
|
+
readonly?: boolean;
|
|
27
|
+
control?: Control<TFieldValues>;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* A React component that allows users to manage key-value pairs
|
|
31
|
+
*/
|
|
32
|
+
export declare const KeyValueField: <TFieldValues extends FieldValues = FieldValues, TFieldArrayName extends FieldArrayPath<TFieldValues> = FieldArrayPath<TFieldValues>>({ name, inputKey, inputValue, addButton, maxSize, readonly, control, }: KeyValueFieldProps<TFieldValues, TFieldArrayName>) => import("@emotion/react/jsx-runtime").JSX.Element;
|
|
33
|
+
export {};
|