@strictly/react-form 0.0.37 → 0.0.39

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.
@@ -31,7 +31,6 @@ export type ValuePathsToAdaptersOf<TypePathsToAdapters extends Partial<Readonly<
31
31
  export type ContextOf<TypePathsToAdapters extends Partial<Readonly<Record<string, FieldAdapter>>>> = UnionToIntersection<{
32
32
  readonly [K in keyof TypePathsToAdapters]: TypePathsToAdapters[K] extends undefined ? undefined : unknown extends ContextOfFieldAdapter<NonNullable<TypePathsToAdapters[K]>> ? never : ContextOfFieldAdapter<NonNullable<TypePathsToAdapters[K]>>;
33
33
  }[keyof TypePathsToAdapters] | {}>;
34
- export type FormMode = 'edit' | 'create';
35
34
  export type FormModelContextSource<ContextType, V, ValuePath extends string | number | symbol> = {
36
35
  forPath(value: V, valuePath: ValuePath): ContextType;
37
36
  };
@@ -40,7 +39,6 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
40
39
  private readonly originalValue;
41
40
  protected readonly adapters: TypePathsToAdapters;
42
41
  protected readonly contextSource: ContextSource;
43
- protected readonly mode: FormMode;
44
42
  private accessor observableValue;
45
43
  accessor fieldOverrides: FlattenedFieldOverrides<ValuePathsToAdapters>;
46
44
  accessor errorOverrides: FlattenedErrorOverrides<ValuePathsToAdapters>;
@@ -48,8 +46,7 @@ export declare abstract class FormModel<T extends Type, ValueToTypePaths extends
48
46
  private readonly flattenedTypeDefs;
49
47
  private readonly originalValues;
50
48
  private readonly listIndicesToKeys;
51
- constructor(type: T, originalValue: ValueOfType<ReadonlyTypeOfType<T>>, adapters: TypePathsToAdapters, contextSource: ContextSource, mode: FormMode);
52
- get forceMutableFields(): boolean;
49
+ constructor(type: T, originalValue: ValueOfType<ReadonlyTypeOfType<T>>, adapters: TypePathsToAdapters, contextSource: ContextSource);
53
50
  get value(): ValueOfType<ReadonlyTypeOfType<T>>;
54
51
  get fields(): SimplifyDeep<FlattenedConvertedFieldsOf<ValuePathsToAdapters>>;
55
52
  private get knownFields();
@@ -87,7 +87,7 @@ let FormModel = (() => {
87
87
  set errorOverrides(value) { __classPrivateFieldSet(this, _FormModel_errorOverrides_accessor_storage, value, "f"); }
88
88
  get validation() { return __classPrivateFieldGet(this, _FormModel_validation_accessor_storage, "f"); }
89
89
  set validation(value) { __classPrivateFieldSet(this, _FormModel_validation_accessor_storage, value, "f"); }
90
- constructor(type, originalValue, adapters, contextSource, mode) {
90
+ constructor(type, originalValue, adapters, contextSource) {
91
91
  Object.defineProperty(this, "type", {
92
92
  enumerable: true,
93
93
  configurable: true,
@@ -112,12 +112,6 @@ let FormModel = (() => {
112
112
  writable: true,
113
113
  value: contextSource
114
114
  });
115
- Object.defineProperty(this, "mode", {
116
- enumerable: true,
117
- configurable: true,
118
- writable: true,
119
- value: mode
120
- });
121
115
  _FormModel_observableValue_accessor_storage.set(this, __runInitializers(this, _observableValue_initializers, void 0));
122
116
  _FormModel_fieldOverrides_accessor_storage.set(this, (__runInitializers(this, _observableValue_extraInitializers), __runInitializers(this, _fieldOverrides_initializers, void 0)));
123
117
  _FormModel_errorOverrides_accessor_storage.set(this, (__runInitializers(this, _fieldOverrides_extraInitializers), __runInitializers(this, _errorOverrides_initializers, {})));
@@ -169,16 +163,6 @@ let FormModel = (() => {
169
163
  return v && [v.value];
170
164
  });
171
165
  }
172
- get forceMutableFields() {
173
- switch (this.mode) {
174
- case 'create':
175
- return true;
176
- case 'edit':
177
- return false;
178
- default:
179
- throw new UnreachableError(this.mode);
180
- }
181
- }
182
166
  get value() {
183
167
  // copy and strip out the mobx so this computed will fire every time anything changes
184
168
  return copy(this.type, this.observableValue);
@@ -308,7 +292,7 @@ let FormModel = (() => {
308
292
  return {
309
293
  value: displayedValue,
310
294
  error,
311
- readonly: readonly && !this.forceMutableFields,
295
+ readonly,
312
296
  required,
313
297
  // make a copy of the index mapping and remove the final value (next id)
314
298
  // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
@@ -1,5 +1,5 @@
1
1
  import { expectDefinedAndReturn } from '@strictly/base';
2
- import { booleanType, flattenValidatorsOfValidatingType, list, nullType, numberType, object, record, stringType, union, } from '@strictly/define';
2
+ import { booleanType, flattenValidatorsOfValidatingTypeWithMutability, list, nullType, numberType, object, record, stringType, union, } from '@strictly/define';
3
3
  import { adapterFromTwoWayConverter, identityAdapter, } from 'core/mobx/fieldAdapterBuilder';
4
4
  import { FormModel, Validation, } from 'core/mobx/FormModel';
5
5
  import { mergeAdaptersWithValidators } from 'core/mobx/mergeFieldAdaptersWithValidators';
@@ -13,16 +13,25 @@ const IS_NAN_ERROR = 1;
13
13
  const originalIntegerToStringAdapter = adapterFromTwoWayConverter(new IntegerToStringConverter(IS_NAN_ERROR), prototypingFieldValueFactory(0));
14
14
  const originalBooleanToBooleanAdapter = identityAdapter(false);
15
15
  class TestFormContextSource {
16
+ constructor(forceMutable) {
17
+ Object.defineProperty(this, "forceMutable", {
18
+ enumerable: true,
19
+ configurable: true,
20
+ writable: true,
21
+ value: forceMutable
22
+ });
23
+ }
16
24
  forPath(value, valuePath) {
17
25
  return {
26
+ forceMutable: this.forceMutable,
18
27
  value,
19
28
  valuePath,
20
29
  };
21
30
  }
22
31
  }
23
32
  class TestFormModel extends FormModel {
24
- constructor(type, originalValue, adapters, mode) {
25
- super(type, originalValue, adapters, new TestFormContextSource(), mode);
33
+ constructor(type, originalValue, adapters, forceMutable = false) {
34
+ super(type, originalValue, adapters, new TestFormContextSource(forceMutable));
26
35
  }
27
36
  setFieldValueAndValidate(valuePath, value) {
28
37
  this.setFieldValue(valuePath, value, Validation.Always);
@@ -81,7 +90,7 @@ describe('all', function () {
81
90
  let model;
82
91
  beforeEach(function () {
83
92
  originalValue = 5;
84
- model = new TestFormModel(typeDef, originalValue, adapters, 'create');
93
+ model = new TestFormModel(typeDef, originalValue, adapters);
85
94
  });
86
95
  describe('accessors', function () {
87
96
  it('gets the expected value', function () {
@@ -122,7 +131,7 @@ describe('all', function () {
122
131
  readonly: false,
123
132
  });
124
133
  originalValue = 5;
125
- model = new TestFormModel(typeDef, originalValue, adapters, 'create');
134
+ model = new TestFormModel(typeDef, originalValue, adapters);
126
135
  });
127
136
  it('reports required status', function () {
128
137
  expect(model.fields).toEqual(expect.objectContaining({
@@ -147,7 +156,7 @@ describe('all', function () {
147
156
  4,
148
157
  17,
149
158
  ];
150
- model = new TestFormModel(typeDef, value, adapters, 'create');
159
+ model = new TestFormModel(typeDef, value, adapters);
151
160
  });
152
161
  describe('accessors', function () {
153
162
  it.each([
@@ -209,7 +218,7 @@ describe('all', function () {
209
218
  a: 1,
210
219
  b: 2,
211
220
  };
212
- model = new TestFormModel(typeDef, value, converters, 'create');
221
+ model = new TestFormModel(typeDef, value, converters);
213
222
  });
214
223
  describe('accessors', function () {
215
224
  it.each([
@@ -260,7 +269,7 @@ describe('all', function () {
260
269
  a: 1,
261
270
  b: true,
262
271
  };
263
- model = new TestFormModel(typeDef, value, converters, 'create');
272
+ model = new TestFormModel(typeDef, value, converters);
264
273
  });
265
274
  describe('accessors', function () {
266
275
  it.each([
@@ -306,7 +315,7 @@ describe('all', function () {
306
315
  const originalValue = 2;
307
316
  let model;
308
317
  beforeEach(function () {
309
- model = new TestFormModel(typeDef, originalValue, adapters, 'create');
318
+ model = new TestFormModel(typeDef, originalValue, adapters);
310
319
  });
311
320
  describe('setFieldValueAndValidate', function () {
312
321
  describe('success', function () {
@@ -408,7 +417,7 @@ describe('all', function () {
408
417
  3,
409
418
  7,
410
419
  ];
411
- model = new TestFormModel(typeDef, originalValue, converters, 'create');
420
+ model = new TestFormModel(typeDef, originalValue, converters);
412
421
  });
413
422
  describe('setFieldValueAndValidate', function () {
414
423
  describe('success', function () {
@@ -518,6 +527,7 @@ describe('all', function () {
518
527
  // if the value has since changed
519
528
  value: model.value,
520
529
  valuePath: '$.2',
530
+ forceMutable: false,
521
531
  });
522
532
  });
523
533
  it('supplies the correct context value at the time it is being checked', function () {
@@ -529,6 +539,7 @@ describe('all', function () {
529
539
  7,
530
540
  ],
531
541
  valuePath: '$.2',
542
+ forceMutable: false,
532
543
  });
533
544
  });
534
545
  });
@@ -710,7 +721,7 @@ describe('all', function () {
710
721
  let model;
711
722
  beforeEach(function () {
712
723
  originalValue = null;
713
- model = new TestFormModel(type, originalValue, adapters, 'create');
724
+ model = new TestFormModel(type, originalValue, adapters);
714
725
  });
715
726
  it('has the expected fields', function () {
716
727
  expect(model.fields).toEqual({
@@ -758,7 +769,7 @@ describe('all', function () {
758
769
  const model = new TestFormModel(type, {
759
770
  d: 'x',
760
771
  a: 1,
761
- }, adapters, 'create');
772
+ }, adapters);
762
773
  it.each([
763
774
  [
764
775
  '$',
@@ -781,7 +792,7 @@ describe('all', function () {
781
792
  const model = new TestFormModel(type, {
782
793
  d: 'y',
783
794
  b: false,
784
- }, adapters, 'create');
795
+ }, adapters);
785
796
  it.each([
786
797
  [
787
798
  '$',
@@ -813,7 +824,7 @@ describe('all', function () {
813
824
  let model;
814
825
  beforeEach(function () {
815
826
  originalValue = 1;
816
- model = new TestFormModel(typeDef, originalValue, converters, 'create');
827
+ model = new TestFormModel(typeDef, originalValue, converters);
817
828
  });
818
829
  it('returns the default value for the fake field', function () {
819
830
  expect(model.fields['$.fake']).toEqual(expect.objectContaining({
@@ -834,12 +845,12 @@ describe('all', function () {
834
845
  });
835
846
  });
836
847
  });
837
- describe('interaction with create and edit modes', () => {
848
+ describe('interaction with mutability', () => {
838
849
  const typeDef = object().readonlyField('n', numberType.enforce(n => n < 10 ? 'err' : null));
839
850
  const adapters = mergeAdaptersWithValidators({
840
851
  $: identityAdapter({ n: 0 }),
841
852
  '$.n': integerToStringAdapter,
842
- }, flattenValidatorsOfValidatingType(typeDef));
853
+ }, flattenValidatorsOfValidatingTypeWithMutability(typeDef));
843
854
  let originalValue;
844
855
  beforeEach(() => {
845
856
  originalValue = {
@@ -849,7 +860,7 @@ describe('all', function () {
849
860
  describe('create mode', () => {
850
861
  let model;
851
862
  beforeEach(() => {
852
- model = new TestFormModel(typeDef, originalValue, adapters, 'create');
863
+ model = new TestFormModel(typeDef, originalValue, adapters, true);
853
864
  });
854
865
  it('makes the field editable', () => {
855
866
  expect(model.fields['$.n'].readonly).toBeFalsy();
@@ -862,26 +873,6 @@ describe('all', function () {
862
873
  expect(model.validateAll()).toBeTruthy();
863
874
  });
864
875
  });
865
- describe('edit model', () => {
866
- let model;
867
- beforeEach(function () {
868
- model = new TestFormModel(typeDef, originalValue, adapters, 'edit');
869
- });
870
- it('respects the field being readonly', () => {
871
- expect(model.fields['$.n'].readonly).toBeTruthy();
872
- });
873
- it('fails validation with invalid, clean data', () => {
874
- expect(model.validateAll()).toBeFalsy();
875
- });
876
- it('fails validation with invalid, dirty data', () => {
877
- model.setFieldValue('$.n', '2');
878
- expect(model.validateAll()).toBeFalsy();
879
- });
880
- it('passes validation with valid, dirty data', () => {
881
- model.setFieldValue('$.n', '10');
882
- expect(model.validateAll()).toBeTruthy();
883
- });
884
- });
885
876
  });
886
877
  });
887
878
  });
@@ -7,6 +7,8 @@ import { type ValueTypeOfField } from 'types/ValueTypeOfField';
7
7
  import { type MantineForm } from './types';
8
8
  export type FieldViewProps<F extends Fields, K extends keyof F> = {
9
9
  children: (props: {
10
+ disabled: boolean;
11
+ required: boolean;
10
12
  value: ValueTypeOfField<F[K]>;
11
13
  error: ErrorOfField<F[K]> | undefined;
12
14
  ErrorSink: ComponentType<{
@@ -35,8 +35,10 @@ function FieldView({ valuePath, form, children, }) {
35
35
  valuePath,
36
36
  ]);
37
37
  return (_jsx(Observer, { children: () => {
38
- const { value, error, } = form.fields[valuePath];
38
+ const { value, error, readonly, required, } = form.fields[valuePath];
39
39
  return children({
40
+ disabled: readonly,
41
+ required,
40
42
  value,
41
43
  error,
42
44
  ErrorSink: Empty,