@strictly/react-form 0.0.5 → 0.0.6

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 (59) hide show
  1. package/.out/core/mobx/hooks.d.ts +10 -0
  2. package/.out/core/mobx/hooks.js +47 -0
  3. package/.out/core/props.d.ts +2 -2
  4. package/.out/index.d.ts +1 -0
  5. package/.out/index.js +1 -0
  6. package/.out/mantine/create_fields_view.d.ts +7 -0
  7. package/.out/mantine/{create_sub_form.js → create_fields_view.js} +4 -5
  8. package/.out/mantine/create_form.d.ts +7 -0
  9. package/.out/mantine/create_form.js +13 -0
  10. package/.out/mantine/hooks.d.ts +6 -4
  11. package/.out/mantine/hooks.js +17 -7
  12. package/.out/mantine/specs/checkbox_hooks.stories.d.ts +2 -2
  13. package/.out/mantine/specs/checkbox_hooks.stories.js +2 -2
  14. package/.out/mantine/specs/{sub_form_hooks.stories.d.ts → fields_view_hooks.stories.d.ts} +2 -2
  15. package/.out/mantine/specs/{sub_form_hooks.stories.js → fields_view_hooks.stories.js} +9 -8
  16. package/.out/mantine/specs/fields_view_hooks.tests.d.ts +1 -0
  17. package/.out/mantine/specs/fields_view_hooks.tests.js +12 -0
  18. package/.out/mantine/specs/form_hooks.stories.d.ts +12 -0
  19. package/.out/mantine/specs/form_hooks.stories.js +60 -0
  20. package/.out/mantine/specs/form_hooks.tests.d.ts +1 -0
  21. package/.out/mantine/specs/form_hooks.tests.js +12 -0
  22. package/.out/mantine/specs/list_hooks.stories.d.ts +2 -2
  23. package/.out/mantine/specs/list_hooks.stories.js +2 -2
  24. package/.out/mantine/specs/radio_group_hooks.stories.d.ts +2 -2
  25. package/.out/mantine/specs/radio_group_hooks.stories.js +2 -2
  26. package/.out/mantine/specs/select_hooks.stories.d.ts +2 -2
  27. package/.out/mantine/specs/select_hooks.stories.js +2 -2
  28. package/.out/mantine/specs/text_input_hooks.stories.d.ts +2 -2
  29. package/.out/mantine/specs/text_input_hooks.stories.js +2 -2
  30. package/.out/mantine/specs/value_input_hooks.stories.d.ts +2 -2
  31. package/.out/mantine/specs/value_input_hooks.stories.js +2 -2
  32. package/.out/tsconfig.tsbuildinfo +1 -1
  33. package/.turbo/turbo-build.log +8 -8
  34. package/.turbo/turbo-check-types.log +1 -1
  35. package/.turbo/turbo-release$colon$exports.log +1 -1
  36. package/core/mobx/hooks.ts +94 -0
  37. package/core/props.ts +2 -2
  38. package/dist/index.cjs +167 -77
  39. package/dist/index.d.cts +42 -34
  40. package/dist/index.d.ts +42 -34
  41. package/dist/index.js +162 -68
  42. package/index.ts +1 -0
  43. package/mantine/{create_sub_form.tsx → create_fields_view.tsx} +27 -16
  44. package/mantine/create_form.tsx +43 -0
  45. package/mantine/hooks.tsx +48 -14
  46. package/mantine/specs/__snapshots__/fields_view_hooks.tests.tsx.snap +460 -0
  47. package/mantine/specs/__snapshots__/form_hooks.tests.tsx.snap +273 -0
  48. package/mantine/specs/checkbox_hooks.stories.tsx +4 -4
  49. package/mantine/specs/{sub_form_hooks.stories.tsx → fields_view_hooks.stories.tsx} +23 -11
  50. package/mantine/specs/fields_view_hooks.tests.tsx +15 -0
  51. package/mantine/specs/form_hooks.stories.tsx +107 -0
  52. package/mantine/specs/form_hooks.tests.tsx +15 -0
  53. package/mantine/specs/list_hooks.stories.tsx +4 -4
  54. package/mantine/specs/radio_group_hooks.stories.tsx +4 -4
  55. package/mantine/specs/select_hooks.stories.tsx +4 -4
  56. package/mantine/specs/text_input_hooks.stories.tsx +4 -4
  57. package/mantine/specs/value_input_hooks.stories.tsx +4 -4
  58. package/package.json +1 -1
  59. package/.out/mantine/create_sub_form.d.ts +0 -6
@@ -0,0 +1,10 @@
1
+ import { type ReadonlyTypeOfType, type ValueOfType } from '@strictly/define';
2
+ import { type FieldsViewProps } from 'core/props';
3
+ import { type FormPresenter } from './form_presenter';
4
+ import { type ValuePathsOfPresenter } from './types';
5
+ type ValueOfPresenter<P extends FormPresenter<any, any, any, any>> = P extends FormPresenter<infer T, any, any, any> ? ValueOfType<ReadonlyTypeOfType<T>> : never;
6
+ type ModelOfPresenter<P extends FormPresenter<any, any, any, any>> = ReturnType<P['createModel']>;
7
+ export declare function useDefaultMobxFormHooks<P extends FormPresenter<any, any, any, any>>(presenter: P, value: ValueOfPresenter<P>, onValidSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void): {
8
+ model: ModelOfPresenter<P>;
9
+ } & Omit<FieldsViewProps<ModelOfPresenter<P>['fields']>, 'fields'>;
10
+ export {};
@@ -0,0 +1,47 @@
1
+ import { useCallback, useMemo, } from 'react';
2
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
3
+ export function useDefaultMobxFormHooks(presenter, value, onValidSubmit) {
4
+ const model = useMemo(function () {
5
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6
+ return presenter.createModel(value);
7
+ }, [
8
+ presenter,
9
+ value,
10
+ ]);
11
+ const onFieldValueChange = useCallback(function (path, value) {
12
+ presenter.clearFieldError(model, path);
13
+ presenter.setFieldValue(model, path, value);
14
+ }, [
15
+ presenter,
16
+ model,
17
+ ]);
18
+ const onFieldSubmit = useCallback(function (valuePath) {
19
+ if (presenter.validateField(model, valuePath)) {
20
+ onValidSubmit?.(model, valuePath);
21
+ }
22
+ return false;
23
+ }, [
24
+ presenter,
25
+ model,
26
+ onValidSubmit,
27
+ ]);
28
+ const onFieldBlur = useCallback(function (path) {
29
+ // work around potential loss of focus prior to state potentially invalidating change triggering
30
+ // (e.g. changing a discriminator)
31
+ // TODO debounce?
32
+ setTimeout(function () {
33
+ if (presenter.isValuePathActive(model, path)) {
34
+ presenter.validateField(model, path);
35
+ }
36
+ }, 100);
37
+ }, [
38
+ presenter,
39
+ model,
40
+ ]);
41
+ return {
42
+ model,
43
+ onFieldValueChange,
44
+ onFieldSubmit,
45
+ onFieldBlur,
46
+ };
47
+ }
@@ -1,12 +1,12 @@
1
1
  import { type Fields } from 'types/field';
2
- export type FormProps<F extends Fields> = {
2
+ export type FieldsViewProps<F extends Fields> = {
3
3
  fields: F;
4
4
  onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void;
5
5
  onFieldFocus?(this: void, key: keyof F): void;
6
6
  onFieldBlur?(this: void, key: keyof F): void;
7
7
  onFieldSubmit?(this: void, key: keyof F): boolean | void;
8
8
  };
9
- export type EditorProps<O> = {
9
+ export type FormProps<O> = {
10
10
  value: O;
11
11
  onValueChange: (value: O) => void;
12
12
  };
package/.out/index.d.ts CHANGED
@@ -4,6 +4,7 @@ export * from './core/mobx/field_adapters_of_values';
4
4
  export * from './core/mobx/flattened_adapters_of_fields';
5
5
  export * from './core/mobx/form_fields_of_field_adapters';
6
6
  export * from './core/mobx/form_presenter';
7
+ export * from './core/mobx/hooks';
7
8
  export * from './core/mobx/merge_field_adapters_with_two_way_converter';
8
9
  export * from './core/mobx/merge_field_adapters_with_validators';
9
10
  export * from './core/mobx/sub_form_field_adapters';
package/.out/index.js CHANGED
@@ -4,6 +4,7 @@ export * from './core/mobx/field_adapters_of_values';
4
4
  export * from './core/mobx/flattened_adapters_of_fields';
5
5
  export * from './core/mobx/form_fields_of_field_adapters';
6
6
  export * from './core/mobx/form_presenter';
7
+ export * from './core/mobx/hooks';
7
8
  export * from './core/mobx/merge_field_adapters_with_two_way_converter';
8
9
  export * from './core/mobx/merge_field_adapters_with_validators';
9
10
  export * from './core/mobx/sub_form_field_adapters';
@@ -0,0 +1,7 @@
1
+ import type { FieldsViewProps } from 'core/props';
2
+ import type { ComponentType } from 'react';
3
+ import type { AllFieldsOfFields } from 'types/all_fields_of_fields';
4
+ import type { Fields } from 'types/field';
5
+ import type { SubFormFields } from 'types/sub_form_fields';
6
+ import type { MantineFieldComponent } from './types';
7
+ export declare function createFieldsView<F extends Fields, K extends keyof AllFieldsOfFields<F>, P extends FieldsViewProps<Fields> = FieldsViewProps<SubFormFields<F, K>>>(valuePath: K, FieldsView: ComponentType<P>, observableProps: FieldsViewProps<F>): MantineFieldComponent<FieldsViewProps<P['fields']>, P>;
@@ -1,6 +1,6 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { observer } from 'mobx-react';
3
- export function createSubForm(valuePath, SubForm, observableProps) {
3
+ export function createFieldsView(valuePath, FieldsView, observableProps) {
4
4
  function toKey(subKey) {
5
5
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6
6
  return subKey.replace('$', valuePath);
@@ -22,7 +22,8 @@ export function createSubForm(valuePath, SubForm, observableProps) {
22
22
  function onFieldSubmit(subKey) {
23
23
  observableProps.onFieldSubmit?.(toKey(subKey));
24
24
  }
25
- return observer(function () {
25
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
26
+ return observer(function (props) {
26
27
  // convert fields to sub-fields
27
28
  const subFields = Object.entries(observableProps.fields).reduce((acc, [fieldKey, fieldValue,]) => {
28
29
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -31,9 +32,7 @@ export function createSubForm(valuePath, SubForm, observableProps) {
31
32
  }
32
33
  return acc;
33
34
  }, {});
34
- return (_jsx(SubForm
35
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
36
- , {
35
+ return (_jsx(FieldsView, { ...props,
37
36
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
38
37
  fields: subFields, onFieldBlur: onFieldBlur, onFieldFocus: onFieldFocus, onFieldSubmit: onFieldSubmit, onFieldValueChange: onFieldValueChange }));
39
38
  });
@@ -0,0 +1,7 @@
1
+ import { type FieldsViewProps, type FormProps } from 'core/props';
2
+ import { type ComponentType } from 'react';
3
+ import { type AllFieldsOfFields } from 'types/all_fields_of_fields';
4
+ import { type Fields } from 'types/field';
5
+ import { type ValueTypeOfField } from 'types/value_type_of_field';
6
+ import { type MantineFieldComponent } from './types';
7
+ export declare function createForm<F extends Fields, K extends keyof AllFieldsOfFields<F>, P extends FormProps<ValueTypeOfField<F[K]>> = FormProps<ValueTypeOfField<F[K]>>>(valuePath: K, Form: ComponentType<P>, observableProps: FieldsViewProps<F>): MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P>;
@@ -0,0 +1,13 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { observer } from 'mobx-react';
3
+ import { useCallback, } from 'react';
4
+ export function createForm(valuePath, Form, observableProps) {
5
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
6
+ return observer((props) => {
7
+ const { value } = observableProps.fields[valuePath];
8
+ const onValueChange = useCallback((value) => {
9
+ observableProps.onFieldValueChange(valuePath, value);
10
+ }, []);
11
+ return (_jsx(Form, { ...props, onValueChange: onValueChange, value: value }));
12
+ });
13
+ }
@@ -1,6 +1,6 @@
1
1
  import { type CheckboxProps, type PillProps, type RadioGroupProps, type RadioProps, type SelectProps, type TextInputProps } from '@mantine/core';
2
2
  import { type ElementOfArray } from '@strictly/base';
3
- import { type FormProps } from 'core/props';
3
+ import { type FieldsViewProps, type FormProps } from 'core/props';
4
4
  import { type ComponentProps, type ComponentType } from 'react';
5
5
  import { type AllFieldsOfFields } from 'types/all_fields_of_fields';
6
6
  import { type BooleanFieldsOfFields } from 'types/boolean_fields_of_fields';
@@ -21,7 +21,7 @@ import { type MantineFieldComponent, type MantineForm } from './types';
21
21
  declare function SimpleSelect(props: SelectProps & {
22
22
  onChange?: (value: string | null) => void;
23
23
  }): import("react/jsx-runtime").JSX.Element;
24
- export declare function useMantineForm<F extends Fields>({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }: FormProps<F>): MantineFormImpl<F>;
24
+ export declare function useMantineFormFields<F extends Fields>({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }: FieldsViewProps<F>): MantineFormImpl<F>;
25
25
  declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
26
26
  private readonly textInputCache;
27
27
  private readonly valueInputCache;
@@ -30,7 +30,8 @@ declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
30
30
  private readonly radioCache;
31
31
  private readonly pillCache;
32
32
  private readonly listCache;
33
- private readonly subFormCache;
33
+ private readonly fieldsViewCache;
34
+ private readonly formCache;
34
35
  accessor fields: F;
35
36
  onFieldValueChange: <K extends keyof F>(this: void, key: K, value: F[K]['value']) => void;
36
37
  onFieldFocus: ((this: void, key: keyof F) => void) | undefined;
@@ -50,6 +51,7 @@ declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
50
51
  pill<K extends keyof AllFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedPillProps, PillProps, ErrorOfField<F[K]>>;
51
52
  pill<K extends keyof AllFieldsOfFields<F>, P extends SuppliedPillProps>(valuePath: K, Pill: ComponentType<P>): MantineFieldComponent<SuppliedPillProps, P>;
52
53
  list<K extends keyof ListFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedListProps<`${K}.${number}`>, ComponentProps<typeof DefaultList<ElementOfArray<F[K]['value']>, K>>>;
53
- subForm<K extends keyof AllFieldsOfFields<F>, S extends SubFormFields<F, K>>(valuePath: K, SubForm: ComponentType<FormProps<S>>): ComponentType;
54
+ fieldsView<K extends keyof AllFieldsOfFields<F>, P extends FieldsViewProps<Fields> = FieldsViewProps<SubFormFields<F, K>>>(valuePath: K, FieldsView: ComponentType<P>): MantineFieldComponent<FieldsViewProps<P['fields']>, P>;
55
+ form<K extends keyof AllFieldsOfFields<F>, P extends FormProps<ValueTypeOfField<F[K]>> = FormProps<ValueTypeOfField<F[K]>>>(valuePath: K, Form: ComponentType<P>): MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P>;
54
56
  }
55
57
  export {};
@@ -4,17 +4,18 @@ import { Cache, } from '@strictly/base';
4
4
  import { observable, runInAction, } from 'mobx';
5
5
  import { useEffect, useMemo, } from 'react';
6
6
  import { createCheckbox, } from './create_checkbox';
7
+ import { createFieldsView } from './create_fields_view';
8
+ import { createForm } from './create_form';
7
9
  import { createList, DefaultList, } from './create_list';
8
10
  import { createPill, } from './create_pill';
9
11
  import { createRadio, } from './create_radio';
10
12
  import { createRadioGroup, } from './create_radio_group';
11
- import { createSubForm } from './create_sub_form';
12
13
  import { createTextInput, } from './create_text_input';
13
14
  import { createValueInput, } from './create_value_input';
14
15
  function SimpleSelect(props) {
15
16
  return _jsx(Select, { ...props });
16
17
  }
17
- export function useMantineForm({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }) {
18
+ export function useMantineFormFields({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }) {
18
19
  const form = useMemo(function () {
19
20
  return new MantineFormImpl(fields);
20
21
  },
@@ -63,7 +64,8 @@ class MantineFormImpl {
63
64
  radioCache = new Cache(createRadio.bind(this));
64
65
  pillCache = new Cache(createPill.bind(this));
65
66
  listCache = new Cache(createList.bind(this));
66
- subFormCache = new Cache(createSubForm.bind(this));
67
+ fieldsViewCache = new Cache(createFieldsView.bind(this));
68
+ formCache = new Cache(createForm.bind(this));
67
69
  @observable.ref
68
70
  accessor fields;
69
71
  onFieldValueChange;
@@ -129,11 +131,19 @@ class MantineFormImpl {
129
131
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
130
132
  return this.listCache.retrieveOrCreate(valuePath, DefaultList);
131
133
  }
132
- // TODO have the returned component take any non-overlapping props as props
133
- subForm(valuePath, SubForm) {
134
- return this.subFormCache.retrieveOrCreate(valuePath,
134
+ fieldsView(valuePath, FieldsView) {
135
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
136
+ return this.fieldsViewCache.retrieveOrCreate(valuePath,
137
+ // strip props from component since we lose information in the cache
138
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
139
+ FieldsView, this);
140
+ }
141
+ form(valuePath, Form) {
142
+ // strip props from component since we lose information in the cache
143
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
144
+ return this.formCache.retrieveOrCreate(valuePath,
135
145
  // strip props from component since we lose information in the cache
136
146
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
137
- SubForm, this);
147
+ Form, this);
138
148
  }
139
149
  }
@@ -1,8 +1,8 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/react';
2
- import { type FormProps } from 'core/props';
2
+ import { type FieldsViewProps } from 'core/props';
3
3
  import { type ErrorRenderer } from 'mantine/error_renderer';
4
4
  import { type Field } from 'types/field';
5
- declare function Component({ ErrorRenderer, ...props }: FormProps<{
5
+ declare function Component({ ErrorRenderer, ...props }: FieldsViewProps<{
6
6
  $: Field<boolean, string>;
7
7
  }> & {
8
8
  ErrorRenderer?: ErrorRenderer;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { action } from '@storybook/addon-actions';
3
- import { useMantineForm } from 'mantine/hooks';
3
+ import { useMantineFormFields } from 'mantine/hooks';
4
4
  import { CHECKBOX_LABEL } from './checkbox_constants';
5
5
  function Component({ ErrorRenderer, ...props }) {
6
- const inputProps = useMantineForm(props);
6
+ const inputProps = useMantineFormFields(props);
7
7
  const CheckboxComponent = inputProps.checkbox('$');
8
8
  return (_jsx(CheckboxComponent, { ErrorRenderer: ErrorRenderer, label: CHECKBOX_LABEL }));
9
9
  }
@@ -1,7 +1,7 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/react';
2
- import { type FormProps } from 'core/props';
2
+ import { type FieldsViewProps } from 'core/props';
3
3
  import { type Field } from 'types/field';
4
- declare function Component(props: FormProps<{
4
+ declare function Component(props: FieldsViewProps<{
5
5
  $: Field<string, string>;
6
6
  '$.a': Field<string, string>;
7
7
  }>): import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { Stack, } from '@mantine/core';
2
+ import { Button, Stack, } from '@mantine/core';
3
3
  import { action } from '@storybook/addon-actions';
4
- import { useMantineForm } from 'mantine/hooks';
5
- function SubFormImpl(props) {
6
- const form = useMantineForm(props);
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
+ const onClick = action('some button clicked');
6
+ function SubFieldsView(props) {
7
+ const form = useMantineFormFields(props);
7
8
  const TextInput = form.textInput('$');
8
- return _jsx(TextInput, { label: 'sub form' });
9
+ return (_jsxs(Stack, { children: [_jsx(TextInput, { label: 'sub fields view' }), _jsx(Button, { onClick: props.onClick, children: "Bonus Button" })] }));
9
10
  }
10
11
  function Component(props) {
11
- const form = useMantineForm(props);
12
- const SubForm = form.subForm('$.a', SubFormImpl);
12
+ const form = useMantineFormFields(props);
13
+ const FieldsView = form.fieldsView('$.a', SubFieldsView);
13
14
  const TextInput = form.textInput('$');
14
- return (_jsxs(Stack, { children: [_jsx(TextInput, { label: 'form' }), _jsx(SubForm, {})] }));
15
+ return (_jsxs(Stack, { children: [_jsx(TextInput, { label: 'fields view' }), _jsx(FieldsView, { onClick: onClick })] }));
15
16
  }
16
17
  const meta = {
17
18
  component: Component,
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { composeStories } from '@storybook/react';
3
+ import { toArray } from '@strictly/base';
4
+ import { render, } from '@testing-library/react';
5
+ import * as stories from './fields_view_hooks.stories';
6
+ const composedStories = composeStories(stories);
7
+ describe('field view hooks', function () {
8
+ it.each(toArray(composedStories))('renders %s', function (_name, Story) {
9
+ const wrapper = render(_jsx(Story, {}));
10
+ expect(wrapper.container).toMatchSnapshot();
11
+ });
12
+ });
@@ -0,0 +1,12 @@
1
+ import { type Meta, type StoryObj } from '@storybook/react';
2
+ import { type FieldsViewProps } from 'core/props';
3
+ import { type Field } from 'types/field';
4
+ declare function Component(props: FieldsViewProps<{
5
+ $: Field<string>;
6
+ '$.a': Field<number>;
7
+ }>): import("react/jsx-runtime").JSX.Element;
8
+ declare const meta: Meta<typeof Component>;
9
+ export default meta;
10
+ type Story = StoryObj<typeof Component>;
11
+ export declare const Empty: Story;
12
+ export declare const Populated: Story;
@@ -0,0 +1,60 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, NumberInput, Stack, } from '@mantine/core';
3
+ import { action } from '@storybook/addon-actions';
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
+ import { useCallback } from 'react';
6
+ const onCancel = action('canceled');
7
+ function SubForm({ value, onValueChange, onCancel, }) {
8
+ const onChange = useCallback((v) => {
9
+ onValueChange(Number.parseInt(`${v}`));
10
+ }, [onValueChange]);
11
+ return (_jsxs(Stack, { children: [_jsx(NumberInput, { allowDecimal: false, label: 'sub form', onChange: onChange, value: value }), _jsx(Button, { onClick: onCancel, children: "Cancel" })] }));
12
+ }
13
+ function Component(props) {
14
+ const form = useMantineFormFields(props);
15
+ const Form = form.form('$.a', SubForm);
16
+ const TextInput = form.textInput('$');
17
+ return (_jsxs(Stack, { children: [_jsx(TextInput, { label: 'fields view' }), _jsx(Form, { onCancel: onCancel })] }));
18
+ }
19
+ const meta = {
20
+ component: Component,
21
+ args: {
22
+ onFieldBlur: action('onFieldBlur'),
23
+ onFieldFocus: action('onFieldFocus'),
24
+ onFieldSubmit: action('onFieldSubmit'),
25
+ onFieldValueChange: action('onFieldValueChange'),
26
+ },
27
+ };
28
+ export default meta;
29
+ export const Empty = {
30
+ args: {
31
+ fields: {
32
+ $: {
33
+ readonly: false,
34
+ required: false,
35
+ value: '',
36
+ },
37
+ '$.a': {
38
+ readonly: false,
39
+ required: false,
40
+ value: 0,
41
+ },
42
+ },
43
+ },
44
+ };
45
+ export const Populated = {
46
+ args: {
47
+ fields: {
48
+ $: {
49
+ readonly: false,
50
+ required: false,
51
+ value: 'Hello',
52
+ },
53
+ '$.a': {
54
+ readonly: false,
55
+ required: false,
56
+ value: 2,
57
+ },
58
+ },
59
+ },
60
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { composeStories } from '@storybook/react';
3
+ import { toArray } from '@strictly/base';
4
+ import { render, } from '@testing-library/react';
5
+ import * as stories from './form_hooks.stories';
6
+ const composedStories = composeStories(stories);
7
+ describe('form hooks', function () {
8
+ it.each(toArray(composedStories))('renders %s', function (_name, Story) {
9
+ const wrapper = render(_jsx(Story, {}));
10
+ expect(wrapper.container).toMatchSnapshot();
11
+ });
12
+ });
@@ -1,7 +1,7 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/react';
2
- import { type FormProps } from 'core/props';
2
+ import { type FieldsViewProps } from 'core/props';
3
3
  import { type Field } from 'types/field';
4
- declare function Component(props: FormProps<{
4
+ declare function Component(props: FieldsViewProps<{
5
5
  $: Field<string[], string>;
6
6
  }>): import("react/jsx-runtime").JSX.Element;
7
7
  declare const meta: Meta<typeof Component>;
@@ -1,9 +1,9 @@
1
1
  import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Code, Paper, Stack, } from '@mantine/core';
3
3
  import { action } from '@storybook/addon-actions';
4
- import { useMantineForm } from 'mantine/hooks';
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
5
  function Component(props) {
6
- const form = useMantineForm(props);
6
+ const form = useMantineFormFields(props);
7
7
  const List = form.list('$');
8
8
  return (_jsx(Paper, { p: 'sm', withBorder: true, children: _jsx(Stack, { children: _jsx(List, { children: function (valuePath, value, index) {
9
9
  return (_jsxs(Code, { children: [_jsxs("span", { children: ["ValuePath: ", valuePath] }), _jsx("br", {}), _jsxs("span", { children: ["Value: ", value] }), _jsx("br", {}), _jsxs("span", { children: ["Index: ", index] })] }, valuePath));
@@ -1,9 +1,9 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/react';
2
- import { type FormProps } from 'core/props';
2
+ import { type FieldsViewProps } from 'core/props';
3
3
  import { type ErrorRenderer } from 'mantine/error_renderer';
4
4
  import { type Field } from 'types/field';
5
5
  import { type RadioValue } from './radio_group_constants';
6
- declare function Component({ ErrorRenderer, ...props }: FormProps<{
6
+ declare function Component({ ErrorRenderer, ...props }: FieldsViewProps<{
7
7
  $: Field<RadioValue | null, string>;
8
8
  }> & {
9
9
  ErrorRenderer?: ErrorRenderer;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { Stack, } from '@mantine/core';
3
3
  import { action } from '@storybook/addon-actions';
4
- import { useMantineForm } from 'mantine/hooks';
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
5
  import { RADIO_GROUP_LABEL, RADIO_LABELS, RADIO_VALUES, } from './radio_group_constants';
6
6
  function Component({ ErrorRenderer, ...props }) {
7
- const form = useMantineForm(props);
7
+ const form = useMantineFormFields(props);
8
8
  const RadioGroupComponent = form.radioGroup('$');
9
9
  return (_jsx(RadioGroupComponent, { ErrorRenderer: ErrorRenderer, label: RADIO_GROUP_LABEL, children: _jsx(Stack, { children: RADIO_VALUES.map(function (value) {
10
10
  const label = RADIO_LABELS[value];
@@ -1,8 +1,8 @@
1
1
  import { type Meta, type StoryObj } from '@storybook/react';
2
- import { type FormProps } from 'core/props';
2
+ import { type FieldsViewProps } from 'core/props';
3
3
  import { type ErrorRenderer } from 'mantine/error_renderer';
4
4
  import { type Field } from 'types/field';
5
- declare function Component({ ErrorRenderer, ...props }: FormProps<{
5
+ declare function Component({ ErrorRenderer, ...props }: FieldsViewProps<{
6
6
  $: Field<string | null, string>;
7
7
  }> & {
8
8
  ErrorRenderer?: ErrorRenderer;
@@ -1,9 +1,9 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { action } from '@storybook/addon-actions';
3
- import { useMantineForm } from 'mantine/hooks';
3
+ import { useMantineFormFields } from 'mantine/hooks';
4
4
  import { SELECT_LABEL } from './select_hooks_constant';
5
5
  function Component({ ErrorRenderer, ...props }) {
6
- const form = useMantineForm(props);
6
+ const form = useMantineFormFields(props);
7
7
  const SelectComponent = form.select('$');
8
8
  return (_jsx(SelectComponent, { ErrorRenderer: ErrorRenderer, data: [
9
9
  'a',
@@ -1,12 +1,12 @@
1
1
  import { type TextInputProps } from '@mantine/core';
2
2
  import { type Meta, type StoryObj } from '@storybook/react';
3
- import { type FormProps } from 'core/props';
3
+ import { type FieldsViewProps } from 'core/props';
4
4
  import { type SuppliedTextInputProps, type TextInputTarget } from 'mantine/create_text_input';
5
5
  import { type ErrorRenderer } from 'mantine/error_renderer';
6
6
  import { type ComponentType } from 'react';
7
7
  import { type Field } from 'types/field';
8
8
  type StoryTextInputProps<T extends TextInputTarget> = SuppliedTextInputProps<T> & Pick<TextInputProps, 'label'>;
9
- declare function Component<T extends TextInputTarget>({ TextInput, ErrorRenderer, ...props }: FormProps<{
9
+ declare function Component<T extends TextInputTarget>({ TextInput, ErrorRenderer, ...props }: FieldsViewProps<{
10
10
  $: Field<string, string>;
11
11
  }> & {
12
12
  TextInput?: ComponentType<StoryTextInputProps<T>>;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { PillsInputField, Textarea, } from '@mantine/core';
3
3
  import { action } from '@storybook/addon-actions';
4
- import { useMantineForm } from 'mantine/hooks';
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
5
  import { TEXT_INPUT_LABEL } from './text_input_constants';
6
6
  function Component({ TextInput, ErrorRenderer, ...props }) {
7
- const form = useMantineForm(props);
7
+ const form = useMantineFormFields(props);
8
8
  const TextInputComponent = form.textInput('$', TextInput);
9
9
  return (_jsx(TextInputComponent, { ErrorRenderer: ErrorRenderer, label: TEXT_INPUT_LABEL }));
10
10
  }
@@ -1,12 +1,12 @@
1
1
  import { type JsonInputProps, type NumberInputProps, type RatingProps, type SliderProps } from '@mantine/core';
2
2
  import { type Meta, type StoryObj } from '@storybook/react';
3
- import { type FormProps } from 'core/props';
3
+ import { type FieldsViewProps } from 'core/props';
4
4
  import { type SuppliedValueInputProps } from 'mantine/create_value_input';
5
5
  import { type ErrorRenderer } from 'mantine/error_renderer';
6
6
  import { type ComponentType } from 'react';
7
7
  import { type Field } from 'types/field';
8
8
  type StoryValueInputProps<V> = SuppliedValueInputProps<V, any>;
9
- declare function Component<V, P extends StoryValueInputProps<V>>({ ValueInput, ErrorRenderer, inputProps, ...props }: FormProps<{
9
+ declare function Component<V, P extends StoryValueInputProps<V>>({ ValueInput, ErrorRenderer, inputProps, ...props }: FieldsViewProps<{
10
10
  $: Field<V, string>;
11
11
  }> & {
12
12
  ValueInput: ComponentType<P>;
@@ -1,10 +1,10 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { JsonInput, NumberInput, Rating, Slider, } from '@mantine/core';
3
3
  import { action } from '@storybook/addon-actions';
4
- import { useMantineForm } from 'mantine/hooks';
4
+ import { useMantineFormFields } from 'mantine/hooks';
5
5
  import { NUMBER_INPUT_LABEL, SLIDER_LABEL, } from './value_input_constants';
6
6
  function Component({ ValueInput, ErrorRenderer, inputProps, ...props }) {
7
- const form = useMantineForm(props);
7
+ const form = useMantineFormFields(props);
8
8
  const ValueInputComponent = form.valueInput('$', ValueInput);
9
9
  return (_jsx(ValueInputComponent, { ...inputProps, ErrorRenderer: ErrorRenderer }));
10
10
  }