@strictly/react-form 0.0.8 → 0.0.10

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 (44) hide show
  1. package/.out/core/mobx/field_adapter_builder.d.ts +4 -0
  2. package/.out/core/mobx/field_adapter_builder.js +31 -0
  3. package/.out/core/mobx/form_presenter.d.ts +5 -5
  4. package/.out/core/mobx/form_presenter.js +8 -6
  5. package/.out/core/mobx/hooks.d.ts +24 -4
  6. package/.out/core/mobx/hooks.js +24 -3
  7. package/.out/core/mobx/specs/form_presenter.tests.js +10 -5
  8. package/.out/core/mobx/sub_form_field_adapters.d.ts +2 -2
  9. package/.out/field_converters/chain_field_converter.js +3 -3
  10. package/.out/mantine/create_fields_view.d.ts +9 -1
  11. package/.out/mantine/create_fields_view.js +13 -1
  12. package/.out/mantine/error_renderer.d.ts +7 -3
  13. package/.out/mantine/hooks.d.ts +2 -1
  14. package/.out/mantine/hooks.js +1 -1
  15. package/.out/mantine/specs/create_fields_view.tests.js +17 -0
  16. package/.out/mantine/specs/fields_view_hooks.stories.d.ts +6 -2
  17. package/.out/mantine/specs/fields_view_hooks.stories.js +26 -7
  18. package/.out/mantine/specs/fields_view_hooks.tests.js +21 -1
  19. package/.out/tsconfig.tsbuildinfo +1 -1
  20. package/.out/types/specs/error_of_field.tests.d.ts +1 -0
  21. package/.out/types/specs/{error_type_of_field.tests.js → error_of_field.tests.js} +1 -1
  22. package/.turbo/turbo-build.log +8 -8
  23. package/.turbo/turbo-check-types.log +1 -1
  24. package/core/mobx/field_adapter_builder.ts +71 -0
  25. package/core/mobx/form_presenter.ts +15 -14
  26. package/core/mobx/hooks.tsx +196 -0
  27. package/core/mobx/specs/form_presenter.tests.ts +24 -5
  28. package/core/mobx/sub_form_field_adapters.ts +14 -3
  29. package/dist/index.cjs +290 -220
  30. package/dist/index.d.cts +63 -32
  31. package/dist/index.d.ts +63 -32
  32. package/dist/index.js +288 -219
  33. package/field_converters/chain_field_converter.ts +3 -3
  34. package/mantine/create_fields_view.tsx +66 -31
  35. package/mantine/error_renderer.ts +12 -3
  36. package/mantine/hooks.tsx +9 -6
  37. package/mantine/specs/__snapshots__/fields_view_hooks.tests.tsx.snap +194 -197
  38. package/mantine/specs/create_fields_view.tests.ts +29 -0
  39. package/mantine/specs/fields_view_hooks.stories.tsx +58 -15
  40. package/mantine/specs/fields_view_hooks.tests.tsx +26 -0
  41. package/package.json +1 -1
  42. package/types/specs/{error_type_of_field.tests.ts → error_of_field.tests.ts} +1 -1
  43. package/core/mobx/hooks.ts +0 -112
  44. /package/.out/{types/specs/error_type_of_field.tests.d.ts → mantine/specs/create_fields_view.tests.d.ts} +0 -0
@@ -19,7 +19,7 @@ exports[`field view hooks > renders Disabled 1`] = `
19
19
  for="mantine-0cyk5rcyk"
20
20
  id="mantine-0cyk5rcyk-label"
21
21
  >
22
- fields view
22
+ $
23
23
  </label>
24
24
  <div
25
25
  class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
@@ -39,51 +39,46 @@ exports[`field view hooks > renders Disabled 1`] = `
39
39
  </div>
40
40
  </div>
41
41
  <div
42
- class="m_6d731127 mantine-Stack-root"
43
- style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
42
+ class="m_1b7284a3 mantine-Paper-root"
43
+ data-with-border="true"
44
44
  >
45
+ <p
46
+ class="mantine-focus-auto m_b6d8b162 mantine-Text-root"
47
+ >
48
+ $.a
49
+ </p>
45
50
  <div
46
- class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
51
+ class="m_6d731127 mantine-Stack-root"
52
+ style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
47
53
  >
48
- <label
49
- class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
50
- for="mantine-0px4bipx4"
51
- id="mantine-0px4bipx4-label"
52
- >
53
- sub fields view
54
- </label>
55
54
  <div
56
- class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
57
- data-disabled="true"
58
- data-variant="default"
55
+ class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
59
56
  >
60
- <input
61
- aria-invalid="false"
62
- class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
57
+ <label
58
+ class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
59
+ for="mantine-0px4bipx4"
60
+ id="mantine-0px4bipx4-label"
61
+ >
62
+ $ (child)
63
+ </label>
64
+ <div
65
+ class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
63
66
  data-disabled="true"
64
67
  data-variant="default"
65
- disabled=""
66
- id="mantine-0px4bipx4"
67
- name="$"
68
- value="yyy"
69
- />
68
+ >
69
+ <input
70
+ aria-invalid="false"
71
+ class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
72
+ data-disabled="true"
73
+ data-variant="default"
74
+ disabled=""
75
+ id="mantine-0px4bipx4"
76
+ name="$"
77
+ value="yyy"
78
+ />
79
+ </div>
70
80
  </div>
71
81
  </div>
72
- <button
73
- class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root"
74
- style="--button-color: var(--mantine-color-white);"
75
- type="button"
76
- >
77
- <span
78
- class="m_80f1301b mantine-Button-inner"
79
- >
80
- <span
81
- class="m_811560b9 mantine-Button-label"
82
- >
83
- Bonus Button
84
- </span>
85
- </span>
86
- </button>
87
82
  </div>
88
83
  </div>
89
84
  </div>
@@ -105,10 +100,10 @@ exports[`field view hooks > renders Empty 1`] = `
105
100
  >
106
101
  <label
107
102
  class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
108
- for="mantine-0px4bipx4"
109
- id="mantine-0px4bipx4-label"
103
+ for="mantine-0cyk5rcyk"
104
+ id="mantine-0cyk5rcyk-label"
110
105
  >
111
- fields view
106
+ $
112
107
  </label>
113
108
  <div
114
109
  class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
@@ -118,55 +113,50 @@ exports[`field view hooks > renders Empty 1`] = `
118
113
  aria-invalid="false"
119
114
  class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
120
115
  data-variant="default"
121
- id="mantine-0px4bipx4"
116
+ id="mantine-0cyk5rcyk"
122
117
  name="$"
123
118
  value=""
124
119
  />
125
120
  </div>
126
121
  </div>
127
122
  <div
128
- class="m_6d731127 mantine-Stack-root"
129
- style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
123
+ class="m_1b7284a3 mantine-Paper-root"
124
+ data-with-border="true"
130
125
  >
126
+ <p
127
+ class="mantine-focus-auto m_b6d8b162 mantine-Text-root"
128
+ >
129
+ $.a
130
+ </p>
131
131
  <div
132
- class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
132
+ class="m_6d731127 mantine-Stack-root"
133
+ style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
133
134
  >
134
- <label
135
- class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
136
- for="mantine-12voha2vo"
137
- id="mantine-12voha2vo-label"
138
- >
139
- sub fields view
140
- </label>
141
135
  <div
142
- class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
143
- data-variant="default"
136
+ class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
144
137
  >
145
- <input
146
- aria-invalid="false"
147
- class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
138
+ <label
139
+ class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
140
+ for="mantine-0px4bipx4"
141
+ id="mantine-0px4bipx4-label"
142
+ >
143
+ $ (child)
144
+ </label>
145
+ <div
146
+ class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
148
147
  data-variant="default"
149
- id="mantine-12voha2vo"
150
- name="$"
151
- value=""
152
- />
148
+ >
149
+ <input
150
+ aria-invalid="false"
151
+ class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
152
+ data-variant="default"
153
+ id="mantine-0px4bipx4"
154
+ name="$"
155
+ value=""
156
+ />
157
+ </div>
153
158
  </div>
154
159
  </div>
155
- <button
156
- class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root"
157
- style="--button-color: var(--mantine-color-white);"
158
- type="button"
159
- >
160
- <span
161
- class="m_80f1301b mantine-Button-inner"
162
- >
163
- <span
164
- class="m_811560b9 mantine-Button-label"
165
- >
166
- Bonus Button
167
- </span>
168
- </span>
169
- </button>
170
160
  </div>
171
161
  </div>
172
162
  </div>
@@ -192,7 +182,7 @@ exports[`field view hooks > renders Errors 1`] = `
192
182
  for="mantine-0cyk5rcyk"
193
183
  id="mantine-0cyk5rcyk-label"
194
184
  >
195
- fields view
185
+ $
196
186
  </label>
197
187
  <div
198
188
  class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
@@ -219,64 +209,70 @@ exports[`field view hooks > renders Errors 1`] = `
219
209
  </p>
220
210
  </div>
221
211
  <div
222
- class="m_6d731127 mantine-Stack-root"
223
- style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
212
+ class="m_1b7284a3 mantine-Paper-root"
213
+ data-with-border="true"
224
214
  >
215
+ <p
216
+ class="mantine-focus-auto m_b6d8b162 mantine-Text-root"
217
+ >
218
+ $.a
219
+ </p>
225
220
  <div
226
- class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
227
- data-error="true"
221
+ class="m_6d731127 mantine-Stack-root"
222
+ style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
228
223
  >
229
- <label
230
- class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
231
- for="mantine-0px4bipx4"
232
- id="mantine-0px4bipx4-label"
233
- >
234
- sub fields view
235
- </label>
236
224
  <div
237
- class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
225
+ class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
238
226
  data-error="true"
239
- data-variant="default"
240
- style="--input-margin-bottom: calc(var(--mantine-spacing-xs) / 2);"
241
227
  >
242
- <input
243
- aria-describedby="mantine-0px4bipx4-error"
244
- aria-invalid="true"
245
- class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
228
+ <label
229
+ class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
230
+ for="mantine-0px4bipx4"
231
+ id="mantine-0px4bipx4-label"
232
+ >
233
+ $ (child)
234
+ </label>
235
+ <div
236
+ class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
246
237
  data-error="true"
247
238
  data-variant="default"
248
- id="mantine-0px4bipx4"
249
- name="$"
250
- value="xxx"
251
- />
239
+ style="--input-margin-bottom: calc(var(--mantine-spacing-xs) / 2);"
240
+ >
241
+ <input
242
+ aria-describedby="mantine-0px4bipx4-error"
243
+ aria-invalid="true"
244
+ class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
245
+ data-error="true"
246
+ data-variant="default"
247
+ id="mantine-0px4bipx4"
248
+ name="$"
249
+ value="xxx"
250
+ />
251
+ </div>
252
+ <p
253
+ class="m_8f816625 mantine-InputWrapper-error mantine-TextInput-error"
254
+ id="mantine-0px4bipx4-error"
255
+ >
256
+ error sub form error
257
+ </p>
252
258
  </div>
253
- <p
254
- class="m_8f816625 mantine-InputWrapper-error mantine-TextInput-error"
255
- id="mantine-0px4bipx4-error"
256
- >
257
- error sub form error
258
- </p>
259
259
  </div>
260
- <button
261
- class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root"
262
- style="--button-color: var(--mantine-color-white);"
263
- type="button"
264
- >
265
- <span
266
- class="m_80f1301b mantine-Button-inner"
267
- >
268
- <span
269
- class="m_811560b9 mantine-Button-label"
270
- >
271
- Bonus Button
272
- </span>
273
- </span>
274
- </button>
275
260
  </div>
276
261
  </div>
277
262
  </div>
278
263
  `;
279
264
 
265
+ exports[`field view hooks > renders ParentFieldLabel 1`] = `
266
+ <div>
267
+ <style
268
+ data-mantine-styles="classes"
269
+ >
270
+ @media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}
271
+ </style>
272
+ $
273
+ </div>
274
+ `;
275
+
280
276
  exports[`field view hooks > renders Populated 1`] = `
281
277
  <div>
282
278
  <style
@@ -296,7 +292,7 @@ exports[`field view hooks > renders Populated 1`] = `
296
292
  for="mantine-0cyk5rcyk"
297
293
  id="mantine-0cyk5rcyk-label"
298
294
  >
299
- fields view
295
+ $
300
296
  </label>
301
297
  <div
302
298
  class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
@@ -313,48 +309,43 @@ exports[`field view hooks > renders Populated 1`] = `
313
309
  </div>
314
310
  </div>
315
311
  <div
316
- class="m_6d731127 mantine-Stack-root"
317
- style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
312
+ class="m_1b7284a3 mantine-Paper-root"
313
+ data-with-border="true"
318
314
  >
315
+ <p
316
+ class="mantine-focus-auto m_b6d8b162 mantine-Text-root"
317
+ >
318
+ $.a
319
+ </p>
319
320
  <div
320
- class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
321
+ class="m_6d731127 mantine-Stack-root"
322
+ style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
321
323
  >
322
- <label
323
- class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
324
- for="mantine-0px4bipx4"
325
- id="mantine-0px4bipx4-label"
326
- >
327
- sub fields view
328
- </label>
329
324
  <div
330
- class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
331
- data-variant="default"
325
+ class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
332
326
  >
333
- <input
334
- aria-invalid="false"
335
- class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
327
+ <label
328
+ class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
329
+ for="mantine-0px4bipx4"
330
+ id="mantine-0px4bipx4-label"
331
+ >
332
+ $ (child)
333
+ </label>
334
+ <div
335
+ class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
336
336
  data-variant="default"
337
- id="mantine-0px4bipx4"
338
- name="$"
339
- value="World"
340
- />
337
+ >
338
+ <input
339
+ aria-invalid="false"
340
+ class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
341
+ data-variant="default"
342
+ id="mantine-0px4bipx4"
343
+ name="$"
344
+ value="World"
345
+ />
346
+ </div>
341
347
  </div>
342
348
  </div>
343
- <button
344
- class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root"
345
- style="--button-color: var(--mantine-color-white);"
346
- type="button"
347
- >
348
- <span
349
- class="m_80f1301b mantine-Button-inner"
350
- >
351
- <span
352
- class="m_811560b9 mantine-Button-label"
353
- >
354
- Bonus Button
355
- </span>
356
- </span>
357
- </button>
358
349
  </div>
359
350
  </div>
360
351
  </div>
@@ -380,7 +371,7 @@ exports[`field view hooks > renders Required 1`] = `
380
371
  for="mantine-0cyk5rcyk"
381
372
  id="mantine-0cyk5rcyk-label"
382
373
  >
383
- fields view
374
+ $
384
375
  <span
385
376
  aria-hidden="true"
386
377
  class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required"
@@ -404,57 +395,63 @@ exports[`field view hooks > renders Required 1`] = `
404
395
  </div>
405
396
  </div>
406
397
  <div
407
- class="m_6d731127 mantine-Stack-root"
408
- style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
398
+ class="m_1b7284a3 mantine-Paper-root"
399
+ data-with-border="true"
409
400
  >
401
+ <p
402
+ class="mantine-focus-auto m_b6d8b162 mantine-Text-root"
403
+ >
404
+ $.a
405
+ </p>
410
406
  <div
411
- class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
407
+ class="m_6d731127 mantine-Stack-root"
408
+ style="--stack-gap: var(--mantine-spacing-md); --stack-align: stretch; --stack-justify: flex-start;"
412
409
  >
413
- <label
414
- class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
415
- data-required="true"
416
- for="mantine-0px4bipx4"
417
- id="mantine-0px4bipx4-label"
418
- >
419
- sub fields view
420
- <span
421
- aria-hidden="true"
422
- class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required"
423
- >
424
- *
425
- </span>
426
- </label>
427
410
  <div
428
- class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
429
- data-variant="default"
411
+ class="m_46b77525 mantine-InputWrapper-root mantine-TextInput-root"
430
412
  >
431
- <input
432
- aria-invalid="false"
433
- class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
413
+ <label
414
+ class="m_8fdc1311 mantine-InputWrapper-label mantine-TextInput-label"
415
+ data-required="true"
416
+ for="mantine-0px4bipx4"
417
+ id="mantine-0px4bipx4-label"
418
+ >
419
+ $ (child)
420
+ <span
421
+ aria-hidden="true"
422
+ class="m_78a94662 mantine-InputWrapper-required mantine-TextInput-required"
423
+ >
424
+ *
425
+ </span>
426
+ </label>
427
+ <div
428
+ class="m_6c018570 mantine-Input-wrapper mantine-TextInput-wrapper"
434
429
  data-variant="default"
435
- id="mantine-0px4bipx4"
436
- name="$"
437
- required=""
438
- value="yyy"
439
- />
430
+ >
431
+ <input
432
+ aria-invalid="false"
433
+ class="m_8fb7ebe7 mantine-Input-input mantine-TextInput-input"
434
+ data-variant="default"
435
+ id="mantine-0px4bipx4"
436
+ name="$"
437
+ required=""
438
+ value="yyy"
439
+ />
440
+ </div>
440
441
  </div>
441
442
  </div>
442
- <button
443
- class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root"
444
- style="--button-color: var(--mantine-color-white);"
445
- type="button"
446
- >
447
- <span
448
- class="m_80f1301b mantine-Button-inner"
449
- >
450
- <span
451
- class="m_811560b9 mantine-Button-label"
452
- >
453
- Bonus Button
454
- </span>
455
- </span>
456
- </button>
457
443
  </div>
458
444
  </div>
459
445
  </div>
460
446
  `;
447
+
448
+ exports[`field view hooks > renders SubFieldLabel 1`] = `
449
+ <div>
450
+ <style
451
+ data-mantine-styles="classes"
452
+ >
453
+ @media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}
454
+ </style>
455
+ $ (child)
456
+ </div>
457
+ `;
@@ -0,0 +1,29 @@
1
+ import { type CallbackMapper } from 'mantine/create_fields_view'
2
+
3
+ describe('createFieldsView', () => {
4
+ describe('CallbackMapper', () => {
5
+ it('maps a root paths', () => {
6
+ type Cm = CallbackMapper<`$`>
7
+ const callbackMapper: Cm = null!
8
+ type Callback = (valuePath: '$') => void
9
+ type MappedCallback = ReturnType<typeof callbackMapper<Callback>>
10
+ expectTypeOf<MappedCallback>().toEqualTypeOf<(valuePath: '$') => void>()
11
+ })
12
+
13
+ it('maps a simple paths', () => {
14
+ type Cm = CallbackMapper<`$.x`>
15
+ const callbackMapper: Cm = null!
16
+ type Callback = (valuePath: '$.x.y') => void
17
+ type MappedCallback = ReturnType<typeof callbackMapper<Callback>>
18
+ expectTypeOf<MappedCallback>().toEqualTypeOf<(valuePath: '$.y') => void>()
19
+ })
20
+
21
+ it('maps a indexed paths', () => {
22
+ type Cm = CallbackMapper<`$.${number}.x`>
23
+ const callbackMapper: Cm = null!
24
+ type Callback = (valuePath: `$.${number}.x.${number}.y`) => void
25
+ type MappedCallback = ReturnType<typeof callbackMapper<Callback>>
26
+ expectTypeOf<MappedCallback>().toEqualTypeOf<(valuePath: `$.${number}.y`) => void>()
27
+ })
28
+ })
29
+ })
@@ -1,6 +1,7 @@
1
1
  import {
2
- Button,
2
+ Paper,
3
3
  Stack,
4
+ Text,
4
5
  } from '@mantine/core'
5
6
  import { action } from '@storybook/addon-actions'
6
7
  import {
@@ -9,50 +10,91 @@ import {
9
10
  } from '@storybook/react'
10
11
  import { type FieldsViewProps } from 'core/props'
11
12
  import { useMantineFormFields } from 'mantine/hooks'
13
+ import {
14
+ useCallback,
15
+ useMemo,
16
+ } from 'react'
12
17
  import { type Field } from 'types/field'
13
18
 
14
- const onClick = action('some button clicked')
19
+ export function ParentFieldLabel() {
20
+ return '$'
21
+ }
22
+
23
+ export function SubFieldLabel() {
24
+ return '$ (child)'
25
+ }
15
26
 
16
27
  function ErrorRenderer({ error }: { error: string }) {
17
28
  return `error ${error}`
18
29
  }
19
30
 
20
- function SubFieldsView(props: FieldsViewProps<{
31
+ function SubFieldsView({
32
+ onClickField: onClickFieldImpl,
33
+ ...props
34
+ }: FieldsViewProps<{
21
35
  $: Field<string, string>,
22
36
  }> & {
23
- onClick: () => void,
37
+ onClickField: (valuePath: '$') => void,
24
38
  }) {
25
39
  const form = useMantineFormFields(props)
26
40
  const TextInput = form.textInput('$')
41
+ const onClick$ = useCallback(() => {
42
+ onClickFieldImpl('$')
43
+ }, [onClickFieldImpl])
27
44
  return (
28
45
  <Stack>
29
46
  <TextInput
30
47
  ErrorRenderer={ErrorRenderer}
31
- label='sub fields view'
48
+ label={SubFieldLabel()}
49
+ onClick={onClick$}
32
50
  />
33
- <Button onClick={props.onClick}>
34
- Bonus Button
35
- </Button>
36
51
  </Stack>
37
52
  )
38
53
  }
39
54
 
40
- function Component(props: FieldsViewProps<{
55
+ function Component({
56
+ onClickField: onClickFieldImpl,
57
+ ...props
58
+ }: FieldsViewProps<{
41
59
  $: Field<string, string>,
42
60
  '$.a': Field<string, string>,
43
- }>) {
61
+ }> & {
62
+ onClickField: (valuePath: '$' | '$.a') => void,
63
+ }) {
44
64
  const form = useMantineFormFields(props)
45
- const FieldsView = form.fieldsView('$.a', SubFieldsView)
65
+ const {
66
+ Component,
67
+ callbackMapper,
68
+ } = form.fieldsView('$.a', SubFieldsView)
46
69
  const TextInput = form.textInput('$')
70
+ const onClick$ = useCallback(() => {
71
+ onClickFieldImpl('$')
72
+ }, [onClickFieldImpl])
73
+
74
+ const onClickChildField = useMemo(() => {
75
+ return callbackMapper(onClickFieldImpl)
76
+ }, [
77
+ onClickFieldImpl,
78
+ callbackMapper,
79
+ ])
47
80
  return (
48
81
  <Stack>
49
82
  <TextInput
50
83
  ErrorRenderer={ErrorRenderer}
51
- label='fields view'
52
- />
53
- <FieldsView
54
- onClick={onClick}
84
+ label={ParentFieldLabel()}
85
+ onClick={onClick$}
55
86
  />
87
+ <Paper
88
+ p='sm'
89
+ withBorder={true}
90
+ >
91
+ <Text>
92
+ $.a
93
+ </Text>
94
+ <Component
95
+ onClickField={onClickChildField}
96
+ />
97
+ </Paper>
56
98
  </Stack>
57
99
  )
58
100
  }
@@ -64,6 +106,7 @@ const meta: Meta<typeof Component> = {
64
106
  onFieldFocus: action('onFieldFocus'),
65
107
  onFieldSubmit: action('onFieldSubmit'),
66
108
  onFieldValueChange: action('onFieldValueChange'),
109
+ onClickField: action('onClickField'),
67
110
  },
68
111
  }
69
112