@strictly/react-form 0.0.31 → 0.0.33
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/.storybook/preview.js +7 -0
- package/.out/core/mobx/FormModel.d.ts +3 -2
- package/.out/core/mobx/FormModel.js +46 -34
- package/.out/core/mobx/hooks.js +14 -5
- package/.out/core/mobx/peek.d.ts +5 -0
- package/.out/core/mobx/peek.js +16 -0
- package/.out/index.d.ts +1 -0
- package/.out/index.js +1 -0
- package/.out/mantine/createFieldView.d.ts +3 -2
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/util/Partial.js +8 -6
- package/.storybook/preview.tsx +8 -0
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-check-types.log +1 -1
- package/.turbo/turbo-release$colon$exports.log +1 -1
- package/core/mobx/FormModel.ts +29 -22
- package/core/mobx/hooks.tsx +17 -5
- package/core/mobx/peek.ts +17 -0
- package/dist/index.cjs +94 -65
- package/dist/index.d.cts +12 -4
- package/dist/index.d.ts +12 -4
- package/dist/index.js +103 -73
- package/index.ts +1 -0
- package/mantine/createFieldView.tsx +2 -1
- package/mantine/hooks.tsx +1 -1
- package/package.json +7 -6
- package/util/Partial.tsx +57 -54
package/dist/index.js
CHANGED
|
@@ -312,6 +312,7 @@ import {
|
|
|
312
312
|
UnreachableError as UnreachableError2
|
|
313
313
|
} from "@strictly/base";
|
|
314
314
|
import {
|
|
315
|
+
copy,
|
|
315
316
|
equals,
|
|
316
317
|
flattenAccessorsOfType,
|
|
317
318
|
flattenTypesOfType,
|
|
@@ -322,6 +323,7 @@ import {
|
|
|
322
323
|
valuePathToTypePath
|
|
323
324
|
} from "@strictly/define";
|
|
324
325
|
import {
|
|
326
|
+
action,
|
|
325
327
|
computed,
|
|
326
328
|
observable,
|
|
327
329
|
runInAction
|
|
@@ -332,8 +334,8 @@ var Validation = /* @__PURE__ */ ((Validation2) => {
|
|
|
332
334
|
Validation2[Validation2["Always"] = 2] = "Always";
|
|
333
335
|
return Validation2;
|
|
334
336
|
})(Validation || {});
|
|
335
|
-
var _valueChanged_dec, _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec,
|
|
336
|
-
|
|
337
|
+
var _validateAll_dec, _validateField_dec, _setFieldValue_dec, _valueChanged_dec, _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _value_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec, _observableValue_dec, _init, _observableValue, _fieldOverrides, _errorOverrides, _validation;
|
|
338
|
+
_observableValue_dec = [observable.ref], _fieldOverrides_dec = [observable.shallow], _errorOverrides_dec = [observable.shallow], _validation_dec = [observable.shallow], _value_dec = [computed], _fields_dec = [computed], _knownFields_dec = [computed], _accessors_dec = [computed], _dirty_dec = [computed], _valueChanged_dec = [computed], _setFieldValue_dec = [action], _validateField_dec = [action], _validateAll_dec = [action];
|
|
337
339
|
var FormModel = class {
|
|
338
340
|
constructor(type, originalValue, adapters, mode) {
|
|
339
341
|
this.type = type;
|
|
@@ -341,7 +343,7 @@ var FormModel = class {
|
|
|
341
343
|
this.adapters = adapters;
|
|
342
344
|
this.mode = mode;
|
|
343
345
|
__runInitializers(_init, 5, this);
|
|
344
|
-
__privateAdd(this,
|
|
346
|
+
__privateAdd(this, _observableValue, __runInitializers(_init, 8, this)), __runInitializers(_init, 11, this);
|
|
345
347
|
__privateAdd(this, _fieldOverrides, __runInitializers(_init, 12, this)), __runInitializers(_init, 15, this);
|
|
346
348
|
__privateAdd(this, _errorOverrides, __runInitializers(_init, 16, this, {})), __runInitializers(_init, 19, this);
|
|
347
349
|
__privateAdd(this, _validation, __runInitializers(_init, 20, this, {})), __runInitializers(_init, 23, this);
|
|
@@ -352,11 +354,11 @@ var FormModel = class {
|
|
|
352
354
|
// maintains the value paths of lists when the original order is destroyed by deletes or reordering
|
|
353
355
|
__publicField(this, "listIndicesToKeys", {});
|
|
354
356
|
this.originalValues = flattenValuesOfType(type, originalValue, this.listIndicesToKeys);
|
|
355
|
-
this.
|
|
357
|
+
this.observableValue = mobxCopy(type, originalValue);
|
|
356
358
|
this.flattenedTypeDefs = flattenTypesOfType(type);
|
|
357
359
|
const conversions = flattenValueTo(
|
|
358
360
|
type,
|
|
359
|
-
|
|
361
|
+
originalValue,
|
|
360
362
|
() => {
|
|
361
363
|
},
|
|
362
364
|
(_t, fieldValue, _setter, typePath, valuePath) => {
|
|
@@ -390,6 +392,9 @@ var FormModel = class {
|
|
|
390
392
|
throw new UnreachableError2(this.mode);
|
|
391
393
|
}
|
|
392
394
|
}
|
|
395
|
+
get value() {
|
|
396
|
+
return copy(this.type, this.observableValue);
|
|
397
|
+
}
|
|
393
398
|
get fields() {
|
|
394
399
|
return new Proxy(
|
|
395
400
|
this.knownFields,
|
|
@@ -409,7 +414,7 @@ var FormModel = class {
|
|
|
409
414
|
get knownFields() {
|
|
410
415
|
return flattenValueTo(
|
|
411
416
|
this.type,
|
|
412
|
-
this.
|
|
417
|
+
this.observableValue,
|
|
413
418
|
() => {
|
|
414
419
|
},
|
|
415
420
|
// TODO swap these to valuePath, typePath in flatten
|
|
@@ -451,7 +456,7 @@ var FormModel = class {
|
|
|
451
456
|
const fieldOverride = this.fieldOverrides[valuePath];
|
|
452
457
|
const accessor = this.getAccessorForValuePath(valuePath);
|
|
453
458
|
const fieldTypeDef = this.flattenedTypeDefs[typePath];
|
|
454
|
-
const context = this.toContext(this.
|
|
459
|
+
const context = this.toContext(this.observableValue, valuePath);
|
|
455
460
|
const defaultValue = create(valuePath, context);
|
|
456
461
|
const {
|
|
457
462
|
value,
|
|
@@ -543,9 +548,9 @@ var FormModel = class {
|
|
|
543
548
|
get accessors() {
|
|
544
549
|
return flattenAccessorsOfType(
|
|
545
550
|
this.type,
|
|
546
|
-
this.
|
|
551
|
+
this.observableValue,
|
|
547
552
|
(value) => {
|
|
548
|
-
this.
|
|
553
|
+
this.observableValue = mobxCopy(this.type, value);
|
|
549
554
|
},
|
|
550
555
|
this.listIndicesToKeys
|
|
551
556
|
);
|
|
@@ -567,7 +572,7 @@ var FormModel = class {
|
|
|
567
572
|
});
|
|
568
573
|
}
|
|
569
574
|
get valueChanged() {
|
|
570
|
-
return !equals(this.type, this.
|
|
575
|
+
return !equals(this.type, this.observableValue, this.originalValue);
|
|
571
576
|
}
|
|
572
577
|
typePath(valuePath) {
|
|
573
578
|
return valuePathToTypePath(this.type, valuePath, true);
|
|
@@ -592,7 +597,7 @@ var FormModel = class {
|
|
|
592
597
|
elementTypePath,
|
|
593
598
|
// TODO what can we use for the value path here?
|
|
594
599
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
595
|
-
this.toContext(this.
|
|
600
|
+
this.toContext(this.observableValue, valuePath)
|
|
596
601
|
);
|
|
597
602
|
const originalList = accessor.value;
|
|
598
603
|
const newList = [
|
|
@@ -647,7 +652,7 @@ var FormModel = class {
|
|
|
647
652
|
internalSetFieldValue(valuePath, value, validation) {
|
|
648
653
|
const { revert } = this.getAdapterForValuePath(valuePath);
|
|
649
654
|
assertExists(revert, "setting value not supported {}", valuePath);
|
|
650
|
-
const conversion = revert(value, valuePath, this.toContext(this.
|
|
655
|
+
const conversion = revert(value, valuePath, this.toContext(this.observableValue, valuePath));
|
|
651
656
|
const accessor = this.getAccessorForValuePath(valuePath);
|
|
652
657
|
return runInAction(() => {
|
|
653
658
|
this.fieldOverrides[valuePath] = [value];
|
|
@@ -702,7 +707,7 @@ var FormModel = class {
|
|
|
702
707
|
convert,
|
|
703
708
|
create
|
|
704
709
|
} = adapter2;
|
|
705
|
-
const context = this.toContext(this.
|
|
710
|
+
const context = this.toContext(this.observableValue, valuePath);
|
|
706
711
|
const value = create(valuePath, context);
|
|
707
712
|
const {
|
|
708
713
|
value: displayValue
|
|
@@ -719,11 +724,11 @@ var FormModel = class {
|
|
|
719
724
|
this.validation = {};
|
|
720
725
|
this.fieldOverrides = {};
|
|
721
726
|
this.errorOverrides = {};
|
|
722
|
-
this.
|
|
727
|
+
this.observableValue = mobxCopy(this.type, value);
|
|
723
728
|
});
|
|
724
729
|
}
|
|
725
730
|
isValuePathActive(valuePath) {
|
|
726
|
-
const values = flattenValuesOfType(this.type, this.
|
|
731
|
+
const values = flattenValuesOfType(this.type, this.observableValue, this.listIndicesToKeys);
|
|
727
732
|
const keys = new Set(Object.keys(values));
|
|
728
733
|
return keys.has(valuePath);
|
|
729
734
|
}
|
|
@@ -766,18 +771,14 @@ var FormModel = class {
|
|
|
766
771
|
return displayedValue !== originalDisplayedValue;
|
|
767
772
|
}
|
|
768
773
|
validateField(valuePath, validation = 2 /* Always */) {
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
delete this.errorOverrides[valuePath];
|
|
772
|
-
});
|
|
774
|
+
this.validation[valuePath] = validation;
|
|
775
|
+
delete this.errorOverrides[valuePath];
|
|
773
776
|
return this.fields[valuePath].error == null;
|
|
774
777
|
}
|
|
775
778
|
validateAll(validation = 2 /* Always */) {
|
|
776
779
|
const accessors = toArray(this.accessors);
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
this.validation[valuePath] = validation;
|
|
780
|
-
});
|
|
780
|
+
accessors.forEach(([valuePath]) => {
|
|
781
|
+
this.validation[valuePath] = validation;
|
|
781
782
|
});
|
|
782
783
|
return accessors.every(
|
|
783
784
|
([valuePath]) => {
|
|
@@ -791,32 +792,50 @@ var FormModel = class {
|
|
|
791
792
|
}
|
|
792
793
|
};
|
|
793
794
|
_init = __decoratorStart(null);
|
|
794
|
-
|
|
795
|
+
_observableValue = new WeakMap();
|
|
795
796
|
_fieldOverrides = new WeakMap();
|
|
796
797
|
_errorOverrides = new WeakMap();
|
|
797
798
|
_validation = new WeakMap();
|
|
798
|
-
__decorateElement(_init, 4, "
|
|
799
|
+
__decorateElement(_init, 4, "observableValue", _observableValue_dec, FormModel, _observableValue);
|
|
799
800
|
__decorateElement(_init, 4, "fieldOverrides", _fieldOverrides_dec, FormModel, _fieldOverrides);
|
|
800
801
|
__decorateElement(_init, 4, "errorOverrides", _errorOverrides_dec, FormModel, _errorOverrides);
|
|
801
802
|
__decorateElement(_init, 4, "validation", _validation_dec, FormModel, _validation);
|
|
803
|
+
__decorateElement(_init, 2, "value", _value_dec, FormModel);
|
|
802
804
|
__decorateElement(_init, 2, "fields", _fields_dec, FormModel);
|
|
803
805
|
__decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
|
|
804
806
|
__decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
|
|
805
807
|
__decorateElement(_init, 2, "dirty", _dirty_dec, FormModel);
|
|
806
808
|
__decorateElement(_init, 2, "valueChanged", _valueChanged_dec, FormModel);
|
|
809
|
+
__decorateElement(_init, 1, "setFieldValue", _setFieldValue_dec, FormModel);
|
|
810
|
+
__decorateElement(_init, 1, "validateField", _validateField_dec, FormModel);
|
|
811
|
+
__decorateElement(_init, 1, "validateAll", _validateAll_dec, FormModel);
|
|
807
812
|
__decoratorMetadata(_init, FormModel);
|
|
808
813
|
|
|
809
814
|
// core/mobx/hooks.tsx
|
|
810
815
|
import {
|
|
811
816
|
useCallback
|
|
812
817
|
} from "react";
|
|
818
|
+
|
|
819
|
+
// core/mobx/peek.ts
|
|
820
|
+
import { when } from "mobx";
|
|
821
|
+
function peek(operation) {
|
|
822
|
+
let result;
|
|
823
|
+
void when(() => {
|
|
824
|
+
result = operation();
|
|
825
|
+
return true;
|
|
826
|
+
});
|
|
827
|
+
return result;
|
|
828
|
+
}
|
|
829
|
+
|
|
830
|
+
// core/mobx/hooks.tsx
|
|
813
831
|
function useDefaultMobxFormHooks(model, {
|
|
814
832
|
onValidFieldSubmit,
|
|
815
833
|
onValidFormSubmit
|
|
816
834
|
} = {}) {
|
|
817
835
|
const onFieldValueChange = useCallback(
|
|
818
836
|
function(path, value) {
|
|
819
|
-
const
|
|
837
|
+
const activeValidation = peek(() => model.getValidation(path));
|
|
838
|
+
const validation = Math.min(activeValidation, 1 /* Changed */);
|
|
820
839
|
model.setFieldValue(path, value, validation);
|
|
821
840
|
},
|
|
822
841
|
[model]
|
|
@@ -836,8 +855,16 @@ function useDefaultMobxFormHooks(model, {
|
|
|
836
855
|
const onFieldBlur = useCallback(
|
|
837
856
|
function(path) {
|
|
838
857
|
setTimeout(function() {
|
|
839
|
-
|
|
840
|
-
|
|
858
|
+
const [
|
|
859
|
+
validate4,
|
|
860
|
+
activeValidation
|
|
861
|
+
] = peek(() => [
|
|
862
|
+
model.isValuePathActive(path) && model.isFieldDirty(path) && model.fields[path].error == null,
|
|
863
|
+
model.getValidation(path)
|
|
864
|
+
]);
|
|
865
|
+
if (validate4) {
|
|
866
|
+
const validation = Math.max(1 /* Changed */, activeValidation);
|
|
867
|
+
model.validateField(path, validation);
|
|
841
868
|
}
|
|
842
869
|
}, 100);
|
|
843
870
|
},
|
|
@@ -845,8 +872,10 @@ function useDefaultMobxFormHooks(model, {
|
|
|
845
872
|
);
|
|
846
873
|
const onFormSubmit = useCallback(
|
|
847
874
|
function() {
|
|
848
|
-
|
|
849
|
-
|
|
875
|
+
const valid = peek(() => model.validateSubmit());
|
|
876
|
+
if (valid && onValidFormSubmit) {
|
|
877
|
+
const value = peek(() => model.value);
|
|
878
|
+
onValidFormSubmit(value);
|
|
850
879
|
}
|
|
851
880
|
},
|
|
852
881
|
[
|
|
@@ -1002,7 +1031,7 @@ var IntegerToStringConverter = class {
|
|
|
1002
1031
|
|
|
1003
1032
|
// field_converters/NullableToBooleanConverter.ts
|
|
1004
1033
|
import {
|
|
1005
|
-
copy
|
|
1034
|
+
copy as copy2
|
|
1006
1035
|
} from "@strictly/define";
|
|
1007
1036
|
var NullableToBooleanConverter = class {
|
|
1008
1037
|
constructor(typeDef, prototype, nullType, defaultToNull = true) {
|
|
@@ -1021,7 +1050,7 @@ var NullableToBooleanConverter = class {
|
|
|
1021
1050
|
}
|
|
1022
1051
|
revert(from) {
|
|
1023
1052
|
if (from) {
|
|
1024
|
-
const value =
|
|
1053
|
+
const value = copy2(this.typeDef, this.prototype);
|
|
1025
1054
|
return {
|
|
1026
1055
|
type: 0 /* Success */,
|
|
1027
1056
|
value
|
|
@@ -1042,7 +1071,7 @@ import {
|
|
|
1042
1071
|
reverse
|
|
1043
1072
|
} from "@strictly/base";
|
|
1044
1073
|
import {
|
|
1045
|
-
copy as
|
|
1074
|
+
copy as copy3
|
|
1046
1075
|
} from "@strictly/define";
|
|
1047
1076
|
var AbstractSelectValueTypeConverter = class {
|
|
1048
1077
|
constructor(typeDef, values, defaultValueKey, noSuchValueError, required) {
|
|
@@ -1061,7 +1090,7 @@ var AbstractSelectValueTypeConverter = class {
|
|
|
1061
1090
|
value: null
|
|
1062
1091
|
};
|
|
1063
1092
|
}
|
|
1064
|
-
const value = prototype == null ? prototype :
|
|
1093
|
+
const value = prototype == null ? prototype : copy3(this.typeDef, prototype);
|
|
1065
1094
|
return {
|
|
1066
1095
|
type: 0 /* Success */,
|
|
1067
1096
|
value
|
|
@@ -1191,7 +1220,7 @@ import {
|
|
|
1191
1220
|
} from "react";
|
|
1192
1221
|
|
|
1193
1222
|
// util/Partial.tsx
|
|
1194
|
-
import {
|
|
1223
|
+
import { Observer } from "mobx-react";
|
|
1195
1224
|
import {
|
|
1196
1225
|
forwardRef,
|
|
1197
1226
|
useMemo
|
|
@@ -1277,36 +1306,36 @@ function createPartialObserverComponent(Component, curriedPropsSource, additiona
|
|
|
1277
1306
|
);
|
|
1278
1307
|
}
|
|
1279
1308
|
function createUnsafePartialObserverComponent(Component, curriedPropsSource, additionalPropKeys = []) {
|
|
1280
|
-
return
|
|
1281
|
-
|
|
1282
|
-
|
|
1283
|
-
|
|
1284
|
-
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1309
|
+
return forwardRef(
|
|
1310
|
+
function(props, ref) {
|
|
1311
|
+
const C = Component;
|
|
1312
|
+
const [
|
|
1313
|
+
additionalProps,
|
|
1314
|
+
exposedProps
|
|
1315
|
+
] = additionalPropKeys.reduce(
|
|
1316
|
+
function([
|
|
1317
|
+
additionalProps2,
|
|
1318
|
+
exposedProps2
|
|
1319
|
+
], key) {
|
|
1320
|
+
const value = props[
|
|
1321
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1322
|
+
key
|
|
1323
|
+
];
|
|
1324
|
+
delete exposedProps2[key];
|
|
1325
|
+
additionalProps2[key] = value;
|
|
1326
|
+
return [
|
|
1289
1327
|
additionalProps2,
|
|
1290
1328
|
exposedProps2
|
|
1291
|
-
]
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
];
|
|
1302
|
-
},
|
|
1303
|
-
[
|
|
1304
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1305
|
-
{},
|
|
1306
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1307
|
-
__spreadValues({}, props)
|
|
1308
|
-
]
|
|
1309
|
-
);
|
|
1329
|
+
];
|
|
1330
|
+
},
|
|
1331
|
+
[
|
|
1332
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1333
|
+
{},
|
|
1334
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
1335
|
+
__spreadValues({}, props)
|
|
1336
|
+
]
|
|
1337
|
+
);
|
|
1338
|
+
return /* @__PURE__ */ jsx(Observer, { children: () => {
|
|
1310
1339
|
const curriedProps = curriedPropsSource(additionalProps);
|
|
1311
1340
|
return /* @__PURE__ */ jsx(
|
|
1312
1341
|
C,
|
|
@@ -1314,8 +1343,8 @@ function createUnsafePartialObserverComponent(Component, curriedPropsSource, add
|
|
|
1314
1343
|
ref
|
|
1315
1344
|
}, curriedProps), exposedProps)
|
|
1316
1345
|
);
|
|
1317
|
-
}
|
|
1318
|
-
|
|
1346
|
+
} });
|
|
1347
|
+
}
|
|
1319
1348
|
);
|
|
1320
1349
|
}
|
|
1321
1350
|
function usePartialObserverComponent(curriedPropsSource, deps, Component, additionalPropKeys = []) {
|
|
@@ -1395,7 +1424,7 @@ import {
|
|
|
1395
1424
|
jsonPathPrefix,
|
|
1396
1425
|
jsonPathUnprefix
|
|
1397
1426
|
} from "@strictly/define";
|
|
1398
|
-
import { observer
|
|
1427
|
+
import { observer } from "mobx-react";
|
|
1399
1428
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1400
1429
|
function createFieldsView(valuePath, FieldsView, observableProps) {
|
|
1401
1430
|
function toKey(subKey) {
|
|
@@ -1419,7 +1448,7 @@ function createFieldsView(valuePath, FieldsView, observableProps) {
|
|
|
1419
1448
|
var _a;
|
|
1420
1449
|
(_a = observableProps.onFieldSubmit) == null ? void 0 : _a.call(observableProps, toKey(subKey));
|
|
1421
1450
|
}
|
|
1422
|
-
const Component =
|
|
1451
|
+
const Component = observer(
|
|
1423
1452
|
function(props) {
|
|
1424
1453
|
const subFields = Object.entries(observableProps.fields).reduce(
|
|
1425
1454
|
(acc, [
|
|
@@ -1459,7 +1488,7 @@ function createFieldsView(valuePath, FieldsView, observableProps) {
|
|
|
1459
1488
|
}
|
|
1460
1489
|
|
|
1461
1490
|
// mantine/createFieldView.tsx
|
|
1462
|
-
import { Observer } from "mobx-react";
|
|
1491
|
+
import { Observer as Observer2 } from "mobx-react";
|
|
1463
1492
|
import {
|
|
1464
1493
|
useCallback as useCallback2
|
|
1465
1494
|
} from "react";
|
|
@@ -1504,7 +1533,7 @@ function FieldView({
|
|
|
1504
1533
|
form,
|
|
1505
1534
|
valuePath
|
|
1506
1535
|
]);
|
|
1507
|
-
return /* @__PURE__ */ jsx4(
|
|
1536
|
+
return /* @__PURE__ */ jsx4(Observer2, { children: () => {
|
|
1508
1537
|
const {
|
|
1509
1538
|
value,
|
|
1510
1539
|
error
|
|
@@ -1533,13 +1562,13 @@ function createFieldView(valuePath) {
|
|
|
1533
1562
|
}
|
|
1534
1563
|
|
|
1535
1564
|
// mantine/createForm.tsx
|
|
1536
|
-
import { observer as
|
|
1565
|
+
import { observer as observer2 } from "mobx-react";
|
|
1537
1566
|
import {
|
|
1538
1567
|
useCallback as useCallback3
|
|
1539
1568
|
} from "react";
|
|
1540
1569
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1541
1570
|
function createForm(valuePath, Form, observableProps) {
|
|
1542
|
-
return
|
|
1571
|
+
return observer2((props) => {
|
|
1543
1572
|
const { value } = observableProps.fields[valuePath];
|
|
1544
1573
|
const onValueChange = useCallback3((value2) => {
|
|
1545
1574
|
observableProps.onFieldValueChange(valuePath, value2);
|
|
@@ -1587,7 +1616,7 @@ function DefaultList({
|
|
|
1587
1616
|
indexKeys[index]
|
|
1588
1617
|
];
|
|
1589
1618
|
}).filter(function([
|
|
1590
|
-
|
|
1619
|
+
_value,
|
|
1591
1620
|
_index,
|
|
1592
1621
|
key
|
|
1593
1622
|
]) {
|
|
@@ -1959,7 +1988,7 @@ var MantineFormImpl = class {
|
|
|
1959
1988
|
this
|
|
1960
1989
|
);
|
|
1961
1990
|
}
|
|
1962
|
-
// TODO have an option to bind to a Text/(value: T) =>
|
|
1991
|
+
// TODO have an option to bind to a Text/(value: T) => ReactNode for viewing form fields
|
|
1963
1992
|
};
|
|
1964
1993
|
_init2 = __decoratorStart(null);
|
|
1965
1994
|
_fields = new WeakMap();
|
|
@@ -2029,6 +2058,7 @@ export {
|
|
|
2029
2058
|
mergeAdaptersWithValidators,
|
|
2030
2059
|
mergeFieldAdaptersWithTwoWayConverter,
|
|
2031
2060
|
mergeValidators,
|
|
2061
|
+
peek,
|
|
2032
2062
|
prototypingFieldValueFactory,
|
|
2033
2063
|
subFormFieldAdapters,
|
|
2034
2064
|
trimmingStringAdapter,
|
package/index.ts
CHANGED
|
@@ -7,6 +7,7 @@ export * from './core/mobx/FormModel'
|
|
|
7
7
|
export * from './core/mobx/hooks'
|
|
8
8
|
export * from './core/mobx/mergeFieldAdaptersWithTwoWayConverter'
|
|
9
9
|
export * from './core/mobx/mergeFieldAdaptersWithValidators'
|
|
10
|
+
export * from './core/mobx/peek'
|
|
10
11
|
export * from './core/mobx/subFormFieldAdapters'
|
|
11
12
|
export * from './core/props'
|
|
12
13
|
export * from './field_converters/IntegerToStringConverter'
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Observer } from 'mobx-react'
|
|
2
2
|
import {
|
|
3
|
+
type ComponentProps,
|
|
3
4
|
type ComponentType,
|
|
4
5
|
useCallback,
|
|
5
6
|
} from 'react'
|
|
@@ -19,7 +20,7 @@ export type FieldViewProps<F extends Fields, K extends keyof F> = {
|
|
|
19
20
|
onBlur: () => void,
|
|
20
21
|
onValueChange: (v: ValueTypeOfField<F[K]>) => void,
|
|
21
22
|
onSubmit: () => void,
|
|
22
|
-
}) =>
|
|
23
|
+
}) => ReturnType<NonNullable<ComponentProps<typeof Observer>['render']>>,
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
/**
|
package/mantine/hooks.tsx
CHANGED
|
@@ -457,5 +457,5 @@ class MantineFormImpl<
|
|
|
457
457
|
) as unknown as MantineFieldComponent<FormProps<ValueTypeOfField<F[K]>>, P, never>
|
|
458
458
|
}
|
|
459
459
|
|
|
460
|
-
// TODO have an option to bind to a Text/(value: T) =>
|
|
460
|
+
// TODO have an option to bind to a Text/(value: T) => ReactNode for viewing form fields
|
|
461
461
|
}
|
package/package.json
CHANGED
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"author": "Chris <chris.glover@gmail.com> (@madmaw)",
|
|
3
|
-
"dependencies": {
|
|
4
|
-
"@types/react": "^18.3.12",
|
|
5
|
-
"@types/react-dom": "^18.3.1",
|
|
6
|
-
"type-fest": "^4.27.0"
|
|
7
|
-
},
|
|
3
|
+
"dependencies": {},
|
|
8
4
|
"description": "Types and utilities for creating React forms",
|
|
9
5
|
"devDependencies": {
|
|
10
6
|
"@babel/plugin-proposal-decorators": "^7.25.9",
|
|
@@ -22,11 +18,14 @@
|
|
|
22
18
|
"@strictly/support-vite": "*",
|
|
23
19
|
"@testing-library/dom": "^10.4.0",
|
|
24
20
|
"@testing-library/react": "^16.0.1",
|
|
21
|
+
"@types/react": "^18.3.12",
|
|
22
|
+
"@types/react-dom": "^18.3.1",
|
|
25
23
|
"@vitejs/plugin-react": "^4.3.3",
|
|
26
24
|
"concurrently": "^9.1.2",
|
|
27
25
|
"jsdom": "^25.0.1",
|
|
28
26
|
"resize-observer-polyfill": "^1.5.1",
|
|
29
27
|
"storybook": "^8.4.5",
|
|
28
|
+
"type-fest": "^4.27.0",
|
|
30
29
|
"vite": "^6.0.5",
|
|
31
30
|
"vitest-matchmedia-mock": "^1.0.6"
|
|
32
31
|
},
|
|
@@ -43,6 +42,8 @@
|
|
|
43
42
|
"@mantine/hooks": "^7.0.0 || ^8.0.0",
|
|
44
43
|
"@strictly/base": "*",
|
|
45
44
|
"@strictly/define": "*",
|
|
45
|
+
"@types/react": "^19.0.0 || ^18.0.0",
|
|
46
|
+
"@types/react-dom": "^19.0.0 || ^18.0.0",
|
|
46
47
|
"mobx": "^6.0.0",
|
|
47
48
|
"mobx-react": "^9.1.1",
|
|
48
49
|
"react": "^19.0.0 || ^18.0.0",
|
|
@@ -72,7 +73,7 @@
|
|
|
72
73
|
"test:watch": "vitest"
|
|
73
74
|
},
|
|
74
75
|
"type": "module",
|
|
75
|
-
"version": "0.0.
|
|
76
|
+
"version": "0.0.33",
|
|
76
77
|
"exports": {
|
|
77
78
|
".": {
|
|
78
79
|
"import": {
|
package/util/Partial.tsx
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type FriendlyExhaustiveArrayOfUnion } from '@strictly/base'
|
|
2
|
-
import {
|
|
2
|
+
import { Observer } from 'mobx-react'
|
|
3
3
|
import {
|
|
4
4
|
type ComponentProps,
|
|
5
5
|
type ComponentType,
|
|
@@ -274,62 +274,65 @@ export function createUnsafePartialObserverComponent<
|
|
|
274
274
|
additionalPropKeys: readonly (keyof AdditionalProps)[] = [],
|
|
275
275
|
): UnsafePartialComponent<Component, CurriedProps, AdditionalProps> {
|
|
276
276
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
277
|
-
return
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
function (
|
|
294
|
-
[
|
|
295
|
-
additionalProps,
|
|
296
|
-
exposedProps,
|
|
297
|
-
],
|
|
298
|
-
key,
|
|
299
|
-
) {
|
|
300
|
-
const value = props[
|
|
301
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
302
|
-
key as keyof PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>
|
|
303
|
-
]
|
|
304
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
305
|
-
delete exposedProps[key as keyof RemainingComponentProps<Component, CurriedProps>]
|
|
306
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
|
307
|
-
additionalProps[key] = value as any
|
|
308
|
-
return [
|
|
309
|
-
additionalProps,
|
|
310
|
-
exposedProps,
|
|
311
|
-
]
|
|
312
|
-
},
|
|
277
|
+
return forwardRef(
|
|
278
|
+
function (
|
|
279
|
+
props: PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>,
|
|
280
|
+
ref: ForwardedRef<typeof Component>,
|
|
281
|
+
) {
|
|
282
|
+
// forward ref types are really difficult to work with
|
|
283
|
+
// still needs a cast as `extends ComponentType<any>` != `ComponentType<any>`
|
|
284
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any, @typescript-eslint/no-unnecessary-type-assertion
|
|
285
|
+
const C = Component as ComponentType<any>
|
|
286
|
+
// remove the additional props from the exposed props that get passed in to the component
|
|
287
|
+
// as this generates react warnings
|
|
288
|
+
const [
|
|
289
|
+
additionalProps,
|
|
290
|
+
exposedProps,
|
|
291
|
+
] = additionalPropKeys.reduce<[AdditionalProps, RemainingComponentProps<Component, CurriedProps>]>(
|
|
292
|
+
function (
|
|
313
293
|
[
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
317
|
-
{ ...props } as RemainingComponentProps<Component, CurriedProps>,
|
|
294
|
+
additionalProps,
|
|
295
|
+
exposedProps,
|
|
318
296
|
],
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
297
|
+
key,
|
|
298
|
+
) {
|
|
299
|
+
const value = props[
|
|
300
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
301
|
+
key as keyof PropsWithoutRef<RemainingComponentProps<Component, CurriedProps> & AdditionalProps>
|
|
302
|
+
]
|
|
303
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
304
|
+
delete exposedProps[key as keyof RemainingComponentProps<Component, CurriedProps>]
|
|
305
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-explicit-any
|
|
306
|
+
additionalProps[key] = value as any
|
|
307
|
+
return [
|
|
308
|
+
additionalProps,
|
|
309
|
+
exposedProps,
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
[
|
|
313
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
314
|
+
{} as AdditionalProps,
|
|
315
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
316
|
+
{ ...props } as RemainingComponentProps<Component, CurriedProps>,
|
|
317
|
+
],
|
|
318
|
+
)
|
|
319
|
+
return (
|
|
320
|
+
<Observer>
|
|
321
|
+
{() => {
|
|
322
|
+
// TODO is there any way we can memoize this transformation?
|
|
323
|
+
const curriedProps = curriedPropsSource(additionalProps)
|
|
323
324
|
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
325
|
+
return (
|
|
326
|
+
<C
|
|
327
|
+
ref={ref}
|
|
328
|
+
{...curriedProps}
|
|
329
|
+
{...exposedProps}
|
|
330
|
+
/>
|
|
331
|
+
)
|
|
332
|
+
}}
|
|
333
|
+
</Observer>
|
|
334
|
+
)
|
|
335
|
+
},
|
|
333
336
|
) as UnsafePartialComponent<Component, CurriedProps, AdditionalProps>
|
|
334
337
|
}
|
|
335
338
|
|