@strictly/react-form 0.0.27 → 0.0.28
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 +48 -99
- 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 +47 -115
- package/core/mobx/specs/form_model.tests.ts +14 -12
- package/dist/index.cjs +78 -114
- package/dist/index.d.cts +6 -2
- package/dist/index.d.ts +6 -2
- package/dist/index.js +69 -104
- 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) {
|
|
@@ -526,7 +530,9 @@ var FormModel = class {
|
|
|
526
530
|
value: displayedValue,
|
|
527
531
|
error,
|
|
528
532
|
readonly: readonly && !this.forceMutableFields,
|
|
529
|
-
required
|
|
533
|
+
required,
|
|
534
|
+
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
535
|
+
listIndexToKey: this.listIndicesToKeys[valuePath]
|
|
530
536
|
};
|
|
531
537
|
}
|
|
532
538
|
getAccessorForValuePath(valuePath) {
|
|
@@ -539,7 +545,8 @@ var FormModel = class {
|
|
|
539
545
|
this.value,
|
|
540
546
|
(value) => {
|
|
541
547
|
this.value = mobxCopy(this.type, value);
|
|
542
|
-
}
|
|
548
|
+
},
|
|
549
|
+
this.listIndicesToKeys
|
|
543
550
|
);
|
|
544
551
|
}
|
|
545
552
|
maybeGetAdapterForValuePath(valuePath) {
|
|
@@ -558,6 +565,9 @@ var FormModel = class {
|
|
|
558
565
|
return this.isFieldDirty(valuePath);
|
|
559
566
|
});
|
|
560
567
|
}
|
|
568
|
+
get valueChanged() {
|
|
569
|
+
return !equals(this.type, this.value, this.originalValue);
|
|
570
|
+
}
|
|
561
571
|
typePath(valuePath) {
|
|
562
572
|
return valuePathToTypePath(this.type, valuePath, true);
|
|
563
573
|
}
|
|
@@ -589,118 +599,50 @@ var FormModel = class {
|
|
|
589
599
|
element,
|
|
590
600
|
...originalList.slice(definedIndex)
|
|
591
601
|
];
|
|
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
602
|
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
603
|
accessor.set(newList);
|
|
629
604
|
delete this.fieldOverrides[listValuePath];
|
|
605
|
+
const indicesToKeys = assertExistsAndReturn(
|
|
606
|
+
this.listIndicesToKeys[listValuePath],
|
|
607
|
+
"no index to key mapping for list {}",
|
|
608
|
+
listValuePath
|
|
609
|
+
);
|
|
610
|
+
const nextKey = indicesToKeys[indicesToKeys.length - 1];
|
|
611
|
+
indicesToKeys.splice(definedIndex, 0, nextKey);
|
|
612
|
+
indicesToKeys[indicesToKeys.length - 1] = nextKey + 1;
|
|
630
613
|
});
|
|
631
614
|
}
|
|
632
615
|
removeListItem(...elementValuePaths) {
|
|
633
|
-
const orderedElementValuePaths = elementValuePaths.toSorted().reverse();
|
|
634
616
|
runInAction(() => {
|
|
635
|
-
|
|
617
|
+
elementValuePaths.forEach((elementValuePath) => {
|
|
618
|
+
var _a;
|
|
636
619
|
const [
|
|
637
620
|
listValuePath,
|
|
638
|
-
|
|
621
|
+
elementKeyString
|
|
639
622
|
] = assertExistsAndReturn(
|
|
640
623
|
jsonPathPop(elementValuePath),
|
|
641
624
|
"expected a path with two or more segments {}",
|
|
642
625
|
elementValuePath
|
|
643
626
|
);
|
|
644
627
|
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,
|
|
628
|
+
const elementKey = checkValidNumber(
|
|
629
|
+
parseInt(elementKeyString),
|
|
630
|
+
"unexpected id {} ({})",
|
|
631
|
+
elementKeyString,
|
|
656
632
|
elementValuePath
|
|
657
633
|
);
|
|
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];
|
|
634
|
+
const indicesToKeys = this.listIndicesToKeys[listValuePath];
|
|
635
|
+
const elementIndex = (_a = indicesToKeys == null ? void 0 : indicesToKeys.indexOf(elementKey)) != null ? _a : -1;
|
|
636
|
+
if (elementIndex >= 0) {
|
|
637
|
+
const newList = [...accessor.value];
|
|
638
|
+
newList.splice(elementIndex, 1);
|
|
639
|
+
accessor.set(newList);
|
|
640
|
+
delete this.fieldOverrides[listValuePath];
|
|
641
|
+
indicesToKeys.splice(elementIndex, 1);
|
|
642
|
+
}
|
|
697
643
|
});
|
|
698
644
|
});
|
|
699
645
|
}
|
|
700
|
-
moveListItem(fromValuePath, toValuePath) {
|
|
701
|
-
fromValuePath;
|
|
702
|
-
toValuePath;
|
|
703
|
-
}
|
|
704
646
|
internalSetFieldValue(valuePath, value, validation) {
|
|
705
647
|
const { revert } = this.getAdapterForValuePath(valuePath);
|
|
706
648
|
assertExists(revert, "setting value not supported {}", valuePath);
|
|
@@ -780,7 +722,7 @@ var FormModel = class {
|
|
|
780
722
|
});
|
|
781
723
|
}
|
|
782
724
|
isValuePathActive(valuePath) {
|
|
783
|
-
const values = flattenValuesOfType(this.type, this.value);
|
|
725
|
+
const values = flattenValuesOfType(this.type, this.value, this.listIndicesToKeys);
|
|
784
726
|
const keys = new Set(Object.keys(values));
|
|
785
727
|
return keys.has(valuePath);
|
|
786
728
|
}
|
|
@@ -860,6 +802,7 @@ __decorateElement(_init, 2, "fields", _fields_dec, FormModel);
|
|
|
860
802
|
__decorateElement(_init, 2, "knownFields", _knownFields_dec, FormModel);
|
|
861
803
|
__decorateElement(_init, 2, "accessors", _accessors_dec, FormModel);
|
|
862
804
|
__decorateElement(_init, 2, "dirty", _dirty_dec, FormModel);
|
|
805
|
+
__decorateElement(_init, 2, "valueChanged", _valueChanged_dec, FormModel);
|
|
863
806
|
__decoratorMetadata(_init, FormModel);
|
|
864
807
|
|
|
865
808
|
// core/mobx/hooks.tsx
|
|
@@ -1611,27 +1554,49 @@ function createForm(valuePath, Form, observableProps) {
|
|
|
1611
1554
|
}
|
|
1612
1555
|
|
|
1613
1556
|
// mantine/create_list.tsx
|
|
1557
|
+
import {
|
|
1558
|
+
assertExistsAndReturn as assertExistsAndReturn2
|
|
1559
|
+
} from "@strictly/base";
|
|
1614
1560
|
import {
|
|
1615
1561
|
Fragment
|
|
1616
1562
|
} from "react";
|
|
1617
1563
|
import { Fragment as Fragment2, jsx as jsx6 } from "react/jsx-runtime";
|
|
1618
1564
|
function createList(valuePath, List) {
|
|
1619
1565
|
const propSource = () => {
|
|
1620
|
-
const
|
|
1566
|
+
const field = this.fields[valuePath];
|
|
1567
|
+
const values = [...field.value];
|
|
1621
1568
|
return {
|
|
1622
1569
|
values,
|
|
1623
|
-
listPath: valuePath
|
|
1570
|
+
listPath: valuePath,
|
|
1571
|
+
indexKeys: assertExistsAndReturn2(field.listIndexToKey, "list index to key mapping missing in {}", valuePath)
|
|
1624
1572
|
};
|
|
1625
1573
|
};
|
|
1626
1574
|
return createUnsafePartialObserverComponent(List, propSource);
|
|
1627
1575
|
}
|
|
1628
1576
|
function DefaultList({
|
|
1629
1577
|
values,
|
|
1578
|
+
indexKeys,
|
|
1630
1579
|
listPath,
|
|
1631
1580
|
children
|
|
1632
1581
|
}) {
|
|
1633
1582
|
return /* @__PURE__ */ jsx6(Fragment2, { children: values.map(function(value, index) {
|
|
1634
|
-
|
|
1583
|
+
return [
|
|
1584
|
+
value,
|
|
1585
|
+
index,
|
|
1586
|
+
indexKeys[index]
|
|
1587
|
+
];
|
|
1588
|
+
}).filter(function([
|
|
1589
|
+
_value2,
|
|
1590
|
+
_index,
|
|
1591
|
+
key
|
|
1592
|
+
]) {
|
|
1593
|
+
return key != null;
|
|
1594
|
+
}).map(function([
|
|
1595
|
+
value,
|
|
1596
|
+
index,
|
|
1597
|
+
key
|
|
1598
|
+
]) {
|
|
1599
|
+
const valuePath = `${listPath}.${key}`;
|
|
1635
1600
|
return /* @__PURE__ */ jsx6(Fragment, { children: children(valuePath, value, index) }, valuePath);
|
|
1636
1601
|
}) });
|
|
1637
1602
|
}
|
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