@strictly/react-form 0.0.23 → 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 139ms
12
- CJS dist/index.cjs 60.71 KB
13
- CJS ⚡️ Build success in 141ms
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 31420ms
16
- DTS dist/index.d.cts 37.20 KB
17
- DTS dist/index.d.ts 37.20 KB
18
- Done in 32.57s.
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.37s.
3
+ Done in 0.41s.
@@ -1,3 +1,3 @@
1
1
  yarn run v1.22.22
2
2
  $ json -f package.json -f package.exports.json --merge > package.release.json
3
- Done in 0.11s.
3
+ Done in 0.12s.
@@ -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(() => {
@@ -8,6 +8,7 @@ import {
8
8
  import type { ValueTypeOfField } from 'types/value_type_of_field'
9
9
  import {
10
10
  type FormModel,
11
+ Validation,
11
12
  } from './form_model'
12
13
 
13
14
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -40,8 +41,8 @@ export function useDefaultMobxFormHooks<
40
41
  path: Path,
41
42
  value: ValueTypeOfField<F[Path]>,
42
43
  ) {
43
- // clear any validation
44
- model.setFieldValue<Path>(path, value, null)
44
+ // clear validation once there are no errors for the field
45
+ model.setFieldValue<Path>(path, value)
45
46
  },
46
47
  [model],
47
48
  )
@@ -66,7 +67,8 @@ export function useDefaultMobxFormHooks<
66
67
  // TODO debounce?
67
68
  setTimeout(function () {
68
69
  if (model.isValuePathActive(path)) {
69
- 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)))
70
72
  }
71
73
  }, 100)
72
74
  },
@@ -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,6 +156,7 @@ 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
  }
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,6 +156,7 @@ 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
  }
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/package.json CHANGED
@@ -72,7 +72,7 @@
72
72
  "test:watch": "vitest"
73
73
  },
74
74
  "type": "module",
75
- "version": "0.0.23",
75
+ "version": "0.0.24",
76
76
  "exports": {
77
77
  ".": {
78
78
  "import": {