@strictly/react-form 0.0.27 → 0.0.29
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/form_model.d.ts +3 -1
- package/.out/core/mobx/form_model.js +50 -100
- package/.out/core/mobx/specs/form_model.tests.js +14 -12
- package/.out/mantine/create_list.d.ts +2 -1
- package/.out/mantine/create_list.js +15 -3
- package/.out/mantine/specs/list_hooks.stories.js +8 -0
- package/.out/tsconfig.tsbuildinfo +1 -1
- package/.out/types/field.d.ts +1 -0
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-check-types.log +1 -1
- package/core/mobx/form_model.ts +48 -115
- package/core/mobx/specs/form_model.tests.ts +14 -12
- package/dist/index.cjs +80 -115
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +71 -105
- package/mantine/create_list.tsx +27 -3
- package/mantine/specs/__snapshots__/list_hooks.tests.tsx.snap +3 -3
- package/mantine/specs/list_hooks.stories.tsx +8 -0
- package/package.json +1 -1
- package/types/field.ts +1 -0
package/dist/index.js
CHANGED
|
@@ -306,7 +306,6 @@ function listAdapter() {
|
|
|
306
306
|
import {
|
|
307
307
|
assertExists,
|
|
308
308
|
assertExistsAndReturn,
|
|
309
|
-
assertState,
|
|
310
309
|
checkValidNumber,
|
|
311
310
|
map,
|
|
312
311
|
toArray,
|
|
@@ -333,11 +332,12 @@ var Validation = /* @__PURE__ */ ((Validation2) => {
|
|
|
333
332
|
Validation2[Validation2["Always"] = 2] = "Always";
|
|
334
333
|
return Validation2;
|
|
335
334
|
})(Validation || {});
|
|
336
|
-
var _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec, _value_dec, _init, _value, _fieldOverrides, _errorOverrides, _validation;
|
|
337
|
-
_value_dec = [observable.ref], _fieldOverrides_dec = [observable.shallow], _errorOverrides_dec = [observable.shallow], _validation_dec = [observable.shallow], _fields_dec = [computed], _knownFields_dec = [computed], _accessors_dec = [computed], _dirty_dec = [computed];
|
|
335
|
+
var _valueChanged_dec, _dirty_dec, _accessors_dec, _knownFields_dec, _fields_dec, _validation_dec, _errorOverrides_dec, _fieldOverrides_dec, _value_dec, _init, _value, _fieldOverrides, _errorOverrides, _validation;
|
|
336
|
+
_value_dec = [observable.ref], _fieldOverrides_dec = [observable.shallow], _errorOverrides_dec = [observable.shallow], _validation_dec = [observable.shallow], _fields_dec = [computed], _knownFields_dec = [computed], _accessors_dec = [computed], _dirty_dec = [computed], _valueChanged_dec = [computed];
|
|
338
337
|
var FormModel = class {
|
|
339
338
|
constructor(type, originalValue, adapters, mode) {
|
|
340
339
|
this.type = type;
|
|
340
|
+
this.originalValue = originalValue;
|
|
341
341
|
this.adapters = adapters;
|
|
342
342
|
this.mode = mode;
|
|
343
343
|
__runInitializers(_init, 5, this);
|
|
@@ -349,7 +349,9 @@ var FormModel = class {
|
|
|
349
349
|
// cannot be type safe
|
|
350
350
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
351
351
|
__publicField(this, "originalValues");
|
|
352
|
-
|
|
352
|
+
// maintains the value paths of lists when the original order is destroyed by deletes or reordering
|
|
353
|
+
__publicField(this, "listIndicesToKeys", {});
|
|
354
|
+
this.originalValues = flattenValuesOfType(type, originalValue, this.listIndicesToKeys);
|
|
353
355
|
this.value = mobxCopy(type, originalValue);
|
|
354
356
|
this.flattenedTypeDefs = flattenTypesOfType(type);
|
|
355
357
|
const conversions = flattenValueTo(
|
|
@@ -371,7 +373,8 @@ var FormModel = class {
|
|
|
371
373
|
return;
|
|
372
374
|
}
|
|
373
375
|
return convert(fieldValue, valuePath, contextValue);
|
|
374
|
-
}
|
|
376
|
+
},
|
|
377
|
+
this.listIndicesToKeys
|
|
375
378
|
);
|
|
376
379
|
this.fieldOverrides = map(conversions, function(_k, v) {
|
|
377
380
|
return v && [v.value];
|
|
@@ -417,7 +420,8 @@ var FormModel = class {
|
|
|
417
420
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
418
421
|
typePath
|
|
419
422
|
);
|
|
420
|
-
}
|
|
423
|
+
},
|
|
424
|
+
this.listIndicesToKeys
|
|
421
425
|
);
|
|
422
426
|
}
|
|
423
427
|
maybeSynthesizeFieldByValuePath(valuePath) {
|
|
@@ -476,7 +480,7 @@ var FormModel = class {
|
|
|
476
480
|
};
|
|
477
481
|
}
|
|
478
482
|
synthesizeFieldByPaths(valuePath, typePath) {
|
|
479
|
-
var _a;
|
|
483
|
+
var _a, _b;
|
|
480
484
|
const field = this.getField(valuePath, typePath);
|
|
481
485
|
if (field == null) {
|
|
482
486
|
return;
|
|
@@ -526,7 +530,10 @@ var FormModel = class {
|
|
|
526
530
|
value: displayedValue,
|
|
527
531
|
error,
|
|
528
532
|
readonly: readonly && !this.forceMutableFields,
|
|
529
|
-
required
|
|
533
|
+
required,
|
|
534
|
+
// make a copy of the index mapping and remove the final value (next id)
|
|
535
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
536
|
+
listIndexToKey: (_b = this.listIndicesToKeys[valuePath]) == null ? void 0 : _b.slice(0, -1)
|
|
530
537
|
};
|
|
531
538
|
}
|
|
532
539
|
getAccessorForValuePath(valuePath) {
|
|
@@ -539,7 +546,8 @@ var FormModel = class {
|
|
|
539
546
|
this.value,
|
|
540
547
|
(value) => {
|
|
541
548
|
this.value = mobxCopy(this.type, value);
|
|
542
|
-
}
|
|
549
|
+
},
|
|
550
|
+
this.listIndicesToKeys
|
|
543
551
|
);
|
|
544
552
|
}
|
|
545
553
|
maybeGetAdapterForValuePath(valuePath) {
|
|
@@ -558,6 +566,9 @@ var FormModel = class {
|
|
|
558
566
|
return this.isFieldDirty(valuePath);
|
|
559
567
|
});
|
|
560
568
|
}
|
|
569
|
+
get valueChanged() {
|
|
570
|
+
return !equals(this.type, this.value, this.originalValue);
|
|
571
|
+
}
|
|
561
572
|
typePath(valuePath) {
|
|
562
573
|
return valuePathToTypePath(this.type, valuePath, true);
|
|
563
574
|
}
|
|
@@ -589,118 +600,50 @@ var FormModel = class {
|
|
|
589
600
|
element,
|
|
590
601
|
...originalList.slice(definedIndex)
|
|
591
602
|
];
|
|
592
|
-
const targetPaths = Object.keys(this.fieldOverrides).filter(function(v) {
|
|
593
|
-
return v.startsWith(`${listValuePath}.`);
|
|
594
|
-
}).map(function(v) {
|
|
595
|
-
const parts = v.substring(listValuePath.length + 1).split(".");
|
|
596
|
-
const index2 = parseInt(parts[0]);
|
|
597
|
-
return [
|
|
598
|
-
index2,
|
|
599
|
-
parts.slice(1)
|
|
600
|
-
];
|
|
601
|
-
}).filter(function([index2]) {
|
|
602
|
-
return index2 >= definedIndex;
|
|
603
|
-
}).sort(function([a], [b]) {
|
|
604
|
-
return b - a;
|
|
605
|
-
});
|
|
606
603
|
runInAction(() => {
|
|
607
|
-
targetPaths.forEach(([
|
|
608
|
-
index2,
|
|
609
|
-
postfix
|
|
610
|
-
]) => {
|
|
611
|
-
const fromJsonPath = [
|
|
612
|
-
listValuePath,
|
|
613
|
-
`${index2}`,
|
|
614
|
-
...postfix
|
|
615
|
-
].join(".");
|
|
616
|
-
const toJsonPath = [
|
|
617
|
-
listValuePath,
|
|
618
|
-
`${index2 + 1}`,
|
|
619
|
-
...postfix
|
|
620
|
-
].join(".");
|
|
621
|
-
const fieldOverride = this.fieldOverrides[fromJsonPath];
|
|
622
|
-
delete this.fieldOverrides[fromJsonPath];
|
|
623
|
-
this.fieldOverrides[toJsonPath] = fieldOverride;
|
|
624
|
-
const validation = this.validation[fromJsonPath];
|
|
625
|
-
delete this.validation[fromJsonPath];
|
|
626
|
-
this.validation[toJsonPath] = validation;
|
|
627
|
-
});
|
|
628
604
|
accessor.set(newList);
|
|
629
605
|
delete this.fieldOverrides[listValuePath];
|
|
606
|
+
const indicesToKeys = assertExistsAndReturn(
|
|
607
|
+
this.listIndicesToKeys[listValuePath],
|
|
608
|
+
"no index to key mapping for list {}",
|
|
609
|
+
listValuePath
|
|
610
|
+
);
|
|
611
|
+
const nextKey = indicesToKeys[indicesToKeys.length - 1];
|
|
612
|
+
indicesToKeys.splice(definedIndex, 0, nextKey);
|
|
613
|
+
indicesToKeys[indicesToKeys.length - 1] = nextKey + 1;
|
|
630
614
|
});
|
|
631
615
|
}
|
|
632
616
|
removeListItem(...elementValuePaths) {
|
|
633
|
-
const orderedElementValuePaths = elementValuePaths.toSorted().reverse();
|
|
634
617
|
runInAction(() => {
|
|
635
|
-
|
|
618
|
+
elementValuePaths.forEach((elementValuePath) => {
|
|
619
|
+
var _a;
|
|
636
620
|
const [
|
|
637
621
|
listValuePath,
|
|
638
|
-
|
|
622
|
+
elementKeyString
|
|
639
623
|
] = assertExistsAndReturn(
|
|
640
624
|
jsonPathPop(elementValuePath),
|
|
641
625
|
"expected a path with two or more segments {}",
|
|
642
626
|
elementValuePath
|
|
643
627
|
);
|
|
644
628
|
const accessor = this.accessors[listValuePath];
|
|
645
|
-
const
|
|
646
|
-
parseInt(
|
|
647
|
-
"unexpected
|
|
648
|
-
|
|
649
|
-
elementValuePath
|
|
650
|
-
);
|
|
651
|
-
const newList = [...accessor.value];
|
|
652
|
-
assertState(
|
|
653
|
-
elementIndex >= 0 && elementIndex < newList.length,
|
|
654
|
-
"invalid index from path {} ({})",
|
|
655
|
-
elementIndex,
|
|
629
|
+
const elementKey = checkValidNumber(
|
|
630
|
+
parseInt(elementKeyString),
|
|
631
|
+
"unexpected id {} ({})",
|
|
632
|
+
elementKeyString,
|
|
656
633
|
elementValuePath
|
|
657
634
|
);
|
|
658
|
-
|
|
659
|
-
const
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
];
|
|
668
|
-
}).filter(function([index]) {
|
|
669
|
-
return index > elementIndex;
|
|
670
|
-
}).sort(function([a], [b]) {
|
|
671
|
-
return a - b;
|
|
672
|
-
});
|
|
673
|
-
targetPaths.forEach(([
|
|
674
|
-
index,
|
|
675
|
-
postfix
|
|
676
|
-
]) => {
|
|
677
|
-
const fromJsonPath = [
|
|
678
|
-
listValuePath,
|
|
679
|
-
`${index}`,
|
|
680
|
-
...postfix
|
|
681
|
-
].join(".");
|
|
682
|
-
const toJsonPath = [
|
|
683
|
-
listValuePath,
|
|
684
|
-
`${index - 1}`,
|
|
685
|
-
...postfix
|
|
686
|
-
].join(".");
|
|
687
|
-
const fieldOverride = this.fieldOverrides[fromJsonPath];
|
|
688
|
-
delete this.fieldOverrides[fromJsonPath];
|
|
689
|
-
this.fieldOverrides[toJsonPath] = fieldOverride;
|
|
690
|
-
const validation = this.validation[fromJsonPath];
|
|
691
|
-
delete this.validation[fromJsonPath];
|
|
692
|
-
this.validation[toJsonPath] = validation;
|
|
693
|
-
this.moveListItem(fromJsonPath, toJsonPath);
|
|
694
|
-
});
|
|
695
|
-
accessor.set(newList);
|
|
696
|
-
delete this.fieldOverrides[listValuePath];
|
|
635
|
+
const indicesToKeys = this.listIndicesToKeys[listValuePath];
|
|
636
|
+
const elementIndex = (_a = indicesToKeys == null ? void 0 : indicesToKeys.indexOf(elementKey)) != null ? _a : -1;
|
|
637
|
+
if (elementIndex >= 0) {
|
|
638
|
+
const newList = [...accessor.value];
|
|
639
|
+
newList.splice(elementIndex, 1);
|
|
640
|
+
accessor.set(newList);
|
|
641
|
+
delete this.fieldOverrides[listValuePath];
|
|
642
|
+
indicesToKeys.splice(elementIndex, 1);
|
|
643
|
+
}
|
|
697
644
|
});
|
|
698
645
|
});
|
|
699
646
|
}
|
|
700
|
-
moveListItem(fromValuePath, toValuePath) {
|
|
701
|
-
fromValuePath;
|
|
702
|
-
toValuePath;
|
|
703
|
-
}
|
|
704
647
|
internalSetFieldValue(valuePath, value, validation) {
|
|
705
648
|
const { revert } = this.getAdapterForValuePath(valuePath);
|
|
706
649
|
assertExists(revert, "setting value not supported {}", valuePath);
|
|
@@ -780,7 +723,7 @@ var FormModel = class {
|
|
|
780
723
|
});
|
|
781
724
|
}
|
|
782
725
|
isValuePathActive(valuePath) {
|
|
783
|
-
const values = flattenValuesOfType(this.type, this.value);
|
|
726
|
+
const values = flattenValuesOfType(this.type, this.value, this.listIndicesToKeys);
|
|
784
727
|
const keys = new Set(Object.keys(values));
|
|
785
728
|
return keys.has(valuePath);
|
|
786
729
|
}
|
|
@@ -860,6 +803,7 @@ __decorateElement(_init, 2, "fields", _fields_dec, FormModel);
|
|
|
860
803
|
__decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
|
|
861
804
|
__decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
|
|
862
805
|
__decorateElement(_init, 2, "dirty", _dirty_dec, FormModel);
|
|
806
|
+
__decorateElement(_init, 2, "valueChanged", _valueChanged_dec, FormModel);
|
|
863
807
|
__decoratorMetadata(_init, FormModel);
|
|
864
808
|
|
|
865
809
|
// core/mobx/hooks.tsx
|
|
@@ -1611,27 +1555,49 @@ function createForm(valuePath, Form, observableProps) {
|
|
|
1611
1555
|
}
|
|
1612
1556
|
|
|
1613
1557
|
// mantine/create_list.tsx
|
|
1558
|
+
import {
|
|
1559
|
+
assertExistsAndReturn as assertExistsAndReturn2
|
|
1560
|
+
} from "@strictly/base";
|
|
1614
1561
|
import {
|
|
1615
1562
|
Fragment
|
|
1616
1563
|
} from "react";
|
|
1617
1564
|
import { Fragment as Fragment2, jsx as jsx6 } from "react/jsx-runtime";
|
|
1618
1565
|
function createList(valuePath, List) {
|
|
1619
1566
|
const propSource = () => {
|
|
1620
|
-
const
|
|
1567
|
+
const field = this.fields[valuePath];
|
|
1568
|
+
const values = [...field.value];
|
|
1621
1569
|
return {
|
|
1622
1570
|
values,
|
|
1623
|
-
listPath: valuePath
|
|
1571
|
+
listPath: valuePath,
|
|
1572
|
+
indexKeys: assertExistsAndReturn2(field.listIndexToKey, "list index to key mapping missing in {}", valuePath)
|
|
1624
1573
|
};
|
|
1625
1574
|
};
|
|
1626
1575
|
return createUnsafePartialObserverComponent(List, propSource);
|
|
1627
1576
|
}
|
|
1628
1577
|
function DefaultList({
|
|
1629
1578
|
values,
|
|
1579
|
+
indexKeys,
|
|
1630
1580
|
listPath,
|
|
1631
1581
|
children
|
|
1632
1582
|
}) {
|
|
1633
1583
|
return /* @__PURE__ */ jsx6(Fragment2, { children: values.map(function(value, index) {
|
|
1634
|
-
|
|
1584
|
+
return [
|
|
1585
|
+
value,
|
|
1586
|
+
index,
|
|
1587
|
+
indexKeys[index]
|
|
1588
|
+
];
|
|
1589
|
+
}).filter(function([
|
|
1590
|
+
_value2,
|
|
1591
|
+
_index,
|
|
1592
|
+
key
|
|
1593
|
+
]) {
|
|
1594
|
+
return key != null;
|
|
1595
|
+
}).map(function([
|
|
1596
|
+
value,
|
|
1597
|
+
index,
|
|
1598
|
+
key
|
|
1599
|
+
]) {
|
|
1600
|
+
const valuePath = `${listPath}.${key}`;
|
|
1635
1601
|
return /* @__PURE__ */ jsx6(Fragment, { children: children(valuePath, value, index) }, valuePath);
|
|
1636
1602
|
}) });
|
|
1637
1603
|
}
|
package/mantine/create_list.tsx
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
assertExistsAndReturn,
|
|
3
|
+
type ElementOfArray,
|
|
4
|
+
} from '@strictly/base'
|
|
2
5
|
import {
|
|
3
6
|
type ComponentType,
|
|
4
7
|
Fragment,
|
|
@@ -15,6 +18,7 @@ import {
|
|
|
15
18
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
19
|
export type SuppliedListProps<Value = any, ListPath extends string = string> = {
|
|
17
20
|
values: readonly Value[],
|
|
21
|
+
indexKeys: number[],
|
|
18
22
|
listPath: ListPath,
|
|
19
23
|
}
|
|
20
24
|
|
|
@@ -34,10 +38,12 @@ export function createList<
|
|
|
34
38
|
List: ComponentType<Props>,
|
|
35
39
|
): MantineFieldComponent<SuppliedListProps<ElementOfArray<ValueTypeOfField<F[K]>>>, Props, never> {
|
|
36
40
|
const propSource = () => {
|
|
37
|
-
const
|
|
41
|
+
const field = this.fields[valuePath]
|
|
42
|
+
const values = [...field.value]
|
|
38
43
|
return {
|
|
39
44
|
values,
|
|
40
45
|
listPath: valuePath,
|
|
46
|
+
indexKeys: assertExistsAndReturn(field.listIndexToKey, 'list index to key mapping missing in {}', valuePath),
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
return createUnsafePartialObserverComponent(List, propSource)
|
|
@@ -48,6 +54,7 @@ export function DefaultList<
|
|
|
48
54
|
ListPath extends string,
|
|
49
55
|
>({
|
|
50
56
|
values,
|
|
57
|
+
indexKeys,
|
|
51
58
|
listPath,
|
|
52
59
|
children,
|
|
53
60
|
}: SuppliedListProps<Value, ListPath> & {
|
|
@@ -56,7 +63,24 @@ export function DefaultList<
|
|
|
56
63
|
return (
|
|
57
64
|
<>
|
|
58
65
|
{values.map(function (value, index) {
|
|
59
|
-
|
|
66
|
+
return [
|
|
67
|
+
value,
|
|
68
|
+
index,
|
|
69
|
+
indexKeys[index],
|
|
70
|
+
] as const
|
|
71
|
+
}).filter(function ([
|
|
72
|
+
_value,
|
|
73
|
+
_index,
|
|
74
|
+
key,
|
|
75
|
+
]) {
|
|
76
|
+
// omit entries without keys
|
|
77
|
+
return key != null
|
|
78
|
+
}).map(function ([
|
|
79
|
+
value,
|
|
80
|
+
index,
|
|
81
|
+
key,
|
|
82
|
+
]) {
|
|
83
|
+
const valuePath: `${ListPath}.${number}` = `${listPath}.${key}`
|
|
60
84
|
return (
|
|
61
85
|
<Fragment key={valuePath}>
|
|
62
86
|
{children(valuePath, value, index)}
|
|
@@ -40,7 +40,7 @@ exports[`mantine list hooks > renders Populated 1`] = `
|
|
|
40
40
|
>
|
|
41
41
|
<span>
|
|
42
42
|
ValuePath:
|
|
43
|
-
$.
|
|
43
|
+
$.100
|
|
44
44
|
</span>
|
|
45
45
|
<br />
|
|
46
46
|
<span>
|
|
@@ -78,7 +78,7 @@ exports[`mantine list hooks > renders Populated 1`] = `
|
|
|
78
78
|
>
|
|
79
79
|
<span>
|
|
80
80
|
ValuePath:
|
|
81
|
-
$.
|
|
81
|
+
$.33
|
|
82
82
|
</span>
|
|
83
83
|
<br />
|
|
84
84
|
<span>
|
|
@@ -97,7 +97,7 @@ exports[`mantine list hooks > renders Populated 1`] = `
|
|
|
97
97
|
>
|
|
98
98
|
<span>
|
|
99
99
|
ValuePath:
|
|
100
|
-
$.
|
|
100
|
+
$.5
|
|
101
101
|
</span>
|
|
102
102
|
<br />
|
|
103
103
|
<span>
|
|
@@ -70,6 +70,7 @@ export const Empty: Story = {
|
|
|
70
70
|
readonly: false,
|
|
71
71
|
required: false,
|
|
72
72
|
value: [],
|
|
73
|
+
listIndexToKey: [0],
|
|
73
74
|
},
|
|
74
75
|
},
|
|
75
76
|
},
|
|
@@ -87,6 +88,13 @@ export const Populated: Story = {
|
|
|
87
88
|
'C',
|
|
88
89
|
'D',
|
|
89
90
|
],
|
|
91
|
+
listIndexToKey: [
|
|
92
|
+
100,
|
|
93
|
+
1,
|
|
94
|
+
33,
|
|
95
|
+
5,
|
|
96
|
+
101,
|
|
97
|
+
],
|
|
90
98
|
},
|
|
91
99
|
},
|
|
92
100
|
},
|
package/package.json
CHANGED