@strictly/react-form 0.0.9 → 0.0.11
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.
- package/.out/core/mobx/field_adapter_builder.js +18 -6
- package/.out/core/mobx/form_presenter.d.ts +5 -5
- package/.out/core/mobx/form_presenter.js +232 -127
- package/.out/core/mobx/hooks.d.ts +24 -4
- package/.out/core/mobx/hooks.js +26 -5
- package/.out/core/mobx/merge_field_adapters_with_validators.js +1 -5
- package/.out/core/mobx/specs/fixtures.js +2 -1
- package/.out/core/mobx/specs/form_presenter.tests.js +16 -8
- package/.out/core/mobx/specs/sub_form_field_adapters.tests.js +2 -1
- package/.out/core/mobx/sub_form_field_adapters.d.ts +2 -2
- package/.out/field_converters/integer_to_string_converter.js +12 -4
- package/.out/field_converters/maybe_identity_converter.js +12 -4
- package/.out/field_converters/nullable_to_boolean_converter.js +24 -7
- package/.out/field_converters/select_value_type_converter.js +36 -12
- package/.out/mantine/create_checkbox.js +8 -4
- package/.out/mantine/create_fields_view.d.ts +9 -1
- package/.out/mantine/create_fields_view.js +20 -5
- package/.out/mantine/create_form.js +1 -1
- package/.out/mantine/create_radio_group.js +8 -4
- package/.out/mantine/create_text_input.js +8 -4
- package/.out/mantine/create_value_input.js +8 -4
- package/.out/mantine/hooks.d.ts +2 -1
- package/.out/mantine/hooks.js +219 -93
- package/.out/mantine/specs/checkbox_hooks.stories.js +13 -1
- package/.out/mantine/specs/checkbox_hooks.tests.js +22 -9
- package/.out/mantine/specs/create_fields_view.tests.d.ts +1 -0
- package/.out/mantine/specs/create_fields_view.tests.js +17 -0
- package/.out/mantine/specs/fields_view_hooks.stories.d.ts +6 -2
- package/.out/mantine/specs/fields_view_hooks.stories.js +39 -7
- package/.out/mantine/specs/fields_view_hooks.tests.js +30 -1
- package/.out/mantine/specs/radio_group_hooks.stories.js +13 -1
- package/.out/mantine/specs/radio_group_hooks.tests.js +23 -10
- package/.out/mantine/specs/select_hooks.stories.js +13 -1
- package/.out/mantine/specs/text_input_hooks.stories.js +13 -1
- package/.out/mantine/specs/text_input_hooks.tests.js +18 -7
- package/.out/mantine/specs/value_input_hooks.stories.js +14 -2
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/tsup.config.js +2 -9
- package/.out/types/merge_validators.js +1 -4
- package/.out/util/partial.js +5 -5
- package/.out/vitest.workspace.js +2 -10
- package/.turbo/turbo-build.log +9 -9
- package/.turbo/turbo-check-types.log +1 -1
- package/.turbo/turbo-release$colon$exports.log +1 -1
- package/core/mobx/form_presenter.ts +15 -14
- package/core/mobx/hooks.tsx +197 -0
- package/core/mobx/specs/form_presenter.tests.ts +24 -5
- package/core/mobx/sub_form_field_adapters.ts +14 -3
- package/dist/index.cjs +395 -277
- package/dist/index.d.cts +52 -26
- package/dist/index.d.ts +52 -26
- package/dist/index.js +398 -276
- package/mantine/create_fields_view.tsx +66 -31
- package/mantine/hooks.tsx +9 -6
- package/mantine/specs/__snapshots__/fields_view_hooks.tests.tsx.snap +194 -197
- package/mantine/specs/create_fields_view.tests.ts +29 -0
- package/mantine/specs/fields_view_hooks.stories.tsx +58 -15
- package/mantine/specs/fields_view_hooks.tests.tsx +26 -0
- package/package.json +1 -1
- package/core/mobx/hooks.ts +0 -112
|
@@ -5,13 +5,25 @@ import { TrimmingStringConverter } from 'field_converters/trimming_string_conver
|
|
|
5
5
|
import { prototypingFieldValueFactory } from 'field_value_factories/prototyping_field_value_factory';
|
|
6
6
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
7
7
|
class FieldAdapterBuilder {
|
|
8
|
-
convert;
|
|
9
|
-
create;
|
|
10
|
-
revert;
|
|
11
8
|
constructor(convert, create, revert) {
|
|
12
|
-
this
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
Object.defineProperty(this, "convert", {
|
|
10
|
+
enumerable: true,
|
|
11
|
+
configurable: true,
|
|
12
|
+
writable: true,
|
|
13
|
+
value: convert
|
|
14
|
+
});
|
|
15
|
+
Object.defineProperty(this, "create", {
|
|
16
|
+
enumerable: true,
|
|
17
|
+
configurable: true,
|
|
18
|
+
writable: true,
|
|
19
|
+
value: create
|
|
20
|
+
});
|
|
21
|
+
Object.defineProperty(this, "revert", {
|
|
22
|
+
enumerable: true,
|
|
23
|
+
configurable: true,
|
|
24
|
+
writable: true,
|
|
25
|
+
value: revert
|
|
26
|
+
});
|
|
15
27
|
}
|
|
16
28
|
chain(converter, reverter) {
|
|
17
29
|
return new FieldAdapterBuilder(chainAnnotatedFieldConverter(this.convert, converter), this.create, this.revert && reverter && chainUnreliableFieldConverter(reverter, this.revert));
|
|
@@ -20,9 +20,9 @@ type FlattenedErrors<ValuePathsToAdapters extends Readonly<Record<string, FieldA
|
|
|
20
20
|
export type ValuePathsToAdaptersOf<TypePathsToAdapters extends Partial<Readonly<Record<string, FieldAdapter>>>, ValuePathsToTypePaths extends Readonly<Record<string, string>>> = keyof TypePathsToAdapters extends ValueOf<ValuePathsToTypePaths> ? {
|
|
21
21
|
readonly [K in keyof ValuePathsToTypePaths as unknown extends TypePathsToAdapters[ValuePathsToTypePaths[K]] ? never : K]: NonNullable<TypePathsToAdapters[ValuePathsToTypePaths[K]]>;
|
|
22
22
|
} : never;
|
|
23
|
-
export declare class FormPresenter<T extends Type, ValueToTypePaths extends Readonly<Record<string, string>>, TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<FlattenedValuesOfType<T, '*'>, ValueOfType<ReadonlyTypeOfType<T>>>, ValuePathsToAdapters extends ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths> = ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths>> {
|
|
23
|
+
export declare abstract class FormPresenter<T extends Type, ValueToTypePaths extends Readonly<Record<string, string>>, TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<FlattenedValuesOfType<T, '*'>, ValueOfType<ReadonlyTypeOfType<T>>>, ValuePathsToAdapters extends ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths> = ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths>> {
|
|
24
24
|
readonly type: T;
|
|
25
|
-
|
|
25
|
+
protected readonly adapters: TypePathsToAdapters;
|
|
26
26
|
constructor(type: T, adapters: TypePathsToAdapters);
|
|
27
27
|
private maybeGetAdapterForValuePath;
|
|
28
28
|
private getAdapterForValuePath;
|
|
@@ -33,12 +33,12 @@ export declare class FormPresenter<T extends Type, ValueToTypePaths extends Read
|
|
|
33
33
|
removeListItem<K extends keyof FlattenedListTypesOfType<T>>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, elementValuePath: `${K}.${number}`): void;
|
|
34
34
|
private internalSetFieldValue;
|
|
35
35
|
clearFieldError<K extends keyof ValuePathsToAdapters>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, valuePath: K): void;
|
|
36
|
-
clearFieldValue<K extends StringKeyOf<
|
|
36
|
+
clearFieldValue<K extends StringKeyOf<ValueToTypePaths>>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, valuePath: K): void;
|
|
37
37
|
clearAll(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, value: ValueOfType<T>): void;
|
|
38
38
|
isValuePathActive<K extends keyof ValuePathsToAdapters>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, valuePath: K): boolean;
|
|
39
|
-
validateField<K extends keyof ValuePathsToAdapters>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, valuePath: K): boolean;
|
|
39
|
+
validateField<K extends keyof ValuePathsToAdapters>(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>, valuePath: K, ignoreDefaultValue?: boolean): boolean;
|
|
40
40
|
validateAll(model: FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>): boolean;
|
|
41
|
-
createModel(value: ValueOfType<ReadonlyTypeOfType<T>>): FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>;
|
|
41
|
+
abstract createModel(value: ValueOfType<ReadonlyTypeOfType<T>>): FormModel<T, ValueToTypePaths, TypePathsToAdapters, ValuePathsToAdapters>;
|
|
42
42
|
}
|
|
43
43
|
export declare class FormModel<T extends Type, ValueToTypePaths extends Readonly<Record<string, string>>, TypePathsToAdapters extends FlattenedTypePathsToAdaptersOf<FlattenedValuesOfType<T, '*'>, ValueOfType<ReadonlyTypeOfType<T>>>, ValuePathsToAdapters extends ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths> = ValuePathsToAdaptersOf<TypePathsToAdapters, ValueToTypePaths>> {
|
|
44
44
|
private readonly type;
|
|
@@ -1,13 +1,66 @@
|
|
|
1
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
2
|
+
var useValue = arguments.length > 2;
|
|
3
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
4
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
5
|
+
}
|
|
6
|
+
return useValue ? value : void 0;
|
|
7
|
+
};
|
|
8
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
9
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
10
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
11
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
12
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
13
|
+
var _, done = false;
|
|
14
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
15
|
+
var context = {};
|
|
16
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
17
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
18
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
19
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
20
|
+
if (kind === "accessor") {
|
|
21
|
+
if (result === void 0) continue;
|
|
22
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
23
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
24
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
25
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
26
|
+
}
|
|
27
|
+
else if (_ = accept(result)) {
|
|
28
|
+
if (kind === "field") initializers.unshift(_);
|
|
29
|
+
else descriptor[key] = _;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
33
|
+
done = true;
|
|
34
|
+
};
|
|
35
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
36
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
37
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
38
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
39
|
+
};
|
|
40
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
41
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
42
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
43
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
44
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
45
|
+
};
|
|
1
46
|
import { assertExists, assertExistsAndReturn, assertState, checkValidNumber, map, toArray, UnreachableError, } from '@strictly/base';
|
|
2
47
|
import { flattenAccessorsOfType, flattenTypesOfType, flattenValuesOfType, flattenValueTo, jsonPathPop, mobxCopy, valuePathToTypePath, } from '@strictly/define';
|
|
3
48
|
import { computed, observable, runInAction, } from 'mobx';
|
|
4
49
|
import { UnreliableFieldConversionType, } from 'types/field_converters';
|
|
5
50
|
export class FormPresenter {
|
|
6
|
-
type;
|
|
7
|
-
adapters;
|
|
8
51
|
constructor(type, adapters) {
|
|
9
|
-
this
|
|
10
|
-
|
|
52
|
+
Object.defineProperty(this, "type", {
|
|
53
|
+
enumerable: true,
|
|
54
|
+
configurable: true,
|
|
55
|
+
writable: true,
|
|
56
|
+
value: type
|
|
57
|
+
});
|
|
58
|
+
Object.defineProperty(this, "adapters", {
|
|
59
|
+
enumerable: true,
|
|
60
|
+
configurable: true,
|
|
61
|
+
writable: true,
|
|
62
|
+
value: adapters
|
|
63
|
+
});
|
|
11
64
|
}
|
|
12
65
|
maybeGetAdapterForValuePath(valuePath) {
|
|
13
66
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
@@ -34,7 +87,7 @@ export class FormPresenter {
|
|
|
34
87
|
const listValuePath = valuePath;
|
|
35
88
|
const accessor = model.accessors[valuePath];
|
|
36
89
|
const listTypePath = this.typePath(valuePath);
|
|
37
|
-
const definedIndex = index
|
|
90
|
+
const definedIndex = index !== null && index !== void 0 ? index : accessor.value.length;
|
|
38
91
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
39
92
|
const elementTypePath = `${listTypePath}.*`;
|
|
40
93
|
const elementAdapter = assertExistsAndReturn(this.adapters[elementTypePath], 'no adapter specified for list {} ({})', elementTypePath, valuePath);
|
|
@@ -165,7 +218,7 @@ export class FormPresenter {
|
|
|
165
218
|
return false;
|
|
166
219
|
case UnreliableFieldConversionType.Success:
|
|
167
220
|
delete model.errors[valuePath];
|
|
168
|
-
accessor
|
|
221
|
+
accessor === null || accessor === void 0 ? void 0 : accessor.set(conversion.value);
|
|
169
222
|
return true;
|
|
170
223
|
default:
|
|
171
224
|
throw new UnreachableError(conversion);
|
|
@@ -188,8 +241,7 @@ export class FormPresenter {
|
|
|
188
241
|
return;
|
|
189
242
|
}
|
|
190
243
|
const { convert, create, } = adapter;
|
|
191
|
-
const
|
|
192
|
-
const value = accessor == null ? create(valuePath, model.value) : accessor.value;
|
|
244
|
+
const value = create(valuePath, model.value);
|
|
193
245
|
const { value: displayValue, } = convert(value, valuePath, model.value);
|
|
194
246
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
195
247
|
const key = valuePath;
|
|
@@ -211,7 +263,7 @@ export class FormPresenter {
|
|
|
211
263
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
212
264
|
return keys.has(valuePath);
|
|
213
265
|
}
|
|
214
|
-
validateField(model, valuePath) {
|
|
266
|
+
validateField(model, valuePath, ignoreDefaultValue = false) {
|
|
215
267
|
const { convert, revert, create, } = this.getAdapterForValuePath(valuePath);
|
|
216
268
|
const fieldOverride = model.fieldOverrides[valuePath];
|
|
217
269
|
const accessor = model.getAccessorForValuePath(valuePath);
|
|
@@ -226,6 +278,12 @@ export class FormPresenter {
|
|
|
226
278
|
: storedValue;
|
|
227
279
|
const dirty = storedValue !== value;
|
|
228
280
|
assertExists(revert, 'changing field directly not supported {}', valuePath);
|
|
281
|
+
if (ignoreDefaultValue) {
|
|
282
|
+
const { value: defaultDisplayValue, } = convert(create(valuePath, model.value), valuePath, model.value);
|
|
283
|
+
if (defaultDisplayValue === value) {
|
|
284
|
+
return true;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
229
287
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
230
288
|
const conversion = revert(value, valuePath, model.value);
|
|
231
289
|
return runInAction(function () {
|
|
@@ -293,128 +351,175 @@ export class FormPresenter {
|
|
|
293
351
|
}, true);
|
|
294
352
|
});
|
|
295
353
|
}
|
|
296
|
-
createModel(value) {
|
|
297
|
-
return new FormModel(this.type, value, this.adapters);
|
|
298
|
-
}
|
|
299
354
|
}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
355
|
+
let FormModel = (() => {
|
|
356
|
+
var _a, _FormModel_value_accessor_storage, _FormModel_fieldOverrides_accessor_storage, _FormModel_errors_accessor_storage;
|
|
357
|
+
var _b, _c, _d;
|
|
358
|
+
let _instanceExtraInitializers = [];
|
|
359
|
+
let _value_decorators;
|
|
360
|
+
let _value_initializers = [];
|
|
361
|
+
let _value_extraInitializers = [];
|
|
362
|
+
let _fieldOverrides_decorators;
|
|
363
|
+
let _fieldOverrides_initializers = [];
|
|
364
|
+
let _fieldOverrides_extraInitializers = [];
|
|
365
|
+
let _errors_decorators;
|
|
366
|
+
let _errors_initializers = [];
|
|
367
|
+
let _errors_extraInitializers = [];
|
|
368
|
+
let _get_fields_decorators;
|
|
369
|
+
let _get_knownFields_decorators;
|
|
370
|
+
let _get_accessors_decorators;
|
|
371
|
+
return _a = class FormModel {
|
|
372
|
+
get value() { return __classPrivateFieldGet(this, _FormModel_value_accessor_storage, "f"); }
|
|
373
|
+
set value(value) { __classPrivateFieldSet(this, _FormModel_value_accessor_storage, value, "f"); }
|
|
374
|
+
get fieldOverrides() { return __classPrivateFieldGet(this, _FormModel_fieldOverrides_accessor_storage, "f"); }
|
|
375
|
+
set fieldOverrides(value) { __classPrivateFieldSet(this, _FormModel_fieldOverrides_accessor_storage, value, "f"); }
|
|
376
|
+
get errors() { return __classPrivateFieldGet(this, _FormModel_errors_accessor_storage, "f"); }
|
|
377
|
+
set errors(value) { __classPrivateFieldSet(this, _FormModel_errors_accessor_storage, value, "f"); }
|
|
378
|
+
constructor(type, value, adapters) {
|
|
379
|
+
Object.defineProperty(this, "type", {
|
|
380
|
+
enumerable: true,
|
|
381
|
+
configurable: true,
|
|
382
|
+
writable: true,
|
|
383
|
+
value: (__runInitializers(this, _instanceExtraInitializers), type)
|
|
384
|
+
});
|
|
385
|
+
Object.defineProperty(this, "adapters", {
|
|
386
|
+
enumerable: true,
|
|
387
|
+
configurable: true,
|
|
388
|
+
writable: true,
|
|
389
|
+
value: adapters
|
|
390
|
+
});
|
|
391
|
+
_FormModel_value_accessor_storage.set(this, __runInitializers(this, _value_initializers, void 0));
|
|
392
|
+
_FormModel_fieldOverrides_accessor_storage.set(this, (__runInitializers(this, _value_extraInitializers), __runInitializers(this, _fieldOverrides_initializers, void 0)));
|
|
393
|
+
_FormModel_errors_accessor_storage.set(this, (__runInitializers(this, _fieldOverrides_extraInitializers), __runInitializers(this, _errors_initializers, {})));
|
|
394
|
+
Object.defineProperty(this, "flattenedTypeDefs", {
|
|
395
|
+
enumerable: true,
|
|
396
|
+
configurable: true,
|
|
397
|
+
writable: true,
|
|
398
|
+
value: __runInitializers(this, _errors_extraInitializers)
|
|
399
|
+
});
|
|
400
|
+
this.value = mobxCopy(type, value);
|
|
401
|
+
this.flattenedTypeDefs = flattenTypesOfType(type);
|
|
402
|
+
// pre-populate field overrides for consistent behavior when default information is overwritten
|
|
403
|
+
// then returned to
|
|
404
|
+
const conversions = flattenValueTo(type, this.value, () => { }, (_t, value, _setter, typePath, valuePath) => {
|
|
405
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
406
|
+
const adapter = this.adapters[typePath];
|
|
407
|
+
if (adapter == null) {
|
|
408
|
+
return;
|
|
409
|
+
}
|
|
410
|
+
const { convert, revert, } = adapter;
|
|
411
|
+
if (revert == null) {
|
|
412
|
+
// no need to store a temporary value if the value cannot be written back
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
return convert(value, valuePath, this.value);
|
|
416
|
+
});
|
|
417
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
418
|
+
this.fieldOverrides = map(conversions, function (_k, v) {
|
|
419
|
+
return v && [v.value];
|
|
420
|
+
});
|
|
322
421
|
}
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
422
|
+
get fields() {
|
|
423
|
+
return new Proxy(this.knownFields, {
|
|
424
|
+
get: (target, prop) => {
|
|
425
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
|
426
|
+
const field = target[prop];
|
|
427
|
+
if (field != null) {
|
|
428
|
+
return field;
|
|
429
|
+
}
|
|
430
|
+
if (typeof prop === 'string') {
|
|
431
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
432
|
+
return this.maybeSynthesizeFieldByValuePath(prop);
|
|
433
|
+
}
|
|
434
|
+
},
|
|
435
|
+
});
|
|
327
436
|
}
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
@computed
|
|
336
|
-
get fields() {
|
|
337
|
-
return new Proxy(this.knownFields, {
|
|
338
|
-
get: (target, prop) => {
|
|
339
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
|
340
|
-
const field = target[prop];
|
|
341
|
-
if (field != null) {
|
|
342
|
-
return field;
|
|
343
|
-
}
|
|
344
|
-
if (typeof prop === 'string') {
|
|
437
|
+
get knownFields() {
|
|
438
|
+
return flattenValueTo(this.type, this.value, () => { },
|
|
439
|
+
// TODO swap these to valuePath, typePath in flatten
|
|
440
|
+
(_t, _v, _setter, typePath, valuePath) => {
|
|
441
|
+
return this.synthesizeFieldByPaths(
|
|
442
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
443
|
+
valuePath,
|
|
345
444
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
346
|
-
|
|
445
|
+
typePath);
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
maybeSynthesizeFieldByValuePath(valuePath) {
|
|
449
|
+
let typePath;
|
|
450
|
+
try {
|
|
451
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
452
|
+
typePath = valuePathToTypePath(this.type,
|
|
453
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
454
|
+
valuePath, true);
|
|
347
455
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
try {
|
|
366
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
367
|
-
typePath = valuePathToTypePath(this.type,
|
|
368
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
369
|
-
valuePath, true);
|
|
370
|
-
}
|
|
371
|
-
catch (e) {
|
|
372
|
-
// TODO make jsonValuePathToTypePath return null in the event of an invalid
|
|
373
|
-
// value path instead of throwing an exception
|
|
374
|
-
// assume that the path was invalid
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
return this.synthesizeFieldByPaths(valuePath, typePath);
|
|
378
|
-
}
|
|
379
|
-
synthesizeFieldByPaths(valuePath, typePath) {
|
|
380
|
-
const adapter = this.adapters[typePath];
|
|
381
|
-
if (adapter == null) {
|
|
382
|
-
// invalid path, which can happen
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
const { convert, create, } = adapter;
|
|
386
|
-
const fieldOverride = this.fieldOverrides[valuePath];
|
|
387
|
-
const accessor = this.getAccessorForValuePath(valuePath);
|
|
388
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
389
|
-
const fieldTypeDef = this.flattenedTypeDefs[typePath];
|
|
390
|
-
const { value, required, readonly, } = convert(accessor != null
|
|
391
|
-
? accessor.value
|
|
392
|
-
: fieldTypeDef != null
|
|
393
|
-
? mobxCopy(fieldTypeDef,
|
|
456
|
+
catch (e) {
|
|
457
|
+
// TODO make jsonValuePathToTypePath return null in the event of an invalid
|
|
458
|
+
// value path instead of throwing an exception
|
|
459
|
+
// assume that the path was invalid
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
return this.synthesizeFieldByPaths(valuePath, typePath);
|
|
463
|
+
}
|
|
464
|
+
synthesizeFieldByPaths(valuePath, typePath) {
|
|
465
|
+
const adapter = this.adapters[typePath];
|
|
466
|
+
if (adapter == null) {
|
|
467
|
+
// invalid path, which can happen
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
const { convert, create, } = adapter;
|
|
471
|
+
const fieldOverride = this.fieldOverrides[valuePath];
|
|
472
|
+
const accessor = this.getAccessorForValuePath(valuePath);
|
|
394
473
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
395
|
-
|
|
396
|
-
|
|
474
|
+
const fieldTypeDef = this.flattenedTypeDefs[typePath];
|
|
475
|
+
const { value, required, readonly, } = convert(accessor != null
|
|
476
|
+
? accessor.value
|
|
477
|
+
: fieldTypeDef != null
|
|
478
|
+
? mobxCopy(fieldTypeDef,
|
|
479
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
480
|
+
create(valuePath, this.value))
|
|
481
|
+
// fake values can't be copied
|
|
482
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
483
|
+
: create(valuePath, this.value),
|
|
397
484
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
485
|
+
valuePath, this.value);
|
|
486
|
+
const error = this.errors[valuePath];
|
|
487
|
+
return {
|
|
488
|
+
value: fieldOverride != null ? fieldOverride[0] : value,
|
|
489
|
+
error,
|
|
490
|
+
readonly,
|
|
491
|
+
required,
|
|
492
|
+
};
|
|
493
|
+
}
|
|
494
|
+
getAccessorForValuePath(valuePath) {
|
|
495
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
496
|
+
return this.accessors[valuePath];
|
|
497
|
+
}
|
|
498
|
+
get accessors() {
|
|
499
|
+
return flattenAccessorsOfType(this.type, this.value, (value) => {
|
|
500
|
+
this.value = mobxCopy(this.type, value);
|
|
501
|
+
});
|
|
502
|
+
}
|
|
503
|
+
},
|
|
504
|
+
_FormModel_value_accessor_storage = new WeakMap(),
|
|
505
|
+
_FormModel_fieldOverrides_accessor_storage = new WeakMap(),
|
|
506
|
+
_FormModel_errors_accessor_storage = new WeakMap(),
|
|
507
|
+
(() => {
|
|
508
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
|
|
509
|
+
_value_decorators = [(_b = observable).ref.bind(_b)];
|
|
510
|
+
_fieldOverrides_decorators = [(_c = observable).shallow.bind(_c)];
|
|
511
|
+
_errors_decorators = [(_d = observable).shallow.bind(_d)];
|
|
512
|
+
_get_fields_decorators = [computed];
|
|
513
|
+
_get_knownFields_decorators = [computed];
|
|
514
|
+
_get_accessors_decorators = [computed];
|
|
515
|
+
__esDecorate(_a, null, _value_decorators, { kind: "accessor", name: "value", static: false, private: false, access: { has: obj => "value" in obj, get: obj => obj.value, set: (obj, value) => { obj.value = value; } }, metadata: _metadata }, _value_initializers, _value_extraInitializers);
|
|
516
|
+
__esDecorate(_a, null, _fieldOverrides_decorators, { kind: "accessor", name: "fieldOverrides", static: false, private: false, access: { has: obj => "fieldOverrides" in obj, get: obj => obj.fieldOverrides, set: (obj, value) => { obj.fieldOverrides = value; } }, metadata: _metadata }, _fieldOverrides_initializers, _fieldOverrides_extraInitializers);
|
|
517
|
+
__esDecorate(_a, null, _errors_decorators, { kind: "accessor", name: "errors", static: false, private: false, access: { has: obj => "errors" in obj, get: obj => obj.errors, set: (obj, value) => { obj.errors = value; } }, metadata: _metadata }, _errors_initializers, _errors_extraInitializers);
|
|
518
|
+
__esDecorate(_a, null, _get_fields_decorators, { kind: "getter", name: "fields", static: false, private: false, access: { has: obj => "fields" in obj, get: obj => obj.fields }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
519
|
+
__esDecorate(_a, null, _get_knownFields_decorators, { kind: "getter", name: "knownFields", static: false, private: false, access: { has: obj => "knownFields" in obj, get: obj => obj.knownFields }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
520
|
+
__esDecorate(_a, null, _get_accessors_decorators, { kind: "getter", name: "accessors", static: false, private: false, access: { has: obj => "accessors" in obj, get: obj => obj.accessors }, metadata: _metadata }, null, _instanceExtraInitializers);
|
|
521
|
+
if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
522
|
+
})(),
|
|
523
|
+
_a;
|
|
524
|
+
})();
|
|
525
|
+
export { FormModel };
|
|
@@ -1,14 +1,34 @@
|
|
|
1
1
|
import { type ReadonlyTypeOfType, type ValueOfType } from '@strictly/define';
|
|
2
2
|
import { type FieldsViewProps } from 'core/props';
|
|
3
|
+
import { type ComponentType } from 'react';
|
|
4
|
+
import { type UnsafePartialComponent } from 'util/partial';
|
|
3
5
|
import { type FormPresenter } from './form_presenter';
|
|
4
|
-
import { type ValuePathsOfPresenter } from './types';
|
|
6
|
+
import { type FormFieldsOfPresenter, type ValuePathsOfPresenter } from './types';
|
|
5
7
|
type ValueOfPresenter<P extends FormPresenter<any, any, any, any>> = P extends FormPresenter<infer T, any, any, any> ? ValueOfType<ReadonlyTypeOfType<T>> : never;
|
|
6
8
|
type ModelOfPresenter<P extends FormPresenter<any, any, any, any>> = ReturnType<P['createModel']>;
|
|
7
|
-
export declare function useDefaultMobxFormHooks<P extends FormPresenter<any, any, any, any>>(presenter: P, value: ValueOfPresenter<P>,
|
|
9
|
+
export declare function useDefaultMobxFormHooks<P extends FormPresenter<any, any, any, any>, C extends ComponentType<FieldsViewProps<F>>, F extends FormFieldsOfPresenter<P> = FormFieldsOfPresenter<P>>(presenter: P, value: ValueOfPresenter<P>, options?: {
|
|
8
10
|
onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void;
|
|
9
11
|
onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void;
|
|
10
12
|
}): {
|
|
11
13
|
model: ModelOfPresenter<P>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
FormFields?: UnsafePartialComponent<C, FieldsViewProps<F>>;
|
|
15
|
+
onFormSubmit: () => void;
|
|
16
|
+
onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void;
|
|
17
|
+
onFieldFocus?(this: void, key: keyof F): void;
|
|
18
|
+
onFieldBlur?(this: void, key: keyof F): void;
|
|
19
|
+
onFieldSubmit?(this: void, key: keyof F): boolean | void;
|
|
20
|
+
};
|
|
21
|
+
export declare function useDefaultMobxFormHooks<P extends FormPresenter<any, any, any, any>, C extends ComponentType<FieldsViewProps<F>>, F extends FormFieldsOfPresenter<P> = FormFieldsOfPresenter<P>>(presenter: P, value: ValueOfPresenter<P>, options: {
|
|
22
|
+
onValidFieldSubmit?: <Path extends ValuePathsOfPresenter<P>>(model: ModelOfPresenter<P>, valuePath: Path) => void;
|
|
23
|
+
onValidFormSubmit?: (model: ModelOfPresenter<P>, value: ValueOfPresenter<P>) => void;
|
|
24
|
+
FormFieldsView: C;
|
|
25
|
+
}): {
|
|
26
|
+
model: ModelOfPresenter<P>;
|
|
27
|
+
FormFields: UnsafePartialComponent<C, FieldsViewProps<F>>;
|
|
28
|
+
onFormSubmit: () => void;
|
|
29
|
+
onFieldValueChange<K extends keyof F>(this: void, key: K, value: F[K]['value']): void;
|
|
30
|
+
onFieldFocus?(this: void, key: keyof F): void;
|
|
31
|
+
onFieldBlur?(this: void, key: keyof F): void;
|
|
32
|
+
onFieldSubmit?(this: void, key: keyof F): boolean | void;
|
|
33
|
+
};
|
|
14
34
|
export {};
|
package/.out/core/mobx/hooks.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useCallback, useMemo, } from 'react';
|
|
2
|
-
|
|
3
|
-
export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit, onValidFormSubmit, } = {}) {
|
|
2
|
+
import { createUnsafePartialObserverComponent, } from 'util/partial';
|
|
3
|
+
export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit, onValidFormSubmit, FormFieldsView, } = {}) {
|
|
4
4
|
const model = useMemo(function () {
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
6
6
|
return presenter.createModel(value);
|
|
@@ -17,7 +17,7 @@ export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit,
|
|
|
17
17
|
]);
|
|
18
18
|
const onFieldSubmit = useCallback(function (valuePath) {
|
|
19
19
|
if (presenter.validateField(model, valuePath)) {
|
|
20
|
-
onValidFieldSubmit
|
|
20
|
+
onValidFieldSubmit === null || onValidFieldSubmit === void 0 ? void 0 : onValidFieldSubmit(model, valuePath);
|
|
21
21
|
}
|
|
22
22
|
return false;
|
|
23
23
|
}, [
|
|
@@ -31,7 +31,7 @@ export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit,
|
|
|
31
31
|
// TODO debounce?
|
|
32
32
|
setTimeout(function () {
|
|
33
33
|
if (presenter.isValuePathActive(model, path)) {
|
|
34
|
-
presenter.validateField(model, path);
|
|
34
|
+
presenter.validateField(model, path, true);
|
|
35
35
|
}
|
|
36
36
|
}, 100);
|
|
37
37
|
}, [
|
|
@@ -40,18 +40,39 @@ export function useDefaultMobxFormHooks(presenter, value, { onValidFieldSubmit,
|
|
|
40
40
|
]);
|
|
41
41
|
const onFormSubmit = useCallback(function () {
|
|
42
42
|
if (presenter.validateAll(model)) {
|
|
43
|
-
onValidFormSubmit
|
|
43
|
+
onValidFormSubmit === null || onValidFormSubmit === void 0 ? void 0 : onValidFormSubmit(model, model.value);
|
|
44
44
|
}
|
|
45
45
|
}, [
|
|
46
46
|
presenter,
|
|
47
47
|
model,
|
|
48
48
|
onValidFormSubmit,
|
|
49
49
|
]);
|
|
50
|
+
const FormFields = useMemo(() => {
|
|
51
|
+
if (FormFieldsView == null) {
|
|
52
|
+
return undefined;
|
|
53
|
+
}
|
|
54
|
+
return createUnsafePartialObserverComponent(FormFieldsView, () => {
|
|
55
|
+
return {
|
|
56
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
57
|
+
fields: model.fields,
|
|
58
|
+
onFieldBlur,
|
|
59
|
+
onFieldSubmit,
|
|
60
|
+
onFieldValueChange,
|
|
61
|
+
};
|
|
62
|
+
});
|
|
63
|
+
}, [
|
|
64
|
+
model,
|
|
65
|
+
FormFieldsView,
|
|
66
|
+
onFieldBlur,
|
|
67
|
+
onFieldSubmit,
|
|
68
|
+
onFieldValueChange,
|
|
69
|
+
]);
|
|
50
70
|
return {
|
|
51
71
|
model,
|
|
52
72
|
onFieldValueChange,
|
|
53
73
|
onFieldSubmit,
|
|
54
74
|
onFieldBlur,
|
|
55
75
|
onFormSubmit,
|
|
76
|
+
FormFields,
|
|
56
77
|
};
|
|
57
78
|
}
|
|
@@ -35,11 +35,7 @@ export function mergeAdaptersWithValidators(adapters, validators) {
|
|
|
35
35
|
readonly: readonly1 || readonly2,
|
|
36
36
|
};
|
|
37
37
|
}
|
|
38
|
-
acc[key] = {
|
|
39
|
-
...adapter,
|
|
40
|
-
convert,
|
|
41
|
-
revert: adapter.revert && revert,
|
|
42
|
-
};
|
|
38
|
+
acc[key] = Object.assign(Object.assign({}, adapter), { convert, revert: adapter.revert && revert });
|
|
43
39
|
return acc;
|
|
44
40
|
}, {});
|
|
45
41
|
}
|
|
@@ -3,9 +3,10 @@ export function createMockedAdapter(_original) {
|
|
|
3
3
|
return mock();
|
|
4
4
|
}
|
|
5
5
|
export function resetMockAdapter({ convert, revert, create, }, mockedAdapter) {
|
|
6
|
+
var _a;
|
|
6
7
|
mockReset(mockedAdapter);
|
|
7
8
|
if (revert) {
|
|
8
|
-
mockedAdapter.revert
|
|
9
|
+
(_a = mockedAdapter.revert) === null || _a === void 0 ? void 0 : _a.mockImplementation(revert);
|
|
9
10
|
}
|
|
10
11
|
mockedAdapter.convert.mockImplementation(convert);
|
|
11
12
|
mockedAdapter.create.mockImplementation(create);
|