@strictly/react-form 0.0.22 → 0.0.24

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.
@@ -7,12 +7,12 @@ $ tsup
7
7
  CLI Target: es6
8
8
  CJS Build start
9
9
  ESM Build start
10
- ESM dist/index.js 56.70 KB
11
- ESM ⚡️ Build success in 124ms
12
- CJS dist/index.cjs 60.71 KB
13
- CJS ⚡️ Build success in 127ms
10
+ CJS dist/index.cjs 60.74 KB
11
+ CJS ⚡️ Build success in 148ms
12
+ ESM dist/index.js 56.72 KB
13
+ ESM ⚡️ Build success in 148ms
14
14
  DTS Build start
15
- DTS ⚡️ Build success in 10452ms
16
- DTS dist/index.d.cts 38.50 KB
17
- DTS dist/index.d.ts 38.50 KB
18
- Done in 11.53s.
15
+ DTS ⚡️ Build success in 31697ms
16
+ DTS dist/index.d.cts 37.27 KB
17
+ DTS dist/index.d.ts 37.27 KB
18
+ Done in 32.89s.
@@ -1,3 +1,3 @@
1
1
  yarn run v1.22.22
2
2
  $ tsc -b
3
- Done in 0.40s.
3
+ Done in 0.41s.
@@ -89,6 +89,7 @@ type FlattenedFieldOverrides<
89
89
  }
90
90
 
91
91
  export enum Validation {
92
+ None = 0,
92
93
  Changed = 1,
93
94
  Always = 2,
94
95
  }
@@ -211,7 +212,7 @@ export abstract class FormModel<
211
212
  case 'edit':
212
213
  return false
213
214
  default:
214
- return this.mode satisfies never
215
+ throw new UnreachableError(this.mode)
215
216
  }
216
217
  }
217
218
 
@@ -310,12 +311,11 @@ export abstract class FormModel<
310
311
  valuePath as string,
311
312
  context,
312
313
  )
313
- // const error = this.errors[valuePath]
314
314
  let error: unknown = undefined
315
315
  const displayedValue = fieldOverride != null ? fieldOverride[0] : value
316
- const validation = this.validation[valuePath]
316
+ const validation = this.validation[valuePath] ?? Validation.None
317
317
  switch (validation) {
318
- case undefined:
318
+ case Validation.None:
319
319
  // skip validation
320
320
  break
321
321
  case Validation.Changed:
@@ -393,7 +393,7 @@ export abstract class FormModel<
393
393
  setFieldValue<K extends keyof ValuePathsToAdapters>(
394
394
  valuePath: K,
395
395
  value: ToOfFieldAdapter<ValuePathsToAdapters[K]>,
396
- validation: Validation | undefined | null = this.validation[valuePath],
396
+ validation?: Validation,
397
397
  ): boolean {
398
398
  return this.internalSetFieldValue(valuePath, value, validation)
399
399
  }
@@ -563,7 +563,7 @@ export abstract class FormModel<
563
563
  private internalSetFieldValue<K extends keyof ValuePathsToAdapters>(
564
564
  valuePath: K,
565
565
  value: ToOfFieldAdapter<ValuePathsToAdapters[K]>,
566
- validation: Validation | undefined | null,
566
+ validation: Validation | undefined,
567
567
  ): boolean {
568
568
  const { revert } = this.getAdapterForValuePath(valuePath)
569
569
 
@@ -576,8 +576,6 @@ export abstract class FormModel<
576
576
  this.fieldOverrides[valuePath] = [value]
577
577
  if (validation != null) {
578
578
  this.validation[valuePath] = validation
579
- } else {
580
- delete this.validation[valuePath]
581
579
  }
582
580
  switch (conversion.type) {
583
581
  case UnreliableFieldConversionType.Failure:
@@ -644,12 +642,13 @@ export abstract class FormModel<
644
642
  return keys.has(valuePath as string)
645
643
  }
646
644
 
645
+ getValidation<K extends keyof ValuePathsToAdapters>(valuePath: K): Validation {
646
+ return this.validation[valuePath] ?? Validation.None
647
+ }
648
+
647
649
  validateField<K extends keyof ValuePathsToAdapters>(
648
650
  valuePath: K,
649
- validation: Validation = Math.max(
650
- this.mode === 'create' ? Validation.Always : Validation.Changed,
651
- this.validation[valuePath] ?? Validation.Changed,
652
- ),
651
+ validation: Validation = Validation.Always,
653
652
  ): boolean {
654
653
  runInAction(() => {
655
654
  this.validation[valuePath] = validation
@@ -657,7 +656,7 @@ export abstract class FormModel<
657
656
  return this.fields[valuePath].error == null
658
657
  }
659
658
 
660
- validateAll(validation: Validation = this.mode === 'create' ? Validation.Always : Validation.Changed): boolean {
659
+ validateAll(validation: Validation = Validation.Always): boolean {
661
660
  const accessors = toArray(this.accessors)
662
661
 
663
662
  runInAction(() => {
@@ -5,14 +5,11 @@ import {
5
5
  import {
6
6
  useCallback,
7
7
  } from 'react'
8
+ import type { ValueTypeOfField } from 'types/value_type_of_field'
8
9
  import {
9
10
  type FormModel,
11
+ Validation,
10
12
  } from './form_model'
11
- import {
12
- type FormFieldsOfModel,
13
- type ToValueOfModelValuePath,
14
- type ValuePathsOfModel,
15
- } from './types'
16
13
 
17
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
15
  type ValueOfModel<M extends FormModel<any, any, any, any, any>> = M extends FormModel<infer T, any, any, any, any>
@@ -22,14 +19,14 @@ type ValueOfModel<M extends FormModel<any, any, any, any, any>> = M extends Form
22
19
  export function useDefaultMobxFormHooks<
23
20
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
24
21
  M extends FormModel<any, any, any, any, any>,
25
- F extends FormFieldsOfModel<M> = FormFieldsOfModel<M>,
22
+ F extends M['fields'] = M['fields'],
26
23
  >(
27
24
  model: M,
28
25
  {
29
26
  onValidFieldSubmit,
30
27
  onValidFormSubmit,
31
28
  }: {
32
- onValidFieldSubmit?: <Path extends ValuePathsOfModel<M>>(valuePath: Path) => void,
29
+ onValidFieldSubmit?: <Path extends keyof F>(valuePath: Path) => void,
33
30
  onValidFormSubmit?: (value: ValueOfModel<M>) => void,
34
31
  } = {},
35
32
  ): {
@@ -40,18 +37,18 @@ export function useDefaultMobxFormHooks<
40
37
  onFieldSubmit?(this: void, key: keyof F): boolean | void,
41
38
  } {
42
39
  const onFieldValueChange = useCallback(
43
- function<Path extends ValuePathsOfModel<M>> (
40
+ function<Path extends keyof F> (
44
41
  path: Path,
45
- value: ToValueOfModelValuePath<M, Path>,
42
+ value: ValueTypeOfField<F[Path]>,
46
43
  ) {
47
- // clear any validation
48
- model.setFieldValue<Path>(path, value, null)
44
+ // clear validation once there are no errors for the field
45
+ model.setFieldValue<Path>(path, value)
49
46
  },
50
47
  [model],
51
48
  )
52
49
 
53
50
  const onFieldSubmit = useCallback(
54
- function<Path extends ValuePathsOfModel<M>> (valuePath: Path) {
51
+ function<Path extends keyof F> (valuePath: Path) {
55
52
  if (model.validateField(valuePath)) {
56
53
  onValidFieldSubmit?.(valuePath)
57
54
  }
@@ -64,13 +61,14 @@ export function useDefaultMobxFormHooks<
64
61
  )
65
62
 
66
63
  const onFieldBlur = useCallback(
67
- function<Path extends ValuePathsOfModel<M>> (path: Path) {
64
+ function<Path extends keyof F> (path: Path) {
68
65
  // work around potential loss of focus prior to state potentially invalidating change triggering
69
66
  // (e.g. changing a discriminator)
70
67
  // TODO debounce?
71
68
  setTimeout(function () {
72
69
  if (model.isValuePathActive(path)) {
73
- model.validateField(path)
70
+ // further workaround to make sure we don't downgrade the existing validation
71
+ model.validateField(path, Math.max(Validation.Changed, model.getValidation(path)))
74
72
  }
75
73
  }, 100)
76
74
  },
@@ -93,7 +93,7 @@ describe('all', function () {
93
93
  resetMockAdapter(originalBooleanToBooleanAdapter, booleanToBooleanAdapter)
94
94
  })
95
95
 
96
- describe('FlattenedTypePathsToConvertersOf', function () {
96
+ describe('FlattenedTypePathsToAdaptersOf', function () {
97
97
  type ConvenientFieldAdapter<
98
98
  From,
99
99
  Context,
@@ -1066,8 +1066,8 @@ describe('all', function () {
1066
1066
  'x',
1067
1067
  true,
1068
1068
  )).narrow,
1069
- '$.x:a': identityAdapter(0).narrow,
1070
- '$.y:b': identityAdapter(false).narrow,
1069
+ '$:x.a': identityAdapter(0).narrow,
1070
+ '$:y.b': identityAdapter(false).narrow,
1071
1071
  } as const
1072
1072
 
1073
1073
  describe('isValuePathActive', function () {
@@ -1091,11 +1091,11 @@ describe('all', function () {
1091
1091
  true,
1092
1092
  ],
1093
1093
  [
1094
- '$.x:a',
1094
+ '$:x.a',
1095
1095
  true,
1096
1096
  ],
1097
1097
  [
1098
- '$.y:b',
1098
+ '$:y.b',
1099
1099
  false,
1100
1100
  ],
1101
1101
  ] as const)('value path %s is active %s', function (path, expected) {
@@ -1124,11 +1124,11 @@ describe('all', function () {
1124
1124
  true,
1125
1125
  ],
1126
1126
  [
1127
- '$.x:a',
1127
+ '$:x.a',
1128
1128
  false,
1129
1129
  ],
1130
1130
  [
1131
- '$.y:b',
1131
+ '$:y.b',
1132
1132
  true,
1133
1133
  ],
1134
1134
  ] as const)('value path %s is active %s', function (path, expected) {
@@ -1267,8 +1267,8 @@ describe('all', function () {
1267
1267
  expect(model.fields['$.n'].readonly).toBeTruthy()
1268
1268
  })
1269
1269
 
1270
- it('validates successfully with clean, but invalid data', () => {
1271
- expect(model.validateAll()).toBeTruthy()
1270
+ it('fails validation with invalid, clean data', () => {
1271
+ expect(model.validateAll()).toBeFalsy()
1272
1272
  })
1273
1273
 
1274
1274
  it('fails validation with invalid, dirty data', () => {
package/dist/index.cjs CHANGED
@@ -358,6 +358,7 @@ var import_base2 = require("@strictly/base");
358
358
  var import_define = require("@strictly/define");
359
359
  var import_mobx = require("mobx");
360
360
  var Validation = /* @__PURE__ */ ((Validation2) => {
361
+ Validation2[Validation2["None"] = 0] = "None";
361
362
  Validation2[Validation2["Changed"] = 1] = "Changed";
362
363
  Validation2[Validation2["Always"] = 2] = "Always";
363
364
  return Validation2;
@@ -412,7 +413,7 @@ var FormModel = class {
412
413
  case "edit":
413
414
  return false;
414
415
  default:
415
- return this.mode;
416
+ throw new import_base2.UnreachableError(this.mode);
416
417
  }
417
418
  }
418
419
  get fields() {
@@ -463,6 +464,7 @@ var FormModel = class {
463
464
  return this.synthesizeFieldByPaths(valuePath, typePath);
464
465
  }
465
466
  synthesizeFieldByPaths(valuePath, typePath) {
467
+ var _a;
466
468
  const adapter2 = this.adapters[typePath];
467
469
  if (adapter2 == null) {
468
470
  return;
@@ -492,9 +494,9 @@ var FormModel = class {
492
494
  );
493
495
  let error = void 0;
494
496
  const displayedValue = fieldOverride != null ? fieldOverride[0] : value;
495
- const validation = this.validation[valuePath];
497
+ const validation = (_a = this.validation[valuePath]) != null ? _a : 0 /* None */;
496
498
  switch (validation) {
497
- case void 0:
499
+ case 0 /* None */:
498
500
  break;
499
501
  case 1 /* Changed */:
500
502
  if (revert != null) {
@@ -555,7 +557,7 @@ var FormModel = class {
555
557
  typePath(valuePath) {
556
558
  return (0, import_define.valuePathToTypePath)(this.type, valuePath, true);
557
559
  }
558
- setFieldValue(valuePath, value, validation = this.validation[valuePath]) {
560
+ setFieldValue(valuePath, value, validation) {
559
561
  return this.internalSetFieldValue(valuePath, value, validation);
560
562
  }
561
563
  addListItem(valuePath, elementValue = null, index) {
@@ -699,8 +701,6 @@ var FormModel = class {
699
701
  this.fieldOverrides[valuePath] = [value];
700
702
  if (validation != null) {
701
703
  this.validation[valuePath] = validation;
702
- } else {
703
- delete this.validation[valuePath];
704
704
  }
705
705
  switch (conversion.type) {
706
706
  case 1 /* Failure */:
@@ -757,16 +757,17 @@ var FormModel = class {
757
757
  const keys = new Set(Object.keys(values));
758
758
  return keys.has(valuePath);
759
759
  }
760
- validateField(valuePath, validation = Math.max(
761
- this.mode === "create" ? 2 /* Always */ : 1 /* Changed */,
762
- ((_a) => (_a = this.validation[valuePath]) != null ? _a : 1 /* Changed */)()
763
- )) {
760
+ getValidation(valuePath) {
761
+ var _a;
762
+ return (_a = this.validation[valuePath]) != null ? _a : 0 /* None */;
763
+ }
764
+ validateField(valuePath, validation = 2 /* Always */) {
764
765
  (0, import_mobx.runInAction)(() => {
765
766
  this.validation[valuePath] = validation;
766
767
  });
767
768
  return this.fields[valuePath].error == null;
768
769
  }
769
- validateAll(validation = this.mode === "create" ? 2 /* Always */ : 1 /* Changed */) {
770
+ validateAll(validation = 2 /* Always */) {
770
771
  const accessors = (0, import_base2.toArray)(this.accessors);
771
772
  (0, import_mobx.runInAction)(() => {
772
773
  accessors.forEach(([valuePath]) => {
@@ -801,7 +802,7 @@ function useDefaultMobxFormHooks(model, {
801
802
  } = {}) {
802
803
  const onFieldValueChange = (0, import_react.useCallback)(
803
804
  function(path, value) {
804
- model.setFieldValue(path, value, null);
805
+ model.setFieldValue(path, value);
805
806
  },
806
807
  [model]
807
808
  );
@@ -821,7 +822,7 @@ function useDefaultMobxFormHooks(model, {
821
822
  function(path) {
822
823
  setTimeout(function() {
823
824
  if (model.isValuePathActive(path)) {
824
- model.validateField(path);
825
+ model.validateField(path, Math.max(1 /* Changed */, model.getValidation(path)));
825
826
  }
826
827
  }, 100);
827
828
  },
package/dist/index.d.cts CHANGED
@@ -113,6 +113,7 @@ type FlattenedFieldOverrides<ValuePathsToAdapters extends Readonly<Record<string
113
113
  -readonly [K in keyof ValuePathsToAdapters]?: FieldOverride<ToOfFieldAdapter<ValuePathsToAdapters[K]>>;
114
114
  };
115
115
  declare enum Validation {
116
+ None = 0,
116
117
  Changed = 1,
117
118
  Always = 2
118
119
  }
@@ -147,7 +148,7 @@ declare abstract class FormModel<T extends Type, ValueToTypePaths extends Readon
147
148
  private maybeGetAdapterForValuePath;
148
149
  private getAdapterForValuePath;
149
150
  typePath<K extends keyof ValueToTypePaths>(valuePath: K): ValueToTypePaths[K];
150
- setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation | undefined | null): boolean;
151
+ setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation): boolean;
151
152
  addListItem<K extends keyof FlattenedListTypesOfType<T>>(valuePath: K, elementValue?: Maybe<ElementOfArray<FlattenedValuesOfType<T>[K]>>, index?: number): void;
152
153
  removeListItem<K extends keyof FlattenedListTypesOfType<T>>(...elementValuePaths: readonly `${K}.${number}`[]): void;
153
154
  private internalSetFieldValue;
@@ -155,31 +156,14 @@ declare abstract class FormModel<T extends Type, ValueToTypePaths extends Readon
155
156
  clearFieldValue<K extends StringKeyOf<ValuePathsToAdapters>>(valuePath: K): void;
156
157
  clearAll(value: ValueOfType<T>): void;
157
158
  isValuePathActive<K extends keyof ValuePathsToAdapters>(valuePath: K): boolean;
159
+ getValidation<K extends keyof ValuePathsToAdapters>(valuePath: K): Validation;
158
160
  validateField<K extends keyof ValuePathsToAdapters>(valuePath: K, validation?: Validation): boolean;
159
161
  validateAll(validation?: Validation): boolean;
160
162
  }
161
163
 
162
- /**
163
- * Used to extract the supported value paths from a model
164
- */
165
- type ValuePathsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? keyof ValuePathsToAdapters : never;
166
- /**
167
- * Used to extract the render type (so the value that is passed to the view) of a given value path
168
- * from a model
169
- */
170
- type ToValueOfModelValuePath<Model extends FormModel<any, any, any, any, any>, K extends ValuePathsOfModel<Model>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? ToOfFieldAdapter<ValuePathsToAdapters[K]> : never;
171
- /**
172
- * Extracts the form fields from a form model. The recommended way is to
173
- * define the form fields explicitly and use that type to enforce the types
174
- * of your converters, but generating the FormFields from your model
175
- * is less typing, albeit at the cost of potentially getting type errors
176
- * reported a long way away from the source
177
- */
178
- type FormFieldsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? FlattenedConvertedFieldsOf<ValuePathsToAdapters> : never;
179
-
180
164
  type ValueOfModel<M extends FormModel<any, any, any, any, any>> = M extends FormModel<infer T, any, any, any, any> ? ValueOfType<ReadonlyTypeOfType<T>> : never;
181
- declare function useDefaultMobxFormHooks<M extends FormModel<any, any, any, any, any>, F extends FormFieldsOfModel<M> = FormFieldsOfModel<M>>(model: M, { onValidFieldSubmit, onValidFormSubmit, }?: {
182
- onValidFieldSubmit?: <Path extends ValuePathsOfModel<M>>(valuePath: Path) => void;
165
+ declare function useDefaultMobxFormHooks<M extends FormModel<any, any, any, any, any>, F extends M['fields'] = M['fields']>(model: M, { onValidFieldSubmit, onValidFormSubmit, }?: {
166
+ onValidFieldSubmit?: <Path extends keyof F>(valuePath: Path) => void;
183
167
  onValidFormSubmit?: (value: ValueOfModel<M>) => void;
184
168
  }): {
185
169
  onFormSubmit: () => void;
@@ -456,4 +440,4 @@ declare function mergeValidators<Validators1 extends Partial<Readonly<Record<Key
456
440
 
457
441
  declare function Empty(): null;
458
442
 
459
- export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, type ContextOf, type ContextOfFieldAdapter, DefaultErrorRenderer, Empty, 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 FormFieldsOfModel, type FormMode, FormModel, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, type RefOfProps, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, type ToValueOfModelValuePath, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, Validation, type ValuePathOfFieldAdapter, type ValuePathsOfModel, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, trimmingStringAdapter, useDefaultMobxFormHooks, useMantineFormFields, usePartialComponent, usePartialObserverComponent, validatingConverter };
443
+ export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, type ContextOf, type ContextOfFieldAdapter, DefaultErrorRenderer, Empty, 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 FormMode, FormModel, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, type RefOfProps, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, Validation, type ValuePathOfFieldAdapter, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, trimmingStringAdapter, useDefaultMobxFormHooks, useMantineFormFields, usePartialComponent, usePartialObserverComponent, validatingConverter };
package/dist/index.d.ts CHANGED
@@ -113,6 +113,7 @@ type FlattenedFieldOverrides<ValuePathsToAdapters extends Readonly<Record<string
113
113
  -readonly [K in keyof ValuePathsToAdapters]?: FieldOverride<ToOfFieldAdapter<ValuePathsToAdapters[K]>>;
114
114
  };
115
115
  declare enum Validation {
116
+ None = 0,
116
117
  Changed = 1,
117
118
  Always = 2
118
119
  }
@@ -147,7 +148,7 @@ declare abstract class FormModel<T extends Type, ValueToTypePaths extends Readon
147
148
  private maybeGetAdapterForValuePath;
148
149
  private getAdapterForValuePath;
149
150
  typePath<K extends keyof ValueToTypePaths>(valuePath: K): ValueToTypePaths[K];
150
- setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation | undefined | null): boolean;
151
+ setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation): boolean;
151
152
  addListItem<K extends keyof FlattenedListTypesOfType<T>>(valuePath: K, elementValue?: Maybe<ElementOfArray<FlattenedValuesOfType<T>[K]>>, index?: number): void;
152
153
  removeListItem<K extends keyof FlattenedListTypesOfType<T>>(...elementValuePaths: readonly `${K}.${number}`[]): void;
153
154
  private internalSetFieldValue;
@@ -155,31 +156,14 @@ declare abstract class FormModel<T extends Type, ValueToTypePaths extends Readon
155
156
  clearFieldValue<K extends StringKeyOf<ValuePathsToAdapters>>(valuePath: K): void;
156
157
  clearAll(value: ValueOfType<T>): void;
157
158
  isValuePathActive<K extends keyof ValuePathsToAdapters>(valuePath: K): boolean;
159
+ getValidation<K extends keyof ValuePathsToAdapters>(valuePath: K): Validation;
158
160
  validateField<K extends keyof ValuePathsToAdapters>(valuePath: K, validation?: Validation): boolean;
159
161
  validateAll(validation?: Validation): boolean;
160
162
  }
161
163
 
162
- /**
163
- * Used to extract the supported value paths from a model
164
- */
165
- type ValuePathsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? keyof ValuePathsToAdapters : never;
166
- /**
167
- * Used to extract the render type (so the value that is passed to the view) of a given value path
168
- * from a model
169
- */
170
- type ToValueOfModelValuePath<Model extends FormModel<any, any, any, any, any>, K extends ValuePathsOfModel<Model>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? ToOfFieldAdapter<ValuePathsToAdapters[K]> : never;
171
- /**
172
- * Extracts the form fields from a form model. The recommended way is to
173
- * define the form fields explicitly and use that type to enforce the types
174
- * of your converters, but generating the FormFields from your model
175
- * is less typing, albeit at the cost of potentially getting type errors
176
- * reported a long way away from the source
177
- */
178
- type FormFieldsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? FlattenedConvertedFieldsOf<ValuePathsToAdapters> : never;
179
-
180
164
  type ValueOfModel<M extends FormModel<any, any, any, any, any>> = M extends FormModel<infer T, any, any, any, any> ? ValueOfType<ReadonlyTypeOfType<T>> : never;
181
- declare function useDefaultMobxFormHooks<M extends FormModel<any, any, any, any, any>, F extends FormFieldsOfModel<M> = FormFieldsOfModel<M>>(model: M, { onValidFieldSubmit, onValidFormSubmit, }?: {
182
- onValidFieldSubmit?: <Path extends ValuePathsOfModel<M>>(valuePath: Path) => void;
165
+ declare function useDefaultMobxFormHooks<M extends FormModel<any, any, any, any, any>, F extends M['fields'] = M['fields']>(model: M, { onValidFieldSubmit, onValidFormSubmit, }?: {
166
+ onValidFieldSubmit?: <Path extends keyof F>(valuePath: Path) => void;
183
167
  onValidFormSubmit?: (value: ValueOfModel<M>) => void;
184
168
  }): {
185
169
  onFormSubmit: () => void;
@@ -456,4 +440,4 @@ declare function mergeValidators<Validators1 extends Partial<Readonly<Record<Key
456
440
 
457
441
  declare function Empty(): null;
458
442
 
459
- export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, type ContextOf, type ContextOfFieldAdapter, DefaultErrorRenderer, Empty, 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 FormFieldsOfModel, type FormMode, FormModel, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, type RefOfProps, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, type ToValueOfModelValuePath, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, Validation, type ValuePathOfFieldAdapter, type ValuePathsOfModel, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, trimmingStringAdapter, useDefaultMobxFormHooks, useMantineFormFields, usePartialComponent, usePartialObserverComponent, validatingConverter };
443
+ export { AbstractSelectValueTypeConverter, type AnnotatedFieldConversion, type AnnotatedFieldConverter, type Annotation, type ContextOf, type ContextOfFieldAdapter, DefaultErrorRenderer, Empty, 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 FormMode, FormModel, type FormProps, type FromOfFieldAdapter, IntegerToStringConverter, type MergedOfFieldAdaptersWithTwoWayConverter, type MergedOfFieldAdaptersWithValidators, type MergedOfValidator, type MergedOfValidators, NullableToBooleanConverter, type PartialComponent, type RefOfProps, SelectDiscriminatedUnionConverter, SelectLiteralConverter, SelectStringConverter, type ToOfFieldAdapter, TrimmingStringConverter, type TwoWayFieldConverter, type TwoWayFieldConverterWithValueFactory, type UnreliableFieldConversion, UnreliableFieldConversionType, type UnreliableFieldConverter, type UnsafePartialComponent, Validation, type ValuePathOfFieldAdapter, type ValuePathsToAdaptersOf, adapter, adapterFromPrototype, adapterFromTwoWayConverter, createPartialComponent, createPartialObserverComponent, createSimplePartialComponent, createUnsafePartialObserverComponent, identityAdapter, listAdapter, mergeAdaptersWithValidators, mergeFieldAdaptersWithTwoWayConverter, mergeValidators, prototypingFieldValueFactory, subFormFieldAdapters, trimmingStringAdapter, useDefaultMobxFormHooks, useMantineFormFields, usePartialComponent, usePartialObserverComponent, validatingConverter };
package/dist/index.js CHANGED
@@ -327,6 +327,7 @@ import {
327
327
  runInAction
328
328
  } from "mobx";
329
329
  var Validation = /* @__PURE__ */ ((Validation2) => {
330
+ Validation2[Validation2["None"] = 0] = "None";
330
331
  Validation2[Validation2["Changed"] = 1] = "Changed";
331
332
  Validation2[Validation2["Always"] = 2] = "Always";
332
333
  return Validation2;
@@ -381,7 +382,7 @@ var FormModel = class {
381
382
  case "edit":
382
383
  return false;
383
384
  default:
384
- return this.mode;
385
+ throw new UnreachableError2(this.mode);
385
386
  }
386
387
  }
387
388
  get fields() {
@@ -432,6 +433,7 @@ var FormModel = class {
432
433
  return this.synthesizeFieldByPaths(valuePath, typePath);
433
434
  }
434
435
  synthesizeFieldByPaths(valuePath, typePath) {
436
+ var _a;
435
437
  const adapter2 = this.adapters[typePath];
436
438
  if (adapter2 == null) {
437
439
  return;
@@ -461,9 +463,9 @@ var FormModel = class {
461
463
  );
462
464
  let error = void 0;
463
465
  const displayedValue = fieldOverride != null ? fieldOverride[0] : value;
464
- const validation = this.validation[valuePath];
466
+ const validation = (_a = this.validation[valuePath]) != null ? _a : 0 /* None */;
465
467
  switch (validation) {
466
- case void 0:
468
+ case 0 /* None */:
467
469
  break;
468
470
  case 1 /* Changed */:
469
471
  if (revert != null) {
@@ -524,7 +526,7 @@ var FormModel = class {
524
526
  typePath(valuePath) {
525
527
  return valuePathToTypePath(this.type, valuePath, true);
526
528
  }
527
- setFieldValue(valuePath, value, validation = this.validation[valuePath]) {
529
+ setFieldValue(valuePath, value, validation) {
528
530
  return this.internalSetFieldValue(valuePath, value, validation);
529
531
  }
530
532
  addListItem(valuePath, elementValue = null, index) {
@@ -668,8 +670,6 @@ var FormModel = class {
668
670
  this.fieldOverrides[valuePath] = [value];
669
671
  if (validation != null) {
670
672
  this.validation[valuePath] = validation;
671
- } else {
672
- delete this.validation[valuePath];
673
673
  }
674
674
  switch (conversion.type) {
675
675
  case 1 /* Failure */:
@@ -726,16 +726,17 @@ var FormModel = class {
726
726
  const keys = new Set(Object.keys(values));
727
727
  return keys.has(valuePath);
728
728
  }
729
- validateField(valuePath, validation = Math.max(
730
- this.mode === "create" ? 2 /* Always */ : 1 /* Changed */,
731
- ((_a) => (_a = this.validation[valuePath]) != null ? _a : 1 /* Changed */)()
732
- )) {
729
+ getValidation(valuePath) {
730
+ var _a;
731
+ return (_a = this.validation[valuePath]) != null ? _a : 0 /* None */;
732
+ }
733
+ validateField(valuePath, validation = 2 /* Always */) {
733
734
  runInAction(() => {
734
735
  this.validation[valuePath] = validation;
735
736
  });
736
737
  return this.fields[valuePath].error == null;
737
738
  }
738
- validateAll(validation = this.mode === "create" ? 2 /* Always */ : 1 /* Changed */) {
739
+ validateAll(validation = 2 /* Always */) {
739
740
  const accessors = toArray(this.accessors);
740
741
  runInAction(() => {
741
742
  accessors.forEach(([valuePath]) => {
@@ -772,7 +773,7 @@ function useDefaultMobxFormHooks(model, {
772
773
  } = {}) {
773
774
  const onFieldValueChange = useCallback(
774
775
  function(path, value) {
775
- model.setFieldValue(path, value, null);
776
+ model.setFieldValue(path, value);
776
777
  },
777
778
  [model]
778
779
  );
@@ -792,7 +793,7 @@ function useDefaultMobxFormHooks(model, {
792
793
  function(path) {
793
794
  setTimeout(function() {
794
795
  if (model.isValuePathActive(path)) {
795
- model.validateField(path);
796
+ model.validateField(path, Math.max(1 /* Changed */, model.getValidation(path)));
796
797
  }
797
798
  }, 100);
798
799
  },
package/index.ts CHANGED
@@ -8,7 +8,6 @@ export * from './core/mobx/hooks'
8
8
  export * from './core/mobx/merge_field_adapters_with_two_way_converter'
9
9
  export * from './core/mobx/merge_field_adapters_with_validators'
10
10
  export * from './core/mobx/sub_form_field_adapters'
11
- export * from './core/mobx/types'
12
11
  export * from './core/props'
13
12
  export * from './field_converters/integer_to_string_converter'
14
13
  export * from './field_converters/nullable_to_boolean_converter'
package/package.json CHANGED
@@ -72,7 +72,7 @@
72
72
  "test:watch": "vitest"
73
73
  },
74
74
  "type": "module",
75
- "version": "0.0.22",
75
+ "version": "0.0.24",
76
76
  "exports": {
77
77
  ".": {
78
78
  "import": {
@@ -1,19 +0,0 @@
1
- import { type ToOfFieldAdapter } from './field_adapter';
2
- import { type FlattenedConvertedFieldsOf, type FormModel } from './form_model';
3
- /**
4
- * Used to extract the supported value paths from a model
5
- */
6
- export type ValuePathsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? keyof ValuePathsToAdapters : never;
7
- /**
8
- * Used to extract the render type (so the value that is passed to the view) of a given value path
9
- * from a model
10
- */
11
- export type ToValueOfModelValuePath<Model extends FormModel<any, any, any, any, any>, K extends ValuePathsOfModel<Model>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? ToOfFieldAdapter<ValuePathsToAdapters[K]> : never;
12
- /**
13
- * Extracts the form fields from a form model. The recommended way is to
14
- * define the form fields explicitly and use that type to enforce the types
15
- * of your converters, but generating the FormFields from your model
16
- * is less typing, albeit at the cost of potentially getting type errors
17
- * reported a long way away from the source
18
- */
19
- export type FormFieldsOfModel<Model extends FormModel<any, any, any, any, any>> = Model extends FormModel<infer _1, infer _2, infer _3, infer _4, infer ValuePathsToAdapters> ? FlattenedConvertedFieldsOf<ValuePathsToAdapters> : never;
@@ -1 +0,0 @@
1
- export {};