@ultraviolet/form 2.0.0-next.7 → 2.0.0-next.8

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.
@@ -1,10 +1,12 @@
1
1
  import { SelectInput } from '@ultraviolet/ui';
2
2
  import { useMemo, Children, useCallback } from 'react';
3
+ import { useController } from 'react-hook-form';
3
4
  import { jsx } from '@emotion/react/jsx-runtime';
4
5
  import { useErrors } from '../../providers/ErrorContext/index.js';
5
- import { useFormField } from '../../hooks/useFormField.js';
6
6
 
7
7
  const identity = x => x;
8
+ // const identity = <T,>(x: T) => x
9
+
8
10
  const SelectInputField = _ref => {
9
11
  let {
10
12
  animation,
@@ -13,9 +15,9 @@ const SelectInputField = _ref => {
13
15
  children,
14
16
  className,
15
17
  disabled,
16
- error: errorProp,
18
+ // error: errorProp,
17
19
  format: formatProp = identity,
18
- formatOnBlur,
20
+ // formatOnBlur,
19
21
  id,
20
22
  inputId,
21
23
  isClearable,
@@ -35,16 +37,12 @@ const SelectInputField = _ref => {
35
37
  placeholder,
36
38
  readOnly,
37
39
  required,
38
- value,
40
+ rules,
39
41
  noTopLabel,
40
42
  noOptionsMessage,
41
43
  customStyle,
42
- validate,
43
- 'data-testid': dataTestId
44
+ shouldUnregister = false
44
45
  } = _ref;
45
- const {
46
- getError
47
- } = useErrors();
48
46
  const options = useMemo(() => optionsProp || Children.toArray(children).flat().filter(Boolean).map(_ref2 => {
49
47
  let {
50
48
  props: {
@@ -75,63 +73,59 @@ const SelectInputField = _ref => {
75
73
  return formatProp(selected, name);
76
74
  }, [formatProp, multiple, name, options]);
77
75
  const {
78
- input,
79
- meta
80
- } = useFormField(name, {
81
- disabled,
82
- format,
83
- formatOnBlur,
84
- maxLength,
85
- minLength: minLength || required ? 1 : undefined,
86
- multiple,
87
- parse,
88
- required,
89
- value,
90
- validate
91
- });
92
- const error = getError({
93
- errorProp,
94
- label,
95
- meta: meta,
76
+ getError
77
+ } = useErrors();
78
+ const {
79
+ field,
80
+ fieldState: {
81
+ error
82
+ }
83
+ } = useController({
96
84
  name,
97
- value: input.value
85
+ shouldUnregister,
86
+ rules: {
87
+ required,
88
+ minLength: minLength || required ? 1 : undefined,
89
+ maxLength,
90
+ ...rules
91
+ }
98
92
  });
99
93
  return jsx(SelectInput, {
94
+ name: field.name,
100
95
  animation: animation,
101
96
  animationDuration: animationDuration,
102
97
  animationOnChange: animationOnChange,
103
98
  className: className,
104
99
  disabled: disabled,
105
- error: error,
100
+ error: getError({
101
+ label,
102
+ minLength,
103
+ maxLength
104
+ }, error),
106
105
  id: id,
107
106
  inputId: inputId,
108
107
  isClearable: isClearable,
109
108
  isLoading: isLoading,
110
- isMulti: input.multiple,
109
+ isMulti: multiple,
111
110
  customStyle: customStyle,
112
111
  isSearchable: isSearchable,
113
112
  menuPortalTarget: menuPortalTarget,
114
- name: name,
115
113
  onBlur: event => {
116
- input.onBlur(event);
114
+ field.onBlur();
117
115
  onBlur?.(event);
118
116
  },
119
117
  onChange: (event, action) => {
120
- input.onChange(event);
118
+ field.onChange(parse(event));
121
119
  onChange?.(event, action);
122
120
  },
123
- onFocus: event => {
124
- input.onFocus(event);
125
- onFocus?.(event);
126
- },
121
+ onFocus: onFocus,
127
122
  options: options,
128
123
  placeholder: placeholder,
129
124
  readOnly: readOnly,
130
- value: input.value,
131
125
  noTopLabel: noTopLabel,
132
126
  required: required,
127
+ value: format(field.value),
133
128
  noOptionsMessage: noOptionsMessage,
134
- "data-testid": dataTestId,
135
129
  children: children
136
130
  });
137
131
  };
@@ -1,7 +1,6 @@
1
1
  import { SelectableCard } from '@ultraviolet/ui';
2
+ import { useController } from 'react-hook-form';
2
3
  import { jsx } from '@emotion/react/jsx-runtime';
3
- import { useErrors } from '../../providers/ErrorContext/index.js';
4
- import { useFormField } from '../../hooks/useFormField.js';
5
4
 
6
5
  const SelectableCardField = _ref => {
7
6
  let {
@@ -16,56 +15,48 @@ const SelectableCardField = _ref => {
16
15
  onFocus,
17
16
  onBlur,
18
17
  required,
19
- validate,
20
18
  tooltip,
21
19
  id,
22
20
  label,
23
- 'data-testid': dataTestId
21
+ rules,
22
+ shouldUnregister = false
24
23
  } = _ref;
25
24
  const {
26
- getError
27
- } = useErrors();
28
- const {
29
- input,
30
- meta
31
- } = useFormField(name, {
32
- disabled,
33
- required,
34
- type: type ?? 'radio',
35
- validate,
36
- value
37
- });
38
- const error = getError({
39
- label: name,
40
- meta: meta,
25
+ field,
26
+ fieldState: {
27
+ error
28
+ }
29
+ } = useController({
41
30
  name,
42
- value: input.value
31
+ shouldUnregister,
32
+ rules: {
33
+ required,
34
+ ...rules
35
+ }
43
36
  });
44
37
  return jsx(SelectableCard, {
45
38
  isError: !!error,
46
39
  showTick: showTick,
47
- checked: input.checked,
40
+ checked: field.value === value,
48
41
  className: className,
49
42
  disabled: disabled,
50
- name: input.name,
51
43
  onChange: event => {
52
- input.onChange(event);
44
+ field.onChange(event);
53
45
  onChange?.(event);
54
46
  },
55
47
  onBlur: event => {
56
- input.onBlur(event);
48
+ field.onBlur();
57
49
  onBlur?.(event);
58
50
  },
59
51
  onFocus: event => {
60
- input.onFocus(event);
61
52
  onFocus?.(event);
62
53
  },
63
54
  type: type,
64
- value: input.value,
65
55
  id: id,
66
56
  tooltip: tooltip,
67
57
  label: label,
68
- "data-testid": dataTestId,
58
+ value: value ?? '',
59
+ name: field.name,
69
60
  children: children
70
61
  });
71
62
  };
@@ -1,6 +1,5 @@
1
1
  import { Button } from '@ultraviolet/ui';
2
- import { useState, useEffect } from 'react';
3
- import { useFormState } from 'react-final-form';
2
+ import { useFormState } from 'react-hook-form';
4
3
  import { jsx } from '@emotion/react/jsx-runtime';
5
4
 
6
5
  const Submit = _ref => {
@@ -18,27 +17,16 @@ const Submit = _ref => {
18
17
  onClick
19
18
  } = _ref;
20
19
  const {
21
- invalid,
22
- submitting,
23
- hasValidationErrors,
24
- dirtySinceLastSubmit
25
- } = useFormState({
26
- subscription: {
27
- dirtySinceLastSubmit: true,
28
- hasValidationErrors: true,
29
- invalid: true,
30
- submitting: true
31
- }
32
- });
33
- const [isLoading, setIsLoading] = useState(true);
34
- const isDisabled = disabled || submitting || isLoading || invalid && hasValidationErrors && !dirtySinceLastSubmit;
35
- useEffect(() => setIsLoading(false), []);
20
+ isSubmitting,
21
+ isValid
22
+ } = useFormState();
23
+ const isDisabled = disabled || isSubmitting || !isValid;
36
24
  return jsx(Button, {
37
25
  className: className,
38
26
  disabled: isDisabled,
39
27
  icon: icon,
40
28
  iconPosition: iconPosition,
41
- isLoading: submitting,
29
+ isLoading: isSubmitting,
42
30
  size: size,
43
31
  type: "submit",
44
32
  variant: variant,
@@ -1,26 +1,19 @@
1
1
  import { Alert } from '@ultraviolet/ui';
2
- import { FormSpy } from 'react-final-form';
2
+ import { useFormState } from 'react-hook-form';
3
3
  import { jsx } from '@emotion/react/jsx-runtime';
4
4
 
5
5
  const SubmitErrorAlert = _ref => {
6
6
  let {
7
7
  className
8
8
  } = _ref;
9
- return jsx(FormSpy, {
10
- subscription: {
11
- submitError: true
12
- },
13
- children: _ref2 => {
14
- let {
15
- submitError
16
- } = _ref2;
17
- return submitError ? jsx(Alert, {
18
- className: className,
19
- sentiment: "danger",
20
- children: submitError
21
- }) : null;
22
- }
23
- });
9
+ const {
10
+ errors
11
+ } = useFormState();
12
+ return errors?.root?.['submit']?.message ? jsx(Alert, {
13
+ className: className,
14
+ sentiment: "danger",
15
+ children: errors.root['submit'].message
16
+ }) : null;
24
17
  };
25
18
 
26
19
  export { SubmitErrorAlert };
@@ -1,44 +1,42 @@
1
1
  import { TagInput } from '@ultraviolet/ui';
2
+ import { useController } from 'react-hook-form';
2
3
  import { jsx } from '@emotion/react/jsx-runtime';
3
- import { useFormField } from '../../hooks/useFormField.js';
4
4
 
5
5
  const TagInputField = _ref => {
6
6
  let {
7
7
  className,
8
- 'data-testid': dataTestId,
9
8
  disabled,
10
9
  id,
11
10
  name,
12
11
  onChange,
13
12
  placeholder,
14
13
  required,
15
- tags,
16
- validate,
17
- variant
14
+ rules,
15
+ variant,
16
+ shouldUnregister = false
18
17
  } = _ref;
19
18
  const {
20
- input
21
- } = useFormField(name, {
22
- disabled,
23
- required,
24
- initialValue: tags,
25
- type: 'text',
26
- validate,
27
- value: tags
19
+ field
20
+ } = useController({
21
+ name,
22
+ rules: {
23
+ required,
24
+ shouldUnregister,
25
+ ...rules
26
+ }
28
27
  });
29
28
  return jsx(TagInput, {
29
+ name: field.name,
30
30
  className: className,
31
31
  disabled: disabled,
32
32
  id: id,
33
- name: name,
34
33
  onChange: event => {
34
+ field.onChange(event);
35
35
  onChange?.(event);
36
- input.onChange(event);
37
36
  },
38
37
  placeholder: placeholder,
39
38
  variant: variant,
40
- tags: input.value,
41
- "data-testid": dataTestId
39
+ tags: field.value
42
40
  });
43
41
  };
44
42
 
@@ -1,105 +1,91 @@
1
1
  import { TextInput } from '@ultraviolet/ui';
2
- import { forwardRef } from 'react';
2
+ import { useController } from 'react-hook-form';
3
3
  import { jsx } from '@emotion/react/jsx-runtime';
4
4
  import { useErrors } from '../../providers/ErrorContext/index.js';
5
- import { useFormField } from '../../hooks/useFormField.js';
6
5
 
7
- const TextInputField = /*#__PURE__*/forwardRef((_ref, ref) => {
6
+ const TextInputField = _ref => {
8
7
  let {
9
- afterSubmit,
10
- allowNull,
11
8
  autoCapitalize,
12
9
  autoComplete,
13
10
  autoCorrect,
14
11
  autoFocus,
15
12
  autoSave,
16
- beforeSubmit,
17
13
  className,
18
14
  cols,
19
- 'data-testid': dataTestId,
20
- defaultValue,
21
15
  disabled,
22
16
  fillAvailable,
23
- format,
24
- formatOnBlur,
25
17
  generated,
26
18
  id,
27
- initialValue,
28
- isEqual,
29
19
  label = '',
30
- max,
31
- maxLength,
32
- min,
33
- minLength,
34
20
  multiline,
35
- multiple,
36
21
  name,
37
22
  noTopLabel,
38
23
  notice,
39
- onBlur,
40
24
  onChange,
41
25
  onFocus,
42
26
  onKeyDown,
43
27
  onKeyUp,
44
- parse,
28
+ onBlur,
45
29
  placeholder,
46
30
  random,
47
31
  readOnly,
48
- regex,
49
32
  required,
50
33
  resizable,
51
34
  rows,
52
- subscription,
53
35
  type,
54
36
  unit,
55
37
  size,
56
- validate,
57
- validateFields,
38
+ rules,
58
39
  valid,
59
- value
40
+ parse,
41
+ format,
42
+ formatOnBlur = false,
43
+ regex: regexes,
44
+ min,
45
+ max,
46
+ minLength,
47
+ maxLength,
48
+ validate,
49
+ defaultValue,
50
+ customError,
51
+ innerRef,
52
+ shouldUnregister = false
60
53
  } = _ref;
61
54
  const {
62
55
  getError
63
56
  } = useErrors();
64
57
  const {
65
- input,
66
- meta
67
- } = useFormField(name, {
68
- afterSubmit,
69
- allowNull,
70
- beforeSubmit,
71
- defaultValue,
72
- disabled,
73
- format,
74
- formatOnBlur,
75
- initialValue,
76
- isEqual,
77
- max,
78
- maxLength,
79
- min,
80
- minLength,
81
- multiple,
82
- parse,
83
- regex,
84
- required,
85
- subscription,
86
- type,
87
- validate,
88
- validateFields,
89
- value
90
- });
91
- const error = getError({
92
- label,
93
- max,
94
- maxLength,
95
- meta: meta,
96
- min,
97
- minLength,
58
+ field,
59
+ fieldState: {
60
+ error
61
+ }
62
+ } = useController({
98
63
  name,
99
- regex,
100
- value: input.value
64
+ defaultValue,
65
+ shouldUnregister,
66
+ rules: {
67
+ required,
68
+ validate: {
69
+ ...(regexes ? {
70
+ pattern: value => regexes.every(regex => value === undefined || value === '' || (Array.isArray(regex) ? regex.some(regexOr => regexOr.test(value)) : regex.test(value)))
71
+ } : {}),
72
+ ...validate
73
+ },
74
+ minLength,
75
+ maxLength,
76
+ max,
77
+ min,
78
+ ...rules
79
+ }
101
80
  });
81
+ const transformedValue = () => {
82
+ if (format && !formatOnBlur) {
83
+ return format(field.value);
84
+ }
85
+ return field.value;
86
+ };
102
87
  return jsx(TextInput, {
88
+ name: field.name,
103
89
  autoCapitalize: autoCapitalize,
104
90
  autoComplete: autoComplete,
105
91
  autoCorrect: autoCorrect,
@@ -107,30 +93,40 @@ const TextInputField = /*#__PURE__*/forwardRef((_ref, ref) => {
107
93
  autoSave: autoSave,
108
94
  className: className,
109
95
  cols: cols,
110
- "data-testid": dataTestId,
111
96
  disabled: disabled,
112
- error: error,
97
+ error: customError ?? getError({
98
+ regex: regexes,
99
+ minLength,
100
+ maxLength,
101
+ label,
102
+ min,
103
+ max,
104
+ value: field.value
105
+ }, error),
113
106
  fillAvailable: fillAvailable,
114
107
  generated: generated,
115
108
  id: id,
116
109
  label: label,
117
- max: max,
118
- maxLength: maxLength,
119
- min: min,
120
- minLength: minLength,
121
110
  multiline: multiline,
122
- name: input.name,
123
111
  notice: notice,
112
+ required: required,
124
113
  onBlur: event => {
125
- input.onBlur(event);
114
+ field.onBlur();
126
115
  onBlur?.(event);
116
+ if (formatOnBlur && format) {
117
+ field.onChange(format(field.value));
118
+ }
127
119
  },
128
120
  onChange: event => {
129
- input.onChange(event);
130
- onChange?.(event);
121
+ if (parse) {
122
+ field.onChange(parse(event));
123
+ onChange?.(parse(event));
124
+ } else {
125
+ field.onChange(event);
126
+ onChange?.(event);
127
+ }
131
128
  },
132
129
  onFocus: event => {
133
- input.onFocus(event);
134
130
  onFocus?.(event);
135
131
  },
136
132
  onKeyUp: onKeyUp,
@@ -138,17 +134,16 @@ const TextInputField = /*#__PURE__*/forwardRef((_ref, ref) => {
138
134
  placeholder: placeholder,
139
135
  random: random,
140
136
  readOnly: readOnly,
141
- ref: ref,
142
- required: required,
143
137
  resizable: resizable,
144
138
  rows: rows,
145
- type: input.type,
146
- value: input.value,
139
+ type: type,
147
140
  noTopLabel: noTopLabel,
148
141
  unit: unit,
149
142
  valid: valid,
150
- size: size
143
+ size: size,
144
+ value: transformedValue(),
145
+ ref: innerRef
151
146
  });
152
- });
147
+ };
153
148
 
154
149
  export { TextInputField };
@@ -1,7 +1,6 @@
1
1
  import { TimeInput } from '@ultraviolet/ui';
2
- import { useMemo } from 'react';
2
+ import { useController } from 'react-hook-form';
3
3
  import { jsx } from '@emotion/react/jsx-runtime';
4
- import { useFormField } from '../../hooks/useFormField.js';
5
4
 
6
5
  const parseTime = date => {
7
6
  const timeStr = date && typeof date !== 'string' ? date.toLocaleTimeString().slice(0, -3) : '';
@@ -17,60 +16,59 @@ const TimeField = _ref => {
17
16
  schedule,
18
17
  placeholder,
19
18
  disabled,
20
- initialValue,
21
- validate,
22
19
  readOnly,
23
- value,
24
- onChange,
25
20
  onBlur,
26
21
  onFocus,
22
+ onChange,
27
23
  isLoading,
28
24
  isClearable,
29
25
  inputId,
30
26
  id,
31
- formatOnBlur,
32
27
  animation,
33
28
  animationDuration,
34
29
  animationOnChange,
35
30
  className,
36
31
  isSearchable,
32
+ rules,
37
33
  options,
38
- 'data-testid': dataTestId
34
+ 'data-testid': dataTestId,
35
+ shouldUnregister = false
39
36
  } = _ref;
40
37
  const {
41
- input,
42
- meta
43
- } = useFormField(name, {
44
- disabled,
45
- formatOnBlur,
46
- initialValue,
47
- required,
48
- validate,
49
- value
38
+ field,
39
+ fieldState: {
40
+ error
41
+ }
42
+ } = useController({
43
+ name,
44
+ shouldUnregister,
45
+ rules: {
46
+ required,
47
+ ...rules
48
+ }
50
49
  });
51
- const error = useMemo(() => input.value && meta.error ? meta.error : undefined, [input.value, meta.error]);
52
50
  return jsx(TimeInput, {
51
+ name: field.name,
53
52
  placeholder: placeholder,
54
53
  schedule: schedule,
55
54
  required: required,
56
- value: parseTime(input.value),
57
- onChange: (val, action) => {
55
+ value: parseTime(field.value),
56
+ onChange: val => {
58
57
  if (!val) return;
59
- onChange?.(val, action);
58
+ onChange?.(val);
60
59
  const [hours, minutes] = val.value.split(':');
61
- const date = input.value ? new Date(input.value) : new Date();
60
+ const date = field.value ? new Date(field.value) : new Date();
62
61
  date.setHours(Number(hours), Number(minutes), 0);
63
- input.onChange(date);
62
+ field.onChange(date);
64
63
  },
65
64
  onBlur: event => {
66
- input.onBlur(event);
65
+ field.onBlur();
67
66
  onBlur?.(event);
68
67
  },
69
68
  onFocus: event => {
70
- input.onFocus(event);
71
69
  onFocus?.(event);
72
70
  },
73
- error: error,
71
+ error: error?.message,
74
72
  disabled: disabled,
75
73
  readOnly: readOnly,
76
74
  animation: animation,