@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
@@ -1,15 +1,41 @@
1
1
  import { composeStories } from '@storybook/react'
2
2
  import { toArray } from '@strictly/base'
3
3
  import {
4
+ fireEvent,
4
5
  render,
5
6
  } from '@testing-library/react'
6
7
  import * as stories from './fields_view_hooks.stories'
7
8
 
8
9
  const composedStories = composeStories(stories)
10
+ const {
11
+ Empty,
12
+ } = composedStories
9
13
 
10
14
  describe('field view hooks', function () {
11
15
  it.each(toArray(composedStories))('renders %s', function (_name, Story) {
12
16
  const wrapper = render(<Story />)
13
17
  expect(wrapper.container).toMatchSnapshot()
14
18
  })
19
+
20
+ describe('callbackMapper', () => {
21
+ it.each(
22
+ [
23
+ [
24
+ '$',
25
+ stories.ParentFieldLabel(),
26
+ ],
27
+ [
28
+ '$.a',
29
+ stories.SubFieldLabel(),
30
+ ],
31
+ ],
32
+ )('calls back with the correct paths for field at %s', async (valuePath, labelText) => {
33
+ const onClickField = vi.fn()
34
+ const wrapper = render(<Empty onClickField={onClickField} />)
35
+ const element = await wrapper.findByLabelText(labelText)
36
+ fireEvent.click(element)
37
+ expect(onClickField).toHaveBeenCalledOnce()
38
+ expect(onClickField).toHaveBeenCalledWith(valuePath)
39
+ })
40
+ })
15
41
  })
package/package.json CHANGED
@@ -70,7 +70,7 @@
70
70
  "test:watch": "vitest"
71
71
  },
72
72
  "type": "module",
73
- "version": "0.0.8",
73
+ "version": "0.0.10",
74
74
  "exports": {
75
75
  ".": {
76
76
  "import": {
@@ -1,7 +1,7 @@
1
1
  import { type ErrorOfField } from 'types/error_of_field'
2
2
  import { type Field } from 'types/field'
3
3
 
4
- describe('ErrorTypeOfField', function () {
4
+ describe('ErrorOfField', function () {
5
5
  it('equals expected type', function () {
6
6
  const e = Symbol()
7
7
  type E = typeof e
@@ -1,112 +0,0 @@
1
- import {
2
- type ReadonlyTypeOfType,
3
- type ValueOfType,
4
- } from '@strictly/define'
5
- import { type FieldsViewProps } from 'core/props'
6
- import {
7
- useCallback,
8
- useMemo,
9
- } from 'react'
10
- import { type FormPresenter } from './form_presenter'
11
- import {
12
- type ToValueOfPresenterValuePath,
13
- type ValuePathsOfPresenter,
14
- } from './types'
15
-
16
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
- type ValueOfPresenter<P extends FormPresenter<any, any, any, any>> = P extends FormPresenter<infer T, any, any, any>
18
- ? ValueOfType<ReadonlyTypeOfType<T>>
19
- : never
20
-
21
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
22
- type ModelOfPresenter<P extends FormPresenter<any, any, any, any>> = ReturnType<P['createModel']>
23
-
24
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
- export function useDefaultMobxFormHooks<P extends FormPresenter<any, any, any, any>>(
26
- presenter: P,
27
- value: ValueOfPresenter<P>,
28
- {
29
- onValidFieldSubmit,
30
- onValidFormSubmit,
31
- }: {
32
- onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void,
33
- onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void,
34
- },
35
- ): {
36
- model: ModelOfPresenter<P>,
37
- onFormSubmit?: (value: ValueOfPresenter<P>) => void,
38
- } & Omit<FieldsViewProps<ModelOfPresenter<P>['fields']>, 'fields'> {
39
- const model = useMemo(function () {
40
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
41
- return presenter.createModel(value) as ReturnType<P['createModel']>
42
- }, [
43
- presenter,
44
- value,
45
- ])
46
-
47
- const onFieldValueChange = useCallback(
48
- function<Path extends ValuePathsOfPresenter<P>> (
49
- path: Path,
50
- value: ToValueOfPresenterValuePath<P, Path>,
51
- ) {
52
- presenter.clearFieldError(model, path)
53
- presenter.setFieldValue<Path>(model, path, value)
54
- },
55
- [
56
- presenter,
57
- model,
58
- ],
59
- )
60
-
61
- const onFieldSubmit = useCallback(
62
- function<Path extends ValuePathsOfPresenter<P>> (valuePath: Path) {
63
- if (presenter.validateField(model, valuePath)) {
64
- onValidFieldSubmit?.(model, valuePath)
65
- }
66
- return false
67
- },
68
- [
69
- presenter,
70
- model,
71
- onValidFieldSubmit,
72
- ],
73
- )
74
-
75
- const onFieldBlur = useCallback(
76
- function<Path extends ValuePathsOfPresenter<P>> (path: Path) {
77
- // work around potential loss of focus prior to state potentially invalidating change triggering
78
- // (e.g. changing a discriminator)
79
- // TODO debounce?
80
- setTimeout(function () {
81
- if (presenter.isValuePathActive(model, path)) {
82
- presenter.validateField(model, path)
83
- }
84
- }, 100)
85
- },
86
- [
87
- presenter,
88
- model,
89
- ],
90
- )
91
-
92
- const onFormSubmit = useCallback(
93
- function () {
94
- if (presenter.validateAll(model)) {
95
- onValidFormSubmit?.(model, model.value)
96
- }
97
- },
98
- [
99
- presenter,
100
- model,
101
- onValidFormSubmit,
102
- ],
103
- )
104
-
105
- return {
106
- model,
107
- onFieldValueChange,
108
- onFieldSubmit,
109
- onFieldBlur,
110
- onFormSubmit,
111
- }
112
- }