react-luna-form 0.0.25 → 0.0.27
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/dist/client/cjs/index.js +927 -447
- package/dist/client/esm/index.js +916 -436
- package/dist/server/cjs/index.js +462 -101
- package/dist/server/esm/index.js +463 -102
- package/dist/types/luna-core/src/handle/state-event.d.ts +1 -1
- package/dist/types/luna-core/src/index.d.ts +1 -0
- package/dist/types/luna-core/src/type.d.ts +17 -2
- package/dist/types/luna-core/src/util/constant.d.ts +4 -0
- package/dist/types/luna-core/src/util/extract.d.ts +2 -1
- package/dist/types/luna-core/src/util/is-input.d.ts +4 -3
- package/dist/types/luna-core/src/util/is-type.d.ts +1 -0
- package/dist/types/luna-core/src/util/list.d.ts +4 -0
- package/dist/types/luna-core/src/util/prepare.d.ts +2 -2
- package/dist/types/luna-core/src/util/string.d.ts +1 -0
- package/dist/types/luna-react/src/client/component/field/field-list.d.ts +2 -0
- package/dist/types/luna-react/src/client/component/{wrapper/with-error.d.ts → field/field-with-error.d.ts} +1 -1
- package/dist/types/luna-react/src/client/component/{wrapper/with-field-state.d.ts → field/field-with-state.d.ts} +1 -1
- package/dist/types/luna-react/src/client/component/guard/list-guard.d.ts +2 -0
- package/dist/types/luna-react/src/client/component/guard/visibility-guard.d.ts +6 -0
- package/dist/types/luna-react/src/client/component/slot/slot.d.ts +7 -0
- package/dist/types/luna-react/src/client/hook/use-field-list.d.ts +2 -0
- package/dist/types/luna-react/src/component/chevron-icon.d.ts +3 -0
- package/dist/types/luna-react/src/component/column.d.ts +2 -3
- package/dist/types/luna-react/src/component/field/field-base.d.ts +4 -2
- package/dist/types/luna-react/src/component/field/field-horizontal.d.ts +2 -8
- package/dist/types/luna-react/src/component/field/field-list-item.d.ts +8 -0
- package/dist/types/luna-react/src/component/field/field-list.d.ts +7 -0
- package/dist/types/luna-react/src/component/field/field-set-advanced.d.ts +5 -0
- package/dist/types/luna-react/src/component/field/field-set-base.d.ts +7 -0
- package/dist/types/luna-react/src/component/field/field-vertical.d.ts +2 -8
- package/dist/types/luna-react/src/component/list.d.ts +5 -0
- package/dist/types/luna-react/src/component/slot/list-slot.d.ts +2 -0
- package/dist/types/luna-react/src/component/slot/slot-base.d.ts +8 -6
- package/dist/types/luna-react/src/component/slot/slot-create.d.ts +4 -3
- package/dist/types/luna-react/src/component/slot/slot-list.d.ts +12 -0
- package/dist/types/luna-react/src/component/slot/slot.d.ts +1 -0
- package/package.json +5 -5
- package/dist/types/luna-react/src/component/input/input-attributes.d.ts +0 -3
- package/dist/types/luna-react/src/component/input/input-common.d.ts +0 -2
- package/dist/types/luna-react/src/component/input/input-option-select.d.ts +0 -5
- /package/dist/types/luna-react/src/client/component/{wrapper/index.d.ts → field/field.d.ts} +0 -0
package/dist/client/esm/index.js
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
|
-
// src/component/
|
|
1
|
+
// src/component/control.tsx
|
|
2
2
|
import { jsx } from "react/jsx-runtime";
|
|
3
|
-
function
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
function Control(props) {
|
|
4
|
+
const content = typeof props.children === "function" ? props.children({ isPending: props.isPending }) : props.children;
|
|
5
|
+
return /* @__PURE__ */ jsx("div", { "data-slot": "field-control", className: "w-full", children: content });
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// src/component/field/field-set-advanced.tsx
|
|
9
|
+
import { Activity, useCallback, useState } from "react";
|
|
10
|
+
|
|
11
|
+
// src/component/chevron-icon.tsx
|
|
12
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
13
|
+
function ChevronIcon(props) {
|
|
14
|
+
return /* @__PURE__ */ jsx2(
|
|
15
|
+
"svg",
|
|
9
16
|
{
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
17
|
+
xmlns: "http://www.w3.org/2000/svg",
|
|
18
|
+
viewBox: "0 0 20 20",
|
|
19
|
+
fill: "currentColor",
|
|
20
|
+
className: `size-4 transition-transform duration-200 ${props.expanded ? "rotate-90" : ""}`,
|
|
21
|
+
children: /* @__PURE__ */ jsx2(
|
|
22
|
+
"path",
|
|
23
|
+
{
|
|
24
|
+
fillRule: "evenodd",
|
|
25
|
+
d: "M8.22 5.22a.75.75 0 0 1 1.06 0l4.25 4.25a.75.75 0 0 1 0 1.06l-4.25 4.25a.75.75 0 0 1-1.06-1.06L11.94 10 8.22 6.28a.75.75 0 0 1 0-1.06Z",
|
|
26
|
+
clipRule: "evenodd"
|
|
27
|
+
}
|
|
28
|
+
)
|
|
13
29
|
}
|
|
14
30
|
);
|
|
15
31
|
}
|
|
@@ -21,10 +37,12 @@ var INPUT_NUMBER = "input/number";
|
|
|
21
37
|
var TEXTAREA = "textarea";
|
|
22
38
|
var RADIO = "radio";
|
|
23
39
|
var CHECKBOX = "checkbox";
|
|
40
|
+
var LIST = "list";
|
|
24
41
|
var SELECT = "select";
|
|
25
42
|
var SELECT_MONTH = "select/month";
|
|
26
43
|
var SELECT_YEAR = "select/year";
|
|
27
44
|
var COLUMN = "column";
|
|
45
|
+
var FIELDS = "fields";
|
|
28
46
|
var LABEL = "label";
|
|
29
47
|
var VALUE = "value";
|
|
30
48
|
var OPTIONS = "options";
|
|
@@ -49,6 +67,7 @@ var STATE = "state";
|
|
|
49
67
|
var COMMON_URL = "http://luna.internal";
|
|
50
68
|
var VERTICAL = "vertical";
|
|
51
69
|
var HORIZONTAL = "horizontal";
|
|
70
|
+
var TYPE = "type";
|
|
52
71
|
|
|
53
72
|
// ../luna-core/src/util/is-type.ts
|
|
54
73
|
function isObject(value) {
|
|
@@ -58,7 +77,7 @@ function isEmpty(value) {
|
|
|
58
77
|
return value === null || value === void 0 || value === "";
|
|
59
78
|
}
|
|
60
79
|
function isValue(value) {
|
|
61
|
-
return
|
|
80
|
+
return isString(value) || typeof value === "number" || isBoolean(value);
|
|
62
81
|
}
|
|
63
82
|
function isString(value) {
|
|
64
83
|
return typeof value === "string";
|
|
@@ -66,9 +85,13 @@ function isString(value) {
|
|
|
66
85
|
function isDataSource(value) {
|
|
67
86
|
return isObject(value) && "url" in value;
|
|
68
87
|
}
|
|
88
|
+
function isBoolean(value) {
|
|
89
|
+
return typeof value === "boolean";
|
|
90
|
+
}
|
|
69
91
|
|
|
70
92
|
// ../luna-core/src/util/extract.ts
|
|
71
93
|
var REGEX_TYPE = /[^/]+$/;
|
|
94
|
+
var REGEX_NUMERIC = /^\d+$/;
|
|
72
95
|
function getEntity(selected, collection = [], entity = VALUE) {
|
|
73
96
|
if (Array.isArray(collection)) {
|
|
74
97
|
return collection.find((item) => {
|
|
@@ -78,6 +101,7 @@ function getEntity(selected, collection = [], entity = VALUE) {
|
|
|
78
101
|
}
|
|
79
102
|
}) ?? { value: selected };
|
|
80
103
|
}
|
|
104
|
+
return { value: selected };
|
|
81
105
|
}
|
|
82
106
|
function getCurrentValue(value, entity = VALUE) {
|
|
83
107
|
if (value !== null && value !== void 0) {
|
|
@@ -162,6 +186,46 @@ function getFormData(formData) {
|
|
|
162
186
|
}
|
|
163
187
|
return data;
|
|
164
188
|
}
|
|
189
|
+
function unflatten(data) {
|
|
190
|
+
const result = {};
|
|
191
|
+
for (const key in data) {
|
|
192
|
+
const parts = key.split(".");
|
|
193
|
+
if (parts.length === 1) {
|
|
194
|
+
result[key] = data[key];
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
let current = result;
|
|
198
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
199
|
+
const part = parts[i];
|
|
200
|
+
const next = parts[i + 1];
|
|
201
|
+
const isNextIndex = REGEX_NUMERIC.test(next);
|
|
202
|
+
if (!(part in current)) {
|
|
203
|
+
current[part] = isNextIndex ? [] : {};
|
|
204
|
+
}
|
|
205
|
+
current = current[part];
|
|
206
|
+
}
|
|
207
|
+
const last = parts[parts.length - 1];
|
|
208
|
+
current[last] = data[key];
|
|
209
|
+
}
|
|
210
|
+
compactArrays(result);
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
function compactArrays(obj) {
|
|
214
|
+
for (const key in obj) {
|
|
215
|
+
const value = obj[key];
|
|
216
|
+
if (Array.isArray(value)) {
|
|
217
|
+
const compacted = value.filter((item) => item !== void 0);
|
|
218
|
+
compacted.forEach((item) => {
|
|
219
|
+
if (item !== null && typeof item === "object" && !Array.isArray(item)) {
|
|
220
|
+
compactArrays(item);
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
obj[key] = compacted;
|
|
224
|
+
} else if (value !== null && typeof value === "object") {
|
|
225
|
+
compactArrays(value);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
165
229
|
|
|
166
230
|
// ../luna-core/src/util/string.ts
|
|
167
231
|
var REGEX_MARKDOWN_LINK = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
@@ -183,6 +247,9 @@ function interpolate(template, values = {}) {
|
|
|
183
247
|
}
|
|
184
248
|
return template;
|
|
185
249
|
}
|
|
250
|
+
function interpolateIfNeeded(template, values = {}) {
|
|
251
|
+
return isInterpolated(template) ? interpolate(template, values) : template;
|
|
252
|
+
}
|
|
186
253
|
function isInterpolated(template) {
|
|
187
254
|
if (isString(template)) {
|
|
188
255
|
return /{([^}]+)}/.test(template);
|
|
@@ -259,7 +326,7 @@ function handleProxyEvent(events = [], callback) {
|
|
|
259
326
|
const values = [];
|
|
260
327
|
const sources = [];
|
|
261
328
|
const states = [];
|
|
262
|
-
|
|
329
|
+
for (const event of events) {
|
|
263
330
|
if (event.action === VALUE) {
|
|
264
331
|
values.push(event);
|
|
265
332
|
}
|
|
@@ -269,17 +336,17 @@ function handleProxyEvent(events = [], callback) {
|
|
|
269
336
|
if (event.action === STATE) {
|
|
270
337
|
states.push(event);
|
|
271
338
|
}
|
|
272
|
-
}
|
|
339
|
+
}
|
|
273
340
|
callback({ sources, states, values });
|
|
274
341
|
}
|
|
275
342
|
|
|
276
343
|
// ../luna-core/src/handle/source-event.ts
|
|
277
344
|
function handleSourceEvent(selected = null, events = [], setSource) {
|
|
278
|
-
|
|
345
|
+
for (const event of events) {
|
|
279
346
|
const { target, source } = event;
|
|
280
347
|
if (!selected) {
|
|
281
348
|
setSource(target, void 0);
|
|
282
|
-
|
|
349
|
+
continue;
|
|
283
350
|
}
|
|
284
351
|
if (isDataSource(source)) {
|
|
285
352
|
const newUrl = interpolate(source.url, selected);
|
|
@@ -290,7 +357,7 @@ function handleSourceEvent(selected = null, events = [], setSource) {
|
|
|
290
357
|
body: newBody
|
|
291
358
|
});
|
|
292
359
|
}
|
|
293
|
-
}
|
|
360
|
+
}
|
|
294
361
|
}
|
|
295
362
|
|
|
296
363
|
// ../luna-core/src/util/operator.ts
|
|
@@ -363,31 +430,39 @@ function lte(current, value) {
|
|
|
363
430
|
|
|
364
431
|
// ../luna-core/src/handle/state-event.ts
|
|
365
432
|
function handleStateEvent(selected = null, events = [], setState) {
|
|
366
|
-
|
|
433
|
+
for (const event of events) {
|
|
367
434
|
const { target, state, when } = event;
|
|
435
|
+
const targets = Array.isArray(target) ? target : [target];
|
|
368
436
|
if (!selected) {
|
|
369
|
-
setState(
|
|
370
|
-
|
|
437
|
+
setState(targets);
|
|
438
|
+
continue;
|
|
371
439
|
}
|
|
440
|
+
logger.info(`Selected value for state event: ${JSON.stringify(selected)}, evaluating condition: ${JSON.stringify(when)}`);
|
|
372
441
|
const matches = evaluateCondition(selected, when);
|
|
373
|
-
|
|
374
|
-
|
|
442
|
+
logger.info(`Condition evaluated to: ${matches}, setting state for targets: ${targets.join(", ")}`);
|
|
443
|
+
setState(targets, matches ? state : void 0);
|
|
444
|
+
}
|
|
375
445
|
}
|
|
376
446
|
function evaluateCondition(selected, when) {
|
|
377
447
|
if (when === void 0) {
|
|
378
448
|
return true;
|
|
379
449
|
}
|
|
380
450
|
if (isString(when)) {
|
|
381
|
-
|
|
451
|
+
logger.info(`Evaluating string condition: ${when} against selected value: ${JSON.stringify(selected)} using VALUE field`);
|
|
452
|
+
logger.info(`Extracted value for comparison: ${JSON.stringify(getValue2(selected, VALUE))}`);
|
|
453
|
+
logger.info(`Comparison result: ${getValue2(selected, VALUE) === when}`);
|
|
454
|
+
return getValue2(selected, VALUE) === when;
|
|
455
|
+
}
|
|
456
|
+
if (isBoolean(when)) {
|
|
457
|
+
return Boolean(getValue2(selected, VALUE)) === when;
|
|
382
458
|
}
|
|
383
459
|
if (Array.isArray(when)) {
|
|
384
|
-
|
|
385
|
-
return when.includes(String(current));
|
|
460
|
+
return when.includes(String(getValue2(selected, VALUE)));
|
|
386
461
|
}
|
|
387
462
|
return evaluateOperator(selected, when);
|
|
388
463
|
}
|
|
389
464
|
function evaluateOperator(selected = null, condition) {
|
|
390
|
-
const current = getValue2(selected, condition.field ??
|
|
465
|
+
const current = getValue2(selected, condition.field ?? VALUE);
|
|
391
466
|
const { operator = "eq", value } = condition;
|
|
392
467
|
const operation = operators[operator];
|
|
393
468
|
if (operation) {
|
|
@@ -397,18 +472,18 @@ function evaluateOperator(selected = null, condition) {
|
|
|
397
472
|
}
|
|
398
473
|
function getValue2(selected, field) {
|
|
399
474
|
if (isObject(selected)) {
|
|
400
|
-
return
|
|
475
|
+
return extract(selected, field);
|
|
401
476
|
}
|
|
402
477
|
return selected;
|
|
403
478
|
}
|
|
404
479
|
|
|
405
480
|
// ../luna-core/src/handle/value-event.ts
|
|
406
481
|
function handleValueEvent(selected = null, events = [], setValue) {
|
|
407
|
-
|
|
408
|
-
Object.entries(event.value)
|
|
482
|
+
for (const event of events) {
|
|
483
|
+
for (const [target, value] of Object.entries(event.value)) {
|
|
409
484
|
setValue(target, selected ? interpolate(value, selected) : void 0);
|
|
410
|
-
}
|
|
411
|
-
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
412
487
|
}
|
|
413
488
|
|
|
414
489
|
// ../luna-core/src/util/is-input.ts
|
|
@@ -430,11 +505,14 @@ var isNumber = createTypeChecker(INPUT_NUMBER, TYPE_NUMBER);
|
|
|
430
505
|
function isClickable(field) {
|
|
431
506
|
return isRadio(field) || isCheckbox(field);
|
|
432
507
|
}
|
|
508
|
+
function isList(slot) {
|
|
509
|
+
return slot.type === LIST;
|
|
510
|
+
}
|
|
433
511
|
function isColumn(slot) {
|
|
434
512
|
return slot.type === COLUMN;
|
|
435
513
|
}
|
|
436
514
|
function isField(slot) {
|
|
437
|
-
return slot.type !== COLUMN;
|
|
515
|
+
return slot.type !== COLUMN && slot.type !== LIST;
|
|
438
516
|
}
|
|
439
517
|
function isOptions(field) {
|
|
440
518
|
return isSelect(field) || isRadio(field);
|
|
@@ -699,7 +777,7 @@ function prepareInputValue(field, value) {
|
|
|
699
777
|
var REGEX_REF = /^#\/definition\//;
|
|
700
778
|
function prepare(base = [], definition) {
|
|
701
779
|
const resolved = resolveRefs(base, definition);
|
|
702
|
-
return Array.isArray(resolved) ? resolved.sort((a, b) => getOrder(a) - getOrder(b)) : [];
|
|
780
|
+
return Array.isArray(resolved) ? resolved.filter(filter).sort((a, b) => getOrder(a) - getOrder(b)) : [];
|
|
703
781
|
}
|
|
704
782
|
function resolveRefs(base, definition, cache = /* @__PURE__ */ new Map(), visited = /* @__PURE__ */ new WeakSet()) {
|
|
705
783
|
if (!isDefinition(definition) || !base || typeof base !== "object") {
|
|
@@ -740,6 +818,15 @@ function getOrder(item) {
|
|
|
740
818
|
function isDefinition(definition) {
|
|
741
819
|
return definition !== void 0 && isObject(definition) && Object.keys(definition).length > 0;
|
|
742
820
|
}
|
|
821
|
+
function filter(base) {
|
|
822
|
+
if (TYPE in base) {
|
|
823
|
+
return true;
|
|
824
|
+
}
|
|
825
|
+
if (Array.isArray(base[FIELDS])) {
|
|
826
|
+
return base[FIELDS].length > 0;
|
|
827
|
+
}
|
|
828
|
+
return true;
|
|
829
|
+
}
|
|
743
830
|
|
|
744
831
|
// ../luna-core/src/util/attributes.ts
|
|
745
832
|
function getPrefixedAttributes(prefix, record) {
|
|
@@ -787,6 +874,31 @@ function getSpan(value) {
|
|
|
787
874
|
}
|
|
788
875
|
}
|
|
789
876
|
|
|
877
|
+
// ../luna-core/src/util/list.ts
|
|
878
|
+
function getInitialCount(list, value) {
|
|
879
|
+
const min2 = list.advanced?.length?.min ?? 1;
|
|
880
|
+
if (value) {
|
|
881
|
+
const data = extract(value, list.name);
|
|
882
|
+
if (Array.isArray(data)) {
|
|
883
|
+
return Math.max(data.length, min2);
|
|
884
|
+
}
|
|
885
|
+
}
|
|
886
|
+
return Math.max(min2, 0);
|
|
887
|
+
}
|
|
888
|
+
function isMultiFieldList(list) {
|
|
889
|
+
if (!Array.isArray(list.fields) || list.fields.length === 0) {
|
|
890
|
+
return false;
|
|
891
|
+
}
|
|
892
|
+
return list.fields.length > 1 || list.fields[0].type === COLUMN;
|
|
893
|
+
}
|
|
894
|
+
function getInitialList(list, value) {
|
|
895
|
+
const count = getInitialCount(list, value);
|
|
896
|
+
return Array.from({ length: count }, (_, index) => index);
|
|
897
|
+
}
|
|
898
|
+
function getLabel(list) {
|
|
899
|
+
return list.label ?? list.name;
|
|
900
|
+
}
|
|
901
|
+
|
|
790
902
|
// ../luna-core/src/util/schema.ts
|
|
791
903
|
import { z } from "zod";
|
|
792
904
|
|
|
@@ -1079,161 +1191,140 @@ function mergeStyle(globalStyle, localStyle) {
|
|
|
1079
1191
|
return { ...globalStyle, ...localStyle };
|
|
1080
1192
|
}
|
|
1081
1193
|
|
|
1082
|
-
// src/
|
|
1083
|
-
import {
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
"data-[clickable=true]:has-[>[data-slot=field-content]]:[&>:first-child]:mt-px",
|
|
1100
|
-
props.className
|
|
1101
|
-
),
|
|
1102
|
-
children: props.children
|
|
1194
|
+
// src/lib/string.tsx
|
|
1195
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
1196
|
+
function formatMarkdown2(text) {
|
|
1197
|
+
return formatMarkdown(
|
|
1198
|
+
text,
|
|
1199
|
+
(index, url, text2) => {
|
|
1200
|
+
return /* @__PURE__ */ jsx3(
|
|
1201
|
+
"a",
|
|
1202
|
+
{
|
|
1203
|
+
className: "underline",
|
|
1204
|
+
href: url,
|
|
1205
|
+
rel: "noopener noreferrer",
|
|
1206
|
+
target: "_blank",
|
|
1207
|
+
children: text2
|
|
1208
|
+
},
|
|
1209
|
+
`${url}-${index}`
|
|
1210
|
+
);
|
|
1103
1211
|
}
|
|
1104
1212
|
);
|
|
1105
1213
|
}
|
|
1106
1214
|
|
|
1107
|
-
// src/component/field/field-
|
|
1108
|
-
import {
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1215
|
+
// src/component/field/field-set-advanced.tsx
|
|
1216
|
+
import { jsx as jsx4, jsxs } from "react/jsx-runtime";
|
|
1217
|
+
function FieldSetAdvanced(props) {
|
|
1218
|
+
const { fields = [] } = props.section;
|
|
1219
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
1220
|
+
const handleOpen = useCallback(() => setIsOpen((previous) => !previous), []);
|
|
1221
|
+
return /* @__PURE__ */ jsxs(
|
|
1222
|
+
"fieldset",
|
|
1113
1223
|
{
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
),
|
|
1120
|
-
children:
|
|
1224
|
+
"data-slot": "field-set",
|
|
1225
|
+
"data-advanced": "true",
|
|
1226
|
+
"data-expanded": isOpen,
|
|
1227
|
+
"data-empty": fields.length === 0,
|
|
1228
|
+
className: "flex flex-col",
|
|
1229
|
+
id: props.section.id?.toString(),
|
|
1230
|
+
children: [
|
|
1231
|
+
/* @__PURE__ */ jsx4("legend", { children: /* @__PURE__ */ jsxs(
|
|
1232
|
+
"button",
|
|
1233
|
+
{
|
|
1234
|
+
className: "flex cursor-pointer items-center gap-2 text-base font-medium text-slate-600 dark:text-slate-400",
|
|
1235
|
+
onClick: handleOpen,
|
|
1236
|
+
type: "button",
|
|
1237
|
+
children: [
|
|
1238
|
+
/* @__PURE__ */ jsx4(ChevronIcon, { expanded: isOpen }),
|
|
1239
|
+
/* @__PURE__ */ jsx4("span", { children: formatMarkdown2(props.section.title) })
|
|
1240
|
+
]
|
|
1241
|
+
}
|
|
1242
|
+
) }),
|
|
1243
|
+
/* @__PURE__ */ jsx4(Activity, { mode: isOpen ? "visible" : "hidden", children: /* @__PURE__ */ jsxs(
|
|
1244
|
+
"div",
|
|
1245
|
+
{
|
|
1246
|
+
className: "mt-3 ml-1.5 flex flex-col gap-4 border-l-2 border-slate-300 pl-4 dark:border-slate-600",
|
|
1247
|
+
"data-slot": "field-set-content",
|
|
1248
|
+
children: [
|
|
1249
|
+
props.section.description && /* @__PURE__ */ jsx4("p", { className: "text-sm leading-normal font-normal text-slate-600 dark:text-slate-400", children: formatMarkdown2(props.section.description) }),
|
|
1250
|
+
props.group
|
|
1251
|
+
]
|
|
1252
|
+
}
|
|
1253
|
+
) })
|
|
1254
|
+
]
|
|
1121
1255
|
}
|
|
1122
1256
|
);
|
|
1123
1257
|
}
|
|
1124
1258
|
|
|
1125
|
-
// src/component/
|
|
1126
|
-
import {
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1259
|
+
// src/component/legend.tsx
|
|
1260
|
+
import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1261
|
+
function Legend(props) {
|
|
1262
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1263
|
+
props.title && /* @__PURE__ */ jsx5("legend", { className: "mb-3 font-medium text-slate-800 dark:text-slate-200", children: formatMarkdown2(props.title) }),
|
|
1264
|
+
props.description && /* @__PURE__ */ jsx5("p", { className: "-mt-2 text-sm leading-normal font-normal text-slate-600 dark:text-slate-400", children: formatMarkdown2(props.description) })
|
|
1265
|
+
] });
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
// src/component/field/field-set-base.tsx
|
|
1269
|
+
import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1270
|
+
function FieldSetBase(props) {
|
|
1271
|
+
return /* @__PURE__ */ jsxs3(
|
|
1272
|
+
"fieldset",
|
|
1131
1273
|
{
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
className:
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
props.
|
|
1139
|
-
|
|
1140
|
-
"md:justify-between",
|
|
1141
|
-
"[&>*:not([data-slot=field-content])]:w-full",
|
|
1142
|
-
"[&>*:not([data-slot=field-content])]:md:w-1/2",
|
|
1143
|
-
"[&>*:not([data-slot=field-content])]:xl:w-2/5"
|
|
1144
|
-
]
|
|
1145
|
-
),
|
|
1146
|
-
children: props.children
|
|
1274
|
+
"data-slot": "field-set",
|
|
1275
|
+
"data-empty": props.empty,
|
|
1276
|
+
className: "flex flex-col data-[empty=false]:gap-6",
|
|
1277
|
+
id: props.id,
|
|
1278
|
+
children: [
|
|
1279
|
+
/* @__PURE__ */ jsx6(Legend, { description: props.description, title: props.title }),
|
|
1280
|
+
props.children
|
|
1281
|
+
]
|
|
1147
1282
|
}
|
|
1148
1283
|
);
|
|
1149
1284
|
}
|
|
1150
1285
|
|
|
1151
|
-
// src/component/
|
|
1152
|
-
import { jsx as
|
|
1153
|
-
function
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
const reversed = buildReverse(props.field);
|
|
1157
|
-
if (props.orientation === VERTICAL) {
|
|
1158
|
-
return /* @__PURE__ */ jsx5(
|
|
1159
|
-
FieldVertical,
|
|
1160
|
-
{
|
|
1161
|
-
disabled: props.disabled,
|
|
1162
|
-
errors: props.errors,
|
|
1163
|
-
isCheckbox: checkbox,
|
|
1164
|
-
isReversed: reversed,
|
|
1165
|
-
isClickable: clickable,
|
|
1166
|
-
children: props.children
|
|
1167
|
-
}
|
|
1168
|
-
);
|
|
1169
|
-
}
|
|
1170
|
-
return /* @__PURE__ */ jsx5(
|
|
1171
|
-
FieldHorizontal,
|
|
1286
|
+
// src/component/group.tsx
|
|
1287
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1288
|
+
function Group(props) {
|
|
1289
|
+
return /* @__PURE__ */ jsx7(
|
|
1290
|
+
"div",
|
|
1172
1291
|
{
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
isReversed: reversed,
|
|
1177
|
-
isClickable: clickable,
|
|
1292
|
+
"data-slot": "field-group",
|
|
1293
|
+
"data-compact": props.compact,
|
|
1294
|
+
className: "flex w-full flex-col gap-8 data-[compact=true]:gap-3",
|
|
1178
1295
|
children: props.children
|
|
1179
1296
|
}
|
|
1180
1297
|
);
|
|
1181
1298
|
}
|
|
1182
1299
|
|
|
1183
|
-
// src/component/
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
}
|
|
1188
|
-
|
|
1189
|
-
const dataAttributes = buildDataAttributes(props.field);
|
|
1190
|
-
const ariaAttributes = buildAriaAttributes(props.field, props.errors);
|
|
1191
|
-
const field = {
|
|
1192
|
-
...props.field,
|
|
1193
|
-
disabled: commonProps.disabled
|
|
1194
|
-
};
|
|
1195
|
-
return props.children({
|
|
1196
|
-
ariaAttributes,
|
|
1197
|
-
commonProps,
|
|
1198
|
-
dataAttributes,
|
|
1199
|
-
field,
|
|
1200
|
-
orientation: props.orientation
|
|
1300
|
+
// src/component/field/field-set.tsx
|
|
1301
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1302
|
+
function FieldSet(props) {
|
|
1303
|
+
const { fields = [] } = props.section;
|
|
1304
|
+
const { compact } = mergeStyle(props.style, {
|
|
1305
|
+
compact: props.section.compact
|
|
1201
1306
|
});
|
|
1307
|
+
const group = /* @__PURE__ */ jsx8(Group, { compact, children: props.children });
|
|
1308
|
+
if (!props.section.title && !props.section.description) {
|
|
1309
|
+
return group;
|
|
1310
|
+
}
|
|
1311
|
+
if (props.section.advanced) {
|
|
1312
|
+
return /* @__PURE__ */ jsx8(FieldSetAdvanced, { section: props.section, group });
|
|
1313
|
+
}
|
|
1314
|
+
return /* @__PURE__ */ jsx8(
|
|
1315
|
+
FieldSetBase,
|
|
1316
|
+
{
|
|
1317
|
+
description: props.section.description,
|
|
1318
|
+
empty: fields.length === 0,
|
|
1319
|
+
id: props.section.id?.toString(),
|
|
1320
|
+
title: props.section.title,
|
|
1321
|
+
children: group
|
|
1322
|
+
}
|
|
1323
|
+
);
|
|
1202
1324
|
}
|
|
1203
1325
|
|
|
1204
|
-
// src/component/
|
|
1205
|
-
import {
|
|
1206
|
-
import { jsx as jsx6, jsxs } from "react/jsx-runtime";
|
|
1207
|
-
function Field(props) {
|
|
1208
|
-
const cols2 = props.field.advanced?.cols;
|
|
1209
|
-
const errors = props.field.name ? props.errors?.[props.field.name] : void 0;
|
|
1210
|
-
const { orientation } = mergeStyle(props.style, {
|
|
1211
|
-
orientation: buildOrientation(props.field)
|
|
1212
|
-
});
|
|
1213
|
-
const disabled = buildDisabled(props.field, props.disabled);
|
|
1214
|
-
return /* @__PURE__ */ jsxs("div", { className: twMerge4("flex flex-col gap-3", getSpan(cols2)), children: [
|
|
1215
|
-
/* @__PURE__ */ jsx6(
|
|
1216
|
-
FieldGroup,
|
|
1217
|
-
{
|
|
1218
|
-
disabled,
|
|
1219
|
-
errors,
|
|
1220
|
-
field: props.field,
|
|
1221
|
-
orientation,
|
|
1222
|
-
children: /* @__PURE__ */ jsx6(
|
|
1223
|
-
InputBase,
|
|
1224
|
-
{
|
|
1225
|
-
disabled,
|
|
1226
|
-
errors,
|
|
1227
|
-
field: props.field,
|
|
1228
|
-
orientation,
|
|
1229
|
-
children: props.children
|
|
1230
|
-
}
|
|
1231
|
-
)
|
|
1232
|
-
}
|
|
1233
|
-
),
|
|
1234
|
-
/* @__PURE__ */ jsx6(FieldError, { errors, name: props.field.name })
|
|
1235
|
-
] });
|
|
1236
|
-
}
|
|
1326
|
+
// src/client/component/guard/visibility-guard.tsx
|
|
1327
|
+
import { useAtomValue } from "jotai";
|
|
1237
1328
|
|
|
1238
1329
|
// src/client/lib/store-helper.ts
|
|
1239
1330
|
import { atom } from "jotai";
|
|
@@ -1379,179 +1470,80 @@ function createAtomStore(initialValue = {}) {
|
|
|
1379
1470
|
};
|
|
1380
1471
|
}
|
|
1381
1472
|
|
|
1382
|
-
// src/client/lib/
|
|
1473
|
+
// src/client/lib/state-store.ts
|
|
1383
1474
|
var store = createAtomStore();
|
|
1384
|
-
var
|
|
1385
|
-
var
|
|
1386
|
-
var reportInputErrorAtom = store.report;
|
|
1475
|
+
var fieldStateAtom = store.atom;
|
|
1476
|
+
var reportFieldStateAtom = store.report;
|
|
1387
1477
|
|
|
1388
|
-
// src/client/component/
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
function withErrors(Component) {
|
|
1392
|
-
const WithErrors = (props) => {
|
|
1393
|
-
const errors = useAtomValue(reportInputErrorAtom(props.field.name));
|
|
1394
|
-
return /* @__PURE__ */ jsx7(
|
|
1395
|
-
Component,
|
|
1396
|
-
{
|
|
1397
|
-
...props,
|
|
1398
|
-
errors: errors ? { [props.field.name]: errors } : void 0
|
|
1399
|
-
}
|
|
1400
|
-
);
|
|
1401
|
-
};
|
|
1402
|
-
return WithErrors;
|
|
1478
|
+
// src/client/component/guard/visibility-guard.tsx
|
|
1479
|
+
function isColumnHidden(column, states) {
|
|
1480
|
+
return column.fields.every((field) => isFieldHidden(field, states));
|
|
1403
1481
|
}
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
var store2 = createAtomStore();
|
|
1407
|
-
var fieldStateAtom = store2.atom;
|
|
1408
|
-
var reportFieldStateAtom = store2.report;
|
|
1409
|
-
|
|
1410
|
-
// src/client/component/wrapper/with-field-state.tsx
|
|
1411
|
-
import { useAtomValue as useAtomValue2 } from "jotai";
|
|
1412
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1413
|
-
function withFieldState(Component) {
|
|
1414
|
-
const WithFieldState = (props) => {
|
|
1415
|
-
const fieldState = useAtomValue2(reportFieldStateAtom(props.field.name));
|
|
1416
|
-
const hidden = fieldState?.hidden ?? props.field.hidden ?? false;
|
|
1417
|
-
if (hidden) {
|
|
1418
|
-
return null;
|
|
1419
|
-
}
|
|
1420
|
-
const disabled = fieldState?.disabled ?? props.disabled;
|
|
1421
|
-
return /* @__PURE__ */ jsx8(Component, { ...props, disabled });
|
|
1422
|
-
};
|
|
1423
|
-
return WithFieldState;
|
|
1482
|
+
function isFieldHidden(field, states) {
|
|
1483
|
+
return states[field.name]?.hidden ?? field.hidden ?? false;
|
|
1424
1484
|
}
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
var Field2 = withFieldState(withErrors(Field));
|
|
1428
|
-
|
|
1429
|
-
// src/component/control.tsx
|
|
1430
|
-
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1431
|
-
function Control(props) {
|
|
1432
|
-
const content = typeof props.children === "function" ? props.children({ isPending: props.isPending }) : props.children;
|
|
1433
|
-
return /* @__PURE__ */ jsx9("div", { "data-slot": "field-control", className: "w-full", children: content });
|
|
1485
|
+
function isEntryHidden(entry, states) {
|
|
1486
|
+
return isColumn(entry) ? isColumnHidden(entry, states) : isFieldHidden(entry, states);
|
|
1434
1487
|
}
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
{
|
|
1442
|
-
"data-slot": "field-group",
|
|
1443
|
-
"data-compact": props.compact,
|
|
1444
|
-
className: "flex w-full flex-col gap-8 data-[compact=true]:gap-3",
|
|
1445
|
-
children: props.children
|
|
1446
|
-
}
|
|
1447
|
-
);
|
|
1448
|
-
}
|
|
1449
|
-
|
|
1450
|
-
// src/lib/string.tsx
|
|
1451
|
-
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1452
|
-
function formatMarkdown2(text) {
|
|
1453
|
-
return formatMarkdown(
|
|
1454
|
-
text,
|
|
1455
|
-
(index, url, text2) => {
|
|
1456
|
-
return /* @__PURE__ */ jsx11(
|
|
1457
|
-
"a",
|
|
1458
|
-
{
|
|
1459
|
-
className: "underline",
|
|
1460
|
-
href: url,
|
|
1461
|
-
rel: "noopener noreferrer",
|
|
1462
|
-
target: "_blank",
|
|
1463
|
-
children: text2
|
|
1464
|
-
},
|
|
1465
|
-
`${url}-${index}`
|
|
1466
|
-
);
|
|
1488
|
+
function VisibilityGuard(props) {
|
|
1489
|
+
const states = useAtomValue(fieldStateAtom);
|
|
1490
|
+
if (props.container) {
|
|
1491
|
+
const hidden = states[props.container.name]?.hidden ?? props.container.hidden ?? false;
|
|
1492
|
+
if (hidden) {
|
|
1493
|
+
return null;
|
|
1467
1494
|
}
|
|
1468
|
-
);
|
|
1469
|
-
}
|
|
1470
|
-
|
|
1471
|
-
// src/component/legend.tsx
|
|
1472
|
-
import { Fragment, jsx as jsx12, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1473
|
-
function Legend(props) {
|
|
1474
|
-
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
1475
|
-
props.title && /* @__PURE__ */ jsx12("legend", { className: "mb-3 font-medium text-slate-800 dark:text-slate-200", children: formatMarkdown2(props.title) }),
|
|
1476
|
-
props.description && /* @__PURE__ */ jsx12("p", { className: "-mt-2 text-sm leading-normal font-normal text-slate-600 dark:text-slate-400", children: formatMarkdown2(props.description) })
|
|
1477
|
-
] });
|
|
1478
|
-
}
|
|
1479
|
-
|
|
1480
|
-
// src/component/field/field-set.tsx
|
|
1481
|
-
import { jsx as jsx13, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1482
|
-
function FieldSet(props) {
|
|
1483
|
-
const fields = props.section.fields || [];
|
|
1484
|
-
const { compact } = mergeStyle(props.style, {
|
|
1485
|
-
compact: props.section.compact
|
|
1486
|
-
});
|
|
1487
|
-
if (!props.section.title && !props.section.description) {
|
|
1488
|
-
return /* @__PURE__ */ jsx13(Group, { compact, children: props.children });
|
|
1489
1495
|
}
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
/* @__PURE__ */ jsx13(
|
|
1499
|
-
Legend,
|
|
1500
|
-
{
|
|
1501
|
-
description: props.section.description,
|
|
1502
|
-
title: props.section.title
|
|
1503
|
-
}
|
|
1504
|
-
),
|
|
1505
|
-
/* @__PURE__ */ jsx13(Group, { compact, children: props.children })
|
|
1506
|
-
]
|
|
1507
|
-
}
|
|
1508
|
-
);
|
|
1496
|
+
if (props.fields.length === 0) {
|
|
1497
|
+
return null;
|
|
1498
|
+
}
|
|
1499
|
+
const allHidden = props.fields.every((entry) => isEntryHidden(entry, states));
|
|
1500
|
+
if (allHidden) {
|
|
1501
|
+
return null;
|
|
1502
|
+
}
|
|
1503
|
+
return props.children;
|
|
1509
1504
|
}
|
|
1510
1505
|
|
|
1511
|
-
// src/component/form.tsx
|
|
1512
|
-
import { Fragment as Fragment2 } from "react";
|
|
1513
|
-
|
|
1514
1506
|
// src/component/separator.tsx
|
|
1515
|
-
import { jsx as
|
|
1507
|
+
import { jsx as jsx9 } from "react/jsx-runtime";
|
|
1516
1508
|
function Separator() {
|
|
1517
|
-
return /* @__PURE__ */
|
|
1509
|
+
return /* @__PURE__ */ jsx9("div", { "data-slot": "field-separator", className: "relative -my-2 h-5 text-sm", children: /* @__PURE__ */ jsx9("div", { className: "absolute inset-0 top-1/2 h-px w-full bg-slate-200 dark:bg-slate-800" }) });
|
|
1518
1510
|
}
|
|
1519
1511
|
|
|
1520
1512
|
// src/component/form.tsx
|
|
1521
|
-
import { jsx as
|
|
1513
|
+
import { jsx as jsx10, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1522
1514
|
function Form(props) {
|
|
1523
1515
|
const sections = prepare(props.sections, props.definition);
|
|
1524
|
-
return /* @__PURE__ */
|
|
1525
|
-
sections.map((section, index) => /* @__PURE__ */ jsxs4(
|
|
1526
|
-
/* @__PURE__ */
|
|
1516
|
+
return /* @__PURE__ */ jsx10("div", { className: "h-full w-full", children: /* @__PURE__ */ jsx10("form", { noValidate: props.noValidate, action: props.action, children: /* @__PURE__ */ jsxs4(Group, { children: [
|
|
1517
|
+
sections.map((section, index) => /* @__PURE__ */ jsxs4(VisibilityGuard, { fields: section.fields ?? [], children: [
|
|
1518
|
+
/* @__PURE__ */ jsx10(FieldSet, { section, style: props.config.style, children: props.children({
|
|
1527
1519
|
disabled: props.readOnly,
|
|
1528
1520
|
fields: section.fields
|
|
1529
1521
|
}) }),
|
|
1530
|
-
section.separator && /* @__PURE__ */
|
|
1522
|
+
section.separator && /* @__PURE__ */ jsx10(Separator, {})
|
|
1531
1523
|
] }, index)),
|
|
1532
|
-
props.control && /* @__PURE__ */
|
|
1524
|
+
props.control && /* @__PURE__ */ jsx10(Control, { isPending: props.isPending, children: props.control })
|
|
1533
1525
|
] }) }) });
|
|
1534
1526
|
}
|
|
1535
1527
|
|
|
1536
1528
|
// src/component/description.tsx
|
|
1537
|
-
import { jsx as
|
|
1529
|
+
import { jsx as jsx11 } from "react/jsx-runtime";
|
|
1538
1530
|
function Description(props) {
|
|
1539
|
-
return /* @__PURE__ */
|
|
1531
|
+
return /* @__PURE__ */ jsx11("p", { className: "-mt-2 text-xs leading-normal font-normal text-slate-600 dark:text-slate-400", children: props.children });
|
|
1540
1532
|
}
|
|
1541
1533
|
|
|
1542
1534
|
// src/component/formatted-description.tsx
|
|
1543
|
-
import { jsx as
|
|
1535
|
+
import { jsx as jsx12 } from "react/jsx-runtime";
|
|
1544
1536
|
function FormattedDescription(props) {
|
|
1545
1537
|
const content = formatMarkdown2(props.text);
|
|
1546
1538
|
if (content) {
|
|
1547
|
-
return /* @__PURE__ */
|
|
1539
|
+
return /* @__PURE__ */ jsx12(Description, { children: content });
|
|
1548
1540
|
}
|
|
1549
1541
|
return null;
|
|
1550
1542
|
}
|
|
1551
1543
|
|
|
1552
1544
|
// src/component/label.tsx
|
|
1553
|
-
import { twMerge
|
|
1554
|
-
import { jsx as
|
|
1545
|
+
import { twMerge } from "tailwind-merge";
|
|
1546
|
+
import { jsx as jsx13, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1555
1547
|
function Label(props) {
|
|
1556
1548
|
const showOptionalLabel = props.style?.showOptionalLabel ?? true;
|
|
1557
1549
|
const normal = isRadio(props.field) || isCheckbox(props.field);
|
|
@@ -1560,7 +1552,7 @@ function Label(props) {
|
|
|
1560
1552
|
{
|
|
1561
1553
|
"data-slot": "field-label",
|
|
1562
1554
|
"data-normal": normal,
|
|
1563
|
-
className:
|
|
1555
|
+
className: twMerge(
|
|
1564
1556
|
"flex w-fit items-center gap-2 text-sm leading-snug font-medium select-none",
|
|
1565
1557
|
"data-[normal=true]:font-normal",
|
|
1566
1558
|
"group-data-[readonly=true]:cursor-not-allowed group-data-[readonly=true]:opacity-50"
|
|
@@ -1568,30 +1560,31 @@ function Label(props) {
|
|
|
1568
1560
|
htmlFor: props.field.name,
|
|
1569
1561
|
children: [
|
|
1570
1562
|
props.children,
|
|
1571
|
-
showOptionalLabel && !props.field.required && /* @__PURE__ */
|
|
1563
|
+
showOptionalLabel && !props.field.required && /* @__PURE__ */ jsx13("span", { className: "text-sm text-slate-600 dark:text-slate-400", children: translate("(Optional)", props.translations) })
|
|
1572
1564
|
]
|
|
1573
1565
|
}
|
|
1574
1566
|
);
|
|
1575
1567
|
}
|
|
1576
1568
|
|
|
1577
1569
|
// src/component/input-label.tsx
|
|
1578
|
-
import { jsx as
|
|
1570
|
+
import { jsx as jsx14, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1579
1571
|
function InputLabel(props) {
|
|
1580
|
-
const
|
|
1572
|
+
const interpolateOpts = {
|
|
1581
1573
|
context: props.context,
|
|
1582
1574
|
env: props.config?.env
|
|
1583
|
-
}
|
|
1584
|
-
const
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1575
|
+
};
|
|
1576
|
+
const label = interpolateIfNeeded(props.field.label, interpolateOpts);
|
|
1577
|
+
const description = interpolateIfNeeded(
|
|
1578
|
+
props.field.description,
|
|
1579
|
+
interpolateOpts
|
|
1580
|
+
);
|
|
1588
1581
|
return /* @__PURE__ */ jsxs6(
|
|
1589
1582
|
"div",
|
|
1590
1583
|
{
|
|
1591
1584
|
"data-slot": "field-content",
|
|
1592
1585
|
className: "flex w-full flex-1 flex-col gap-1.5 leading-snug",
|
|
1593
1586
|
children: [
|
|
1594
|
-
/* @__PURE__ */
|
|
1587
|
+
/* @__PURE__ */ jsx14(
|
|
1595
1588
|
Label,
|
|
1596
1589
|
{
|
|
1597
1590
|
field: props.field,
|
|
@@ -1600,7 +1593,7 @@ function InputLabel(props) {
|
|
|
1600
1593
|
children: translate(label, props.translations)
|
|
1601
1594
|
}
|
|
1602
1595
|
),
|
|
1603
|
-
props.orientation === HORIZONTAL && /* @__PURE__ */
|
|
1596
|
+
props.orientation === HORIZONTAL && /* @__PURE__ */ jsx14(
|
|
1604
1597
|
FormattedDescription,
|
|
1605
1598
|
{
|
|
1606
1599
|
text: translate(description, props.translations)
|
|
@@ -1612,10 +1605,10 @@ function InputLabel(props) {
|
|
|
1612
1605
|
}
|
|
1613
1606
|
|
|
1614
1607
|
// src/component/input-group.tsx
|
|
1615
|
-
import { Fragment as
|
|
1608
|
+
import { Fragment as Fragment2, jsx as jsx15, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1616
1609
|
function InputGroup(props) {
|
|
1617
|
-
return /* @__PURE__ */ jsxs7(
|
|
1618
|
-
props.field.name && props.field.label && /* @__PURE__ */
|
|
1610
|
+
return /* @__PURE__ */ jsxs7(Fragment2, { children: [
|
|
1611
|
+
props.field.name && props.field.label && /* @__PURE__ */ jsx15(
|
|
1619
1612
|
InputLabel,
|
|
1620
1613
|
{
|
|
1621
1614
|
config: props.config,
|
|
@@ -1626,7 +1619,7 @@ function InputGroup(props) {
|
|
|
1626
1619
|
}
|
|
1627
1620
|
),
|
|
1628
1621
|
props.children,
|
|
1629
|
-
props.orientation === VERTICAL && props.field.description && /* @__PURE__ */
|
|
1622
|
+
props.orientation === VERTICAL && props.field.description && /* @__PURE__ */ jsx15(
|
|
1630
1623
|
FormattedDescription,
|
|
1631
1624
|
{
|
|
1632
1625
|
text: translate(props.field.description, props.translations)
|
|
@@ -1643,8 +1636,14 @@ function renderIfExists(value, render) {
|
|
|
1643
1636
|
return render(value);
|
|
1644
1637
|
}
|
|
1645
1638
|
|
|
1639
|
+
// src/client/lib/error-store.ts
|
|
1640
|
+
var store2 = createAtomStore();
|
|
1641
|
+
var clearInputErrorAtom = store2.clear;
|
|
1642
|
+
var reportErrorAtom = store2.bulkReport;
|
|
1643
|
+
var reportInputErrorAtom = store2.report;
|
|
1644
|
+
|
|
1646
1645
|
// src/client/component/input.tsx
|
|
1647
|
-
import { useCallback as
|
|
1646
|
+
import { useCallback as useCallback4, useRef as useRef3, useTransition } from "react";
|
|
1648
1647
|
|
|
1649
1648
|
// src/client/lib/source-store.ts
|
|
1650
1649
|
import { atom as atom2 } from "jotai";
|
|
@@ -1750,7 +1749,7 @@ function useInput(field, onMount, onUnmount, translations) {
|
|
|
1750
1749
|
import { useSetAtom, useStore } from "jotai";
|
|
1751
1750
|
|
|
1752
1751
|
// src/client/hook/use-timeout.ts
|
|
1753
|
-
import { useCallback, useEffect as useEffect2, useRef } from "react";
|
|
1752
|
+
import { useCallback as useCallback2, useEffect as useEffect2, useRef } from "react";
|
|
1754
1753
|
function useTimeout() {
|
|
1755
1754
|
const timeoutRef = useRef(null);
|
|
1756
1755
|
useEffect2(() => {
|
|
@@ -1760,14 +1759,11 @@ function useTimeout() {
|
|
|
1760
1759
|
}
|
|
1761
1760
|
};
|
|
1762
1761
|
}, []);
|
|
1763
|
-
|
|
1762
|
+
const setTimeoutRef = useCallback2((callback, delay) => {
|
|
1764
1763
|
if (timeoutRef.current) {
|
|
1765
1764
|
clearTimeout(timeoutRef.current);
|
|
1766
1765
|
timeoutRef.current = null;
|
|
1767
1766
|
}
|
|
1768
|
-
}
|
|
1769
|
-
const setTimeoutRef = useCallback((callback, delay) => {
|
|
1770
|
-
clearTimeoutRef();
|
|
1771
1767
|
timeoutRef.current = setTimeout(callback, delay);
|
|
1772
1768
|
}, []);
|
|
1773
1769
|
return setTimeoutRef;
|
|
@@ -1782,26 +1778,27 @@ var reportValueAtom = store3.report;
|
|
|
1782
1778
|
|
|
1783
1779
|
// src/client/hook/use-value.ts
|
|
1784
1780
|
import { useAtom as useAtom2 } from "jotai";
|
|
1785
|
-
import { useCallback as
|
|
1781
|
+
import { useCallback as useCallback3, useEffect as useEffect3, useRef as useRef2, useEffectEvent as useEffectEvent2 } from "react";
|
|
1786
1782
|
function useValue(field, currentValue) {
|
|
1787
1783
|
const { name } = field;
|
|
1788
1784
|
const skipNextOnChangeRef = useRef2(false);
|
|
1789
1785
|
const [value, setValue] = useAtom2(reportValueAtom(name));
|
|
1786
|
+
const onCurrentValueChange = useEffectEvent2(
|
|
1787
|
+
(currentValue2) => {
|
|
1788
|
+
const newValue = resolveValue(name, currentValue2);
|
|
1789
|
+
if (isValidValue(newValue)) {
|
|
1790
|
+
skipNextOnChangeRef.current = true;
|
|
1791
|
+
setValue(newValue);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
);
|
|
1790
1795
|
useEffect3(() => {
|
|
1791
|
-
if (!currentValue
|
|
1796
|
+
if (!currentValue) {
|
|
1792
1797
|
return;
|
|
1793
1798
|
}
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
fieldName: name,
|
|
1798
|
-
newValue
|
|
1799
|
-
});
|
|
1800
|
-
skipNextOnChangeRef.current = true;
|
|
1801
|
-
setValue(newValue);
|
|
1802
|
-
}
|
|
1803
|
-
}, [name, currentValue, setValue]);
|
|
1804
|
-
const shouldSkipOnChange = useCallback2(() => {
|
|
1799
|
+
onCurrentValueChange(currentValue);
|
|
1800
|
+
}, [currentValue]);
|
|
1801
|
+
const shouldSkipOnChange = useCallback3(() => {
|
|
1805
1802
|
if (skipNextOnChangeRef.current) {
|
|
1806
1803
|
skipNextOnChangeRef.current = false;
|
|
1807
1804
|
return true;
|
|
@@ -1814,14 +1811,38 @@ function useValue(field, currentValue) {
|
|
|
1814
1811
|
value
|
|
1815
1812
|
};
|
|
1816
1813
|
}
|
|
1814
|
+
function resolveValue(name, currentValue) {
|
|
1815
|
+
if (name in currentValue) {
|
|
1816
|
+
return currentValue[name];
|
|
1817
|
+
}
|
|
1818
|
+
if (!name.includes(".")) {
|
|
1819
|
+
return void 0;
|
|
1820
|
+
}
|
|
1821
|
+
const keys = name.split(".");
|
|
1822
|
+
let result = currentValue;
|
|
1823
|
+
for (const key of keys) {
|
|
1824
|
+
if (result === null || result === void 0) {
|
|
1825
|
+
return void 0;
|
|
1826
|
+
}
|
|
1827
|
+
if (Array.isArray(result)) {
|
|
1828
|
+
const index = Number(key);
|
|
1829
|
+
result = Number.isInteger(index) ? result[index] : void 0;
|
|
1830
|
+
} else if (typeof result === "object") {
|
|
1831
|
+
result = result[key];
|
|
1832
|
+
} else {
|
|
1833
|
+
return void 0;
|
|
1834
|
+
}
|
|
1835
|
+
}
|
|
1836
|
+
return result;
|
|
1837
|
+
}
|
|
1817
1838
|
|
|
1818
1839
|
// src/client/component/input.tsx
|
|
1819
|
-
import { jsx as
|
|
1840
|
+
import { jsx as jsx16 } from "react/jsx-runtime";
|
|
1820
1841
|
function Input(props) {
|
|
1821
1842
|
const entity = props.field.advanced?.entity;
|
|
1822
1843
|
const store4 = useStore();
|
|
1823
1844
|
const setTimeoutRef = useTimeout();
|
|
1824
|
-
const [,
|
|
1845
|
+
const [, startTransition2] = useTransition();
|
|
1825
1846
|
const { setValue, shouldSkipOnChange, value } = useValue(
|
|
1826
1847
|
props.field,
|
|
1827
1848
|
props.value
|
|
@@ -1864,7 +1885,7 @@ function Input(props) {
|
|
|
1864
1885
|
}
|
|
1865
1886
|
};
|
|
1866
1887
|
const inputProps = prepareInputValue(props.field, defaultValue);
|
|
1867
|
-
const validated =
|
|
1888
|
+
const validated = useCallback4(
|
|
1868
1889
|
(value2) => {
|
|
1869
1890
|
const results = schema.safeParse(value2);
|
|
1870
1891
|
const errors = results.error?.issues.map((issue) => issue.message) ?? [];
|
|
@@ -1879,7 +1900,7 @@ function Input(props) {
|
|
|
1879
1900
|
},
|
|
1880
1901
|
[props.field.validation?.custom, schema, setErrors, store4]
|
|
1881
1902
|
);
|
|
1882
|
-
const handleTriggerEvent =
|
|
1903
|
+
const handleTriggerEvent = useCallback4(
|
|
1883
1904
|
(value2, callback) => {
|
|
1884
1905
|
if (hasTextable) {
|
|
1885
1906
|
setTimeoutRef(() => {
|
|
@@ -1887,37 +1908,18 @@ function Input(props) {
|
|
|
1887
1908
|
}, 500);
|
|
1888
1909
|
return;
|
|
1889
1910
|
}
|
|
1890
|
-
|
|
1891
|
-
callback(currentValue);
|
|
1911
|
+
callback(getEntity(value2, data, entity));
|
|
1892
1912
|
},
|
|
1893
1913
|
[data, entity, hasTextable, setTimeoutRef]
|
|
1894
1914
|
);
|
|
1895
|
-
const onChange =
|
|
1915
|
+
const onChange = useCallback4(
|
|
1896
1916
|
(event) => {
|
|
1897
1917
|
const inputValue = event.target.value;
|
|
1898
|
-
logger.info("onChange fired", {
|
|
1899
|
-
fieldName: props.field.name,
|
|
1900
|
-
fieldType: props.field.type,
|
|
1901
|
-
inputValue,
|
|
1902
|
-
currentValue: valueRef.current,
|
|
1903
|
-
hasTextable,
|
|
1904
|
-
hasClickable
|
|
1905
|
-
});
|
|
1906
1918
|
if (!hasClickable && shouldSkipOnChange()) {
|
|
1907
|
-
logger.info("shouldSkipOnChange returned true", {
|
|
1908
|
-
fieldName: props.field.name,
|
|
1909
|
-
willSkip: !hasTextable || inputValue === valueRef.current,
|
|
1910
|
-
reason: !hasTextable ? "not textable (checkbox/radio/select)" : "value unchanged"
|
|
1911
|
-
});
|
|
1912
1919
|
if (!hasTextable || inputValue === valueRef.current) {
|
|
1913
|
-
logger.info("SKIPPING onChange", { fieldName: props.field.name });
|
|
1914
1920
|
return;
|
|
1915
1921
|
}
|
|
1916
1922
|
}
|
|
1917
|
-
logger.info("onChange processing", {
|
|
1918
|
-
fieldName: props.field.name,
|
|
1919
|
-
inputValue
|
|
1920
|
-
});
|
|
1921
1923
|
onValueChangeRef.current?.(inputValue);
|
|
1922
1924
|
if (props.config.validation.change) {
|
|
1923
1925
|
validated(inputValue);
|
|
@@ -1926,19 +1928,32 @@ function Input(props) {
|
|
|
1926
1928
|
if (events) {
|
|
1927
1929
|
handleTriggerEvent(inputValue, (selected) => {
|
|
1928
1930
|
handleProxyEvent(events, ({ sources, states, values }) => {
|
|
1929
|
-
|
|
1931
|
+
startTransition2(() => {
|
|
1930
1932
|
handleSourceEvent(
|
|
1931
1933
|
selected,
|
|
1932
1934
|
sources,
|
|
1933
1935
|
(target, source) => setSource(target, source)
|
|
1934
1936
|
);
|
|
1935
|
-
handleStateEvent(selected, states, (
|
|
1937
|
+
handleStateEvent(selected, states, (targets, state) => {
|
|
1938
|
+
logger.info(
|
|
1939
|
+
`Setting field states for targets: ${targets.join(
|
|
1940
|
+
", "
|
|
1941
|
+
)} with state: ${JSON.stringify(state)}`
|
|
1942
|
+
);
|
|
1936
1943
|
setFieldStates((prev) => {
|
|
1937
1944
|
if (state) {
|
|
1938
|
-
return
|
|
1945
|
+
return targets.reduce(
|
|
1946
|
+
(acc, target) => ({
|
|
1947
|
+
...acc,
|
|
1948
|
+
[target]: state
|
|
1949
|
+
}),
|
|
1950
|
+
prev
|
|
1951
|
+
);
|
|
1939
1952
|
}
|
|
1940
|
-
|
|
1941
|
-
|
|
1953
|
+
return targets.reduce((acc, target) => {
|
|
1954
|
+
const { [target]: _removed, ...rest } = acc;
|
|
1955
|
+
return rest;
|
|
1956
|
+
}, prev);
|
|
1942
1957
|
});
|
|
1943
1958
|
});
|
|
1944
1959
|
handleValueEvent(selected, values, (target, value2) => {
|
|
@@ -1958,8 +1973,6 @@ function Input(props) {
|
|
|
1958
1973
|
hasTextable,
|
|
1959
1974
|
props.config.validation.change,
|
|
1960
1975
|
props.field.event?.change,
|
|
1961
|
-
props.field.name,
|
|
1962
|
-
props.field.type,
|
|
1963
1976
|
setFieldStates,
|
|
1964
1977
|
setSource,
|
|
1965
1978
|
setValues,
|
|
@@ -1967,7 +1980,7 @@ function Input(props) {
|
|
|
1967
1980
|
validated
|
|
1968
1981
|
]
|
|
1969
1982
|
);
|
|
1970
|
-
const onBlur =
|
|
1983
|
+
const onBlur = useCallback4(
|
|
1971
1984
|
(event) => {
|
|
1972
1985
|
if (!hasClickable) {
|
|
1973
1986
|
const value2 = event.target.value;
|
|
@@ -1978,7 +1991,7 @@ function Input(props) {
|
|
|
1978
1991
|
},
|
|
1979
1992
|
[hasClickable, props.config.validation.blur, validated]
|
|
1980
1993
|
);
|
|
1981
|
-
return renderIfExists(props.config.inputs[props.field.type], (Component) => /* @__PURE__ */
|
|
1994
|
+
return renderIfExists(props.config.inputs[props.field.type], (Component) => /* @__PURE__ */ jsx16(
|
|
1982
1995
|
InputGroup,
|
|
1983
1996
|
{
|
|
1984
1997
|
config: props.config,
|
|
@@ -1986,7 +1999,7 @@ function Input(props) {
|
|
|
1986
1999
|
field: props.field,
|
|
1987
2000
|
orientation: props.orientation,
|
|
1988
2001
|
translations: props.translations,
|
|
1989
|
-
children: /* @__PURE__ */
|
|
2002
|
+
children: /* @__PURE__ */ jsx16(
|
|
1990
2003
|
Component,
|
|
1991
2004
|
{
|
|
1992
2005
|
...commonPropsWithOptions,
|
|
@@ -2001,39 +2014,493 @@ function Input(props) {
|
|
|
2001
2014
|
));
|
|
2002
2015
|
}
|
|
2003
2016
|
|
|
2004
|
-
// src/component/
|
|
2017
|
+
// src/component/field/field-error.tsx
|
|
2018
|
+
import { jsx as jsx17 } from "react/jsx-runtime";
|
|
2019
|
+
function FieldError(props) {
|
|
2020
|
+
if (!props.errors || props.errors.length === 0) {
|
|
2021
|
+
return null;
|
|
2022
|
+
}
|
|
2023
|
+
return /* @__PURE__ */ jsx17(
|
|
2024
|
+
"ul",
|
|
2025
|
+
{
|
|
2026
|
+
className: "text-sm text-red-600 dark:text-red-500",
|
|
2027
|
+
id: props.name ? `${props.name}-error` : void 0,
|
|
2028
|
+
children: props.errors?.map((error, index) => /* @__PURE__ */ jsx17("li", { children: error }, props.name ? `${props.name}-error-${index}` : index))
|
|
2029
|
+
}
|
|
2030
|
+
);
|
|
2031
|
+
}
|
|
2032
|
+
|
|
2033
|
+
// src/component/field/field-base.tsx
|
|
2034
|
+
import { twMerge as twMerge2 } from "tailwind-merge";
|
|
2035
|
+
import { jsx as jsx18 } from "react/jsx-runtime";
|
|
2036
|
+
function FieldBase(props) {
|
|
2037
|
+
const errors = props.errors && props.errors.length > 0;
|
|
2038
|
+
return /* @__PURE__ */ jsx18(
|
|
2039
|
+
"div",
|
|
2040
|
+
{
|
|
2041
|
+
"data-slot": "field",
|
|
2042
|
+
"data-clickable": props.isClickable ? "true" : "false",
|
|
2043
|
+
...errors && { [DATA_INVALID]: "true" },
|
|
2044
|
+
...props.disabled && { [DATA_READONLY]: "true" },
|
|
2045
|
+
"data-orientation": props.orientation,
|
|
2046
|
+
className: twMerge2(
|
|
2047
|
+
"group flex w-full flex-col items-center data-[invalid=true]:text-red-600 data-[invalid=true]:dark:text-red-500",
|
|
2048
|
+
"data-[clickable=true]:items-start",
|
|
2049
|
+
props.isCheckbox && (props.isReversed ? "flex-row-reverse!" : "flex-row!"),
|
|
2050
|
+
"data-[clickable=true]:has-[>[data-slot=field-content]]:[&>:first-child]:mt-px",
|
|
2051
|
+
props.className
|
|
2052
|
+
),
|
|
2053
|
+
children: props.children
|
|
2054
|
+
}
|
|
2055
|
+
);
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// src/component/field/field-vertical.tsx
|
|
2059
|
+
import { twMerge as twMerge3 } from "tailwind-merge";
|
|
2060
|
+
import { jsx as jsx19 } from "react/jsx-runtime";
|
|
2061
|
+
function FieldVertical(props) {
|
|
2062
|
+
return /* @__PURE__ */ jsx19(
|
|
2063
|
+
FieldBase,
|
|
2064
|
+
{
|
|
2065
|
+
...props,
|
|
2066
|
+
orientation: VERTICAL,
|
|
2067
|
+
className: twMerge3(
|
|
2068
|
+
"gap-3 has-[>[data-slot=field-content]]:items-start",
|
|
2069
|
+
!props.isClickable && "[&>*]:w-full"
|
|
2070
|
+
),
|
|
2071
|
+
children: props.children
|
|
2072
|
+
}
|
|
2073
|
+
);
|
|
2074
|
+
}
|
|
2075
|
+
|
|
2076
|
+
// src/component/field/field-horizontal.tsx
|
|
2077
|
+
import { twMerge as twMerge4 } from "tailwind-merge";
|
|
2078
|
+
import { jsx as jsx20 } from "react/jsx-runtime";
|
|
2079
|
+
function FieldHorizontal(props) {
|
|
2080
|
+
return /* @__PURE__ */ jsx20(
|
|
2081
|
+
FieldBase,
|
|
2082
|
+
{
|
|
2083
|
+
...props,
|
|
2084
|
+
orientation: HORIZONTAL,
|
|
2085
|
+
className: twMerge4(
|
|
2086
|
+
"gap-2 md:flex-row md:gap-4",
|
|
2087
|
+
"[&>[data-slot=field-content]]:min-w-0 [&>[data-slot=field-content]]:flex-grow [&>[data-slot=field-content]]:self-start",
|
|
2088
|
+
"[&_[role=checkbox]]:mt-[1.5px]",
|
|
2089
|
+
props.isClickable && "md:flex-col",
|
|
2090
|
+
!props.isClickable && [
|
|
2091
|
+
"md:justify-between",
|
|
2092
|
+
"[&>*:not([data-slot=field-content])]:w-full",
|
|
2093
|
+
"[&>*:not([data-slot=field-content])]:md:w-1/2",
|
|
2094
|
+
"[&>*:not([data-slot=field-content])]:xl:w-2/5"
|
|
2095
|
+
]
|
|
2096
|
+
),
|
|
2097
|
+
children: props.children
|
|
2098
|
+
}
|
|
2099
|
+
);
|
|
2100
|
+
}
|
|
2101
|
+
|
|
2102
|
+
// src/component/field/field-group.tsx
|
|
2103
|
+
import { jsx as jsx21 } from "react/jsx-runtime";
|
|
2104
|
+
function FieldGroup(props) {
|
|
2105
|
+
const clickable = isClickable(props.field);
|
|
2106
|
+
const checkbox = isCheckbox(props.field);
|
|
2107
|
+
const reversed = buildReverse(props.field);
|
|
2108
|
+
if (props.orientation === VERTICAL) {
|
|
2109
|
+
return /* @__PURE__ */ jsx21(
|
|
2110
|
+
FieldVertical,
|
|
2111
|
+
{
|
|
2112
|
+
disabled: props.disabled,
|
|
2113
|
+
errors: props.errors,
|
|
2114
|
+
isCheckbox: checkbox,
|
|
2115
|
+
isReversed: reversed,
|
|
2116
|
+
isClickable: clickable,
|
|
2117
|
+
children: props.children
|
|
2118
|
+
}
|
|
2119
|
+
);
|
|
2120
|
+
}
|
|
2121
|
+
return /* @__PURE__ */ jsx21(
|
|
2122
|
+
FieldHorizontal,
|
|
2123
|
+
{
|
|
2124
|
+
disabled: props.disabled,
|
|
2125
|
+
errors: props.errors,
|
|
2126
|
+
isCheckbox: checkbox,
|
|
2127
|
+
isReversed: reversed,
|
|
2128
|
+
isClickable: clickable,
|
|
2129
|
+
children: props.children
|
|
2130
|
+
}
|
|
2131
|
+
);
|
|
2132
|
+
}
|
|
2133
|
+
|
|
2134
|
+
// src/component/input/input-base.tsx
|
|
2135
|
+
function InputBase(props) {
|
|
2136
|
+
if (!props.field.type) {
|
|
2137
|
+
return null;
|
|
2138
|
+
}
|
|
2139
|
+
const commonProps = buildCommon(props.field, props.disabled);
|
|
2140
|
+
const dataAttributes = buildDataAttributes(props.field);
|
|
2141
|
+
const ariaAttributes = buildAriaAttributes(props.field, props.errors);
|
|
2142
|
+
const field = {
|
|
2143
|
+
...props.field,
|
|
2144
|
+
disabled: commonProps.disabled
|
|
2145
|
+
};
|
|
2146
|
+
return props.children({
|
|
2147
|
+
ariaAttributes,
|
|
2148
|
+
commonProps,
|
|
2149
|
+
dataAttributes,
|
|
2150
|
+
field,
|
|
2151
|
+
orientation: props.orientation
|
|
2152
|
+
});
|
|
2153
|
+
}
|
|
2154
|
+
|
|
2155
|
+
// src/component/field/field.tsx
|
|
2156
|
+
import { twMerge as twMerge5 } from "tailwind-merge";
|
|
2157
|
+
import { jsx as jsx22, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2158
|
+
function Field(props) {
|
|
2159
|
+
const cols2 = props.field.advanced?.cols;
|
|
2160
|
+
const errors = props.field.name ? props.errors?.[props.field.name] : void 0;
|
|
2161
|
+
const { orientation } = mergeStyle(props.style, {
|
|
2162
|
+
orientation: buildOrientation(props.field)
|
|
2163
|
+
});
|
|
2164
|
+
const disabled = buildDisabled(props.field, props.disabled);
|
|
2165
|
+
return /* @__PURE__ */ jsxs8("div", { className: twMerge5("flex flex-col gap-3", getSpan(cols2)), children: [
|
|
2166
|
+
/* @__PURE__ */ jsx22(
|
|
2167
|
+
FieldGroup,
|
|
2168
|
+
{
|
|
2169
|
+
disabled,
|
|
2170
|
+
errors,
|
|
2171
|
+
field: props.field,
|
|
2172
|
+
orientation,
|
|
2173
|
+
children: /* @__PURE__ */ jsx22(
|
|
2174
|
+
InputBase,
|
|
2175
|
+
{
|
|
2176
|
+
disabled,
|
|
2177
|
+
errors,
|
|
2178
|
+
field: props.field,
|
|
2179
|
+
orientation,
|
|
2180
|
+
children: props.children
|
|
2181
|
+
}
|
|
2182
|
+
)
|
|
2183
|
+
}
|
|
2184
|
+
),
|
|
2185
|
+
/* @__PURE__ */ jsx22(FieldError, { errors, name: props.field.name })
|
|
2186
|
+
] });
|
|
2187
|
+
}
|
|
2188
|
+
|
|
2189
|
+
// src/client/component/field/field-with-error.tsx
|
|
2190
|
+
import { useAtomValue as useAtomValue2 } from "jotai";
|
|
2191
|
+
import { jsx as jsx23 } from "react/jsx-runtime";
|
|
2192
|
+
function withError(Component) {
|
|
2193
|
+
const WithError = (props) => {
|
|
2194
|
+
const errors = useAtomValue2(reportInputErrorAtom(props.field.name));
|
|
2195
|
+
return /* @__PURE__ */ jsx23(
|
|
2196
|
+
Component,
|
|
2197
|
+
{
|
|
2198
|
+
...props,
|
|
2199
|
+
errors: errors ? { [props.field.name]: errors } : void 0
|
|
2200
|
+
}
|
|
2201
|
+
);
|
|
2202
|
+
};
|
|
2203
|
+
return WithError;
|
|
2204
|
+
}
|
|
2205
|
+
|
|
2206
|
+
// src/client/component/field/field-with-state.tsx
|
|
2207
|
+
import { useAtomValue as useAtomValue3 } from "jotai";
|
|
2208
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
2209
|
+
function withState(Component) {
|
|
2210
|
+
const WithFieldState = (props) => {
|
|
2211
|
+
const fieldState = useAtomValue3(reportFieldStateAtom(props.field.name));
|
|
2212
|
+
const hidden = fieldState?.hidden ?? props.field.hidden ?? false;
|
|
2213
|
+
if (hidden) {
|
|
2214
|
+
return null;
|
|
2215
|
+
}
|
|
2216
|
+
return /* @__PURE__ */ jsx24(Component, { ...props, disabled: fieldState?.disabled ?? props.disabled });
|
|
2217
|
+
};
|
|
2218
|
+
return WithFieldState;
|
|
2219
|
+
}
|
|
2220
|
+
|
|
2221
|
+
// src/client/component/field/field.tsx
|
|
2222
|
+
var Field2 = withState(withError(Field));
|
|
2223
|
+
|
|
2224
|
+
// src/component/field/field-list-item.tsx
|
|
2005
2225
|
import { twMerge as twMerge6 } from "tailwind-merge";
|
|
2006
|
-
import { jsx as
|
|
2226
|
+
import { jsx as jsx25, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2227
|
+
function FieldListItem(props) {
|
|
2228
|
+
function handleRemove() {
|
|
2229
|
+
if (props.canRemove && props.onRemove) {
|
|
2230
|
+
props.onRemove(props.index);
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
const removeButton = props.canRemove && props.onRemove != null && /* @__PURE__ */ jsx25(
|
|
2234
|
+
"button",
|
|
2235
|
+
{
|
|
2236
|
+
"aria-label": `Remove ${props.label} item ${props.index + 1}`,
|
|
2237
|
+
className: twMerge6(
|
|
2238
|
+
"rounded p-1 text-xl text-slate-400",
|
|
2239
|
+
"transition-colors duration-150",
|
|
2240
|
+
"hover:text-red-500",
|
|
2241
|
+
"focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:outline-none",
|
|
2242
|
+
"dark:text-slate-500 dark:hover:text-red-400"
|
|
2243
|
+
),
|
|
2244
|
+
onClick: handleRemove,
|
|
2245
|
+
type: "button",
|
|
2246
|
+
children: /* @__PURE__ */ jsx25("span", { "aria-hidden": "true", children: "\xD7" })
|
|
2247
|
+
}
|
|
2248
|
+
);
|
|
2249
|
+
if (props.isMultiField) {
|
|
2250
|
+
return /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-slate-100 p-4 dark:border-slate-900", children: [
|
|
2251
|
+
/* @__PURE__ */ jsxs9("div", { className: "mb-3 flex items-center justify-between", children: [
|
|
2252
|
+
/* @__PURE__ */ jsxs9("span", { className: "text-sm font-medium text-slate-400 dark:text-slate-500", children: [
|
|
2253
|
+
props.label,
|
|
2254
|
+
" ",
|
|
2255
|
+
props.index + 1
|
|
2256
|
+
] }),
|
|
2257
|
+
removeButton
|
|
2258
|
+
] }),
|
|
2259
|
+
/* @__PURE__ */ jsx25(Group, { children: props.children })
|
|
2260
|
+
] });
|
|
2261
|
+
}
|
|
2262
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex items-start gap-2", children: [
|
|
2263
|
+
/* @__PURE__ */ jsx25(Group, { children: props.children }),
|
|
2264
|
+
removeButton && /* @__PURE__ */ jsx25("div", { className: "shrink-0", children: removeButton })
|
|
2265
|
+
] });
|
|
2266
|
+
}
|
|
2267
|
+
|
|
2268
|
+
// src/client/component/field/field-list.tsx
|
|
2269
|
+
import { twMerge as twMerge7 } from "tailwind-merge";
|
|
2270
|
+
|
|
2271
|
+
// src/client/hook/use-field-list.ts
|
|
2272
|
+
import { useSetAtom as useSetAtom2 } from "jotai";
|
|
2273
|
+
import { useCallback as useCallback5, useRef as useRef4, useState as useState2 } from "react";
|
|
2274
|
+
function useFieldList(field, value) {
|
|
2275
|
+
const min2 = field.advanced?.length?.min ?? 1;
|
|
2276
|
+
const max2 = field.advanced?.length?.max ?? Infinity;
|
|
2277
|
+
const [items, setItems] = useState2(
|
|
2278
|
+
() => getInitialList(field, value)
|
|
2279
|
+
);
|
|
2280
|
+
const nextId = useRef4(items.length);
|
|
2281
|
+
const itemsRef = useRef4(items);
|
|
2282
|
+
itemsRef.current = items;
|
|
2283
|
+
const setValues = useSetAtom2(valueAtom);
|
|
2284
|
+
const addItem = useCallback5(() => {
|
|
2285
|
+
setItems((previous) => {
|
|
2286
|
+
if (previous.length >= max2) {
|
|
2287
|
+
return previous;
|
|
2288
|
+
}
|
|
2289
|
+
const id = nextId.current++;
|
|
2290
|
+
return [...previous, id];
|
|
2291
|
+
});
|
|
2292
|
+
}, [max2]);
|
|
2293
|
+
const handleRemove = useCallback5(
|
|
2294
|
+
(index) => {
|
|
2295
|
+
if (items.length <= min2) {
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
const stableId = items[index];
|
|
2299
|
+
setItems((previous) => {
|
|
2300
|
+
if (previous.length <= min2) {
|
|
2301
|
+
return previous;
|
|
2302
|
+
}
|
|
2303
|
+
return previous.filter((_, i) => i !== index);
|
|
2304
|
+
});
|
|
2305
|
+
setValues((current) => {
|
|
2306
|
+
const next = { ...current };
|
|
2307
|
+
const prefix = `${field.name}.`;
|
|
2308
|
+
const leafNames = [];
|
|
2309
|
+
for (const row of field.fields) {
|
|
2310
|
+
if (isColumn(row)) {
|
|
2311
|
+
for (const columnField of row.fields) {
|
|
2312
|
+
leafNames.push(columnField.name);
|
|
2313
|
+
}
|
|
2314
|
+
} else {
|
|
2315
|
+
leafNames.push(row.name);
|
|
2316
|
+
}
|
|
2317
|
+
}
|
|
2318
|
+
for (const name of leafNames) {
|
|
2319
|
+
delete next[`${prefix}${stableId}.${name}`];
|
|
2320
|
+
}
|
|
2321
|
+
return next;
|
|
2322
|
+
});
|
|
2323
|
+
},
|
|
2324
|
+
[field.name, field.fields, items, min2, setValues]
|
|
2325
|
+
);
|
|
2326
|
+
const canAdd = items.length < max2;
|
|
2327
|
+
const canRemove = items.length > min2;
|
|
2328
|
+
return [items, addItem, handleRemove, canAdd, canRemove, max2];
|
|
2329
|
+
}
|
|
2330
|
+
|
|
2331
|
+
// src/client/component/field/field-list.tsx
|
|
2332
|
+
import { Fragment as Fragment3, jsx as jsx26, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2333
|
+
function FieldList(props) {
|
|
2334
|
+
const [items, addItem, handleRemove, canAdd, canRemove, max2] = useFieldList(
|
|
2335
|
+
props.field,
|
|
2336
|
+
props.value
|
|
2337
|
+
);
|
|
2338
|
+
const label = getLabel(props.field);
|
|
2339
|
+
const action = props.field.advanced?.action ?? "Add item";
|
|
2340
|
+
const hasLimit = max2 !== Infinity;
|
|
2341
|
+
const isMultiField = isMultiFieldList(props.field);
|
|
2342
|
+
return /* @__PURE__ */ jsxs10(Fragment3, { children: [
|
|
2343
|
+
items.map((key, index) => /* @__PURE__ */ jsx26(
|
|
2344
|
+
FieldListItem,
|
|
2345
|
+
{
|
|
2346
|
+
canRemove,
|
|
2347
|
+
index,
|
|
2348
|
+
isMultiField,
|
|
2349
|
+
label,
|
|
2350
|
+
onRemove: handleRemove,
|
|
2351
|
+
children: props.children(key)
|
|
2352
|
+
},
|
|
2353
|
+
key
|
|
2354
|
+
)),
|
|
2355
|
+
/* @__PURE__ */ jsxs10(
|
|
2356
|
+
"button",
|
|
2357
|
+
{
|
|
2358
|
+
"aria-disabled": !canAdd,
|
|
2359
|
+
"aria-label": hasLimit ? `${action}, ${items.length} of ${max2}` : action,
|
|
2360
|
+
className: twMerge7(
|
|
2361
|
+
"flex w-full items-center gap-1.5 rounded py-1",
|
|
2362
|
+
"text-sm font-medium text-slate-500",
|
|
2363
|
+
"transition-colors duration-150",
|
|
2364
|
+
"hover:text-slate-800",
|
|
2365
|
+
"focus-visible:ring-2 focus-visible:ring-slate-400 focus-visible:ring-offset-2 focus-visible:outline-none",
|
|
2366
|
+
"dark:text-slate-400 dark:hover:text-slate-200",
|
|
2367
|
+
!canAdd && "cursor-not-allowed opacity-50 hover:text-slate-500 dark:hover:text-slate-400"
|
|
2368
|
+
),
|
|
2369
|
+
disabled: !canAdd,
|
|
2370
|
+
onClick: addItem,
|
|
2371
|
+
type: "button",
|
|
2372
|
+
children: [
|
|
2373
|
+
/* @__PURE__ */ jsx26("span", { "aria-hidden": "true", children: "+" }),
|
|
2374
|
+
action,
|
|
2375
|
+
hasLimit && /* @__PURE__ */ jsxs10(
|
|
2376
|
+
"span",
|
|
2377
|
+
{
|
|
2378
|
+
"aria-hidden": "true",
|
|
2379
|
+
className: "ml-auto text-slate-400 tabular-nums dark:text-slate-500",
|
|
2380
|
+
children: [
|
|
2381
|
+
items.length,
|
|
2382
|
+
" / ",
|
|
2383
|
+
max2
|
|
2384
|
+
]
|
|
2385
|
+
}
|
|
2386
|
+
)
|
|
2387
|
+
]
|
|
2388
|
+
}
|
|
2389
|
+
)
|
|
2390
|
+
] });
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
// src/component/list.tsx
|
|
2394
|
+
import { jsx as jsx27 } from "react/jsx-runtime";
|
|
2395
|
+
function List(props) {
|
|
2396
|
+
const empty = Array.isArray(props.field.fields) && props.field.fields.length === 0;
|
|
2397
|
+
return /* @__PURE__ */ jsx27(
|
|
2398
|
+
FieldSetBase,
|
|
2399
|
+
{
|
|
2400
|
+
description: props.field.description,
|
|
2401
|
+
empty,
|
|
2402
|
+
id: props.field.name,
|
|
2403
|
+
title: props.field.label,
|
|
2404
|
+
children: props.children
|
|
2405
|
+
}
|
|
2406
|
+
);
|
|
2407
|
+
}
|
|
2408
|
+
|
|
2409
|
+
// src/client/component/guard/list-guard.tsx
|
|
2410
|
+
import { jsx as jsx28 } from "react/jsx-runtime";
|
|
2411
|
+
function ListGuard({ children, field, value }) {
|
|
2412
|
+
return /* @__PURE__ */ jsx28(VisibilityGuard, { container: field, fields: field.fields, children: /* @__PURE__ */ jsx28(List, { field, children: /* @__PURE__ */ jsx28(FieldList, { field, value, children }) }) });
|
|
2413
|
+
}
|
|
2414
|
+
|
|
2415
|
+
// src/component/column.tsx
|
|
2416
|
+
import { twMerge as twMerge8 } from "tailwind-merge";
|
|
2417
|
+
import { jsx as jsx29 } from "react/jsx-runtime";
|
|
2007
2418
|
function Column(props) {
|
|
2008
2419
|
const cols2 = getColumn(props.column?.advanced?.cols);
|
|
2009
|
-
return /* @__PURE__ */
|
|
2420
|
+
return /* @__PURE__ */ jsx29("div", { className: "flex w-full flex-col gap-4", children: /* @__PURE__ */ jsx29("div", { className: twMerge8("grid grid-cols-1 gap-3 sm:gap-4", cols2), children: props.children }) });
|
|
2010
2421
|
}
|
|
2011
2422
|
|
|
2012
2423
|
// src/component/slot/slot-base.tsx
|
|
2013
2424
|
import { Fragment as Fragment4 } from "react";
|
|
2014
|
-
|
|
2425
|
+
|
|
2426
|
+
// src/component/slot/slot-list.tsx
|
|
2427
|
+
import { jsx as jsx30 } from "react/jsx-runtime";
|
|
2428
|
+
function SlotList(props) {
|
|
2429
|
+
const fields = Array.isArray(props.field.fields) ? props.field.fields.map((field) => {
|
|
2430
|
+
if (isField(field)) {
|
|
2431
|
+
return {
|
|
2432
|
+
...field,
|
|
2433
|
+
name: `${props.field.name}.${props.index}.${field.name}`
|
|
2434
|
+
};
|
|
2435
|
+
}
|
|
2436
|
+
if (isColumn(field)) {
|
|
2437
|
+
return {
|
|
2438
|
+
...field,
|
|
2439
|
+
fields: field.fields.map((columnField) => ({
|
|
2440
|
+
...columnField,
|
|
2441
|
+
name: `${props.field.name}.${props.index}.${columnField.name}`
|
|
2442
|
+
}))
|
|
2443
|
+
};
|
|
2444
|
+
}
|
|
2445
|
+
return field;
|
|
2446
|
+
}) : [];
|
|
2447
|
+
return /* @__PURE__ */ jsx30(
|
|
2448
|
+
SlotBase,
|
|
2449
|
+
{
|
|
2450
|
+
children: props.children,
|
|
2451
|
+
components: props.components,
|
|
2452
|
+
disabled: props.disabled,
|
|
2453
|
+
fields,
|
|
2454
|
+
style: props.style,
|
|
2455
|
+
value: props.value
|
|
2456
|
+
}
|
|
2457
|
+
);
|
|
2458
|
+
}
|
|
2459
|
+
|
|
2460
|
+
// src/component/slot/slot-base.tsx
|
|
2461
|
+
import { jsx as jsx31, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2015
2462
|
function SlotBase(props) {
|
|
2016
|
-
const {
|
|
2017
|
-
return prepare(props.fields).map((field, index) => /* @__PURE__ */
|
|
2018
|
-
isColumn(field) && /* @__PURE__ */
|
|
2019
|
-
isField(field) && /* @__PURE__ */
|
|
2463
|
+
const { field: Field3, list: List2 } = props.components;
|
|
2464
|
+
return prepare(props.fields).map((field, index) => /* @__PURE__ */ jsxs11(Fragment4, { children: [
|
|
2465
|
+
isColumn(field) && /* @__PURE__ */ jsx31(Column, { column: field, children: /* @__PURE__ */ jsx31(SlotBase, { ...props, fields: field.fields }) }),
|
|
2466
|
+
isField(field) && /* @__PURE__ */ jsx31(Field3, { disabled: props.disabled, field, style: props.style, children: props.children }),
|
|
2467
|
+
isList(field) && /* @__PURE__ */ jsx31(List2, { field, value: props.value, children: (index2) => /* @__PURE__ */ jsx31(
|
|
2468
|
+
SlotList,
|
|
2469
|
+
{
|
|
2470
|
+
children: props.children,
|
|
2471
|
+
components: props.components,
|
|
2472
|
+
disabled: props.disabled,
|
|
2473
|
+
field,
|
|
2474
|
+
index: index2,
|
|
2475
|
+
style: props.style,
|
|
2476
|
+
value: props.value
|
|
2477
|
+
}
|
|
2478
|
+
) })
|
|
2020
2479
|
] }, index));
|
|
2021
2480
|
}
|
|
2022
2481
|
|
|
2023
2482
|
// src/component/slot/slot-create.tsx
|
|
2024
|
-
import { jsx as
|
|
2025
|
-
function createSlot(
|
|
2026
|
-
const CreateSlot = (props) => /* @__PURE__ */
|
|
2483
|
+
import { jsx as jsx32 } from "react/jsx-runtime";
|
|
2484
|
+
function createSlot(components) {
|
|
2485
|
+
const CreateSlot = (props) => /* @__PURE__ */ jsx32(SlotBase, { ...props, components });
|
|
2027
2486
|
return CreateSlot;
|
|
2028
2487
|
}
|
|
2029
2488
|
|
|
2489
|
+
// src/client/component/slot/slot.tsx
|
|
2490
|
+
var Slot = createSlot({ field: Field2, list: ListGuard });
|
|
2491
|
+
|
|
2030
2492
|
// src/client/hook/use-form-action.ts
|
|
2031
|
-
import { useSetAtom as
|
|
2493
|
+
import { useSetAtom as useSetAtom3 } from "jotai";
|
|
2032
2494
|
import { startTransition, useActionState } from "react";
|
|
2033
2495
|
function useFormState(getSchema2, action, options) {
|
|
2034
|
-
const {
|
|
2035
|
-
|
|
2036
|
-
|
|
2496
|
+
const {
|
|
2497
|
+
onSuccess,
|
|
2498
|
+
preserveValues = false,
|
|
2499
|
+
validation = true,
|
|
2500
|
+
translations
|
|
2501
|
+
} = options ?? {};
|
|
2502
|
+
const setError = useSetAtom3(reportErrorAtom);
|
|
2503
|
+
const clearValues = useSetAtom3(clearAllValueAtom);
|
|
2037
2504
|
const initialState = {
|
|
2038
2505
|
data: null,
|
|
2039
2506
|
error: null,
|
|
@@ -2042,7 +2509,7 @@ function useFormState(getSchema2, action, options) {
|
|
|
2042
2509
|
const [state, formAction, isPending] = useActionState(
|
|
2043
2510
|
async (prevState, formData) => {
|
|
2044
2511
|
const [schemas, fields] = getSchema2();
|
|
2045
|
-
const schema = buildSchema(schemas, fields,
|
|
2512
|
+
const schema = buildSchema(schemas, fields, translations);
|
|
2046
2513
|
if (validation === false) {
|
|
2047
2514
|
if (action) {
|
|
2048
2515
|
return await action(formData, schema);
|
|
@@ -2057,16 +2524,23 @@ function useFormState(getSchema2, action, options) {
|
|
|
2057
2524
|
setError(errors);
|
|
2058
2525
|
});
|
|
2059
2526
|
return failure(form, {
|
|
2060
|
-
description:
|
|
2527
|
+
description: translate(
|
|
2528
|
+
"Please correct the errors and try again.",
|
|
2529
|
+
translations
|
|
2530
|
+
),
|
|
2061
2531
|
details: [],
|
|
2062
|
-
title:
|
|
2532
|
+
title: translate(
|
|
2533
|
+
"There were validation errors submitting the form.",
|
|
2534
|
+
translations
|
|
2535
|
+
)
|
|
2063
2536
|
});
|
|
2064
2537
|
}
|
|
2538
|
+
const unflattened = unflatten(form);
|
|
2065
2539
|
if (action) {
|
|
2066
2540
|
try {
|
|
2067
|
-
const result = await action(
|
|
2541
|
+
const result = await action(unflattened, schema);
|
|
2068
2542
|
if (!result.success) {
|
|
2069
|
-
return failure(
|
|
2543
|
+
return failure(unflattened, result.error);
|
|
2070
2544
|
}
|
|
2071
2545
|
onSuccess?.(result.data);
|
|
2072
2546
|
if (!preserveValues) {
|
|
@@ -2074,12 +2548,15 @@ function useFormState(getSchema2, action, options) {
|
|
|
2074
2548
|
clearValues();
|
|
2075
2549
|
});
|
|
2076
2550
|
}
|
|
2077
|
-
return success(
|
|
2551
|
+
return success(unflattened, preserveValues);
|
|
2078
2552
|
} catch (error) {
|
|
2079
2553
|
logger.error("Error executing form action:", error);
|
|
2080
|
-
return failure(
|
|
2081
|
-
title:
|
|
2082
|
-
|
|
2554
|
+
return failure(unflattened, {
|
|
2555
|
+
title: translate(
|
|
2556
|
+
"An unexpected error occurred submitting the form.",
|
|
2557
|
+
translations
|
|
2558
|
+
),
|
|
2559
|
+
details: buildError(error, translations)
|
|
2083
2560
|
});
|
|
2084
2561
|
}
|
|
2085
2562
|
}
|
|
@@ -2089,9 +2566,11 @@ function useFormState(getSchema2, action, options) {
|
|
|
2089
2566
|
);
|
|
2090
2567
|
return [formAction, state, isPending];
|
|
2091
2568
|
}
|
|
2092
|
-
function buildError(error) {
|
|
2093
|
-
|
|
2094
|
-
|
|
2569
|
+
function buildError(error, translations) {
|
|
2570
|
+
if (error instanceof Error) {
|
|
2571
|
+
return [error.message];
|
|
2572
|
+
}
|
|
2573
|
+
return [translate("Unknown error", translations)];
|
|
2095
2574
|
}
|
|
2096
2575
|
function success(value, preserveValues = false) {
|
|
2097
2576
|
const data = preserveValues ? value : null;
|
|
@@ -2110,16 +2589,16 @@ function failure(value, error) {
|
|
|
2110
2589
|
}
|
|
2111
2590
|
|
|
2112
2591
|
// src/client/hook/use-schema.ts
|
|
2113
|
-
import {
|
|
2592
|
+
import { useCallback as useCallback7, useRef as useRef5 } from "react";
|
|
2114
2593
|
|
|
2115
2594
|
// src/client/hook/use-store.ts
|
|
2116
|
-
import { useCallback as
|
|
2117
|
-
import { useSetAtom as
|
|
2595
|
+
import { useCallback as useCallback6 } from "react";
|
|
2596
|
+
import { useSetAtom as useSetAtom4 } from "jotai";
|
|
2118
2597
|
function useStore2() {
|
|
2119
|
-
const clearErrors =
|
|
2120
|
-
const
|
|
2121
|
-
const
|
|
2122
|
-
return
|
|
2598
|
+
const clearErrors = useSetAtom4(clearInputErrorAtom);
|
|
2599
|
+
const clearValues = useSetAtom4(clearInputValueAtom);
|
|
2600
|
+
const clearSources = useSetAtom4(clearInputSourceAtom);
|
|
2601
|
+
return useCallback6(
|
|
2123
2602
|
(names) => {
|
|
2124
2603
|
const target = Array.isArray(names) ? names : [names];
|
|
2125
2604
|
clearErrors(target);
|
|
@@ -2133,42 +2612,34 @@ function useStore2() {
|
|
|
2133
2612
|
// src/client/hook/use-schema.ts
|
|
2134
2613
|
function useSchema() {
|
|
2135
2614
|
const clear = useStore2();
|
|
2136
|
-
const schemaRef =
|
|
2137
|
-
const fieldsRef =
|
|
2138
|
-
const
|
|
2139
|
-
const onMount = useCallback5((name, schema, field) => {
|
|
2615
|
+
const schemaRef = useRef5({});
|
|
2616
|
+
const fieldsRef = useRef5([]);
|
|
2617
|
+
const onMount = useCallback7((name, schema, field) => {
|
|
2140
2618
|
if (!(name in schemaRef.current)) {
|
|
2141
2619
|
schemaRef.current[name] = schema;
|
|
2142
2620
|
fieldsRef.current.push(field);
|
|
2143
2621
|
}
|
|
2144
2622
|
}, []);
|
|
2145
|
-
const onUnmount =
|
|
2623
|
+
const onUnmount = useCallback7(
|
|
2146
2624
|
(name) => {
|
|
2147
2625
|
if (schemaRef.current[name]) {
|
|
2148
2626
|
delete schemaRef.current[name];
|
|
2149
2627
|
fieldsRef.current = fieldsRef.current.filter((field) => {
|
|
2150
2628
|
return field.name !== name;
|
|
2151
2629
|
});
|
|
2152
|
-
|
|
2153
|
-
startTransition2(() => {
|
|
2154
|
-
if (pendingUnmounts.current.size > 0) {
|
|
2155
|
-
clear(Array.from(pendingUnmounts.current));
|
|
2156
|
-
pendingUnmounts.current.clear();
|
|
2157
|
-
}
|
|
2158
|
-
});
|
|
2630
|
+
clear([name]);
|
|
2159
2631
|
}
|
|
2160
2632
|
},
|
|
2161
2633
|
[clear]
|
|
2162
2634
|
);
|
|
2163
|
-
|
|
2635
|
+
const getSchema2 = useCallback7(() => {
|
|
2164
2636
|
return [schemaRef.current, fieldsRef.current];
|
|
2165
|
-
}
|
|
2637
|
+
}, []);
|
|
2166
2638
|
return [getSchema2, onMount, onUnmount];
|
|
2167
2639
|
}
|
|
2168
2640
|
|
|
2169
2641
|
// src/client/component/form-content.tsx
|
|
2170
|
-
import { Fragment as Fragment5, jsx as
|
|
2171
|
-
var Slot = createSlot(Field2);
|
|
2642
|
+
import { Fragment as Fragment5, jsx as jsx33, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2172
2643
|
function FormContent(props) {
|
|
2173
2644
|
const translations = props.translations?.[props.lang ?? ""];
|
|
2174
2645
|
const [schema, onMount, onUnmount] = useSchema();
|
|
@@ -2179,8 +2650,8 @@ function FormContent(props) {
|
|
|
2179
2650
|
});
|
|
2180
2651
|
const isShowingError = props.config.validation.showError && !state.success && state.error;
|
|
2181
2652
|
const value = state.data ?? props.value;
|
|
2182
|
-
return /* @__PURE__ */
|
|
2183
|
-
isShowingError && renderIfExists(props.config.alert, (Alert) => /* @__PURE__ */
|
|
2653
|
+
return /* @__PURE__ */ jsxs12(Fragment5, { children: [
|
|
2654
|
+
isShowingError && renderIfExists(props.config.alert, (Alert) => /* @__PURE__ */ jsx33("div", { className: "mb-4 w-full", children: /* @__PURE__ */ jsx33(
|
|
2184
2655
|
Alert,
|
|
2185
2656
|
{
|
|
2186
2657
|
description: state.error?.description,
|
|
@@ -2188,7 +2659,7 @@ function FormContent(props) {
|
|
|
2188
2659
|
title: state.error.title
|
|
2189
2660
|
}
|
|
2190
2661
|
) })),
|
|
2191
|
-
/* @__PURE__ */
|
|
2662
|
+
/* @__PURE__ */ jsx33(
|
|
2192
2663
|
Form,
|
|
2193
2664
|
{
|
|
2194
2665
|
action,
|
|
@@ -2199,19 +2670,28 @@ function FormContent(props) {
|
|
|
2199
2670
|
noValidate: true,
|
|
2200
2671
|
readOnly: props.readOnly,
|
|
2201
2672
|
sections: props.sections,
|
|
2202
|
-
children: ({ disabled, fields }) => /* @__PURE__ */
|
|
2203
|
-
|
|
2673
|
+
children: ({ disabled, fields }) => /* @__PURE__ */ jsx33(
|
|
2674
|
+
Slot,
|
|
2204
2675
|
{
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2676
|
+
disabled,
|
|
2677
|
+
fields,
|
|
2678
|
+
style: props.config.style,
|
|
2679
|
+
value,
|
|
2680
|
+
children: (internal) => /* @__PURE__ */ jsx33(
|
|
2681
|
+
Input,
|
|
2682
|
+
{
|
|
2683
|
+
...internal,
|
|
2684
|
+
config: props.config,
|
|
2685
|
+
context: props.context,
|
|
2686
|
+
onMount,
|
|
2687
|
+
onUnmount,
|
|
2688
|
+
onValueChange: props.onValueChange,
|
|
2689
|
+
translations,
|
|
2690
|
+
value
|
|
2691
|
+
}
|
|
2692
|
+
)
|
|
2213
2693
|
}
|
|
2214
|
-
)
|
|
2694
|
+
)
|
|
2215
2695
|
}
|
|
2216
2696
|
)
|
|
2217
2697
|
] });
|
|
@@ -2219,9 +2699,9 @@ function FormContent(props) {
|
|
|
2219
2699
|
|
|
2220
2700
|
// src/client/component/form.tsx
|
|
2221
2701
|
import { Provider } from "jotai";
|
|
2222
|
-
import { jsx as
|
|
2702
|
+
import { jsx as jsx34 } from "react/jsx-runtime";
|
|
2223
2703
|
function Form2(props) {
|
|
2224
|
-
return /* @__PURE__ */
|
|
2704
|
+
return /* @__PURE__ */ jsx34(Provider, { children: /* @__PURE__ */ jsx34(FormContent, { ...props }) });
|
|
2225
2705
|
}
|
|
2226
2706
|
export {
|
|
2227
2707
|
Form2 as Form
|