@remoteoss/json-schema-form 0.7.1-dev.20231031082524 → 0.7.2-dev.20231106093837
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/CHANGELOG.md +14 -22
- package/dist/index.cjs +62 -26
- package/dist/index.js +62 -26
- package/dist/standalone.js +62 -26
- package/package.json +1 -1
- package/src/tests/conditions.test.js +309 -6
- package/src/tests/createHeadlessForm.test.js +48 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
#### 0.7.1-beta.0 (2023-10-31)
|
|
2
|
+
|
|
3
|
+
##### Bug Fixes
|
|
4
|
+
|
|
5
|
+
- **select:** support string type ([#54](https://github.com/remoteoss/json-schema-form/pull/54)) ([b00f8776](https://github.com/remoteoss/json-schema-form/commit/b00f8776aa244803375ba64fbdd52c8fff9b9bd8))
|
|
6
|
+
|
|
1
7
|
#### 0.7.0-beta.0 (2023-10-23)
|
|
2
8
|
|
|
3
9
|
##### Chores
|
|
@@ -27,10 +33,8 @@ BREAKING CHANGES:
|
|
|
27
33
|
|
|
28
34
|
- json-logic: Add conditional logic checking. ([#41](https://github.com/remoteoss/json-schema-form/pull/41)) ([6292b01e](https://github.com/remoteoss/json-schema-form/commit/6292b01e3f77a9038328d7375080ffc4cb30dbc8))
|
|
29
35
|
|
|
30
|
-
|
|
31
36
|
###### Full API additions now supported from 0.6.5 onwards.
|
|
32
37
|
|
|
33
|
-
|
|
34
38
|
- New custom JSON Schema keyword `x-jsf-logic` added to support cross-field validations. Built on top of [JsonLogic](https://jsonlogic.com/).
|
|
35
39
|
|
|
36
40
|
- `x-jsf-logic` can contain:
|
|
@@ -49,16 +53,11 @@ While docs are underway, you can read examples from all the [tests](https://gith
|
|
|
49
53
|
|
|
50
54
|
In short: `x-jsf-logic` is added to support complex conditional cross-field validations. Properties like `x-jsf-logic-validations` allow hooking those up to individual fields.
|
|
51
55
|
|
|
52
|
-
|
|
53
56
|
#### 0.6.4-beta.0 (2023-09-15)
|
|
54
57
|
|
|
55
|
-
|
|
56
|
-
|
|
57
58
|
##### Changes
|
|
58
|
-
- json-logic: computedAttrs - handle inline rules ([#40](https://github.com/remoteoss/json-schema-form/pull/40)) ([860ad91b](https://github.com/remoteoss/json-schema-form/commit/860ad91b034ab35d4d4bc51c0c04675f102bf278))
|
|
59
|
-
|
|
60
|
-
|
|
61
59
|
|
|
60
|
+
- json-logic: computedAttrs - handle inline rules ([#40](https://github.com/remoteoss/json-schema-form/pull/40)) ([860ad91b](https://github.com/remoteoss/json-schema-form/commit/860ad91b034ab35d4d4bc51c0c04675f102bf278))
|
|
62
61
|
|
|
63
62
|
#### 0.6.1-beta.0 (2023-09-13)
|
|
64
63
|
|
|
@@ -66,50 +65,43 @@ In short: `x-jsf-logic` is added to support complex conditional cross-field vali
|
|
|
66
65
|
|
|
67
66
|
- json-logic: Computed string based values ([#37](https://github.com/remoteoss/json-schema-form/pull/37)) ([6e042ea5](https://github.com/remoteoss/json-schema-form/commit/6e042ea579497ea573710c307a6ff7ee2f19b931))
|
|
68
67
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
68
|
#### 0.5.0-beta.0 (2023-09-12)
|
|
73
69
|
|
|
74
70
|
##### Changes
|
|
71
|
+
|
|
75
72
|
- json-logic: Computed Attributes ([#36](https://github.com/remoteoss/json-schema-form/pull/36)) ([80c29589](https://github.com/remoteoss/json-schema-form/commit/80c29589ac0972e0f33add70a59df15a46db1b43))
|
|
76
73
|
- json-logic: Initial skeleton implementation ([#35](https://github.com/remoteoss/json-schema-form/pull/35)) ([63149ae8](https://github.com/remoteoss/json-schema-form/commit/63149ae863cf1b5ad76a3b2a49c7f343e55ce07b))
|
|
77
74
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
75
|
#### 0.4.5-beta.0 (2023-08-31)
|
|
76
|
+
|
|
82
77
|
##### Bug fixes
|
|
83
78
|
|
|
84
79
|
- Validate values based on `const` key ([#34](https://github.com/remoteoss/json-schema-form/pull/34)) ([bf07870d](https://github.com/remoteoss/json-schema-form/commit/bf07870d407d9b9b078882a078b9e4c7928df868))
|
|
85
80
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
81
|
#### 0.4.4-beta.0 (2023-08-30)
|
|
90
82
|
|
|
91
83
|
##### Chores
|
|
92
84
|
|
|
93
|
-
|
|
85
|
+
- **fieldset:** ignore values not matching the field type ([#44](https://github.com/remoteoss/json-schema-form/pull/44)) ([f0af54e5](https://github.com/remoteoss/json-schema-form/commit/f0af54e5d425fb78524ab150bb31629d00369a61))
|
|
94
86
|
|
|
95
87
|
#### 0.4.3-beta.0 (2023-08-09)
|
|
96
88
|
|
|
97
89
|
##### Bug fixes
|
|
98
90
|
|
|
99
|
-
|
|
91
|
+
- **conditions:** Validate a deeply nested if (e.g. checking an object with a number property) in an if property now doesn't break the form. ([#33](https://github.com/remoteoss/json-schema-form/pull/33)) ([e34cfcc](https://github.com/remoteoss/json-schema-form/commit/e34cfccaf45f1460b346f3cff0c797b3d11259e3))
|
|
100
92
|
|
|
101
93
|
#### 0.4.2-beta.0 (2023-07-20)
|
|
102
94
|
|
|
103
95
|
##### Bug Fixes
|
|
104
96
|
|
|
105
|
-
|
|
97
|
+
- **date:** Validate based on minDate and maxDate ([#30](https://github.com/remoteoss/json-schema-form/pull/30)) ([01c0143e](https://github.com/remoteoss/json-schema-form/commit/01c0143ea4a3775f9489ae6cb8fd99a90b3f1394))
|
|
106
98
|
|
|
107
99
|
#### 0.4.1-beta.0 (2023-07-03)
|
|
108
100
|
|
|
109
101
|
##### Bug Fixes
|
|
110
102
|
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
- **fieldset:** support root conditionals for fieldsets ([#23](https://github.com/remoteoss/json-schema-form/pull/23)) ([65d87b3a](https://github.com/remoteoss/json-schema-form/commit/65d87b3a93018f0729aed565000eb2a2ce1f2ce7))
|
|
104
|
+
- **select/radio:** Accept just the values in options (plus `''` and `null` for backward-compatibility) ([#18](https://github.com/remoteoss/json-schema-form/pull/18)) ([37501d2d](https://github.com/remoteoss/json-schema-form/commit/37501d2ddafdd5e207b34d2ca3f6b7b7a1006e9d))
|
|
113
105
|
|
|
114
106
|
#### 0.4.0-beta.0 (2023-06-22)
|
|
115
107
|
|
package/dist/index.cjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2023 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.7.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.7.2-dev.20231106093837
|
|
5
|
+
Generated: Mon, 06 Nov 2023 09:38:54 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -1037,6 +1037,33 @@ function processJSONLogicNode({
|
|
|
1037
1037
|
}
|
|
1038
1038
|
|
|
1039
1039
|
// src/helpers.js
|
|
1040
|
+
var dynamicInternalJsfAttrs = [
|
|
1041
|
+
"isVisible",
|
|
1042
|
+
// Driven from conditionals state
|
|
1043
|
+
"fields",
|
|
1044
|
+
// driven from group-array
|
|
1045
|
+
"getComputedAttributes",
|
|
1046
|
+
// From json-logic
|
|
1047
|
+
"computedAttributes",
|
|
1048
|
+
// From json-logic
|
|
1049
|
+
"calculateConditionalProperties",
|
|
1050
|
+
// driven from conditionals
|
|
1051
|
+
"calculateCustomValidationProperties",
|
|
1052
|
+
// To be deprecated in favor of json-logic
|
|
1053
|
+
"scopedJsonSchema"
|
|
1054
|
+
// The respective JSON Schema
|
|
1055
|
+
];
|
|
1056
|
+
var dynamicInternalJsfAttrsObj = Object.fromEntries(
|
|
1057
|
+
dynamicInternalJsfAttrs.map((k) => [k, true])
|
|
1058
|
+
);
|
|
1059
|
+
function removeConditionalStaleAttributes(field, conditionalAttrs, rootAttrs) {
|
|
1060
|
+
Object.keys(field).forEach((key) => {
|
|
1061
|
+
if (conditionalAttrs[key] === void 0 && rootAttrs[key] === void 0 && // Don't remove attrs that were declared in the root field.
|
|
1062
|
+
dynamicInternalJsfAttrsObj[key] === void 0) {
|
|
1063
|
+
field[key] = void 0;
|
|
1064
|
+
}
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1040
1067
|
function hasType(type, typeName) {
|
|
1041
1068
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1042
1069
|
}
|
|
@@ -1129,19 +1156,21 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1129
1156
|
if (fieldIsRequired) {
|
|
1130
1157
|
field.isVisible = true;
|
|
1131
1158
|
}
|
|
1132
|
-
const
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
field.
|
|
1159
|
+
const updateAttributes = (fieldAttrs) => {
|
|
1160
|
+
Object.entries(fieldAttrs).forEach(([key, value]) => {
|
|
1161
|
+
field[key] = typeof value === "function" ? value() : value;
|
|
1162
|
+
if (key === "value") {
|
|
1163
|
+
const readOnlyPropertyWasUpdated = typeof fieldAttrs.readOnly !== "undefined";
|
|
1164
|
+
const isReadonlyByDefault = field.readOnly;
|
|
1165
|
+
const isReadonly = readOnlyPropertyWasUpdated ? fieldAttrs.readOnly : isReadonlyByDefault;
|
|
1166
|
+
if (!isReadonly && (value === null || field.inputType === "checkbox")) {
|
|
1167
|
+
field.value = void 0;
|
|
1168
|
+
}
|
|
1140
1169
|
}
|
|
1141
|
-
}
|
|
1142
|
-
}
|
|
1170
|
+
});
|
|
1171
|
+
};
|
|
1143
1172
|
if (field.getComputedAttributes) {
|
|
1144
|
-
const
|
|
1173
|
+
const newAttributes = field.getComputedAttributes({
|
|
1145
1174
|
field,
|
|
1146
1175
|
isRequired: fieldIsRequired,
|
|
1147
1176
|
node,
|
|
@@ -1149,23 +1178,24 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1149
1178
|
config,
|
|
1150
1179
|
logic
|
|
1151
1180
|
});
|
|
1152
|
-
|
|
1181
|
+
updateAttributes(newAttributes);
|
|
1153
1182
|
}
|
|
1154
1183
|
if (field.calculateConditionalProperties) {
|
|
1155
|
-
const
|
|
1184
|
+
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
1156
1185
|
isRequired: fieldIsRequired,
|
|
1157
1186
|
conditionBranch: node,
|
|
1158
1187
|
formValues
|
|
1159
1188
|
});
|
|
1160
|
-
|
|
1189
|
+
updateAttributes(newAttributes, rootFieldAttrs);
|
|
1190
|
+
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
1161
1191
|
}
|
|
1162
1192
|
if (field.calculateCustomValidationProperties) {
|
|
1163
|
-
const
|
|
1193
|
+
const newAttributes = field.calculateCustomValidationProperties(
|
|
1164
1194
|
fieldIsRequired,
|
|
1165
1195
|
node,
|
|
1166
1196
|
formValues
|
|
1167
1197
|
);
|
|
1168
|
-
|
|
1198
|
+
updateAttributes(newAttributes);
|
|
1169
1199
|
}
|
|
1170
1200
|
}
|
|
1171
1201
|
function processNode({
|
|
@@ -1507,17 +1537,23 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
1507
1537
|
logic
|
|
1508
1538
|
)
|
|
1509
1539
|
};
|
|
1510
|
-
return
|
|
1540
|
+
return {
|
|
1541
|
+
rootFieldAttrs: fieldParams,
|
|
1542
|
+
newAttributes: (0, import_omit2.default)((0, import_merge2.default)(base, presentation, newFieldParams), ["inputType"])
|
|
1543
|
+
};
|
|
1511
1544
|
}
|
|
1512
1545
|
const isVisible = isRequired;
|
|
1513
1546
|
return {
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1547
|
+
rootFieldAttrs: fieldParams,
|
|
1548
|
+
newAttributes: {
|
|
1549
|
+
isVisible,
|
|
1550
|
+
required: isRequired,
|
|
1551
|
+
schema: buildYupSchema({
|
|
1552
|
+
...fieldParams,
|
|
1553
|
+
...extractParametersFromNode(conditionBranch),
|
|
1554
|
+
required: isRequired
|
|
1555
|
+
})
|
|
1556
|
+
}
|
|
1521
1557
|
};
|
|
1522
1558
|
};
|
|
1523
1559
|
}
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2023 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.7.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.7.2-dev.20231106093837
|
|
5
|
+
Generated: Mon, 06 Nov 2023 09:38:54 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -1001,6 +1001,33 @@ function processJSONLogicNode({
|
|
|
1001
1001
|
}
|
|
1002
1002
|
|
|
1003
1003
|
// src/helpers.js
|
|
1004
|
+
var dynamicInternalJsfAttrs = [
|
|
1005
|
+
"isVisible",
|
|
1006
|
+
// Driven from conditionals state
|
|
1007
|
+
"fields",
|
|
1008
|
+
// driven from group-array
|
|
1009
|
+
"getComputedAttributes",
|
|
1010
|
+
// From json-logic
|
|
1011
|
+
"computedAttributes",
|
|
1012
|
+
// From json-logic
|
|
1013
|
+
"calculateConditionalProperties",
|
|
1014
|
+
// driven from conditionals
|
|
1015
|
+
"calculateCustomValidationProperties",
|
|
1016
|
+
// To be deprecated in favor of json-logic
|
|
1017
|
+
"scopedJsonSchema"
|
|
1018
|
+
// The respective JSON Schema
|
|
1019
|
+
];
|
|
1020
|
+
var dynamicInternalJsfAttrsObj = Object.fromEntries(
|
|
1021
|
+
dynamicInternalJsfAttrs.map((k) => [k, true])
|
|
1022
|
+
);
|
|
1023
|
+
function removeConditionalStaleAttributes(field, conditionalAttrs, rootAttrs) {
|
|
1024
|
+
Object.keys(field).forEach((key) => {
|
|
1025
|
+
if (conditionalAttrs[key] === void 0 && rootAttrs[key] === void 0 && // Don't remove attrs that were declared in the root field.
|
|
1026
|
+
dynamicInternalJsfAttrsObj[key] === void 0) {
|
|
1027
|
+
field[key] = void 0;
|
|
1028
|
+
}
|
|
1029
|
+
});
|
|
1030
|
+
}
|
|
1004
1031
|
function hasType(type, typeName) {
|
|
1005
1032
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
1006
1033
|
}
|
|
@@ -1093,19 +1120,21 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1093
1120
|
if (fieldIsRequired) {
|
|
1094
1121
|
field.isVisible = true;
|
|
1095
1122
|
}
|
|
1096
|
-
const
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
field.
|
|
1123
|
+
const updateAttributes = (fieldAttrs) => {
|
|
1124
|
+
Object.entries(fieldAttrs).forEach(([key, value]) => {
|
|
1125
|
+
field[key] = typeof value === "function" ? value() : value;
|
|
1126
|
+
if (key === "value") {
|
|
1127
|
+
const readOnlyPropertyWasUpdated = typeof fieldAttrs.readOnly !== "undefined";
|
|
1128
|
+
const isReadonlyByDefault = field.readOnly;
|
|
1129
|
+
const isReadonly = readOnlyPropertyWasUpdated ? fieldAttrs.readOnly : isReadonlyByDefault;
|
|
1130
|
+
if (!isReadonly && (value === null || field.inputType === "checkbox")) {
|
|
1131
|
+
field.value = void 0;
|
|
1132
|
+
}
|
|
1104
1133
|
}
|
|
1105
|
-
}
|
|
1106
|
-
}
|
|
1134
|
+
});
|
|
1135
|
+
};
|
|
1107
1136
|
if (field.getComputedAttributes) {
|
|
1108
|
-
const
|
|
1137
|
+
const newAttributes = field.getComputedAttributes({
|
|
1109
1138
|
field,
|
|
1110
1139
|
isRequired: fieldIsRequired,
|
|
1111
1140
|
node,
|
|
@@ -1113,23 +1142,24 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
1113
1142
|
config,
|
|
1114
1143
|
logic
|
|
1115
1144
|
});
|
|
1116
|
-
|
|
1145
|
+
updateAttributes(newAttributes);
|
|
1117
1146
|
}
|
|
1118
1147
|
if (field.calculateConditionalProperties) {
|
|
1119
|
-
const
|
|
1148
|
+
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
1120
1149
|
isRequired: fieldIsRequired,
|
|
1121
1150
|
conditionBranch: node,
|
|
1122
1151
|
formValues
|
|
1123
1152
|
});
|
|
1124
|
-
|
|
1153
|
+
updateAttributes(newAttributes, rootFieldAttrs);
|
|
1154
|
+
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
1125
1155
|
}
|
|
1126
1156
|
if (field.calculateCustomValidationProperties) {
|
|
1127
|
-
const
|
|
1157
|
+
const newAttributes = field.calculateCustomValidationProperties(
|
|
1128
1158
|
fieldIsRequired,
|
|
1129
1159
|
node,
|
|
1130
1160
|
formValues
|
|
1131
1161
|
);
|
|
1132
|
-
|
|
1162
|
+
updateAttributes(newAttributes);
|
|
1133
1163
|
}
|
|
1134
1164
|
}
|
|
1135
1165
|
function processNode({
|
|
@@ -1471,17 +1501,23 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
1471
1501
|
logic
|
|
1472
1502
|
)
|
|
1473
1503
|
};
|
|
1474
|
-
return
|
|
1504
|
+
return {
|
|
1505
|
+
rootFieldAttrs: fieldParams,
|
|
1506
|
+
newAttributes: omit2(merge2(base, presentation, newFieldParams), ["inputType"])
|
|
1507
|
+
};
|
|
1475
1508
|
}
|
|
1476
1509
|
const isVisible = isRequired;
|
|
1477
1510
|
return {
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1511
|
+
rootFieldAttrs: fieldParams,
|
|
1512
|
+
newAttributes: {
|
|
1513
|
+
isVisible,
|
|
1514
|
+
required: isRequired,
|
|
1515
|
+
schema: buildYupSchema({
|
|
1516
|
+
...fieldParams,
|
|
1517
|
+
...extractParametersFromNode(conditionBranch),
|
|
1518
|
+
required: isRequired
|
|
1519
|
+
})
|
|
1520
|
+
}
|
|
1485
1521
|
};
|
|
1486
1522
|
};
|
|
1487
1523
|
}
|
package/dist/standalone.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
2
|
/*!
|
|
3
3
|
Copyright (c) 2023 Remote Technology, Inc.
|
|
4
|
-
NPM Package: @remoteoss/json-schema-form@0.7.
|
|
5
|
-
Generated:
|
|
4
|
+
NPM Package: @remoteoss/json-schema-form@0.7.2-dev.20231106093837
|
|
5
|
+
Generated: Mon, 06 Nov 2023 09:38:54 GMT
|
|
6
6
|
|
|
7
7
|
MIT License
|
|
8
8
|
|
|
@@ -12355,6 +12355,33 @@ function processJSONLogicNode({
|
|
|
12355
12355
|
}
|
|
12356
12356
|
|
|
12357
12357
|
// src/helpers.js
|
|
12358
|
+
var dynamicInternalJsfAttrs = [
|
|
12359
|
+
"isVisible",
|
|
12360
|
+
// Driven from conditionals state
|
|
12361
|
+
"fields",
|
|
12362
|
+
// driven from group-array
|
|
12363
|
+
"getComputedAttributes",
|
|
12364
|
+
// From json-logic
|
|
12365
|
+
"computedAttributes",
|
|
12366
|
+
// From json-logic
|
|
12367
|
+
"calculateConditionalProperties",
|
|
12368
|
+
// driven from conditionals
|
|
12369
|
+
"calculateCustomValidationProperties",
|
|
12370
|
+
// To be deprecated in favor of json-logic
|
|
12371
|
+
"scopedJsonSchema"
|
|
12372
|
+
// The respective JSON Schema
|
|
12373
|
+
];
|
|
12374
|
+
var dynamicInternalJsfAttrsObj = Object.fromEntries(
|
|
12375
|
+
dynamicInternalJsfAttrs.map((k) => [k, true])
|
|
12376
|
+
);
|
|
12377
|
+
function removeConditionalStaleAttributes(field, conditionalAttrs, rootAttrs) {
|
|
12378
|
+
Object.keys(field).forEach((key) => {
|
|
12379
|
+
if (conditionalAttrs[key] === void 0 && rootAttrs[key] === void 0 && // Don't remove attrs that were declared in the root field.
|
|
12380
|
+
dynamicInternalJsfAttrsObj[key] === void 0) {
|
|
12381
|
+
field[key] = void 0;
|
|
12382
|
+
}
|
|
12383
|
+
});
|
|
12384
|
+
}
|
|
12358
12385
|
function hasType(type, typeName) {
|
|
12359
12386
|
return Array.isArray(type) ? type.includes(typeName) : type === typeName;
|
|
12360
12387
|
}
|
|
@@ -12447,19 +12474,21 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
12447
12474
|
if (fieldIsRequired) {
|
|
12448
12475
|
field.isVisible = true;
|
|
12449
12476
|
}
|
|
12450
|
-
const
|
|
12451
|
-
|
|
12452
|
-
|
|
12453
|
-
|
|
12454
|
-
|
|
12455
|
-
|
|
12456
|
-
|
|
12457
|
-
field.
|
|
12477
|
+
const updateAttributes = (fieldAttrs) => {
|
|
12478
|
+
Object.entries(fieldAttrs).forEach(([key, value]) => {
|
|
12479
|
+
field[key] = typeof value === "function" ? value() : value;
|
|
12480
|
+
if (key === "value") {
|
|
12481
|
+
const readOnlyPropertyWasUpdated = typeof fieldAttrs.readOnly !== "undefined";
|
|
12482
|
+
const isReadonlyByDefault = field.readOnly;
|
|
12483
|
+
const isReadonly = readOnlyPropertyWasUpdated ? fieldAttrs.readOnly : isReadonlyByDefault;
|
|
12484
|
+
if (!isReadonly && (value === null || field.inputType === "checkbox")) {
|
|
12485
|
+
field.value = void 0;
|
|
12486
|
+
}
|
|
12458
12487
|
}
|
|
12459
|
-
}
|
|
12460
|
-
}
|
|
12488
|
+
});
|
|
12489
|
+
};
|
|
12461
12490
|
if (field.getComputedAttributes) {
|
|
12462
|
-
const
|
|
12491
|
+
const newAttributes = field.getComputedAttributes({
|
|
12463
12492
|
field,
|
|
12464
12493
|
isRequired: fieldIsRequired,
|
|
12465
12494
|
node,
|
|
@@ -12467,23 +12496,24 @@ function updateField(field, requiredFields, node, formValues, logic, config) {
|
|
|
12467
12496
|
config,
|
|
12468
12497
|
logic
|
|
12469
12498
|
});
|
|
12470
|
-
|
|
12499
|
+
updateAttributes(newAttributes);
|
|
12471
12500
|
}
|
|
12472
12501
|
if (field.calculateConditionalProperties) {
|
|
12473
|
-
const
|
|
12502
|
+
const { rootFieldAttrs, newAttributes } = field.calculateConditionalProperties({
|
|
12474
12503
|
isRequired: fieldIsRequired,
|
|
12475
12504
|
conditionBranch: node,
|
|
12476
12505
|
formValues
|
|
12477
12506
|
});
|
|
12478
|
-
|
|
12507
|
+
updateAttributes(newAttributes, rootFieldAttrs);
|
|
12508
|
+
removeConditionalStaleAttributes(field, newAttributes, rootFieldAttrs);
|
|
12479
12509
|
}
|
|
12480
12510
|
if (field.calculateCustomValidationProperties) {
|
|
12481
|
-
const
|
|
12511
|
+
const newAttributes = field.calculateCustomValidationProperties(
|
|
12482
12512
|
fieldIsRequired,
|
|
12483
12513
|
node,
|
|
12484
12514
|
formValues
|
|
12485
12515
|
);
|
|
12486
|
-
|
|
12516
|
+
updateAttributes(newAttributes);
|
|
12487
12517
|
}
|
|
12488
12518
|
}
|
|
12489
12519
|
function processNode({
|
|
@@ -12825,17 +12855,23 @@ function calculateConditionalProperties({ fieldParams, customProperties, logic,
|
|
|
12825
12855
|
logic
|
|
12826
12856
|
)
|
|
12827
12857
|
};
|
|
12828
|
-
return
|
|
12858
|
+
return {
|
|
12859
|
+
rootFieldAttrs: fieldParams,
|
|
12860
|
+
newAttributes: (0, import_omit2.default)((0, import_merge2.default)(base, presentation, newFieldParams), ["inputType"])
|
|
12861
|
+
};
|
|
12829
12862
|
}
|
|
12830
12863
|
const isVisible = isRequired;
|
|
12831
12864
|
return {
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12865
|
+
rootFieldAttrs: fieldParams,
|
|
12866
|
+
newAttributes: {
|
|
12867
|
+
isVisible,
|
|
12868
|
+
required: isRequired,
|
|
12869
|
+
schema: buildYupSchema({
|
|
12870
|
+
...fieldParams,
|
|
12871
|
+
...extractParametersFromNode(conditionBranch),
|
|
12872
|
+
required: isRequired
|
|
12873
|
+
})
|
|
12874
|
+
}
|
|
12839
12875
|
};
|
|
12840
12876
|
};
|
|
12841
12877
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remoteoss/json-schema-form",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.2-dev.20231106093837",
|
|
4
4
|
"description": "Headless UI form powered by JSON Schemas",
|
|
5
5
|
"author": "Remote.com <engineering@remote.com> (https://remote.com/)",
|
|
6
6
|
"license": "MIT",
|
|
@@ -27,12 +27,7 @@ it('Should allow check of a nested property in a conditional', () => {
|
|
|
27
27
|
additionalProperties: false,
|
|
28
28
|
properties: {
|
|
29
29
|
child: {
|
|
30
|
-
oneOf: [
|
|
31
|
-
{
|
|
32
|
-
const: 'yes',
|
|
33
|
-
},
|
|
34
|
-
{ const: 'no' },
|
|
35
|
-
],
|
|
30
|
+
oneOf: [{ const: 'yes' }, { const: 'no' }],
|
|
36
31
|
type: 'string',
|
|
37
32
|
},
|
|
38
33
|
},
|
|
@@ -56,3 +51,311 @@ it('Should allow check of a nested property in a conditional', () => {
|
|
|
56
51
|
undefined
|
|
57
52
|
);
|
|
58
53
|
});
|
|
54
|
+
|
|
55
|
+
describe('Conditional attributes updated', () => {
|
|
56
|
+
it('Update basic case with const, default, maximum', () => {
|
|
57
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
58
|
+
{
|
|
59
|
+
properties: {
|
|
60
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
61
|
+
hours: { type: 'number' },
|
|
62
|
+
},
|
|
63
|
+
allOf: [
|
|
64
|
+
{
|
|
65
|
+
if: {
|
|
66
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
67
|
+
required: ['is_full_time'],
|
|
68
|
+
},
|
|
69
|
+
then: {
|
|
70
|
+
properties: {
|
|
71
|
+
hours: {
|
|
72
|
+
const: 8,
|
|
73
|
+
default: 8,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
else: {
|
|
78
|
+
properties: {
|
|
79
|
+
hours: {
|
|
80
|
+
maximum: 4,
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
},
|
|
87
|
+
{ strictInputType: false }
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Given "Yes" it applies "const" and "default"
|
|
91
|
+
expect(handleValidation({ is_full_time: 'yes', hours: 4 }).formErrors).toEqual({
|
|
92
|
+
hours: 'The only accepted value is 8.',
|
|
93
|
+
});
|
|
94
|
+
expect(fields[1]).toMatchObject({ const: 8, default: 8 });
|
|
95
|
+
expect(fields[1].maximum).toBeUndefined();
|
|
96
|
+
|
|
97
|
+
// Changing to "No", applies the "maximum" and cleans "const" and "default"
|
|
98
|
+
expect(handleValidation({ is_full_time: 'no', hours: 4 }).formErrors).toBeUndefined();
|
|
99
|
+
expect(fields[1]).toMatchObject({ maximum: 4 });
|
|
100
|
+
expect(fields[1].const).toBeUndefined();
|
|
101
|
+
expect(fields[1].default).toBeUndefined();
|
|
102
|
+
|
|
103
|
+
// Changing back to "Yes", it removes "maximum", and applies "const" and "default"
|
|
104
|
+
expect(handleValidation({}).formErrors).toBeUndefined();
|
|
105
|
+
expect(handleValidation({ is_full_time: 'yes', hours: 8 }).formErrors).toBeUndefined();
|
|
106
|
+
expect(fields[1].maximum).toBeUndefined();
|
|
107
|
+
expect(fields[1]).toMatchObject({ const: 8, default: 8 });
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('Update a new attribute (eg description)', () => {
|
|
111
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
112
|
+
{
|
|
113
|
+
properties: {
|
|
114
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
115
|
+
hours: {
|
|
116
|
+
type: 'number',
|
|
117
|
+
},
|
|
118
|
+
},
|
|
119
|
+
allOf: [
|
|
120
|
+
{
|
|
121
|
+
if: {
|
|
122
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
123
|
+
required: ['is_full_time'],
|
|
124
|
+
},
|
|
125
|
+
then: {
|
|
126
|
+
properties: {
|
|
127
|
+
hours: {
|
|
128
|
+
description: 'We recommend 8 hours.',
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
],
|
|
134
|
+
},
|
|
135
|
+
{ strictInputType: false }
|
|
136
|
+
);
|
|
137
|
+
|
|
138
|
+
// By default the attribute is not set.
|
|
139
|
+
expect(fields[1].description).toBeUndefined();
|
|
140
|
+
|
|
141
|
+
// Given "Yes" it applies the conditional attribute
|
|
142
|
+
expect(handleValidation({ is_full_time: 'yes' }).formErrors).toBeUndefined();
|
|
143
|
+
expect(fields[1].description).toBe('We recommend 8 hours.');
|
|
144
|
+
|
|
145
|
+
// Changing to "No", removes the description
|
|
146
|
+
expect(handleValidation({ is_full_time: 'no' }).formErrors).toBeUndefined();
|
|
147
|
+
expect(fields[1].description).toBeUndefined();
|
|
148
|
+
|
|
149
|
+
// Changing back to "Yes", it sets the attribute again
|
|
150
|
+
expect(handleValidation({ is_full_time: 'yes' }).formErrors).toBeUndefined();
|
|
151
|
+
expect(fields[1].description).toBe('We recommend 8 hours.');
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
it('Update an existing attribute (eg description)', () => {
|
|
155
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
156
|
+
{
|
|
157
|
+
properties: {
|
|
158
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
159
|
+
hours: {
|
|
160
|
+
type: 'number',
|
|
161
|
+
description: 'Any value works.',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
allOf: [
|
|
165
|
+
{
|
|
166
|
+
if: {
|
|
167
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
168
|
+
required: ['is_full_time'],
|
|
169
|
+
},
|
|
170
|
+
then: {
|
|
171
|
+
properties: {
|
|
172
|
+
hours: {
|
|
173
|
+
description: 'We recommend 8 hours.',
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
],
|
|
179
|
+
},
|
|
180
|
+
{ strictInputType: false }
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// By default the attribute is set the base value.
|
|
184
|
+
expect(fields[1].description).toBe('Any value works.');
|
|
185
|
+
|
|
186
|
+
// Given "Yes" it applies the conditional attribute
|
|
187
|
+
expect(handleValidation({ is_full_time: 'yes', hours: 4 }).formErrors).toBeUndefined();
|
|
188
|
+
expect(fields[1].description).toBe('We recommend 8 hours.');
|
|
189
|
+
|
|
190
|
+
// Changing to "No", it applies the base value again.
|
|
191
|
+
expect(handleValidation({ is_full_time: 'no', hours: 4 }).formErrors).toBeUndefined();
|
|
192
|
+
expect(fields[1].description).toBe('Any value works.');
|
|
193
|
+
|
|
194
|
+
// Changing back to "Yes", it sets the attribute again
|
|
195
|
+
expect(handleValidation({ is_full_time: 'yes', hours: 8 }).formErrors).toBeUndefined();
|
|
196
|
+
expect(fields[1].description).toBe('We recommend 8 hours.');
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
it('Update a nested attribute', () => {
|
|
200
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
201
|
+
{
|
|
202
|
+
properties: {
|
|
203
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
204
|
+
hours: {
|
|
205
|
+
type: 'number',
|
|
206
|
+
presentation: {
|
|
207
|
+
inputType: 'number',
|
|
208
|
+
anything: 'info',
|
|
209
|
+
},
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
allOf: [
|
|
213
|
+
{
|
|
214
|
+
if: {
|
|
215
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
216
|
+
required: ['is_full_time'],
|
|
217
|
+
},
|
|
218
|
+
then: {
|
|
219
|
+
properties: {
|
|
220
|
+
hours: {
|
|
221
|
+
presentation: {
|
|
222
|
+
anything: 'danger',
|
|
223
|
+
},
|
|
224
|
+
},
|
|
225
|
+
},
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
],
|
|
229
|
+
},
|
|
230
|
+
{ strictInputType: false }
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
// By default the attribute is set the base value.
|
|
234
|
+
expect(fields[1].anything).toBe('info');
|
|
235
|
+
|
|
236
|
+
// Given "Yes" it applies the conditional attribute
|
|
237
|
+
expect(handleValidation({ is_full_time: 'yes' }).formErrors).toBeUndefined();
|
|
238
|
+
expect(fields[1].anything).toBe('danger');
|
|
239
|
+
|
|
240
|
+
// Changing to "No", it applies the base value again.
|
|
241
|
+
expect(handleValidation({ is_full_time: 'no' }).formErrors).toBeUndefined();
|
|
242
|
+
expect(fields[1].anything).toBe('info');
|
|
243
|
+
|
|
244
|
+
// Changing back to "Yes", it sets the attribute again
|
|
245
|
+
expect(handleValidation({ is_full_time: 'yes' }).formErrors).toBeUndefined();
|
|
246
|
+
expect(fields[1].anything).toBe('danger');
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
it('Keeps existing attributes in matches that dont change the attr', () => {
|
|
250
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
251
|
+
{
|
|
252
|
+
properties: {
|
|
253
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
254
|
+
hours: {
|
|
255
|
+
type: 'number',
|
|
256
|
+
description: 'Any value works.',
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
allOf: [
|
|
260
|
+
{
|
|
261
|
+
if: {
|
|
262
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
263
|
+
required: ['is_full_time'],
|
|
264
|
+
},
|
|
265
|
+
then: {
|
|
266
|
+
required: ['hours'],
|
|
267
|
+
},
|
|
268
|
+
else: {
|
|
269
|
+
properties: {
|
|
270
|
+
hours: false,
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
],
|
|
275
|
+
},
|
|
276
|
+
{ strictInputType: false }
|
|
277
|
+
);
|
|
278
|
+
|
|
279
|
+
// By default the attribute is set the base value, even though the field is invisible.
|
|
280
|
+
expect(fields[1].description).toBe('Any value works.');
|
|
281
|
+
expect(fields[1].isVisible).toBe(false);
|
|
282
|
+
|
|
283
|
+
// Given "Yes" it keeps the base value
|
|
284
|
+
expect(handleValidation({ is_full_time: 'yes' }).formErrors).toEqual({
|
|
285
|
+
hours: 'Required field',
|
|
286
|
+
});
|
|
287
|
+
expect(fields[1].description).toBe('Any value works.');
|
|
288
|
+
expect(fields[1].isVisible).toBe(true);
|
|
289
|
+
|
|
290
|
+
// Changing to "No" it keeps the base value
|
|
291
|
+
expect(handleValidation({ is_full_time: 'no' }).formErrors).toBeUndefined();
|
|
292
|
+
expect(fields[1].description).toBe('Any value works.');
|
|
293
|
+
expect(fields[1].isVisible).toBe(false);
|
|
294
|
+
});
|
|
295
|
+
|
|
296
|
+
it('Keeps internal attributes (fieldAttrsFromJsf)', () => {
|
|
297
|
+
// This is necessary while we keep supporting "type", even if deprecated
|
|
298
|
+
// otherwise our Remote app will break because it didn't migrate
|
|
299
|
+
// from "type" to "inputType" yet.
|
|
300
|
+
const { fields, handleValidation } = createHeadlessForm(
|
|
301
|
+
{
|
|
302
|
+
properties: {
|
|
303
|
+
is_full_time: { type: 'string', oneOf: [{ const: 'yes' }, { const: 'no' }] },
|
|
304
|
+
salary_period: {
|
|
305
|
+
type: 'string',
|
|
306
|
+
title: 'Salary period',
|
|
307
|
+
oneOf: [
|
|
308
|
+
{ title: 'Weekly', const: 'weekly' },
|
|
309
|
+
{ title: 'Monthly', const: 'monthly' },
|
|
310
|
+
],
|
|
311
|
+
},
|
|
312
|
+
},
|
|
313
|
+
allOf: [
|
|
314
|
+
{
|
|
315
|
+
if: {
|
|
316
|
+
properties: { is_full_time: { const: 'yes' } },
|
|
317
|
+
required: ['is_full_time'],
|
|
318
|
+
},
|
|
319
|
+
then: {
|
|
320
|
+
properties: {
|
|
321
|
+
salary_period: {
|
|
322
|
+
description: 'We recommend montlhy.',
|
|
323
|
+
},
|
|
324
|
+
},
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
],
|
|
328
|
+
},
|
|
329
|
+
{ strictInputType: false }
|
|
330
|
+
);
|
|
331
|
+
|
|
332
|
+
// Given "Yes" it keeps the "type"
|
|
333
|
+
handleValidation({ is_full_time: 'yes' });
|
|
334
|
+
|
|
335
|
+
// All the following attrs are never removed
|
|
336
|
+
// during conditionals because they are core.
|
|
337
|
+
expect(fields[1]).toMatchObject({
|
|
338
|
+
name: 'salary_period',
|
|
339
|
+
label: 'Salary period',
|
|
340
|
+
required: false,
|
|
341
|
+
type: 'radio',
|
|
342
|
+
inputType: 'radio',
|
|
343
|
+
jsonType: 'string',
|
|
344
|
+
computedAttributes: {},
|
|
345
|
+
calculateConditionalProperties: expect.any(Function),
|
|
346
|
+
schema: expect.any(Object),
|
|
347
|
+
scopedJsonSchema: expect.any(Object),
|
|
348
|
+
isVisible: true,
|
|
349
|
+
options: [
|
|
350
|
+
{
|
|
351
|
+
label: 'Weekly',
|
|
352
|
+
value: 'weekly',
|
|
353
|
+
},
|
|
354
|
+
{
|
|
355
|
+
label: 'Monthly',
|
|
356
|
+
value: 'monthly',
|
|
357
|
+
},
|
|
358
|
+
],
|
|
359
|
+
});
|
|
360
|
+
});
|
|
361
|
+
});
|
|
@@ -445,7 +445,7 @@ describe('createHeadlessForm', () => {
|
|
|
445
445
|
[fieldName]: 'The option "blah-blah" is not valid.',
|
|
446
446
|
});
|
|
447
447
|
|
|
448
|
-
// Given undefined, it says it's a
|
|
448
|
+
// Given undefined, it says it's a required field.
|
|
449
449
|
expect(validateForm({})).toEqual({
|
|
450
450
|
[fieldName]: 'Required field',
|
|
451
451
|
});
|
|
@@ -855,6 +855,7 @@ describe('createHeadlessForm', () => {
|
|
|
855
855
|
has_car: 'yes',
|
|
856
856
|
})
|
|
857
857
|
).toBeUndefined();
|
|
858
|
+
|
|
858
859
|
expect(validateForm({})).toEqual({
|
|
859
860
|
has_siblings: 'Required field',
|
|
860
861
|
});
|
|
@@ -1418,6 +1419,50 @@ describe('createHeadlessForm', () => {
|
|
|
1418
1419
|
],
|
|
1419
1420
|
});
|
|
1420
1421
|
});
|
|
1422
|
+
|
|
1423
|
+
it('can be a conditional field', () => {
|
|
1424
|
+
const { fields, handleValidation } = createHeadlessForm({
|
|
1425
|
+
properties: {
|
|
1426
|
+
yes_or_no: {
|
|
1427
|
+
title: 'Show the dependents or not?',
|
|
1428
|
+
oneOf: [{ const: 'yes' }, { const: 'no' }],
|
|
1429
|
+
'x-jsf-presentation': { inputType: 'radio' },
|
|
1430
|
+
},
|
|
1431
|
+
dependent_details: mockGroupArrayInput,
|
|
1432
|
+
},
|
|
1433
|
+
allOf: [
|
|
1434
|
+
{
|
|
1435
|
+
if: {
|
|
1436
|
+
properties: {
|
|
1437
|
+
yes_or_no: { const: 'yes' },
|
|
1438
|
+
},
|
|
1439
|
+
required: ['yes_or_no'],
|
|
1440
|
+
},
|
|
1441
|
+
then: {
|
|
1442
|
+
required: ['dependent_details'],
|
|
1443
|
+
},
|
|
1444
|
+
else: {
|
|
1445
|
+
properties: {
|
|
1446
|
+
dependent_details: false,
|
|
1447
|
+
},
|
|
1448
|
+
},
|
|
1449
|
+
},
|
|
1450
|
+
],
|
|
1451
|
+
});
|
|
1452
|
+
|
|
1453
|
+
// By default is hidden but the fields are accessible
|
|
1454
|
+
expect(getField(fields, 'dependent_details').isVisible).toBe(false);
|
|
1455
|
+
expect(getField(fields, 'dependent_details').fields).toEqual(expect.any(Function));
|
|
1456
|
+
|
|
1457
|
+
// When the condition matches...
|
|
1458
|
+
const { formErrors } = handleValidation({ yes_or_no: 'yes' });
|
|
1459
|
+
expect(formErrors).toEqual({
|
|
1460
|
+
dependent_details: 'Required field',
|
|
1461
|
+
});
|
|
1462
|
+
// it gets visible with its inner fields.
|
|
1463
|
+
expect(getField(fields, 'dependent_details').isVisible).toBe(true);
|
|
1464
|
+
expect(getField(fields, 'dependent_details').fields).toEqual(expect.any(Function));
|
|
1465
|
+
});
|
|
1421
1466
|
});
|
|
1422
1467
|
|
|
1423
1468
|
it('supports "radio" field type with its "card" and "card-expandable" variants', () => {
|
|
@@ -1762,11 +1807,8 @@ describe('createHeadlessForm', () => {
|
|
|
1762
1807
|
expect(foodField.options).toHaveLength(4);
|
|
1763
1808
|
// ...Food description was back to the original
|
|
1764
1809
|
expect(foodField.description).toBeUndefined();
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
expect(getField(fields, 'pto').description).toBe(
|
|
1768
|
-
'Above 30 hours, the PTO needs to be at least 20 days.'
|
|
1769
|
-
);
|
|
1810
|
+
// ...PTO Description is removed too.
|
|
1811
|
+
expect(getField(fields, 'pto').description).toBeUndefined();
|
|
1770
1812
|
|
|
1771
1813
|
// Given again "low perks", the form valid.
|
|
1772
1814
|
expect(
|