hs-uix 1.6.5 → 1.7.0
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/README.md +2 -0
- package/common-components.d.ts +152 -0
- package/dist/common-components.js +1385 -77
- package/dist/common-components.mjs +1438 -82
- package/dist/datatable.js +291 -239
- package/dist/datatable.mjs +207 -155
- package/dist/feed.js +939 -0
- package/dist/feed.mjs +927 -0
- package/dist/form.js +115 -93
- package/dist/form.mjs +115 -93
- package/dist/index.js +3529 -1060
- package/dist/index.mjs +3231 -770
- package/dist/kanban.js +286 -225
- package/dist/kanban.mjs +180 -119
- package/dist/utils.js +2906 -2
- package/dist/utils.mjs +2944 -1
- package/feed.d.ts +1 -0
- package/index.d.ts +51 -2
- package/package.json +17 -4
- package/packages/datatable/README.md +1046 -0
- package/packages/datatable/index.d.ts +246 -0
- package/packages/feed/README.md +224 -0
- package/packages/feed/index.d.ts +261 -0
- package/packages/form/README.md +1229 -0
- package/packages/form/index.d.ts +498 -0
- package/packages/kanban/README.md +707 -0
- package/packages/kanban/index.d.ts +367 -0
- package/utils.d.ts +122 -0
package/dist/form.js
CHANGED
|
@@ -38,6 +38,9 @@ module.exports = __toCommonJS(form_exports);
|
|
|
38
38
|
var import_react = __toESM(require("react"));
|
|
39
39
|
var import_ui_extensions = require("@hubspot/ui-extensions");
|
|
40
40
|
var import_crm = require("@hubspot/ui-extensions/crm");
|
|
41
|
+
|
|
42
|
+
// packages/form/src/formValues.js
|
|
43
|
+
var isPlainObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
41
44
|
var getEmptyValue = (field) => {
|
|
42
45
|
switch (field.type) {
|
|
43
46
|
case "toggle":
|
|
@@ -73,12 +76,6 @@ var isValueEmpty = (value, field) => {
|
|
|
73
76
|
if ((field.type === "toggle" || field.type === "checkbox") && value === false) return true;
|
|
74
77
|
return false;
|
|
75
78
|
};
|
|
76
|
-
var isPromise = (value) => value && typeof value.then === "function";
|
|
77
|
-
var isAsyncFunction = (fn) => fn && fn.constructor && fn.constructor.name === "AsyncFunction";
|
|
78
|
-
var normalizeValidatorResult = (result) => {
|
|
79
|
-
if (result === true || result === void 0 || result === null || result === false) return null;
|
|
80
|
-
return String(result);
|
|
81
|
-
};
|
|
82
79
|
var isDateValueObject = (value) => isPlainObject(value) && Number.isInteger(value.year) && Number.isInteger(value.month) && Number.isInteger(value.date);
|
|
83
80
|
var isTimeValueObject = (value) => isPlainObject(value) && Number.isInteger(value.hours) && Number.isInteger(value.minutes);
|
|
84
81
|
var compareDateValues = (a, b) => {
|
|
@@ -90,6 +87,64 @@ var compareTimeValues = (a, b) => {
|
|
|
90
87
|
if (a.hours !== b.hours) return a.hours - b.hours;
|
|
91
88
|
return a.minutes - b.minutes;
|
|
92
89
|
};
|
|
90
|
+
var deepEqual = (a, b) => {
|
|
91
|
+
if (Object.is(a, b)) return true;
|
|
92
|
+
if (typeof a !== typeof b) return false;
|
|
93
|
+
if (a == null || b == null) return false;
|
|
94
|
+
if (Array.isArray(a)) {
|
|
95
|
+
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
96
|
+
for (let i = 0; i < a.length; i++) {
|
|
97
|
+
if (!deepEqual(a[i], b[i])) return false;
|
|
98
|
+
}
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
if (a instanceof Date && b instanceof Date) {
|
|
102
|
+
return a.getTime() === b.getTime();
|
|
103
|
+
}
|
|
104
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
105
|
+
const aKeys = Object.keys(a);
|
|
106
|
+
const bKeys = Object.keys(b);
|
|
107
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
108
|
+
for (const key of aKeys) {
|
|
109
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
110
|
+
if (!deepEqual(a[key], b[key])) return false;
|
|
111
|
+
}
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
return false;
|
|
115
|
+
};
|
|
116
|
+
var deepClone = (value) => {
|
|
117
|
+
if (Array.isArray(value)) return value.map(deepClone);
|
|
118
|
+
if (value instanceof Date) return new Date(value.getTime());
|
|
119
|
+
if (isPlainObject(value)) {
|
|
120
|
+
const next = {};
|
|
121
|
+
for (const key of Object.keys(value)) {
|
|
122
|
+
next[key] = deepClone(value[key]);
|
|
123
|
+
}
|
|
124
|
+
return next;
|
|
125
|
+
}
|
|
126
|
+
return value;
|
|
127
|
+
};
|
|
128
|
+
|
|
129
|
+
// packages/form/src/formValidation.js
|
|
130
|
+
var isPromise = (value) => value && typeof value.then === "function";
|
|
131
|
+
var isAsyncFunction = (fn) => fn && fn.constructor && fn.constructor.name === "AsyncFunction";
|
|
132
|
+
var normalizeValidatorResult = (result) => {
|
|
133
|
+
if (result === true || result === void 0 || result === null || result === false) return null;
|
|
134
|
+
return String(result);
|
|
135
|
+
};
|
|
136
|
+
var resolveRequired = (field, allValues) => {
|
|
137
|
+
if (typeof field.required === "function") return field.required(allValues);
|
|
138
|
+
return !!field.required;
|
|
139
|
+
};
|
|
140
|
+
var resolveDisabled = (field, allValues) => {
|
|
141
|
+
if (typeof field.disabled === "function") return field.disabled(allValues);
|
|
142
|
+
return !!field.disabled;
|
|
143
|
+
};
|
|
144
|
+
var resolveOptions = (field, allValues) => {
|
|
145
|
+
if (typeof field.options === "function") return field.options(allValues);
|
|
146
|
+
return field.options || [];
|
|
147
|
+
};
|
|
93
148
|
var runDefaultFieldValidator = (value, field, allValues) => {
|
|
94
149
|
const errorPrefix = field.label || field.name;
|
|
95
150
|
switch (field.type) {
|
|
@@ -259,50 +314,53 @@ var runValidators = (value, field, allValues, fieldTypes, options = {}) => {
|
|
|
259
314
|
}
|
|
260
315
|
return null;
|
|
261
316
|
};
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
return !!field.required;
|
|
265
|
-
};
|
|
266
|
-
var resolveDisabled = (field, allValues) => {
|
|
267
|
-
if (typeof field.disabled === "function") return field.disabled(allValues);
|
|
268
|
-
return !!field.disabled;
|
|
269
|
-
};
|
|
270
|
-
var resolveOptions = (field, allValues) => {
|
|
271
|
-
if (typeof field.options === "function") return field.options(allValues);
|
|
272
|
-
return field.options || [];
|
|
273
|
-
};
|
|
317
|
+
|
|
318
|
+
// packages/form/src/formDependencies.js
|
|
274
319
|
var getDependsOnName = (field) => field.dependsOnConfig && field.dependsOnConfig.field;
|
|
275
320
|
var getDependsOnDisplay = (field) => field.dependsOnConfig && field.dependsOnConfig.display || "grouped";
|
|
276
321
|
var getDependsOnLabel = (field) => field.dependsOnConfig && field.dependsOnConfig.label;
|
|
277
322
|
var getDependsOnMessage = (field) => field.dependsOnConfig && field.dependsOnConfig.message;
|
|
278
|
-
var
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
if (!
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
323
|
+
var resolveDependentCascade = ({ name, value, fields, values, getEmptyValueForField }) => {
|
|
324
|
+
const newValues = { ...values, [name]: value };
|
|
325
|
+
const queue = [name];
|
|
326
|
+
const visited = /* @__PURE__ */ new Set();
|
|
327
|
+
const changedDependents = [];
|
|
328
|
+
while (queue.length > 0) {
|
|
329
|
+
const current = queue.shift();
|
|
330
|
+
if (!current || visited.has(current)) continue;
|
|
331
|
+
visited.add(current);
|
|
332
|
+
fields.forEach((dep) => {
|
|
333
|
+
const parentName = getDependsOnName(dep);
|
|
334
|
+
if (parentName !== current || dep.name === current) return;
|
|
335
|
+
if (!dep.options) return;
|
|
336
|
+
const depOptions = resolveOptions(dep, newValues);
|
|
337
|
+
const depValue = newValues[dep.name];
|
|
338
|
+
if (depValue == null || depValue === "") return;
|
|
339
|
+
const validValues = new Set(depOptions.map((o) => o.value));
|
|
340
|
+
let nextDepValue = depValue;
|
|
341
|
+
let changed = false;
|
|
342
|
+
if (Array.isArray(depValue)) {
|
|
343
|
+
const filtered = depValue.filter((v) => validValues.has(v));
|
|
344
|
+
if (filtered.length !== depValue.length) {
|
|
345
|
+
nextDepValue = filtered;
|
|
346
|
+
changed = true;
|
|
347
|
+
}
|
|
348
|
+
} else if (!validValues.has(depValue)) {
|
|
349
|
+
nextDepValue = getEmptyValueForField(dep);
|
|
350
|
+
changed = true;
|
|
351
|
+
}
|
|
352
|
+
if (changed) {
|
|
353
|
+
newValues[dep.name] = nextDepValue;
|
|
354
|
+
queue.push(dep.name);
|
|
355
|
+
changedDependents.push(dep.name);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
303
358
|
}
|
|
304
|
-
return
|
|
359
|
+
return { newValues, changedDependents };
|
|
305
360
|
};
|
|
361
|
+
|
|
362
|
+
// packages/form/src/FormBuilder.jsx
|
|
363
|
+
var getRepeaterErrorKey = (fieldName, rowIdx, subFieldName) => `${fieldName}[${rowIdx}].${subFieldName}`;
|
|
306
364
|
var fieldSetHasErrors = (errors, fields) => {
|
|
307
365
|
if (!errors || !fields || fields.length === 0) return false;
|
|
308
366
|
const names = new Set(fields.map((field) => field.name));
|
|
@@ -311,18 +369,6 @@ var fieldSetHasErrors = (errors, fields) => {
|
|
|
311
369
|
return names.has(base);
|
|
312
370
|
});
|
|
313
371
|
};
|
|
314
|
-
var deepClone = (value) => {
|
|
315
|
-
if (Array.isArray(value)) return value.map(deepClone);
|
|
316
|
-
if (value instanceof Date) return new Date(value.getTime());
|
|
317
|
-
if (isPlainObject(value)) {
|
|
318
|
-
const next = {};
|
|
319
|
-
for (const key of Object.keys(value)) {
|
|
320
|
-
next[key] = deepClone(value[key]);
|
|
321
|
-
}
|
|
322
|
-
return next;
|
|
323
|
-
}
|
|
324
|
-
return value;
|
|
325
|
-
};
|
|
326
372
|
var useFormPrefill = (properties, mapping) => {
|
|
327
373
|
return (0, import_react.useMemo)(() => {
|
|
328
374
|
if (!properties) return {};
|
|
@@ -1189,42 +1235,18 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
1189
1235
|
const handleFieldChange = (0, import_react.useCallback)(
|
|
1190
1236
|
(name, value, options = {}) => {
|
|
1191
1237
|
const { clearNestedErrors = true } = options;
|
|
1192
|
-
const
|
|
1193
|
-
|
|
1194
|
-
|
|
1238
|
+
const { newValues, changedDependents } = resolveDependentCascade({
|
|
1239
|
+
name,
|
|
1240
|
+
value,
|
|
1241
|
+
fields,
|
|
1242
|
+
values: formValuesRef.current,
|
|
1243
|
+
getEmptyValueForField: getFieldEmptyValue
|
|
1244
|
+
});
|
|
1195
1245
|
const clearedErrors = {};
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
fields.forEach((dep) => {
|
|
1201
|
-
const parentName = getDependsOnName(dep);
|
|
1202
|
-
if (parentName !== current || dep.name === current) return;
|
|
1203
|
-
if (!dep.options) return;
|
|
1204
|
-
const depOptions = resolveOptions(dep, newValues);
|
|
1205
|
-
const depValue = newValues[dep.name];
|
|
1206
|
-
if (depValue == null || depValue === "") return;
|
|
1207
|
-
const validValues = new Set(depOptions.map((o) => o.value));
|
|
1208
|
-
let nextDepValue = depValue;
|
|
1209
|
-
let changed = false;
|
|
1210
|
-
if (Array.isArray(depValue)) {
|
|
1211
|
-
const filtered = depValue.filter((v) => validValues.has(v));
|
|
1212
|
-
if (filtered.length !== depValue.length) {
|
|
1213
|
-
nextDepValue = filtered;
|
|
1214
|
-
changed = true;
|
|
1215
|
-
}
|
|
1216
|
-
} else if (!validValues.has(depValue)) {
|
|
1217
|
-
nextDepValue = getFieldEmptyValue(dep);
|
|
1218
|
-
changed = true;
|
|
1219
|
-
}
|
|
1220
|
-
if (changed) {
|
|
1221
|
-
newValues[dep.name] = nextDepValue;
|
|
1222
|
-
queue.push(dep.name);
|
|
1223
|
-
if (formErrorsRef.current[dep.name] != null) {
|
|
1224
|
-
clearedErrors[dep.name] = null;
|
|
1225
|
-
}
|
|
1226
|
-
}
|
|
1227
|
-
});
|
|
1246
|
+
for (const depName of changedDependents) {
|
|
1247
|
+
if (formErrorsRef.current[depName] != null) {
|
|
1248
|
+
clearedErrors[depName] = null;
|
|
1249
|
+
}
|
|
1228
1250
|
}
|
|
1229
1251
|
if (formErrorsRef.current[name] != null) {
|
|
1230
1252
|
clearedErrors[name] = null;
|
|
@@ -2042,7 +2064,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2042
2064
|
);
|
|
2043
2065
|
}
|
|
2044
2066
|
return /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Box, { key: sf.name, flex: 1 }, sfElement);
|
|
2045
|
-
}), /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Inline, { gap: "xs" }, canReorder &&
|
|
2067
|
+
}), /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Inline, { gap: "xs" }, canReorder && (renderMoveUpControl ? renderMoveUpControl({ index: rowIdx, disabled: rowIdx === 0, onClick: () => moveRow(rowIdx, rowIdx - 1) }) : /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Button, { variant: "secondary", size: "sm", disabled: rowIdx === 0, onClick: () => moveRow(rowIdx, rowIdx - 1) }, moveUpLabel)), canReorder && (renderMoveDownControl ? renderMoveDownControl({ index: rowIdx, disabled: rowIdx === rows.length - 1, onClick: () => moveRow(rowIdx, rowIdx + 1) }) : /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Button, { variant: "secondary", size: "sm", disabled: rowIdx === rows.length - 1, onClick: () => moveRow(rowIdx, rowIdx + 1) }, moveDownLabel)), canRemove && (renderRemoveControl ? renderRemoveControl({ index: rowIdx, onClick: () => removeRow(rowIdx) }) : /* @__PURE__ */ import_react.default.createElement(
|
|
2046
2068
|
import_ui_extensions.Button,
|
|
2047
2069
|
{
|
|
2048
2070
|
variant: "secondary",
|
|
@@ -2050,7 +2072,7 @@ var FormBuilder = (0, import_react.forwardRef)(function FormBuilder2(props, ref)
|
|
|
2050
2072
|
onClick: () => removeRow(rowIdx)
|
|
2051
2073
|
},
|
|
2052
2074
|
removeLabel
|
|
2053
|
-
))))), canAdd && (renderAddControl ? renderAddControl({ onClick: addRow, count: rows.length }) : /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Link, { onClick: addRow }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "row", align: "center", gap: "
|
|
2075
|
+
))))), canAdd && (renderAddControl ? renderAddControl({ onClick: addRow, count: rows.length }) : /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Link, { onClick: addRow }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Icon, { name: "add" }), /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { format: { fontWeight: "demibold" } }, addLabel)))), repeaterHasError && repeaterErrorMessage && /* @__PURE__ */ import_react.default.createElement(import_ui_extensions.Text, { variant: "microcopy" }, repeaterErrorMessage));
|
|
2054
2076
|
}
|
|
2055
2077
|
default:
|
|
2056
2078
|
return /* @__PURE__ */ import_react.default.createElement(
|
package/dist/form.mjs
CHANGED
|
@@ -42,6 +42,9 @@ import {
|
|
|
42
42
|
CrmPropertyList,
|
|
43
43
|
CrmAssociationPropertyList
|
|
44
44
|
} from "@hubspot/ui-extensions/crm";
|
|
45
|
+
|
|
46
|
+
// packages/form/src/formValues.js
|
|
47
|
+
var isPlainObject = (value) => Object.prototype.toString.call(value) === "[object Object]";
|
|
45
48
|
var getEmptyValue = (field) => {
|
|
46
49
|
switch (field.type) {
|
|
47
50
|
case "toggle":
|
|
@@ -77,12 +80,6 @@ var isValueEmpty = (value, field) => {
|
|
|
77
80
|
if ((field.type === "toggle" || field.type === "checkbox") && value === false) return true;
|
|
78
81
|
return false;
|
|
79
82
|
};
|
|
80
|
-
var isPromise = (value) => value && typeof value.then === "function";
|
|
81
|
-
var isAsyncFunction = (fn) => fn && fn.constructor && fn.constructor.name === "AsyncFunction";
|
|
82
|
-
var normalizeValidatorResult = (result) => {
|
|
83
|
-
if (result === true || result === void 0 || result === null || result === false) return null;
|
|
84
|
-
return String(result);
|
|
85
|
-
};
|
|
86
83
|
var isDateValueObject = (value) => isPlainObject(value) && Number.isInteger(value.year) && Number.isInteger(value.month) && Number.isInteger(value.date);
|
|
87
84
|
var isTimeValueObject = (value) => isPlainObject(value) && Number.isInteger(value.hours) && Number.isInteger(value.minutes);
|
|
88
85
|
var compareDateValues = (a, b) => {
|
|
@@ -94,6 +91,64 @@ var compareTimeValues = (a, b) => {
|
|
|
94
91
|
if (a.hours !== b.hours) return a.hours - b.hours;
|
|
95
92
|
return a.minutes - b.minutes;
|
|
96
93
|
};
|
|
94
|
+
var deepEqual = (a, b) => {
|
|
95
|
+
if (Object.is(a, b)) return true;
|
|
96
|
+
if (typeof a !== typeof b) return false;
|
|
97
|
+
if (a == null || b == null) return false;
|
|
98
|
+
if (Array.isArray(a)) {
|
|
99
|
+
if (!Array.isArray(b) || a.length !== b.length) return false;
|
|
100
|
+
for (let i = 0; i < a.length; i++) {
|
|
101
|
+
if (!deepEqual(a[i], b[i])) return false;
|
|
102
|
+
}
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
if (a instanceof Date && b instanceof Date) {
|
|
106
|
+
return a.getTime() === b.getTime();
|
|
107
|
+
}
|
|
108
|
+
if (isPlainObject(a) && isPlainObject(b)) {
|
|
109
|
+
const aKeys = Object.keys(a);
|
|
110
|
+
const bKeys = Object.keys(b);
|
|
111
|
+
if (aKeys.length !== bKeys.length) return false;
|
|
112
|
+
for (const key of aKeys) {
|
|
113
|
+
if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
|
|
114
|
+
if (!deepEqual(a[key], b[key])) return false;
|
|
115
|
+
}
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
return false;
|
|
119
|
+
};
|
|
120
|
+
var deepClone = (value) => {
|
|
121
|
+
if (Array.isArray(value)) return value.map(deepClone);
|
|
122
|
+
if (value instanceof Date) return new Date(value.getTime());
|
|
123
|
+
if (isPlainObject(value)) {
|
|
124
|
+
const next = {};
|
|
125
|
+
for (const key of Object.keys(value)) {
|
|
126
|
+
next[key] = deepClone(value[key]);
|
|
127
|
+
}
|
|
128
|
+
return next;
|
|
129
|
+
}
|
|
130
|
+
return value;
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// packages/form/src/formValidation.js
|
|
134
|
+
var isPromise = (value) => value && typeof value.then === "function";
|
|
135
|
+
var isAsyncFunction = (fn) => fn && fn.constructor && fn.constructor.name === "AsyncFunction";
|
|
136
|
+
var normalizeValidatorResult = (result) => {
|
|
137
|
+
if (result === true || result === void 0 || result === null || result === false) return null;
|
|
138
|
+
return String(result);
|
|
139
|
+
};
|
|
140
|
+
var resolveRequired = (field, allValues) => {
|
|
141
|
+
if (typeof field.required === "function") return field.required(allValues);
|
|
142
|
+
return !!field.required;
|
|
143
|
+
};
|
|
144
|
+
var resolveDisabled = (field, allValues) => {
|
|
145
|
+
if (typeof field.disabled === "function") return field.disabled(allValues);
|
|
146
|
+
return !!field.disabled;
|
|
147
|
+
};
|
|
148
|
+
var resolveOptions = (field, allValues) => {
|
|
149
|
+
if (typeof field.options === "function") return field.options(allValues);
|
|
150
|
+
return field.options || [];
|
|
151
|
+
};
|
|
97
152
|
var runDefaultFieldValidator = (value, field, allValues) => {
|
|
98
153
|
const errorPrefix = field.label || field.name;
|
|
99
154
|
switch (field.type) {
|
|
@@ -263,50 +318,53 @@ var runValidators = (value, field, allValues, fieldTypes, options = {}) => {
|
|
|
263
318
|
}
|
|
264
319
|
return null;
|
|
265
320
|
};
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
return !!field.required;
|
|
269
|
-
};
|
|
270
|
-
var resolveDisabled = (field, allValues) => {
|
|
271
|
-
if (typeof field.disabled === "function") return field.disabled(allValues);
|
|
272
|
-
return !!field.disabled;
|
|
273
|
-
};
|
|
274
|
-
var resolveOptions = (field, allValues) => {
|
|
275
|
-
if (typeof field.options === "function") return field.options(allValues);
|
|
276
|
-
return field.options || [];
|
|
277
|
-
};
|
|
321
|
+
|
|
322
|
+
// packages/form/src/formDependencies.js
|
|
278
323
|
var getDependsOnName = (field) => field.dependsOnConfig && field.dependsOnConfig.field;
|
|
279
324
|
var getDependsOnDisplay = (field) => field.dependsOnConfig && field.dependsOnConfig.display || "grouped";
|
|
280
325
|
var getDependsOnLabel = (field) => field.dependsOnConfig && field.dependsOnConfig.label;
|
|
281
326
|
var getDependsOnMessage = (field) => field.dependsOnConfig && field.dependsOnConfig.message;
|
|
282
|
-
var
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
if (!
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
327
|
+
var resolveDependentCascade = ({ name, value, fields, values, getEmptyValueForField }) => {
|
|
328
|
+
const newValues = { ...values, [name]: value };
|
|
329
|
+
const queue = [name];
|
|
330
|
+
const visited = /* @__PURE__ */ new Set();
|
|
331
|
+
const changedDependents = [];
|
|
332
|
+
while (queue.length > 0) {
|
|
333
|
+
const current = queue.shift();
|
|
334
|
+
if (!current || visited.has(current)) continue;
|
|
335
|
+
visited.add(current);
|
|
336
|
+
fields.forEach((dep) => {
|
|
337
|
+
const parentName = getDependsOnName(dep);
|
|
338
|
+
if (parentName !== current || dep.name === current) return;
|
|
339
|
+
if (!dep.options) return;
|
|
340
|
+
const depOptions = resolveOptions(dep, newValues);
|
|
341
|
+
const depValue = newValues[dep.name];
|
|
342
|
+
if (depValue == null || depValue === "") return;
|
|
343
|
+
const validValues = new Set(depOptions.map((o) => o.value));
|
|
344
|
+
let nextDepValue = depValue;
|
|
345
|
+
let changed = false;
|
|
346
|
+
if (Array.isArray(depValue)) {
|
|
347
|
+
const filtered = depValue.filter((v) => validValues.has(v));
|
|
348
|
+
if (filtered.length !== depValue.length) {
|
|
349
|
+
nextDepValue = filtered;
|
|
350
|
+
changed = true;
|
|
351
|
+
}
|
|
352
|
+
} else if (!validValues.has(depValue)) {
|
|
353
|
+
nextDepValue = getEmptyValueForField(dep);
|
|
354
|
+
changed = true;
|
|
355
|
+
}
|
|
356
|
+
if (changed) {
|
|
357
|
+
newValues[dep.name] = nextDepValue;
|
|
358
|
+
queue.push(dep.name);
|
|
359
|
+
changedDependents.push(dep.name);
|
|
360
|
+
}
|
|
361
|
+
});
|
|
307
362
|
}
|
|
308
|
-
return
|
|
363
|
+
return { newValues, changedDependents };
|
|
309
364
|
};
|
|
365
|
+
|
|
366
|
+
// packages/form/src/FormBuilder.jsx
|
|
367
|
+
var getRepeaterErrorKey = (fieldName, rowIdx, subFieldName) => `${fieldName}[${rowIdx}].${subFieldName}`;
|
|
310
368
|
var fieldSetHasErrors = (errors, fields) => {
|
|
311
369
|
if (!errors || !fields || fields.length === 0) return false;
|
|
312
370
|
const names = new Set(fields.map((field) => field.name));
|
|
@@ -315,18 +373,6 @@ var fieldSetHasErrors = (errors, fields) => {
|
|
|
315
373
|
return names.has(base);
|
|
316
374
|
});
|
|
317
375
|
};
|
|
318
|
-
var deepClone = (value) => {
|
|
319
|
-
if (Array.isArray(value)) return value.map(deepClone);
|
|
320
|
-
if (value instanceof Date) return new Date(value.getTime());
|
|
321
|
-
if (isPlainObject(value)) {
|
|
322
|
-
const next = {};
|
|
323
|
-
for (const key of Object.keys(value)) {
|
|
324
|
-
next[key] = deepClone(value[key]);
|
|
325
|
-
}
|
|
326
|
-
return next;
|
|
327
|
-
}
|
|
328
|
-
return value;
|
|
329
|
-
};
|
|
330
376
|
var useFormPrefill = (properties, mapping) => {
|
|
331
377
|
return useMemo(() => {
|
|
332
378
|
if (!properties) return {};
|
|
@@ -1193,42 +1239,18 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
1193
1239
|
const handleFieldChange = useCallback(
|
|
1194
1240
|
(name, value, options = {}) => {
|
|
1195
1241
|
const { clearNestedErrors = true } = options;
|
|
1196
|
-
const
|
|
1197
|
-
|
|
1198
|
-
|
|
1242
|
+
const { newValues, changedDependents } = resolveDependentCascade({
|
|
1243
|
+
name,
|
|
1244
|
+
value,
|
|
1245
|
+
fields,
|
|
1246
|
+
values: formValuesRef.current,
|
|
1247
|
+
getEmptyValueForField: getFieldEmptyValue
|
|
1248
|
+
});
|
|
1199
1249
|
const clearedErrors = {};
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
fields.forEach((dep) => {
|
|
1205
|
-
const parentName = getDependsOnName(dep);
|
|
1206
|
-
if (parentName !== current || dep.name === current) return;
|
|
1207
|
-
if (!dep.options) return;
|
|
1208
|
-
const depOptions = resolveOptions(dep, newValues);
|
|
1209
|
-
const depValue = newValues[dep.name];
|
|
1210
|
-
if (depValue == null || depValue === "") return;
|
|
1211
|
-
const validValues = new Set(depOptions.map((o) => o.value));
|
|
1212
|
-
let nextDepValue = depValue;
|
|
1213
|
-
let changed = false;
|
|
1214
|
-
if (Array.isArray(depValue)) {
|
|
1215
|
-
const filtered = depValue.filter((v) => validValues.has(v));
|
|
1216
|
-
if (filtered.length !== depValue.length) {
|
|
1217
|
-
nextDepValue = filtered;
|
|
1218
|
-
changed = true;
|
|
1219
|
-
}
|
|
1220
|
-
} else if (!validValues.has(depValue)) {
|
|
1221
|
-
nextDepValue = getFieldEmptyValue(dep);
|
|
1222
|
-
changed = true;
|
|
1223
|
-
}
|
|
1224
|
-
if (changed) {
|
|
1225
|
-
newValues[dep.name] = nextDepValue;
|
|
1226
|
-
queue.push(dep.name);
|
|
1227
|
-
if (formErrorsRef.current[dep.name] != null) {
|
|
1228
|
-
clearedErrors[dep.name] = null;
|
|
1229
|
-
}
|
|
1230
|
-
}
|
|
1231
|
-
});
|
|
1250
|
+
for (const depName of changedDependents) {
|
|
1251
|
+
if (formErrorsRef.current[depName] != null) {
|
|
1252
|
+
clearedErrors[depName] = null;
|
|
1253
|
+
}
|
|
1232
1254
|
}
|
|
1233
1255
|
if (formErrorsRef.current[name] != null) {
|
|
1234
1256
|
clearedErrors[name] = null;
|
|
@@ -2046,7 +2068,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2046
2068
|
);
|
|
2047
2069
|
}
|
|
2048
2070
|
return /* @__PURE__ */ React.createElement(Box, { key: sf.name, flex: 1 }, sfElement);
|
|
2049
|
-
}), /* @__PURE__ */ React.createElement(Inline, { gap: "xs" }, canReorder &&
|
|
2071
|
+
}), /* @__PURE__ */ React.createElement(Inline, { gap: "xs" }, canReorder && (renderMoveUpControl ? renderMoveUpControl({ index: rowIdx, disabled: rowIdx === 0, onClick: () => moveRow(rowIdx, rowIdx - 1) }) : /* @__PURE__ */ React.createElement(Button, { variant: "secondary", size: "sm", disabled: rowIdx === 0, onClick: () => moveRow(rowIdx, rowIdx - 1) }, moveUpLabel)), canReorder && (renderMoveDownControl ? renderMoveDownControl({ index: rowIdx, disabled: rowIdx === rows.length - 1, onClick: () => moveRow(rowIdx, rowIdx + 1) }) : /* @__PURE__ */ React.createElement(Button, { variant: "secondary", size: "sm", disabled: rowIdx === rows.length - 1, onClick: () => moveRow(rowIdx, rowIdx + 1) }, moveDownLabel)), canRemove && (renderRemoveControl ? renderRemoveControl({ index: rowIdx, onClick: () => removeRow(rowIdx) }) : /* @__PURE__ */ React.createElement(
|
|
2050
2072
|
Button,
|
|
2051
2073
|
{
|
|
2052
2074
|
variant: "secondary",
|
|
@@ -2054,7 +2076,7 @@ var FormBuilder = forwardRef(function FormBuilder2(props, ref) {
|
|
|
2054
2076
|
onClick: () => removeRow(rowIdx)
|
|
2055
2077
|
},
|
|
2056
2078
|
removeLabel
|
|
2057
|
-
))))), canAdd && (renderAddControl ? renderAddControl({ onClick: addRow, count: rows.length }) : /* @__PURE__ */ React.createElement(Link, { onClick: addRow }, /* @__PURE__ */ React.createElement(Flex, { direction: "row", align: "center", gap: "
|
|
2079
|
+
))))), canAdd && (renderAddControl ? renderAddControl({ onClick: addRow, count: rows.length }) : /* @__PURE__ */ React.createElement(Link, { onClick: addRow }, /* @__PURE__ */ React.createElement(Flex, { direction: "row", align: "center", gap: "xs" }, /* @__PURE__ */ React.createElement(Icon, { name: "add" }), /* @__PURE__ */ React.createElement(Text, { format: { fontWeight: "demibold" } }, addLabel)))), repeaterHasError && repeaterErrorMessage && /* @__PURE__ */ React.createElement(Text, { variant: "microcopy" }, repeaterErrorMessage));
|
|
2058
2080
|
}
|
|
2059
2081
|
default:
|
|
2060
2082
|
return /* @__PURE__ */ React.createElement(
|