@strictly/react-form 0.0.24 → 0.0.25

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.
@@ -44,6 +44,7 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
44
44
  get fields(): SimplifyDeep<FlattenedConvertedFieldsOf<ValuePathsToAdapters>>;
45
45
  private get knownFields();
46
46
  private maybeSynthesizeFieldByValuePath;
47
+ private getField;
47
48
  private synthesizeFieldByPaths;
48
49
  getAccessorForValuePath(valuePath: keyof ValuePathsToAdapters): Accessor | undefined;
49
50
  get accessors(): Readonly<Record<string, Accessor>>;
@@ -59,6 +60,7 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
59
60
  clearAll(value: ValueOfType<T>): void;
60
61
  isValuePathActive<K extends keyof ValuePathsToAdapters>(valuePath: K): boolean;
61
62
  getValidation<K extends keyof ValuePathsToAdapters>(valuePath: K): Validation;
63
+ isDirty<K extends keyof ValuePathsToAdapters>(valuePath: K): boolean;
62
64
  validateField<K extends keyof ValuePathsToAdapters>(valuePath: K, validation?: Validation): boolean;
63
65
  validateAll(validation?: Validation): boolean;
64
66
  }
@@ -190,8 +190,7 @@ let FormModel = (() => {
190
190
  }
191
191
  return this.synthesizeFieldByPaths(valuePath, typePath);
192
192
  }
193
- synthesizeFieldByPaths(valuePath, typePath) {
194
- var _b;
193
+ getField(valuePath, typePath) {
195
194
  const adapter = this.adapters[typePath];
196
195
  if (adapter == null) {
197
196
  // invalid path, which can happen
@@ -213,9 +212,28 @@ let FormModel = (() => {
213
212
  : defaultValue,
214
213
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
215
214
  valuePath, context);
216
- let error = undefined;
217
215
  const displayedValue = fieldOverride != null ? fieldOverride[0] : value;
216
+ return {
217
+ context,
218
+ convert,
219
+ create,
220
+ revert,
221
+ displayedValue,
222
+ // value,
223
+ required,
224
+ readonly,
225
+ defaultValue,
226
+ };
227
+ }
228
+ synthesizeFieldByPaths(valuePath, typePath) {
229
+ var _b;
230
+ const field = this.getField(valuePath, typePath);
231
+ if (field == null) {
232
+ return;
233
+ }
234
+ const { context, convert, revert, displayedValue, required, readonly, defaultValue, } = field;
218
235
  const validation = (_b = this.validation[valuePath]) !== null && _b !== void 0 ? _b : Validation.None;
236
+ let error;
219
237
  switch (validation) {
220
238
  case Validation.None:
221
239
  // skip validation
@@ -251,7 +269,7 @@ let FormModel = (() => {
251
269
  throw new UnreachableError(validation);
252
270
  }
253
271
  return {
254
- value: fieldOverride != null ? fieldOverride[0] : value,
272
+ value: displayedValue,
255
273
  error,
256
274
  readonly: readonly && !this.forceMutableFields,
257
275
  required,
@@ -477,6 +495,25 @@ let FormModel = (() => {
477
495
  var _b;
478
496
  return (_b = this.validation[valuePath]) !== null && _b !== void 0 ? _b : Validation.None;
479
497
  }
498
+ isDirty(valuePath) {
499
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
500
+ const typePath = valuePathToTypePath(this.type,
501
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
502
+ valuePath, true);
503
+ const field = this.getField(valuePath, typePath);
504
+ if (field == null) {
505
+ return false;
506
+ }
507
+ const { displayedValue, convert, context, defaultValue, } = field;
508
+ const originalValue = valuePath in this.originalValues
509
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
510
+ ? this.originalValues[valuePath]
511
+ : defaultValue;
512
+ // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
513
+ const { value: originalDisplayedValue } = convert(originalValue, valuePath, context);
514
+ // TODO better comparisons, displayed values can still be complex
515
+ return (displayedValue !== originalDisplayedValue);
516
+ }
480
517
  validateField(valuePath, validation = Validation.Always) {
481
518
  runInAction(() => {
482
519
  this.validation[valuePath] = validation;
@@ -2,8 +2,8 @@ import { useCallback, } from 'react';
2
2
  import { Validation, } from './form_model';
3
3
  export function useDefaultMobxFormHooks(model, { onValidFieldSubmit, onValidFormSubmit, } = {}) {
4
4
  const onFieldValueChange = useCallback(function (path, value) {
5
- // clear validation once there are no errors for the field
6
- model.setFieldValue(path, value);
5
+ const validation = Math.min(model.getValidation(path), Validation.Changed);
6
+ model.setFieldValue(path, value, validation);
7
7
  }, [model]);
8
8
  const onFieldSubmit = useCallback(function (valuePath) {
9
9
  if (model.validateField(valuePath)) {
@@ -19,7 +19,8 @@ export function useDefaultMobxFormHooks(model, { onValidFieldSubmit, onValidForm
19
19
  // (e.g. changing a discriminator)
20
20
  // TODO debounce?
21
21
  setTimeout(function () {
22
- if (model.isValuePathActive(path)) {
22
+ // only start validation if the user has changed the field
23
+ if (model.isValuePathActive(path) && model.isDirty(path)) {
23
24
  // further workaround to make sure we don't downgrade the existing validation
24
25
  model.validateField(path, Math.max(Validation.Changed, model.getValidation(path)));
25
26
  }