@strictly/react-form 0.0.5 → 0.0.7

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 (68) 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/mobx/specs/form_presenter.tests.js +3 -6
  4. package/.out/core/mobx/specs/{merge_field_adapters_with_two_way_converter.js → merge_field_adapters_with_two_way_converter.tests.js} +15 -16
  5. package/.out/core/mobx/specs/sub_form_field_adapters.tests.js +78 -10
  6. package/.out/core/mobx/sub_form_field_adapters.d.ts +6 -4
  7. package/.out/core/mobx/sub_form_field_adapters.js +23 -2
  8. package/.out/core/props.d.ts +2 -2
  9. package/.out/index.d.ts +1 -0
  10. package/.out/index.js +1 -0
  11. package/.out/mantine/create_fields_view.d.ts +7 -0
  12. package/.out/mantine/{create_sub_form.js → create_fields_view.js} +4 -5
  13. package/.out/mantine/create_form.d.ts +7 -0
  14. package/.out/mantine/create_form.js +13 -0
  15. package/.out/mantine/hooks.d.ts +6 -4
  16. package/.out/mantine/hooks.js +17 -7
  17. package/.out/mantine/specs/checkbox_hooks.stories.d.ts +2 -2
  18. package/.out/mantine/specs/checkbox_hooks.stories.js +2 -2
  19. package/.out/mantine/specs/{sub_form_hooks.stories.d.ts → fields_view_hooks.stories.d.ts} +2 -2
  20. package/.out/mantine/specs/{sub_form_hooks.stories.js → fields_view_hooks.stories.js} +9 -8
  21. package/.out/mantine/specs/fields_view_hooks.tests.d.ts +1 -0
  22. package/.out/mantine/specs/fields_view_hooks.tests.js +12 -0
  23. package/.out/mantine/specs/form_hooks.stories.d.ts +12 -0
  24. package/.out/mantine/specs/form_hooks.stories.js +60 -0
  25. package/.out/mantine/specs/form_hooks.tests.d.ts +1 -0
  26. package/.out/mantine/specs/form_hooks.tests.js +12 -0
  27. package/.out/mantine/specs/list_hooks.stories.d.ts +2 -2
  28. package/.out/mantine/specs/list_hooks.stories.js +2 -2
  29. package/.out/mantine/specs/radio_group_hooks.stories.d.ts +2 -2
  30. package/.out/mantine/specs/radio_group_hooks.stories.js +2 -2
  31. package/.out/mantine/specs/select_hooks.stories.d.ts +2 -2
  32. package/.out/mantine/specs/select_hooks.stories.js +2 -2
  33. package/.out/mantine/specs/text_input_hooks.stories.d.ts +2 -2
  34. package/.out/mantine/specs/text_input_hooks.stories.js +2 -2
  35. package/.out/mantine/specs/value_input_hooks.stories.d.ts +2 -2
  36. package/.out/mantine/specs/value_input_hooks.stories.js +2 -2
  37. package/.out/tsconfig.tsbuildinfo +1 -1
  38. package/.turbo/turbo-build.log +8 -8
  39. package/.turbo/turbo-check-types.log +1 -1
  40. package/core/mobx/hooks.ts +94 -0
  41. package/core/mobx/specs/form_presenter.tests.ts +6 -6
  42. package/core/mobx/specs/{merge_field_adapters_with_two_way_converter.ts → merge_field_adapters_with_two_way_converter.tests.ts} +16 -16
  43. package/core/mobx/specs/sub_form_field_adapters.tests.ts +93 -10
  44. package/core/mobx/sub_form_field_adapters.ts +54 -7
  45. package/core/props.ts +2 -2
  46. package/dist/index.cjs +200 -90
  47. package/dist/index.d.cts +43 -34
  48. package/dist/index.d.ts +43 -34
  49. package/dist/index.js +186 -70
  50. package/index.ts +1 -0
  51. package/mantine/{create_sub_form.tsx → create_fields_view.tsx} +27 -16
  52. package/mantine/create_form.tsx +43 -0
  53. package/mantine/hooks.tsx +48 -14
  54. package/mantine/specs/__snapshots__/fields_view_hooks.tests.tsx.snap +460 -0
  55. package/mantine/specs/__snapshots__/form_hooks.tests.tsx.snap +273 -0
  56. package/mantine/specs/checkbox_hooks.stories.tsx +4 -4
  57. package/mantine/specs/{sub_form_hooks.stories.tsx → fields_view_hooks.stories.tsx} +23 -11
  58. package/mantine/specs/fields_view_hooks.tests.tsx +15 -0
  59. package/mantine/specs/form_hooks.stories.tsx +107 -0
  60. package/mantine/specs/form_hooks.tests.tsx +15 -0
  61. package/mantine/specs/list_hooks.stories.tsx +4 -4
  62. package/mantine/specs/radio_group_hooks.stories.tsx +4 -4
  63. package/mantine/specs/select_hooks.stories.tsx +4 -4
  64. package/mantine/specs/text_input_hooks.stories.tsx +4 -4
  65. package/mantine/specs/value_input_hooks.stories.tsx +4 -4
  66. package/package.json +1 -1
  67. package/.out/mantine/create_sub_form.d.ts +0 -6
  68. /package/.out/core/mobx/specs/{merge_field_adapters_with_two_way_converter.d.ts → merge_field_adapters_with_two_way_converter.tests.d.ts} +0 -0
package/dist/index.d.ts CHANGED
@@ -149,29 +149,17 @@ declare class FormModel<T extends Type, ValueToTypePaths extends Readonly<Record
149
149
  get accessors(): Readonly<Record<string, Accessor>>;
150
150
  }
151
151
 
152
- type MergedOfFieldAdaptersWithTwoWayConverter<FieldAdapters extends Readonly<Record<string, FieldAdapter>>, E, Context> = {
153
- [K in keyof FieldAdapters]: FieldAdapter<FromOfFieldAdapter<FieldAdapters[K]>, ToOfFieldAdapter<FieldAdapters[K]>, ErrorOfFieldAdapter<FieldAdapters[K]> | E, ValuePathOfFieldAdapter<FieldAdapters[K]>, Context>;
152
+ type FieldsViewProps<F extends Fields> = {
153
+ fields: F;
154
+ onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void;
155
+ onFieldFocus?(this: void, key: keyof F): void;
156
+ onFieldBlur?(this: void, key: keyof F): void;
157
+ onFieldSubmit?(this: void, key: keyof F): boolean | void;
154
158
  };
155
- type ValuePathsOfFieldAdapters<FieldAdapters extends Readonly<Record<string, FieldAdapter>>> = {
156
- [K in keyof FieldAdapters]: ValuePathOfFieldAdapter<FieldAdapters[K]>;
157
- }[keyof FieldAdapters];
158
- type TosOfFieldAdapters<FieldAdapters extends Readonly<Record<string, FieldAdapter>>> = {
159
- [K in keyof FieldAdapters]: ToOfFieldAdapter<FieldAdapters[K]>;
160
- }[keyof FieldAdapters];
161
- declare function mergeFieldAdaptersWithTwoWayConverter<FieldAdapters extends Readonly<Record<string, FieldAdapter>>, E, Context>(fieldAdapters: FieldAdapters, converter: TwoWayFieldConverter<TosOfFieldAdapters<FieldAdapters>, TosOfFieldAdapters<FieldAdapters>, E, ValuePathsOfFieldAdapters<FieldAdapters>, Context>): MergedOfFieldAdaptersWithTwoWayConverter<FieldAdapters, E, Context>;
162
-
163
- type MergedOfFieldAdaptersWithValidators<FieldAdapters extends Readonly<Record<Key, FieldAdapter>>, Validators extends Partial<Readonly<Record<string, Validator>>>, Key extends keyof Validators = keyof Validators> = Simplify<{
164
- readonly [K in Key]: MergedOfFieldAdapterWithValidator<FieldAdapters[K], Validators[K]>;
165
- } & {
166
- readonly [K in Exclude<keyof FieldAdapters, Key>]: FieldAdapters[K];
167
- }>;
168
- type MergedOfFieldAdapterWithValidator<A extends FieldAdapter, V extends Validator | undefined> = undefined extends V ? A : A extends FieldAdapter<infer From, infer To, infer E1, infer P1, infer C1> ? V extends Validator<From, infer E2, infer P2, infer C2> ? FieldAdapter<From, To, E1 | E2, P1 | P2, C1 | C2> : never : never;
169
- declare function mergeAdaptersWithValidators<FieldAdapters extends Readonly<Record<Key, FieldAdapter>>, Validators extends Readonly<Record<string, Validator>>, Key extends keyof Validators = keyof Validators>(adapters: FieldAdapters, validators: Validators): MergedOfFieldAdaptersWithValidators<FieldAdapters, Validators, Key>;
170
-
171
- type SubFormFieldAdapters<SubAdapters extends Record<string, FieldAdapter>, P extends string> = {
172
- [K in keyof SubAdapters as K extends StringConcatOf<'$', infer S> ? `${P}${S}` : never]: SubAdapters[K];
159
+ type FormProps<O> = {
160
+ value: O;
161
+ onValueChange: (value: O) => void;
173
162
  };
174
- declare function subFormFieldAdapters<SubAdapters extends Record<string, FieldAdapter>, P extends string>(subAdapters: SubAdapters, prefix: P): SubFormFieldAdapters<SubAdapters, P>;
175
163
 
176
164
  /**
177
165
  * Used to extract the supported value paths from a presenter
@@ -191,17 +179,36 @@ type ToValueOfPresenterValuePath<Presenter extends FormPresenter<any, any, any,
191
179
  */
192
180
  type FormFieldsOfPresenter<Presenter extends FormPresenter<any, any, any, any>> = Presenter extends FormPresenter<infer _1, infer _2, infer _3, infer ValuePathsToAdapters> ? FlattenedConvertedFieldsOf<ValuePathsToAdapters> : never;
193
181
 
194
- type FormProps<F extends Fields> = {
195
- fields: F;
196
- onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void;
197
- onFieldFocus?(this: void, key: keyof F): void;
198
- onFieldBlur?(this: void, key: keyof F): void;
199
- onFieldSubmit?(this: void, key: keyof F): boolean | void;
182
+ type ValueOfPresenter<P extends FormPresenter<any, any, any, any>> = P extends FormPresenter<infer T, any, any, any> ? ValueOfType<ReadonlyTypeOfType<T>> : never;
183
+ type ModelOfPresenter<P extends FormPresenter<any, any, any, any>> = ReturnType<P['createModel']>;
184
+ 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): {
185
+ model: ModelOfPresenter<P>;
186
+ } & Omit<FieldsViewProps<ModelOfPresenter<P>['fields']>, 'fields'>;
187
+
188
+ type MergedOfFieldAdaptersWithTwoWayConverter<FieldAdapters extends Readonly<Record<string, FieldAdapter>>, E, Context> = {
189
+ [K in keyof FieldAdapters]: FieldAdapter<FromOfFieldAdapter<FieldAdapters[K]>, ToOfFieldAdapter<FieldAdapters[K]>, ErrorOfFieldAdapter<FieldAdapters[K]> | E, ValuePathOfFieldAdapter<FieldAdapters[K]>, Context>;
200
190
  };
201
- type EditorProps<O> = {
202
- value: O;
203
- onValueChange: (value: O) => void;
191
+ type ValuePathsOfFieldAdapters<FieldAdapters extends Readonly<Record<string, FieldAdapter>>> = {
192
+ [K in keyof FieldAdapters]: ValuePathOfFieldAdapter<FieldAdapters[K]>;
193
+ }[keyof FieldAdapters];
194
+ type TosOfFieldAdapters<FieldAdapters extends Readonly<Record<string, FieldAdapter>>> = {
195
+ [K in keyof FieldAdapters]: ToOfFieldAdapter<FieldAdapters[K]>;
196
+ }[keyof FieldAdapters];
197
+ declare function mergeFieldAdaptersWithTwoWayConverter<FieldAdapters extends Readonly<Record<string, FieldAdapter>>, E, Context>(fieldAdapters: FieldAdapters, converter: TwoWayFieldConverter<TosOfFieldAdapters<FieldAdapters>, TosOfFieldAdapters<FieldAdapters>, E, ValuePathsOfFieldAdapters<FieldAdapters>, Context>): MergedOfFieldAdaptersWithTwoWayConverter<FieldAdapters, E, Context>;
198
+
199
+ type MergedOfFieldAdaptersWithValidators<FieldAdapters extends Readonly<Record<Key, FieldAdapter>>, Validators extends Partial<Readonly<Record<string, Validator>>>, Key extends keyof Validators = keyof Validators> = Simplify<{
200
+ readonly [K in Key]: MergedOfFieldAdapterWithValidator<FieldAdapters[K], Validators[K]>;
201
+ } & {
202
+ readonly [K in Exclude<keyof FieldAdapters, Key>]: FieldAdapters[K];
203
+ }>;
204
+ type MergedOfFieldAdapterWithValidator<A extends FieldAdapter, V extends Validator | undefined> = undefined extends V ? A : A extends FieldAdapter<infer From, infer To, infer E1, infer P1, infer C1> ? V extends Validator<From, infer E2, infer P2, infer C2> ? FieldAdapter<From, To, E1 | E2, P1 | P2, C1 | C2> : never : never;
205
+ declare function mergeAdaptersWithValidators<FieldAdapters extends Readonly<Record<Key, FieldAdapter>>, Validators extends Readonly<Record<string, Validator>>, Key extends keyof Validators = keyof Validators>(adapters: FieldAdapters, validators: Validators): MergedOfFieldAdaptersWithValidators<FieldAdapters, Validators, Key>;
206
+
207
+ type SubFormFieldAdapter<F extends FieldAdapter, P extends string, Context> = FieldAdapter<FromOfFieldAdapter<F>, ToOfFieldAdapter<F>, ErrorOfFieldAdapter<F>, P, Context>;
208
+ type SubFormFieldAdapters<SubAdapters extends Record<string, FieldAdapter>, P extends string, Context> = {
209
+ [K in keyof SubAdapters as K extends StringConcatOf<'$', infer S> ? `${P}${S}` : never]: K extends StringConcatOf<'$', infer S> ? SubFormFieldAdapter<SubAdapters[K], `${P}${S}`, Context> : never;
204
210
  };
211
+ declare function subFormFieldAdapters<SubAdapters extends Record<string, FieldAdapter>, P extends string, ContextType extends Type>(subAdapters: SubAdapters, prefix: P, contextType: ContextType): SubFormFieldAdapters<SubAdapters, P, ValueOfType<ContextType>>;
205
212
 
206
213
  declare class IntegerToStringConverter<E, ValuePath extends string, Context> implements TwoWayFieldConverter<number, string, E, ValuePath, Context> {
207
214
  private readonly isNanError;
@@ -360,7 +367,7 @@ type SuppliedValueInputProps<V, T extends Element = Element> = Partial<{
360
367
  declare function SimpleSelect(props: SelectProps & {
361
368
  onChange?: (value: string | null) => void;
362
369
  }): react_jsx_runtime.JSX.Element;
363
- declare function useMantineForm<F extends Fields>({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }: FormProps<F>): MantineFormImpl<F>;
370
+ declare function useMantineFormFields<F extends Fields>({ onFieldValueChange, onFieldBlur, onFieldFocus, onFieldSubmit, fields, }: FieldsViewProps<F>): MantineFormImpl<F>;
364
371
  declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
365
372
  private readonly textInputCache;
366
373
  private readonly valueInputCache;
@@ -369,7 +376,8 @@ declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
369
376
  private readonly radioCache;
370
377
  private readonly pillCache;
371
378
  private readonly listCache;
372
- private readonly subFormCache;
379
+ private readonly fieldsViewCache;
380
+ private readonly formCache;
373
381
  accessor fields: F;
374
382
  onFieldValueChange: <K extends keyof F>(this: void, key: K, value: F[K]['value']) => void;
375
383
  onFieldFocus: ((this: void, key: keyof F) => void) | undefined;
@@ -389,7 +397,8 @@ declare class MantineFormImpl<F extends Fields> implements MantineForm<F> {
389
397
  pill<K extends keyof AllFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedPillProps, PillProps, ErrorOfField<F[K]>>;
390
398
  pill<K extends keyof AllFieldsOfFields<F>, P extends SuppliedPillProps>(valuePath: K, Pill: ComponentType<P>): MantineFieldComponent<SuppliedPillProps, P>;
391
399
  list<K extends keyof ListFieldsOfFields<F>>(valuePath: K): MantineFieldComponent<SuppliedListProps<`${K}.${number}`>, ComponentProps<typeof DefaultList<ElementOfArray<F[K]['value']>, K>>>;
392
- subForm<K extends keyof AllFieldsOfFields<F>, S extends SubFormFields<F, K>>(valuePath: K, SubForm: ComponentType<FormProps<S>>): ComponentType;
400
+ fieldsView<K extends keyof AllFieldsOfFields<F>, P extends FieldsViewProps<Fields> = FieldsViewProps<SubFormFields<F, K>>>(valuePath: K, FieldsView: ComponentType<P>): MantineFieldComponent<FieldsViewProps<P['fields']>, P>;
401
+ 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>;
393
402
  }
394
403
 
395
404
  type MergedOfValidators<Validators1 extends Partial<Readonly<Record<Keys, Validator>>>, Validators2 extends Partial<Readonly<Record<Keys, Validator>>>, Keys extends string = Extract<keyof Validators1 | keyof Validators2, string>> = Simplify<{
@@ -398,4 +407,4 @@ type MergedOfValidators<Validators1 extends Partial<Readonly<Record<Keys, Valida
398
407
  type MergedOfValidator<Validator1 extends Validator, Validator2 extends Validator> = Validator1 extends Validator<infer V, infer E1, infer P, infer C> ? Validator2 extends Validator<V, infer E2, P, C> ? Validator<V, E1 | E2, P, C> : never : never;
399
408
  declare function mergeValidators<Validators1 extends Partial<Readonly<Record<Keys, Validator>>>, Validators2 extends Partial<Readonly<Record<Keys, Validator>>>, Keys extends string = Extract<keyof Validators1 | keyof Validators2, string>>(validators1: Validators1, validators2: Validators2): MergedOfValidators<Validators1, Validators2, Keys>;
400
409
 
401
- export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, DefaultErrorRenderer, type EditorProps, type ErrorOfField, type ErrorOfFieldAdapter, type ErrorRenderer, type ErrorRendererProps, type Field, type FieldAdapter, type FieldAdaptersOfValues, type FieldValueFactory, type Fields, type FlattenedAdaptersOfFields, type FlattenedConvertedFieldsOf, type FlattenedTypePathsToAdaptersOf, type FormFieldsOfFieldAdapters, type FormFieldsOfPresenter, FormModel, FormPresenter, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, type ToValueOfPresenterValuePath, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, type ValuePathOfFieldAdapter, type ValuePathsOfPresenter, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, useMantineForm, usePartialComponent, usePartialObserverComponent, validatingConverter };
410
+ export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, DefaultErrorRenderer, type ErrorOfField, type ErrorOfFieldAdapter, type ErrorRenderer, type ErrorRendererProps, type Field, type FieldAdapter, type FieldAdaptersOfValues, type FieldValueFactory, type Fields, type FieldsViewProps, type FlattenedAdaptersOfFields, type FlattenedConvertedFieldsOf, type FlattenedTypePathsToAdaptersOf, type FormFieldsOfFieldAdapters, type FormFieldsOfPresenter, FormModel, FormPresenter, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, type ToValueOfPresenterValuePath, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, type ValuePathOfFieldAdapter, type ValuePathsOfPresenter, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, useDefaultMobxFormHooks, useMantineFormFields, usePartialComponent, usePartialObserverComponent, validatingConverter };
package/dist/index.js CHANGED
@@ -655,6 +655,62 @@ var FormModel = class {
655
655
  }
656
656
  };
657
657
 
658
+ // core/mobx/hooks.ts
659
+ import {
660
+ useCallback,
661
+ useMemo
662
+ } from "react";
663
+ function useDefaultMobxFormHooks(presenter, value, onValidSubmit) {
664
+ const model = useMemo(function() {
665
+ return presenter.createModel(value);
666
+ }, [
667
+ presenter,
668
+ value
669
+ ]);
670
+ const onFieldValueChange = useCallback(
671
+ function(path, value2) {
672
+ presenter.clearFieldError(model, path);
673
+ presenter.setFieldValue(model, path, value2);
674
+ },
675
+ [
676
+ presenter,
677
+ model
678
+ ]
679
+ );
680
+ const onFieldSubmit = useCallback(
681
+ function(valuePath) {
682
+ if (presenter.validateField(model, valuePath)) {
683
+ onValidSubmit?.(model, valuePath);
684
+ }
685
+ return false;
686
+ },
687
+ [
688
+ presenter,
689
+ model,
690
+ onValidSubmit
691
+ ]
692
+ );
693
+ const onFieldBlur = useCallback(
694
+ function(path) {
695
+ setTimeout(function() {
696
+ if (presenter.isValuePathActive(model, path)) {
697
+ presenter.validateField(model, path);
698
+ }
699
+ }, 100);
700
+ },
701
+ [
702
+ presenter,
703
+ model
704
+ ]
705
+ );
706
+ return {
707
+ model,
708
+ onFieldValueChange,
709
+ onFieldSubmit,
710
+ onFieldBlur
711
+ };
712
+ }
713
+
658
714
  // core/mobx/merge_field_adapters_with_two_way_converter.ts
659
715
  import { map as map2 } from "@strictly/base";
660
716
  function mergeFieldAdaptersWithTwoWayConverter(fieldAdapters, converter) {
@@ -734,13 +790,35 @@ function mergeAdaptersWithValidators(adapters, validators) {
734
790
  }
735
791
 
736
792
  // core/mobx/sub_form_field_adapters.ts
737
- function subFormFieldAdapters(subAdapters, prefix) {
793
+ import {
794
+ flattenValuesOfType as flattenValuesOfType2
795
+ } from "@strictly/define";
796
+ function subFormFieldAdapters(subAdapters, prefix, contextType) {
797
+ function getSubValuePathAndContext(valuePath, context) {
798
+ const subValuePath = valuePath.replace(prefix, "$");
799
+ const subContext = flattenValuesOfType2(contextType, context)[prefix];
800
+ return [
801
+ subValuePath,
802
+ subContext
803
+ ];
804
+ }
738
805
  return Object.entries(subAdapters).reduce((acc, [
739
806
  subKey,
740
807
  subValue
741
808
  ]) => {
742
809
  const key = subKey.replace("$", prefix);
743
- acc[key] = subValue;
810
+ const adaptedAdapter = {
811
+ convert: (from, valuePath, context) => {
812
+ return subValue.convert(from, ...getSubValuePathAndContext(valuePath, context));
813
+ },
814
+ create: (valuePath, context) => {
815
+ return subValue.create(...getSubValuePathAndContext(valuePath, context));
816
+ },
817
+ revert: subValue.revert && ((from, valuePath, context) => {
818
+ return subValue.revert(from, ...getSubValuePathAndContext(valuePath, context));
819
+ })
820
+ };
821
+ acc[key] = adaptedAdapter;
744
822
  return acc;
745
823
  }, {});
746
824
  }
@@ -982,14 +1060,14 @@ import {
982
1060
  } from "mobx";
983
1061
  import {
984
1062
  useEffect,
985
- useMemo as useMemo2
1063
+ useMemo as useMemo3
986
1064
  } from "react";
987
1065
 
988
1066
  // util/partial.tsx
989
1067
  import { observer } from "mobx-react";
990
1068
  import {
991
1069
  forwardRef,
992
- useMemo
1070
+ useMemo as useMemo2
993
1071
  } from "react";
994
1072
  import { jsx } from "react/jsx-runtime";
995
1073
  function createSimplePartialComponent(Component, curriedProps) {
@@ -1050,7 +1128,7 @@ function createPartialComponent(Component, curriedPropsSource, additionalPropKey
1050
1128
  );
1051
1129
  }
1052
1130
  function usePartialComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
1053
- return useMemo(
1131
+ return useMemo2(
1054
1132
  function() {
1055
1133
  return createPartialComponent(
1056
1134
  Component,
@@ -1120,7 +1198,7 @@ function createUnsafePartialObserverComponent(Component, curriedPropsSource, add
1120
1198
  );
1121
1199
  }
1122
1200
  function usePartialObserverComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
1123
- return useMemo(
1201
+ return useMemo2(
1124
1202
  function() {
1125
1203
  return createPartialObserverComponent(
1126
1204
  Component,
@@ -1187,8 +1265,81 @@ function createCheckbox(valuePath, Checkbox) {
1187
1265
  );
1188
1266
  }
1189
1267
 
1268
+ // mantine/create_fields_view.tsx
1269
+ import { observer as observer2 } from "mobx-react";
1270
+ import { jsx as jsx3 } from "react/jsx-runtime";
1271
+ function createFieldsView(valuePath, FieldsView, observableProps) {
1272
+ function toKey(subKey) {
1273
+ return subKey.replace("$", valuePath);
1274
+ }
1275
+ function toSubKey(key) {
1276
+ return key.replace(valuePath, "$");
1277
+ }
1278
+ function onFieldValueChange(subKey, value) {
1279
+ observableProps.onFieldValueChange(toKey(subKey), value);
1280
+ }
1281
+ function onFieldBlur(subKey) {
1282
+ observableProps.onFieldBlur?.(toKey(subKey));
1283
+ }
1284
+ function onFieldFocus(subKey) {
1285
+ observableProps.onFieldFocus?.(toKey(subKey));
1286
+ }
1287
+ function onFieldSubmit(subKey) {
1288
+ observableProps.onFieldSubmit?.(toKey(subKey));
1289
+ }
1290
+ return observer2(function(props) {
1291
+ const subFields = Object.entries(observableProps.fields).reduce((acc, [
1292
+ fieldKey,
1293
+ fieldValue
1294
+ ]) => {
1295
+ if (fieldKey.startsWith(valuePath)) {
1296
+ acc[toSubKey(fieldKey)] = fieldValue;
1297
+ }
1298
+ return acc;
1299
+ }, {});
1300
+ return /* @__PURE__ */ jsx3(
1301
+ FieldsView,
1302
+ {
1303
+ // maybe we can do this in a more type safe way
1304
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions
1305
+ ...props,
1306
+ fields: subFields,
1307
+ onFieldBlur,
1308
+ onFieldFocus,
1309
+ onFieldSubmit,
1310
+ onFieldValueChange
1311
+ }
1312
+ );
1313
+ });
1314
+ }
1315
+
1316
+ // mantine/create_form.tsx
1317
+ import { observer as observer3 } from "mobx-react";
1318
+ import {
1319
+ useCallback as useCallback2
1320
+ } from "react";
1321
+ import { jsx as jsx4 } from "react/jsx-runtime";
1322
+ function createForm(valuePath, Form, observableProps) {
1323
+ return observer3((props) => {
1324
+ const { value } = observableProps.fields[valuePath];
1325
+ const onValueChange = useCallback2((value2) => {
1326
+ observableProps.onFieldValueChange(valuePath, value2);
1327
+ }, []);
1328
+ return /* @__PURE__ */ jsx4(
1329
+ Form,
1330
+ {
1331
+ // maybe we can do this in a more type safe way
1332
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions
1333
+ ...props,
1334
+ onValueChange,
1335
+ value
1336
+ }
1337
+ );
1338
+ });
1339
+ }
1340
+
1190
1341
  // mantine/create_list.tsx
1191
- import { Fragment, jsx as jsx3 } from "react/jsx-runtime";
1342
+ import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
1192
1343
  function createList(valuePath, List) {
1193
1344
  const propSource = () => {
1194
1345
  const values = [...this.fields[valuePath].value];
@@ -1204,7 +1355,7 @@ function DefaultList({
1204
1355
  listPath,
1205
1356
  children
1206
1357
  }) {
1207
- return /* @__PURE__ */ jsx3(Fragment, { children: values.map(function(value, index) {
1358
+ return /* @__PURE__ */ jsx5(Fragment, { children: values.map(function(value, index) {
1208
1359
  const valuePath = `${listPath}.${index}`;
1209
1360
  return children(valuePath, value, index);
1210
1361
  }) });
@@ -1243,7 +1394,7 @@ function createRadio(valuePath, value, Radio) {
1243
1394
  }
1244
1395
 
1245
1396
  // mantine/create_radio_group.tsx
1246
- import { jsx as jsx4 } from "react/jsx-runtime";
1397
+ import { jsx as jsx6 } from "react/jsx-runtime";
1247
1398
  function createRadioGroup(valuePath, RadioGroup) {
1248
1399
  const onChange = (value) => {
1249
1400
  this.onFieldValueChange?.(valuePath, value);
@@ -1271,7 +1422,7 @@ function createRadioGroup(valuePath, RadioGroup) {
1271
1422
  name: valuePath,
1272
1423
  value,
1273
1424
  required,
1274
- error: error && /* @__PURE__ */ jsx4(ErrorRenderer, { error }),
1425
+ error: error && /* @__PURE__ */ jsx6(ErrorRenderer, { error }),
1275
1426
  onChange,
1276
1427
  onFocus,
1277
1428
  onBlur,
@@ -1281,53 +1432,8 @@ function createRadioGroup(valuePath, RadioGroup) {
1281
1432
  return createUnsafePartialObserverComponent(RadioGroup, propSource, ["ErrorRenderer"]);
1282
1433
  }
1283
1434
 
1284
- // mantine/create_sub_form.tsx
1285
- import { observer as observer2 } from "mobx-react";
1286
- import { jsx as jsx5 } from "react/jsx-runtime";
1287
- function createSubForm(valuePath, SubForm, observableProps) {
1288
- function toKey(subKey) {
1289
- return subKey.replace("$", valuePath);
1290
- }
1291
- function toSubKey(key) {
1292
- return key.replace(valuePath, "$");
1293
- }
1294
- function onFieldValueChange(subKey, value) {
1295
- observableProps.onFieldValueChange(toKey(subKey), value);
1296
- }
1297
- function onFieldBlur(subKey) {
1298
- observableProps.onFieldBlur?.(toKey(subKey));
1299
- }
1300
- function onFieldFocus(subKey) {
1301
- observableProps.onFieldFocus?.(toKey(subKey));
1302
- }
1303
- function onFieldSubmit(subKey) {
1304
- observableProps.onFieldSubmit?.(toKey(subKey));
1305
- }
1306
- return observer2(function() {
1307
- const subFields = Object.entries(observableProps.fields).reduce((acc, [
1308
- fieldKey,
1309
- fieldValue
1310
- ]) => {
1311
- if (fieldKey.startsWith(valuePath)) {
1312
- acc[toSubKey(fieldKey)] = fieldValue;
1313
- }
1314
- return acc;
1315
- }, {});
1316
- return /* @__PURE__ */ jsx5(
1317
- SubForm,
1318
- {
1319
- fields: subFields,
1320
- onFieldBlur,
1321
- onFieldFocus,
1322
- onFieldSubmit,
1323
- onFieldValueChange
1324
- }
1325
- );
1326
- });
1327
- }
1328
-
1329
1435
  // mantine/create_text_input.tsx
1330
- import { jsx as jsx6 } from "react/jsx-runtime";
1436
+ import { jsx as jsx7 } from "react/jsx-runtime";
1331
1437
  function createTextInput(valuePath, TextInput) {
1332
1438
  const onChange = (e) => {
1333
1439
  this.onFieldValueChange?.(valuePath, e.target.value);
@@ -1361,7 +1467,7 @@ function createTextInput(valuePath, TextInput) {
1361
1467
  value,
1362
1468
  disabled: readonly,
1363
1469
  required,
1364
- error: error && /* @__PURE__ */ jsx6(ErrorRenderer, { error }),
1470
+ error: error && /* @__PURE__ */ jsx7(ErrorRenderer, { error }),
1365
1471
  onChange,
1366
1472
  onFocus,
1367
1473
  onBlur,
@@ -1376,7 +1482,7 @@ function createTextInput(valuePath, TextInput) {
1376
1482
  }
1377
1483
 
1378
1484
  // mantine/create_value_input.tsx
1379
- import { jsx as jsx7 } from "react/jsx-runtime";
1485
+ import { jsx as jsx8 } from "react/jsx-runtime";
1380
1486
  function createValueInput(valuePath, ValueInput) {
1381
1487
  const onChange = (value) => {
1382
1488
  this.onFieldValueChange?.(valuePath, value);
@@ -1410,7 +1516,7 @@ function createValueInput(valuePath, ValueInput) {
1410
1516
  value,
1411
1517
  disabled: readonly,
1412
1518
  required,
1413
- error: error && /* @__PURE__ */ jsx7(ErrorRenderer, { error }),
1519
+ error: error && /* @__PURE__ */ jsx8(ErrorRenderer, { error }),
1414
1520
  onChange,
1415
1521
  onFocus,
1416
1522
  onBlur,
@@ -1425,18 +1531,18 @@ function createValueInput(valuePath, ValueInput) {
1425
1531
  }
1426
1532
 
1427
1533
  // mantine/hooks.tsx
1428
- import { jsx as jsx8 } from "react/jsx-runtime";
1534
+ import { jsx as jsx9 } from "react/jsx-runtime";
1429
1535
  function SimpleSelect(props) {
1430
- return /* @__PURE__ */ jsx8(Select, { ...props });
1536
+ return /* @__PURE__ */ jsx9(Select, { ...props });
1431
1537
  }
1432
- function useMantineForm({
1538
+ function useMantineFormFields({
1433
1539
  onFieldValueChange,
1434
1540
  onFieldBlur,
1435
1541
  onFieldFocus,
1436
1542
  onFieldSubmit,
1437
1543
  fields
1438
1544
  }) {
1439
- const form = useMemo2(
1545
+ const form = useMemo3(
1440
1546
  function() {
1441
1547
  return new MantineFormImpl(fields);
1442
1548
  },
@@ -1500,9 +1606,10 @@ var MantineFormImpl = class {
1500
1606
  listCache = new Cache(
1501
1607
  createList.bind(this)
1502
1608
  );
1503
- subFormCache = new Cache(
1504
- createSubForm.bind(this)
1609
+ fieldsViewCache = new Cache(
1610
+ createFieldsView.bind(this)
1505
1611
  );
1612
+ formCache = new Cache(createForm.bind(this));
1506
1613
  @observable2.ref
1507
1614
  accessor fields;
1508
1615
  onFieldValueChange;
@@ -1568,13 +1675,21 @@ var MantineFormImpl = class {
1568
1675
  DefaultList
1569
1676
  );
1570
1677
  }
1571
- // TODO have the returned component take any non-overlapping props as props
1572
- subForm(valuePath, SubForm) {
1573
- return this.subFormCache.retrieveOrCreate(
1678
+ fieldsView(valuePath, FieldsView) {
1679
+ return this.fieldsViewCache.retrieveOrCreate(
1680
+ valuePath,
1681
+ // strip props from component since we lose information in the cache
1682
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1683
+ FieldsView,
1684
+ this
1685
+ );
1686
+ }
1687
+ form(valuePath, Form) {
1688
+ return this.formCache.retrieveOrCreate(
1574
1689
  valuePath,
1575
1690
  // strip props from component since we lose information in the cache
1576
1691
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
1577
- SubForm,
1692
+ Form,
1578
1693
  this
1579
1694
  );
1580
1695
  }
@@ -1647,7 +1762,8 @@ export {
1647
1762
  mergeValidators,
1648
1763
  prototypingFieldValueFactory,
1649
1764
  subFormFieldAdapters,
1650
- useMantineForm,
1765
+ useDefaultMobxFormHooks,
1766
+ useMantineFormFields,
1651
1767
  usePartialComponent,
1652
1768
  usePartialObserverComponent,
1653
1769
  validatingConverter
package/index.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'
@@ -1,20 +1,24 @@
1
- import type { FormProps } from 'core/props'
1
+ import type { FieldsViewProps } from 'core/props'
2
2
  import { observer } from 'mobx-react'
3
- import type { ComponentType } from 'react'
3
+ import type {
4
+ ComponentProps,
5
+ ComponentType,
6
+ } from 'react'
4
7
  import type { AllFieldsOfFields } from 'types/all_fields_of_fields'
5
8
  import type { Fields } from 'types/field'
6
9
  import type { SubFormFields } from 'types/sub_form_fields'
7
10
  import type { ValueTypeOfField } from 'types/value_type_of_field'
11
+ import type { MantineFieldComponent } from './types'
8
12
 
9
- export function createSubForm<
13
+ export function createFieldsView<
10
14
  F extends Fields,
11
15
  K extends keyof AllFieldsOfFields<F>,
12
- S extends Fields = SubFormFields<F, K>,
16
+ P extends FieldsViewProps<Fields> = FieldsViewProps<SubFormFields<F, K>>,
13
17
  >(
14
18
  valuePath: K,
15
- SubForm: ComponentType<FormProps<S>>,
16
- observableProps: FormProps<F>,
17
- ) {
19
+ FieldsView: ComponentType<P>,
20
+ observableProps: FieldsViewProps<F>,
21
+ ): MantineFieldComponent<FieldsViewProps<P['fields']>, P> {
18
22
  function toKey(subKey: string | number | symbol): string {
19
23
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
20
24
  return (subKey as string).replace('$', valuePath as string)
@@ -25,25 +29,27 @@ export function createSubForm<
25
29
  return (key as string).replace(valuePath as string, '$')
26
30
  }
27
31
 
28
- function onFieldValueChange<SubK extends keyof S>(
32
+ function onFieldValueChange<SubK extends keyof P['fields']>(
29
33
  subKey: SubK,
30
- value: ValueTypeOfField<S[SubK]>,
34
+ value: ValueTypeOfField<P['fields'][SubK]>,
31
35
  ) {
32
36
  // convert from subKey to key
33
37
  observableProps.onFieldValueChange(toKey(subKey), value)
34
38
  }
35
- function onFieldBlur(subKey: keyof S) {
39
+ function onFieldBlur(subKey: keyof P['fields']) {
36
40
  observableProps.onFieldBlur?.(toKey(subKey))
37
41
  }
38
42
 
39
- function onFieldFocus(subKey: keyof S) {
43
+ function onFieldFocus(subKey: keyof P['fields']) {
40
44
  observableProps.onFieldFocus?.(toKey(subKey))
41
45
  }
42
46
 
43
- function onFieldSubmit(subKey: keyof S) {
47
+ function onFieldSubmit(subKey: keyof P['fields']) {
44
48
  observableProps.onFieldSubmit?.(toKey(subKey))
45
49
  }
46
- return observer(function () {
50
+
51
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
52
+ return observer(function (props: ComponentProps<MantineFieldComponent<FieldsViewProps<P['fields']>, P>>) {
47
53
  // convert fields to sub-fields
48
54
  const subFields = Object.entries(observableProps.fields).reduce<Record<string, unknown>>((acc, [
49
55
  fieldKey,
@@ -57,14 +63,19 @@ export function createSubForm<
57
63
  }, {})
58
64
 
59
65
  return (
60
- <SubForm
66
+ <FieldsView
67
+ {
68
+ // maybe we can do this in a more type safe way
69
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions
70
+ ...props as any
71
+ }
61
72
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
62
- fields={subFields as S}
73
+ fields={subFields as P['fields']}
63
74
  onFieldBlur={onFieldBlur}
64
75
  onFieldFocus={onFieldFocus}
65
76
  onFieldSubmit={onFieldSubmit}
66
77
  onFieldValueChange={onFieldValueChange}
67
78
  />
68
79
  )
69
- })
80
+ }) as unknown as MantineFieldComponent<FieldsViewProps<P['fields']>, P>
70
81
  }
@@ -0,0 +1,43 @@
1
+ import {
2
+ type FieldsViewProps,
3
+ type FormProps,
4
+ } from 'core/props'
5
+ import { observer } from 'mobx-react'
6
+ import {
7
+ type ComponentProps,
8
+ type ComponentType,
9
+ useCallback,
10
+ } from 'react'
11
+ import { type AllFieldsOfFields } from 'types/all_fields_of_fields'
12
+ import { type Fields } from 'types/field'
13
+ import { type ValueTypeOfField } from 'types/value_type_of_field'
14
+ import { type MantineFieldComponent } from './types'
15
+
16
+ export function createForm<
17
+ F extends Fields,
18
+ K extends keyof AllFieldsOfFields<F>,
19
+ P extends FormProps<ValueTypeOfField<F[K]>> = FormProps<ValueTypeOfField<F[K]>>,
20
+ >(
21
+ valuePath: K,
22
+ Form: ComponentType<P>,
23
+ observableProps: FieldsViewProps<F>,
24
+ ): MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P> {
25
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
26
+ return observer((props: ComponentProps<MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P>>) => {
27
+ const { value } = observableProps.fields[valuePath]
28
+ const onValueChange = useCallback((value: ValueTypeOfField<F[K]>) => {
29
+ observableProps.onFieldValueChange(valuePath, value)
30
+ }, [])
31
+ return (
32
+ <Form
33
+ {
34
+ // maybe we can do this in a more type safe way
35
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/consistent-type-assertions
36
+ ...props as any
37
+ }
38
+ onValueChange={onValueChange}
39
+ value={value}
40
+ />
41
+ )
42
+ }) as MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P>
43
+ }