@strictly/react-form 0.0.1 → 0.0.2

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 (173) hide show
  1. package/.out/core/mobx/field_adapter.d.ts +7 -6
  2. package/.out/core/mobx/field_adapter_builder.d.ts +12 -13
  3. package/.out/core/mobx/field_adapter_builder.js +8 -12
  4. package/.out/core/mobx/field_adapters_of_values.d.ts +4 -0
  5. package/.out/core/mobx/flattened_adapters_of_fields.d.ts +2 -2
  6. package/.out/core/mobx/flattened_list_types_of_type.d.ts +8 -0
  7. package/.out/core/mobx/form_fields_of_field_adapters.d.ts +8 -0
  8. package/.out/core/mobx/form_presenter.d.ts +21 -24
  9. package/.out/core/mobx/form_presenter.js +64 -69
  10. package/.out/core/mobx/merge_field_adapters_with_two_way_converter.d.ts +13 -0
  11. package/.out/core/mobx/merge_field_adapters_with_two_way_converter.js +11 -0
  12. package/.out/core/mobx/merge_field_adapters_with_validators.d.ts +11 -0
  13. package/.out/core/mobx/merge_field_adapters_with_validators.js +45 -0
  14. package/.out/core/mobx/specs/fixtures.d.ts +7 -0
  15. package/.out/core/mobx/specs/fixtures.js +20 -0
  16. package/.out/core/mobx/specs/flattened_adapters_of_fields.tests.js +5 -2
  17. package/.out/core/mobx/specs/{flattened_list_type_defs_of.tests.js → flattened_list_types_of_types.tests.js} +7 -7
  18. package/.out/core/mobx/specs/form_presenter.tests.js +162 -60
  19. package/.out/core/mobx/specs/merge_field_adapters_with_two_way_converter.js +89 -0
  20. package/.out/core/mobx/specs/merge_field_adapters_with_validators.tests.js +172 -0
  21. package/.out/core/mobx/types.d.ts +2 -2
  22. package/.out/field_converters/chain_field_converter.d.ts +3 -3
  23. package/.out/field_converters/chain_field_converter.js +17 -12
  24. package/.out/field_converters/identity_converter.d.ts +3 -3
  25. package/.out/field_converters/identity_converter.js +10 -6
  26. package/.out/field_converters/integer_to_string_converter.d.ts +5 -4
  27. package/.out/field_converters/integer_to_string_converter.js +13 -6
  28. package/.out/field_converters/list_converter.d.ts +2 -2
  29. package/.out/field_converters/list_converter.js +6 -1
  30. package/.out/field_converters/maybe_identity_converter.d.ts +3 -3
  31. package/.out/field_converters/maybe_identity_converter.js +3 -1
  32. package/.out/field_converters/nullable_to_boolean_converter.d.ts +9 -8
  33. package/.out/field_converters/nullable_to_boolean_converter.js +13 -7
  34. package/.out/field_converters/select_value_type_converter.d.ts +20 -15
  35. package/.out/field_converters/select_value_type_converter.js +29 -14
  36. package/.out/field_converters/specs/chain_field_converter.tests.d.ts +1 -0
  37. package/.out/field_converters/specs/chain_field_converter.tests.js +251 -0
  38. package/.out/field_converters/trimming_string_converter.d.ts +3 -3
  39. package/.out/field_converters/trimming_string_converter.js +7 -3
  40. package/.out/field_converters/validating_converter.d.ts +3 -3
  41. package/.out/field_converters/validating_converter.js +7 -5
  42. package/.out/index.d.ts +9 -2
  43. package/.out/index.js +9 -2
  44. package/.out/mantine/create_checkbox.d.ts +2 -3
  45. package/.out/mantine/create_checkbox.js +6 -5
  46. package/.out/mantine/create_pill.js +2 -2
  47. package/.out/mantine/create_radio.js +1 -1
  48. package/.out/mantine/create_radio_group.d.ts +2 -3
  49. package/.out/mantine/create_radio_group.js +4 -3
  50. package/.out/mantine/create_text_input.d.ts +2 -3
  51. package/.out/mantine/create_text_input.js +6 -5
  52. package/.out/mantine/create_value_input.d.ts +2 -3
  53. package/.out/mantine/create_value_input.js +6 -5
  54. package/.out/mantine/error_renderer.d.ts +6 -0
  55. package/.out/mantine/error_renderer.js +5 -0
  56. package/.out/mantine/hooks.d.ts +9 -13
  57. package/.out/mantine/hooks.js +10 -15
  58. package/.out/mantine/specs/checkbox_hooks.stories.d.ts +7 -2
  59. package/.out/mantine/specs/checkbox_hooks.stories.js +33 -6
  60. package/.out/mantine/specs/list_hooks.stories.js +2 -2
  61. package/.out/mantine/specs/radio_group_hooks.stories.d.ts +7 -2
  62. package/.out/mantine/specs/radio_group_hooks.stories.js +33 -6
  63. package/.out/mantine/specs/select_hooks.stories.d.ts +8 -2
  64. package/.out/mantine/specs/select_hooks.stories.js +45 -8
  65. package/.out/mantine/specs/text_input_hooks.stories.d.ts +5 -1
  66. package/.out/mantine/specs/text_input_hooks.stories.js +23 -8
  67. package/.out/mantine/specs/value_input_hooks.stories.d.ts +7 -2
  68. package/.out/mantine/specs/value_input_hooks.stories.js +49 -15
  69. package/.out/mantine/types.d.ts +4 -1
  70. package/.out/tsconfig.tsbuildinfo +1 -1
  71. package/.out/types/error_of_field.d.ts +2 -0
  72. package/.out/types/error_of_field.js +1 -0
  73. package/.out/types/field.d.ts +1 -1
  74. package/.out/types/field_converters.d.ts +17 -10
  75. package/.out/types/field_converters.js +5 -5
  76. package/.out/types/flattened_validators_of_fields.d.ts +8 -0
  77. package/.out/types/flattened_validators_of_fields.js +1 -0
  78. package/.out/types/merge_validators.d.ts +7 -0
  79. package/.out/types/merge_validators.js +38 -0
  80. package/.out/types/specs/flattened_validators_of_fields.tests.d.ts +1 -0
  81. package/.out/types/specs/flattened_validators_of_fields.tests.js +16 -0
  82. package/.out/types/specs/merge_validators.tests.d.ts +1 -0
  83. package/.out/types/specs/merge_validators.tests.js +192 -0
  84. package/.out/util/partial.d.ts +11 -5
  85. package/.out/util/partial.js +55 -15
  86. package/.turbo/turbo-build.log +9 -9
  87. package/.turbo/turbo-check-types.log +1 -1
  88. package/.turbo/turbo-release$colon$exports.log +1 -1
  89. package/README.md +5 -1
  90. package/core/mobx/field_adapter.ts +15 -7
  91. package/core/mobx/field_adapter_builder.ts +39 -75
  92. package/core/mobx/field_adapters_of_values.ts +17 -0
  93. package/core/mobx/flattened_adapters_of_fields.ts +3 -3
  94. package/core/mobx/flattened_list_types_of_type.ts +17 -0
  95. package/core/mobx/form_fields_of_field_adapters.ts +16 -0
  96. package/core/mobx/form_presenter.ts +117 -104
  97. package/core/mobx/merge_field_adapters_with_two_way_converter.ts +68 -0
  98. package/core/mobx/merge_field_adapters_with_validators.ts +99 -0
  99. package/core/mobx/specs/fixtures.ts +73 -0
  100. package/core/mobx/specs/flattened_adapters_of_fields.tests.ts +23 -2
  101. package/core/mobx/specs/flattened_list_types_of_types.tests.ts +35 -0
  102. package/core/mobx/specs/form_presenter.tests.ts +248 -124
  103. package/core/mobx/specs/merge_field_adapters_with_two_way_converter.ts +140 -0
  104. package/core/mobx/specs/merge_field_adapters_with_validators.tests.ts +259 -0
  105. package/core/mobx/types.ts +3 -3
  106. package/dist/index.cjs +459 -211
  107. package/dist/index.d.cts +153 -111
  108. package/dist/index.d.ts +153 -111
  109. package/dist/index.js +453 -200
  110. package/field_converters/chain_field_converter.ts +37 -23
  111. package/field_converters/identity_converter.ts +14 -10
  112. package/field_converters/integer_to_string_converter.ts +15 -9
  113. package/field_converters/list_converter.ts +8 -3
  114. package/field_converters/maybe_identity_converter.ts +7 -4
  115. package/field_converters/nullable_to_boolean_converter.ts +23 -16
  116. package/field_converters/select_value_type_converter.ts +86 -26
  117. package/field_converters/specs/chain_field_converter.tests.ts +302 -0
  118. package/field_converters/trimming_string_converter.ts +11 -6
  119. package/field_converters/validating_converter.ts +21 -11
  120. package/index.ts +9 -2
  121. package/mantine/create_checkbox.tsx +15 -8
  122. package/mantine/create_list.tsx +1 -4
  123. package/mantine/create_pill.tsx +2 -2
  124. package/mantine/create_radio.tsx +1 -1
  125. package/mantine/create_radio_group.tsx +8 -6
  126. package/mantine/create_text_input.tsx +20 -8
  127. package/mantine/create_value_input.tsx +17 -8
  128. package/mantine/error_renderer.ts +15 -0
  129. package/mantine/hooks.tsx +25 -51
  130. package/mantine/specs/__snapshots__/checkbox_hooks.tests.tsx.snap +126 -0
  131. package/mantine/specs/__snapshots__/radio_group_hooks.tests.tsx.snap +356 -0
  132. package/mantine/specs/__snapshots__/select_hooks.tests.tsx.snap +208 -12
  133. package/mantine/specs/__snapshots__/text_input_hooks.tests.tsx.snap +45 -0
  134. package/mantine/specs/__snapshots__/value_input_hooks.tests.tsx.snap +194 -8
  135. package/mantine/specs/checkbox_hooks.stories.tsx +47 -7
  136. package/mantine/specs/list_hooks.stories.tsx +2 -2
  137. package/mantine/specs/radio_group_hooks.stories.tsx +47 -7
  138. package/mantine/specs/select_hooks.stories.tsx +55 -8
  139. package/mantine/specs/text_input_hooks.stories.tsx +32 -7
  140. package/mantine/specs/value_input_hooks.stories.tsx +57 -16
  141. package/mantine/types.ts +5 -1
  142. package/package.json +16 -4
  143. package/tsconfig.json +1 -0
  144. package/types/error_of_field.ts +3 -0
  145. package/types/field.ts +1 -1
  146. package/types/field_converters.ts +21 -10
  147. package/types/flattened_validators_of_fields.ts +34 -0
  148. package/types/merge_validators.ts +80 -0
  149. package/types/specs/error_type_of_field.tests.ts +2 -2
  150. package/types/specs/flattened_validators_of_fields.tests.ts +93 -0
  151. package/types/specs/merge_validators.tests.ts +267 -0
  152. package/util/partial.tsx +200 -16
  153. package/.out/core/mobx/flattened_list_type_defs_of.d.ts +0 -8
  154. package/.out/field_validators/minimum_string_length_field_validator.d.ts +0 -2
  155. package/.out/field_validators/minimum_string_length_field_validator.js +0 -8
  156. package/.out/types/error_type_of_field.d.ts +0 -2
  157. package/.out/types/field_validator.d.ts +0 -3
  158. package/.out/types/flattened_form_fields_of.d.ts +0 -9
  159. package/.out/types/specs/flattened_form_fields_of.tests.js +0 -13
  160. package/core/mobx/flattened_list_type_defs_of.ts +0 -17
  161. package/core/mobx/specs/flattened_list_type_defs_of.tests.ts +0 -35
  162. package/field_validators/minimum_string_length_field_validator.ts +0 -13
  163. package/mantine/specs/__snapshots__/check_box_hooks.tests.tsx.snap +0 -227
  164. package/types/error_type_of_field.ts +0 -3
  165. package/types/field_validator.ts +0 -7
  166. package/types/flattened_form_fields_of.ts +0 -16
  167. package/types/specs/flattened_form_fields_of.tests.ts +0 -43
  168. /package/.out/core/mobx/{flattened_list_type_defs_of.js → field_adapters_of_values.js} +0 -0
  169. /package/.out/core/mobx/{specs/flattened_list_type_defs_of.tests.d.ts → flattened_list_types_of_type.js} +0 -0
  170. /package/.out/{types/error_type_of_field.js → core/mobx/form_fields_of_field_adapters.js} +0 -0
  171. /package/.out/{types/field_validator.js → core/mobx/specs/flattened_list_types_of_types.tests.d.ts} +0 -0
  172. /package/.out/{types/flattened_form_fields_of.js → core/mobx/specs/merge_field_adapters_with_two_way_converter.d.ts} +0 -0
  173. /package/.out/{types/specs/flattened_form_fields_of.tests.d.ts → core/mobx/specs/merge_field_adapters_with_validators.tests.d.ts} +0 -0
@@ -0,0 +1,302 @@
1
+ import {
2
+ chainAnnotatedFieldConverter,
3
+ chainUnreliableFieldConverter,
4
+ } from 'field_converters/chain_field_converter'
5
+ import {
6
+ type AnnotatedFieldConversion,
7
+ type AnnotatedFieldConverter,
8
+ type UnreliableFieldConversion,
9
+ UnreliableFieldConversionType,
10
+ type UnreliableFieldConverter,
11
+ } from 'types/field_converters'
12
+ import { type Mock } from 'vitest'
13
+
14
+ const CONTEXT = 'ctx'
15
+ const ERROR1 = 'error 1'
16
+ const ERROR2 = 'error 2'
17
+
18
+ describe('chainUnreliableFieldConverter', function () {
19
+ const from: Mock<UnreliableFieldConverter<number, boolean, typeof ERROR1, 'x', typeof CONTEXT>> = vi.fn()
20
+ const to: Mock<UnreliableFieldConverter<boolean, string, typeof ERROR2, 'x', typeof CONTEXT>> = vi.fn()
21
+
22
+ let chained: UnreliableFieldConverter<number, string, typeof ERROR1 | typeof ERROR2, 'x', typeof CONTEXT>
23
+ let result: UnreliableFieldConversion<string, typeof ERROR1 | typeof ERROR2>
24
+
25
+ beforeEach(function () {
26
+ from.mockReset()
27
+ to.mockReset()
28
+
29
+ chained = chainUnreliableFieldConverter(from, to)
30
+ })
31
+ describe('from succeeds', function () {
32
+ beforeEach(function () {
33
+ from.mockReturnValue({
34
+ type: UnreliableFieldConversionType.Success,
35
+ value: true,
36
+ })
37
+ })
38
+
39
+ describe('to succeeds', function () {
40
+ beforeEach(function () {
41
+ to.mockReturnValue({
42
+ type: UnreliableFieldConversionType.Success,
43
+ value: 'x',
44
+ })
45
+ result = chained(1, 'x', CONTEXT)
46
+ })
47
+
48
+ it('equals expected type', function () {
49
+ expect(result).toEqual({
50
+ type: UnreliableFieldConversionType.Success,
51
+ value: 'x',
52
+ })
53
+ })
54
+
55
+ it('has the original value passed to the from converter', function () {
56
+ expect(from).toHaveBeenCalledOnce()
57
+ expect(from).toHaveBeenCalledWith(1, 'x', CONTEXT)
58
+ })
59
+
60
+ it('has passed the from result to the to converter', function () {
61
+ expect(to).toHaveBeenCalledOnce()
62
+ expect(to).toHaveBeenCalledWith(true, 'x', CONTEXT)
63
+ })
64
+ })
65
+
66
+ describe('to fails with result', function () {
67
+ beforeEach(function () {
68
+ to.mockReturnValue({
69
+ type: UnreliableFieldConversionType.Failure,
70
+ value: ['y'],
71
+ error: ERROR2,
72
+ })
73
+ result = chained(1, 'x', CONTEXT)
74
+ })
75
+
76
+ it('equals expected type', function () {
77
+ expect(result).toEqual({
78
+ type: UnreliableFieldConversionType.Failure,
79
+ value: ['y'],
80
+ error: ERROR2,
81
+ })
82
+ })
83
+ })
84
+ })
85
+
86
+ describe('from fails with a value', function () {
87
+ beforeEach(function () {
88
+ from.mockReturnValue({
89
+ type: UnreliableFieldConversionType.Failure,
90
+ value: [true],
91
+ error: ERROR1,
92
+ })
93
+ })
94
+
95
+ describe('to succeeds', function () {
96
+ beforeEach(function () {
97
+ to.mockReturnValue({
98
+ type: UnreliableFieldConversionType.Success,
99
+ value: 'x',
100
+ })
101
+ result = chained(1, 'x', CONTEXT)
102
+ })
103
+
104
+ it('equals expected type', function () {
105
+ expect(result).toEqual({
106
+ type: UnreliableFieldConversionType.Failure,
107
+ value: ['x'],
108
+ error: ERROR1,
109
+ })
110
+ })
111
+
112
+ it('has the original value passed to the from converter', function () {
113
+ expect(from).toHaveBeenCalledOnce()
114
+ expect(from).toHaveBeenCalledWith(1, 'x', CONTEXT)
115
+ })
116
+
117
+ it('passes the failure result to the to converter', function () {
118
+ expect(to).toHaveBeenCalledOnce()
119
+ expect(to).toHaveBeenCalledWith(true, 'x', CONTEXT)
120
+ })
121
+ })
122
+
123
+ describe('to fails', function () {
124
+ beforeEach(function () {
125
+ to.mockReturnValue({
126
+ type: UnreliableFieldConversionType.Failure,
127
+ value: ['x'],
128
+ error: ERROR2,
129
+ })
130
+ result = chained(1, 'x', CONTEXT)
131
+ })
132
+
133
+ it('equals expected type', function () {
134
+ expect(result).toEqual({
135
+ type: UnreliableFieldConversionType.Failure,
136
+ value: ['x'],
137
+ error: ERROR1,
138
+ })
139
+ })
140
+ })
141
+ })
142
+
143
+ describe('from fails with no value', function () {
144
+ beforeEach(function () {
145
+ from.mockReturnValue({
146
+ type: UnreliableFieldConversionType.Failure,
147
+ value: null,
148
+ error: ERROR1,
149
+ })
150
+ result = chained(1, 'x', CONTEXT)
151
+ })
152
+
153
+ it('equals expected type', function () {
154
+ expect(result).toEqual({
155
+ type: UnreliableFieldConversionType.Failure,
156
+ value: null,
157
+ error: ERROR1,
158
+ })
159
+ })
160
+
161
+ it('does not call to converter', function () {
162
+ expect(to).not.toHaveBeenCalled()
163
+ })
164
+ })
165
+ })
166
+
167
+ describe('chainAnnotatedFieldConverter', function () {
168
+ const from: Mock<AnnotatedFieldConverter<string, boolean, 'x', typeof CONTEXT>> = vi.fn()
169
+ const to: Mock<AnnotatedFieldConverter<boolean, number, 'x', typeof CONTEXT>> = vi.fn()
170
+
171
+ let chained: AnnotatedFieldConverter<string, number, 'x', typeof CONTEXT>
172
+ let result: AnnotatedFieldConversion<number>
173
+
174
+ beforeEach(function () {
175
+ from.mockReset()
176
+ to.mockReset()
177
+
178
+ chained = chainAnnotatedFieldConverter(from, to)
179
+ })
180
+
181
+ describe('value', function () {
182
+ beforeEach(function () {
183
+ from.mockReturnValue({
184
+ value: true,
185
+ readonly: false,
186
+ required: false,
187
+ })
188
+ to.mockReturnValue({
189
+ value: 1,
190
+ readonly: false,
191
+ required: false,
192
+ })
193
+ result = chained('z', 'x', CONTEXT)
194
+ })
195
+
196
+ it('returns expected value', function () {
197
+ expect(result).toEqual(
198
+ expect.objectContaining({
199
+ value: 1,
200
+ }),
201
+ )
202
+ })
203
+
204
+ it('calls the from converter', function () {
205
+ expect(from).toHaveBeenCalledOnce()
206
+ expect(from).toHaveBeenCalledWith('z', 'x', CONTEXT)
207
+ })
208
+
209
+ it('calls the to converter', function () {
210
+ expect(to).toHaveBeenCalledOnce()
211
+ expect(to).toHaveBeenCalledWith(true, 'x', CONTEXT)
212
+ })
213
+ })
214
+
215
+ describe.each([
216
+ [
217
+ true,
218
+ true,
219
+ true,
220
+ ],
221
+ [
222
+ true,
223
+ false,
224
+ true,
225
+ ],
226
+ [
227
+ false,
228
+ true,
229
+ true,
230
+ ],
231
+ [
232
+ false,
233
+ false,
234
+ false,
235
+ ],
236
+ ] as const)(
237
+ 'from required %s to required %s result %s',
238
+ function (fromRequired, toRequired, required) {
239
+ beforeEach(function () {
240
+ from.mockReturnValue({
241
+ value: true,
242
+ readonly: false,
243
+ required: fromRequired,
244
+ })
245
+ to.mockReturnValue({
246
+ value: 1,
247
+ readonly: false,
248
+ required: toRequired,
249
+ })
250
+ result = chained('z', 'x', CONTEXT)
251
+ })
252
+
253
+ it('required matches expected', function () {
254
+ expect(result.required).toEqual(required)
255
+ })
256
+ },
257
+ )
258
+
259
+ describe.each([
260
+ [
261
+ true,
262
+ true,
263
+ true,
264
+ ],
265
+ [
266
+ true,
267
+ false,
268
+ true,
269
+ ],
270
+ [
271
+ false,
272
+ true,
273
+ true,
274
+ ],
275
+ [
276
+ false,
277
+ false,
278
+ false,
279
+ ],
280
+ ] as const)(
281
+ 'from disabled %s to disabled %s result %s',
282
+ function (fromDisabled, toDisabled, disabled) {
283
+ beforeEach(function () {
284
+ from.mockReturnValue({
285
+ value: true,
286
+ readonly: fromDisabled,
287
+ required: false,
288
+ })
289
+ to.mockReturnValue({
290
+ value: 1,
291
+ readonly: toDisabled,
292
+ required: false,
293
+ })
294
+ result = chained('z', 'x', CONTEXT)
295
+ })
296
+
297
+ it('required matches expected', function () {
298
+ expect(result.readonly).toEqual(disabled)
299
+ })
300
+ },
301
+ )
302
+ })
@@ -1,7 +1,8 @@
1
1
  import {
2
- type FieldConversion,
3
- FieldConversionResult,
2
+ type AnnotatedFieldConversion,
4
3
  type TwoWayFieldConverter,
4
+ type UnreliableFieldConversion,
5
+ UnreliableFieldConversionType,
5
6
  } from 'types/field_converters'
6
7
 
7
8
  export class TrimmingStringConverter<ValuePath extends string, Context>
@@ -10,13 +11,17 @@ export class TrimmingStringConverter<ValuePath extends string, Context>
10
11
  constructor() {
11
12
  }
12
13
 
13
- convert(to: string): string {
14
- return to.trim()
14
+ convert(to: string): AnnotatedFieldConversion<string> {
15
+ return {
16
+ value: to.trim(),
17
+ required: false,
18
+ readonly: false,
19
+ }
15
20
  }
16
21
 
17
- revert(from: string): FieldConversion<string, never> {
22
+ revert(from: string): UnreliableFieldConversion<string, never> {
18
23
  return {
19
- type: FieldConversionResult.Success,
24
+ type: UnreliableFieldConversionType.Success,
20
25
  value: from.trim(),
21
26
  }
22
27
  }
@@ -1,24 +1,34 @@
1
1
  import {
2
- type FieldConversion,
3
- FieldConversionResult,
4
- type FieldConverter,
2
+ validate,
3
+ type Validator,
4
+ } from '@strictly/define'
5
+ import {
6
+ type UnreliableFieldConversion,
7
+ UnreliableFieldConversionType,
8
+ type UnreliableFieldConverter,
5
9
  } from 'types/field_converters'
6
- import { type FieldValidator } from 'types/field_validator'
7
10
 
11
+ // delete this?
8
12
  export function validatingConverter<
9
13
  V,
10
14
  E,
11
15
  ValuePath extends string,
12
16
  Context,
13
- >(validators: readonly FieldValidator<V, E, ValuePath, Context>[] = []): FieldConverter<V, V, E, ValuePath, Context> {
14
- return function (value: V, valuePath: ValuePath, context: Context): FieldConversion<V, E> {
15
- return validators.reduce<FieldConversion<V, E>>(
17
+ >(validators: readonly Validator<V, E, ValuePath, Context>[] = []): UnreliableFieldConverter<
18
+ V,
19
+ V,
20
+ E,
21
+ ValuePath,
22
+ Context
23
+ > {
24
+ return function (value: V, valuePath: ValuePath, context: Context): UnreliableFieldConversion<V, E> {
25
+ return validators.reduce<UnreliableFieldConversion<V, E>>(
16
26
  function (acc, validator) {
17
- if (acc.type === FieldConversionResult.Success) {
18
- const error = validator(value, valuePath, context)
27
+ if (acc.type === UnreliableFieldConversionType.Success) {
28
+ const error = validate(validator, value, valuePath, context)
19
29
  if (error != null) {
20
30
  return {
21
- type: FieldConversionResult.Failure,
31
+ type: UnreliableFieldConversionType.Failure,
22
32
  error,
23
33
  value: [value],
24
34
  }
@@ -27,7 +37,7 @@ export function validatingConverter<
27
37
  return acc
28
38
  },
29
39
  {
30
- type: FieldConversionResult.Success,
40
+ type: UnreliableFieldConversionType.Success,
31
41
  value,
32
42
  },
33
43
  )
package/index.ts CHANGED
@@ -1,6 +1,11 @@
1
+ export * from './core/mobx/field_adapter'
1
2
  export * from './core/mobx/field_adapter_builder'
3
+ export * from './core/mobx/field_adapters_of_values'
2
4
  export * from './core/mobx/flattened_adapters_of_fields'
5
+ export * from './core/mobx/form_fields_of_field_adapters'
3
6
  export * from './core/mobx/form_presenter'
7
+ export * from './core/mobx/merge_field_adapters_with_two_way_converter'
8
+ export * from './core/mobx/merge_field_adapters_with_validators'
4
9
  export * from './core/mobx/types'
5
10
  export * from './core/props'
6
11
  export * from './field_converters/integer_to_string_converter'
@@ -8,9 +13,11 @@ export * from './field_converters/nullable_to_boolean_converter'
8
13
  export * from './field_converters/select_value_type_converter'
9
14
  export * from './field_converters/trimming_string_converter'
10
15
  export * from './field_converters/validating_converter'
11
- export * from './field_validators/minimum_string_length_field_validator'
12
16
  export * from './field_value_factories/prototyping_field_value_factory'
17
+ export * from './mantine/error_renderer'
13
18
  export * from './mantine/hooks'
19
+ export * from './types/error_of_field'
14
20
  export * from './types/field'
15
- export * from './types/flattened_form_fields_of'
21
+ export * from './types/field_converters'
22
+ export * from './types/merge_validators'
16
23
  export * from './util/partial'
@@ -3,10 +3,13 @@ import {
3
3
  } from '@mantine/core'
4
4
  import { type ComponentType } from 'react'
5
5
  import { type BooleanFieldsOfFields } from 'types/boolean_fields_of_fields'
6
- import { type ErrorTypeOfField } from 'types/error_type_of_field'
6
+ import { type ErrorOfField } from 'types/error_of_field'
7
7
  import { type Fields } from 'types/field'
8
8
  import { createUnsafePartialObserverComponent } from 'util/partial'
9
- import { type ErrorRenderer } from './hooks'
9
+ import {
10
+ DefaultErrorRenderer,
11
+ type ErrorRenderer,
12
+ } from './error_renderer'
10
13
  import {
11
14
  type MantineFieldComponent,
12
15
  type MantineForm,
@@ -33,8 +36,7 @@ export function createCheckbox<
33
36
  this: MantineForm<F>,
34
37
  valuePath: K,
35
38
  Checkbox: ComponentType<Props>,
36
- ErrorRenderer: ErrorRenderer<ErrorTypeOfField<F[K]>>,
37
- ): MantineFieldComponent<SuppliedCheckboxProps, Props> {
39
+ ): MantineFieldComponent<SuppliedCheckboxProps, Props, ErrorOfField<F[K]>> {
38
40
  const onChange = (e: React.ChangeEvent<HTMLInputElement>) => {
39
41
  this.onFieldValueChange?.(valuePath, e.target.checked)
40
42
  }
@@ -52,9 +54,13 @@ export function createCheckbox<
52
54
  }
53
55
  }
54
56
 
55
- const propSource = () => {
57
+ const propSource = ({
58
+ ErrorRenderer = DefaultErrorRenderer,
59
+ }: {
60
+ ErrorRenderer?: ErrorRenderer<ErrorOfField<F[K]>>,
61
+ }) => {
56
62
  const {
57
- disabled,
63
+ readonly,
58
64
  required,
59
65
  value,
60
66
  error,
@@ -63,7 +69,7 @@ export function createCheckbox<
63
69
  return {
64
70
  name: valuePath,
65
71
  checked: value,
66
- disabled,
72
+ disabled: readonly,
67
73
  required,
68
74
  error: error && <ErrorRenderer error={error} />,
69
75
  onChange,
@@ -72,8 +78,9 @@ export function createCheckbox<
72
78
  onKeyUp,
73
79
  }
74
80
  }
75
- return createUnsafePartialObserverComponent<typeof Checkbox, SuppliedCheckboxProps>(
81
+ return createUnsafePartialObserverComponent(
76
82
  Checkbox,
77
83
  propSource,
84
+ ['ErrorRenderer'],
78
85
  )
79
86
  }
@@ -34,10 +34,7 @@ export function createList<
34
34
  values,
35
35
  }
36
36
  }
37
- return createUnsafePartialObserverComponent<
38
- typeof List,
39
- SuppliedListProps<ElementOfArray<ValueTypeOfField<F[K]>>>
40
- >(List, propSource)
37
+ return createUnsafePartialObserverComponent(List, propSource)
41
38
  }
42
39
 
43
40
  export function DefaultList<
@@ -28,7 +28,7 @@ export function createPill<
28
28
  ): MantineFieldComponent<SuppliedPillProps, Props> {
29
29
  const propSource = () => {
30
30
  const {
31
- disabled,
31
+ readonly,
32
32
  value,
33
33
  // note: individual pills cannot display an error!
34
34
  // error,
@@ -36,7 +36,7 @@ export function createPill<
36
36
  } = this.fields[valuePath as string]
37
37
  return {
38
38
  children: value,
39
- disabled,
39
+ disabled: readonly,
40
40
  }
41
41
  }
42
42
  return createUnsafePartialObserverComponent<typeof Pill, SuppliedPillProps>(Pill, propSource)
@@ -25,7 +25,7 @@ export function createRadio<
25
25
  ): MantineFieldComponent<SuppliedRadioProps, Props> {
26
26
  const propSource = () => {
27
27
  return {
28
- disabled: this.fields[valuePath].disabled,
28
+ disabled: this.fields[valuePath].readonly,
29
29
  value,
30
30
  }
31
31
  }
@@ -2,7 +2,7 @@ import {
2
2
  type RadioGroupProps,
3
3
  } from '@mantine/core'
4
4
  import { type ComponentType } from 'react'
5
- import { type ErrorTypeOfField } from 'types/error_type_of_field'
5
+ import { type ErrorOfField } from 'types/error_of_field'
6
6
  import {
7
7
  type Fields,
8
8
  } from 'types/field'
@@ -10,7 +10,10 @@ import { type StringFieldsOfFields } from 'types/string_fields_of_fields'
10
10
  import {
11
11
  createUnsafePartialObserverComponent,
12
12
  } from 'util/partial'
13
- import { type ErrorRenderer } from './hooks'
13
+ import {
14
+ DefaultErrorRenderer,
15
+ type ErrorRenderer,
16
+ } from './error_renderer'
14
17
  import {
15
18
  type MantineFieldComponent,
16
19
  type MantineForm,
@@ -29,8 +32,7 @@ export function createRadioGroup<
29
32
  this: MantineForm<F>,
30
33
  valuePath: K,
31
34
  RadioGroup: ComponentType<Props>,
32
- ErrorRenderer: ErrorRenderer<ErrorTypeOfField<F[K]>>,
33
- ): MantineFieldComponent<SuppliedRadioGroupProps, Props> {
35
+ ): MantineFieldComponent<SuppliedRadioGroupProps, Props, ErrorOfField<F[K]>> {
34
36
  const onChange = (value: string) => {
35
37
  this.onFieldValueChange?.(valuePath, value)
36
38
  }
@@ -48,7 +50,7 @@ export function createRadioGroup<
48
50
  }
49
51
  }
50
52
 
51
- const propSource = () => {
53
+ const propSource = ({ ErrorRenderer = DefaultErrorRenderer }: { ErrorRenderer?: ErrorRenderer }) => {
52
54
  const {
53
55
  required,
54
56
  value,
@@ -67,5 +69,5 @@ export function createRadioGroup<
67
69
  }
68
70
  }
69
71
 
70
- return createUnsafePartialObserverComponent(RadioGroup, propSource)
72
+ return createUnsafePartialObserverComponent(RadioGroup, propSource, ['ErrorRenderer'])
71
73
  }
@@ -1,8 +1,11 @@
1
- import { type ErrorTypeOfField } from 'types/error_type_of_field'
1
+ import { type ErrorOfField } from 'types/error_of_field'
2
2
  import { type Fields } from 'types/field'
3
3
  import { type StringFieldsOfFields } from 'types/string_fields_of_fields'
4
4
  import { createUnsafePartialObserverComponent } from 'util/partial'
5
- import { type ErrorRenderer } from './hooks'
5
+ import {
6
+ DefaultErrorRenderer,
7
+ type ErrorRenderer,
8
+ } from './error_renderer'
6
9
  import {
7
10
  type MantineFieldComponent,
8
11
  type MantineForm,
@@ -33,8 +36,7 @@ export function createTextInput<
33
36
  this: MantineForm<F>,
34
37
  valuePath: K,
35
38
  TextInput: React.ComponentType<Props>,
36
- ErrorRenderer: ErrorRenderer<ErrorTypeOfField<F[K]>>,
37
- ): MantineFieldComponent<SuppliedTextInputProps, Props> {
39
+ ): MantineFieldComponent<SuppliedTextInputProps, Props, ErrorOfField<F[K]>> {
38
40
  const onChange = (e: React.ChangeEvent<TextInputTarget>) => {
39
41
  this.onFieldValueChange?.(valuePath, e.target.value)
40
42
  }
@@ -52,9 +54,13 @@ export function createTextInput<
52
54
  }
53
55
  }
54
56
 
55
- const propSource = () => {
57
+ const propSource = ({
58
+ ErrorRenderer = DefaultErrorRenderer,
59
+ }: {
60
+ ErrorRenderer?: ErrorRenderer<ErrorOfField<F[K]>>,
61
+ }) => {
56
62
  const {
57
- disabled,
63
+ readonly,
58
64
  required,
59
65
  value,
60
66
  error,
@@ -64,7 +70,7 @@ export function createTextInput<
64
70
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
65
71
  name: valuePath as string,
66
72
  value,
67
- disabled,
73
+ disabled: readonly,
68
74
  required,
69
75
  error: error && <ErrorRenderer error={error} />,
70
76
  onChange,
@@ -73,8 +79,14 @@ export function createTextInput<
73
79
  onKeyUp,
74
80
  }
75
81
  }
76
- return createUnsafePartialObserverComponent<typeof TextInput, SuppliedTextInputProps>(
82
+ return createUnsafePartialObserverComponent<
83
+ typeof TextInput,
84
+ SuppliedTextInputProps,
85
+ { ErrorRenderer?: ErrorRenderer<ErrorOfField<F[K]>> },
86
+ ['ErrorRenderer']
87
+ >(
77
88
  TextInput,
78
89
  propSource,
90
+ ['ErrorRenderer'],
79
91
  )
80
92
  }
@@ -1,9 +1,12 @@
1
1
  import { type AllFieldsOfFields } from 'types/all_fields_of_fields'
2
- import { type ErrorTypeOfField } from 'types/error_type_of_field'
2
+ import { type ErrorOfField } from 'types/error_of_field'
3
3
  import { type Fields } from 'types/field'
4
4
  import { type ValueTypeOfField } from 'types/value_type_of_field'
5
5
  import { createUnsafePartialObserverComponent } from 'util/partial'
6
- import { type ErrorRenderer } from './hooks'
6
+ import {
7
+ DefaultErrorRenderer,
8
+ type ErrorRenderer,
9
+ } from './error_renderer'
7
10
  import {
8
11
  type MantineFieldComponent,
9
12
  type MantineForm,
@@ -31,8 +34,7 @@ export function createValueInput<
31
34
  this: MantineForm<F>,
32
35
  valuePath: K,
33
36
  ValueInput: React.ComponentType<Props>,
34
- ErrorRenderer: ErrorRenderer<ErrorTypeOfField<F[K]>>,
35
- ): MantineFieldComponent<SuppliedValueInputProps<ValueTypeOfField<F[K]>>, Props> {
37
+ ): MantineFieldComponent<SuppliedValueInputProps<ValueTypeOfField<F[K]>>, Props, ErrorOfField<F[K]>> {
36
38
  const onChange = (value: ValueTypeOfField<F[K]>) => {
37
39
  this.onFieldValueChange?.(valuePath, value)
38
40
  }
@@ -50,9 +52,13 @@ export function createValueInput<
50
52
  }
51
53
  }
52
54
 
53
- const propSource = () => {
55
+ const propSource = ({
56
+ ErrorRenderer = DefaultErrorRenderer,
57
+ }: {
58
+ ErrorRenderer?: ErrorRenderer<ErrorOfField<F[K]>>,
59
+ }) => {
54
60
  const {
55
- disabled,
61
+ readonly,
56
62
  required,
57
63
  value,
58
64
  error,
@@ -62,7 +68,7 @@ export function createValueInput<
62
68
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
63
69
  name: valuePath as string,
64
70
  value,
65
- disabled,
71
+ disabled: readonly,
66
72
  required,
67
73
  error: error && <ErrorRenderer error={error} />,
68
74
  onChange,
@@ -73,9 +79,12 @@ export function createValueInput<
73
79
  }
74
80
  return createUnsafePartialObserverComponent<
75
81
  typeof ValueInput,
76
- SuppliedValueInputProps<ValueTypeOfField<F[K]>>
82
+ SuppliedValueInputProps<ValueTypeOfField<F[K]>>,
83
+ { ErrorRenderer?: ErrorRenderer<ErrorOfField<F[K]>> },
84
+ ['ErrorRenderer']
77
85
  >(
78
86
  ValueInput,
79
87
  propSource,
88
+ ['ErrorRenderer'],
80
89
  )
81
90
  }