@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.
@@ -15,6 +15,7 @@ type FlattenedFieldOverrides<ValuePathsToAdapters extends Readonly<Record<string
15
15
  -readonly [K in keyof ValuePathsToAdapters]?: FieldOverride<ToOfFieldAdapter<ValuePathsToAdapters[K]>>;
16
16
  };
17
17
  export declare enum Validation {
18
+ None = 0,
18
19
  Changed = 1,
19
20
  Always = 2
20
21
  }
@@ -49,7 +50,7 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
49
50
  private maybeGetAdapterForValuePath;
50
51
  private getAdapterForValuePath;
51
52
  typePath<K extends keyof ValueToTypePaths>(valuePath: K): ValueToTypePaths[K];
52
- setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation | undefined | null): boolean;
53
+ setFieldValue<K extends keyof ValuePathsToAdapters>(valuePath: K, value: ToOfFieldAdapter<ValuePathsToAdapters[K]>, validation?: Validation): boolean;
53
54
  addListItem<K extends keyof FlattenedListTypesOfType<T>>(valuePath: K, elementValue?: Maybe<ElementOfArray<FlattenedValuesOfType<T>[K]>>, index?: number): void;
54
55
  removeListItem<K extends keyof FlattenedListTypesOfType<T>>(...elementValuePaths: readonly `${K}.${number}`[]): void;
55
56
  private internalSetFieldValue;
@@ -57,6 +58,7 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
57
58
  clearFieldValue<K extends StringKeyOf<ValuePathsToAdapters>>(valuePath: K): void;
58
59
  clearAll(value: ValueOfType<T>): void;
59
60
  isValuePathActive<K extends keyof ValuePathsToAdapters>(valuePath: K): boolean;
61
+ getValidation<K extends keyof ValuePathsToAdapters>(valuePath: K): Validation;
60
62
  validateField<K extends keyof ValuePathsToAdapters>(valuePath: K, validation?: Validation): boolean;
61
63
  validateAll(validation?: Validation): boolean;
62
64
  }
@@ -49,6 +49,7 @@ import { computed, observable, runInAction, } from 'mobx';
49
49
  import { UnreliableFieldConversionType, } from 'types/field_converters';
50
50
  export var Validation;
51
51
  (function (Validation) {
52
+ Validation[Validation["None"] = 0] = "None";
52
53
  Validation[Validation["Changed"] = 1] = "Changed";
53
54
  Validation[Validation["Always"] = 2] = "Always";
54
55
  })(Validation || (Validation = {}));
@@ -144,7 +145,7 @@ let FormModel = (() => {
144
145
  case 'edit':
145
146
  return false;
146
147
  default:
147
- return this.mode;
148
+ throw new UnreachableError(this.mode);
148
149
  }
149
150
  }
150
151
  get fields() {
@@ -190,6 +191,7 @@ let FormModel = (() => {
190
191
  return this.synthesizeFieldByPaths(valuePath, typePath);
191
192
  }
192
193
  synthesizeFieldByPaths(valuePath, typePath) {
194
+ var _b;
193
195
  const adapter = this.adapters[typePath];
194
196
  if (adapter == null) {
195
197
  // invalid path, which can happen
@@ -211,12 +213,11 @@ let FormModel = (() => {
211
213
  : defaultValue,
212
214
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
213
215
  valuePath, context);
214
- // const error = this.errors[valuePath]
215
216
  let error = undefined;
216
217
  const displayedValue = fieldOverride != null ? fieldOverride[0] : value;
217
- const validation = this.validation[valuePath];
218
+ const validation = (_b = this.validation[valuePath]) !== null && _b !== void 0 ? _b : Validation.None;
218
219
  switch (validation) {
219
- case undefined:
220
+ case Validation.None:
220
221
  // skip validation
221
222
  break;
222
223
  case Validation.Changed:
@@ -277,7 +278,7 @@ let FormModel = (() => {
277
278
  typePath(valuePath) {
278
279
  return valuePathToTypePath(this.type, valuePath, true);
279
280
  }
280
- setFieldValue(valuePath, value, validation = this.validation[valuePath]) {
281
+ setFieldValue(valuePath, value, validation) {
281
282
  return this.internalSetFieldValue(valuePath, value, validation);
282
283
  }
283
284
  addListItem(valuePath,
@@ -417,9 +418,6 @@ let FormModel = (() => {
417
418
  if (validation != null) {
418
419
  this.validation[valuePath] = validation;
419
420
  }
420
- else {
421
- delete this.validation[valuePath];
422
- }
423
421
  switch (conversion.type) {
424
422
  case UnreliableFieldConversionType.Failure:
425
423
  if (conversion.value != null && accessor != null) {
@@ -475,15 +473,17 @@ let FormModel = (() => {
475
473
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
476
474
  return keys.has(valuePath);
477
475
  }
478
- validateField(valuePath, validation) {
476
+ getValidation(valuePath) {
479
477
  var _b;
480
- if (validation === void 0) { validation = Math.max(this.mode === 'create' ? Validation.Always : Validation.Changed, (_b = this.validation[valuePath]) !== null && _b !== void 0 ? _b : Validation.Changed); }
478
+ return (_b = this.validation[valuePath]) !== null && _b !== void 0 ? _b : Validation.None;
479
+ }
480
+ validateField(valuePath, validation = Validation.Always) {
481
481
  runInAction(() => {
482
482
  this.validation[valuePath] = validation;
483
483
  });
484
484
  return this.fields[valuePath].error == null;
485
485
  }
486
- validateAll(validation = this.mode === 'create' ? Validation.Always : Validation.Changed) {
486
+ validateAll(validation = Validation.Always) {
487
487
  const accessors = toArray(this.accessors);
488
488
  runInAction(() => {
489
489
  accessors.forEach(([valuePath]) => {
@@ -1,8 +1,9 @@
1
1
  import { useCallback, } from 'react';
2
+ import { Validation, } from './form_model';
2
3
  export function useDefaultMobxFormHooks(model, { onValidFieldSubmit, onValidFormSubmit, } = {}) {
3
4
  const onFieldValueChange = useCallback(function (path, value) {
4
- // clear any validation
5
- model.setFieldValue(path, value, null);
5
+ // clear validation once there are no errors for the field
6
+ model.setFieldValue(path, value);
6
7
  }, [model]);
7
8
  const onFieldSubmit = useCallback(function (valuePath) {
8
9
  if (model.validateField(valuePath)) {
@@ -19,7 +20,8 @@ export function useDefaultMobxFormHooks(model, { onValidFieldSubmit, onValidForm
19
20
  // TODO debounce?
20
21
  setTimeout(function () {
21
22
  if (model.isValuePathActive(path)) {
22
- model.validateField(path);
23
+ // further workaround to make sure we don't downgrade the existing validation
24
+ model.validateField(path, Math.max(Validation.Changed, model.getValidation(path)));
23
25
  }
24
26
  }, 100);
25
27
  }, [model]);
@@ -863,8 +863,8 @@ describe('all', function () {
863
863
  it('respects the field being readonly', () => {
864
864
  expect(model.fields['$.n'].readonly).toBeTruthy();
865
865
  });
866
- it('validates successfully with clean, but invalid data', () => {
867
- expect(model.validateAll()).toBeTruthy();
866
+ it('fails validation with invalid, clean data', () => {
867
+ expect(model.validateAll()).toBeFalsy();
868
868
  });
869
869
  it('fails validation with invalid, dirty data', () => {
870
870
  model.setFieldValue('$.n', '2');