@formancy/react 0.9.0 → 0.10.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/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +190 -81
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/context.tsx","../src/use-field.ts","../src/use-repeater.ts","../src/use-wizard.ts","../src/use-submit.ts","../src/go-to-field.ts","../src/fields/internals.tsx","../src/form.tsx","../src/error-summary.tsx","../src/rich-text.tsx","../src/options-source.ts","../src/scanning.ts","../src/uploads.ts","../src/rich-text-editor.ts","../src/resume-notice.tsx"],"mappings":";;;;;wBAsBgB,mBACd,QACA,OACA;EAEA,QAAQ;;;;;;;EAOR,QAAQ;EACR,WAAW;oBACZ,IAAA;wBAsBe,iBAAiB;;;;;;;;;wBAkBjB,eAAe;;;UCvEd,qBAAqB;EACpC,SAAS;EACT;;EAEA,cAAc;;EAEd;IAAc;IAAY;;;EAE1B;IAAc;;;;;;;;;;;;;wBAaA,SAAS,eAAe,OAAO;;;UCrB9B;EACf;;EAEA;;EAEA;;EAEA;EACA;EACA,UAAU;;EAEV,QAAQ,cAAc;;;;;;;wBAQR,YAAY,eAAe,OAAO;;;UCrBjC;EACf;EACA;;;EAGA;EACA;;EAEA,QAAQ;EACR;;EAEA,KAAK;;;;;;;wBAQS,aAAa;;;;;;;;;;;wBCTb;EAAqB;EAAa,QAAQ;;;;;;;;;;;wBCD1C,iBAAiB;;;;;;;;;;;;;;;;UCYhB;EACf;EACA;;KAGU,iBAAiB,cAAc;UAE1B;EACf,SAAS,QAAQ,OAAO,WAAW;EACnC,SAAS,eAAe;;UAGT;EACf;EACA,QAAQ;;EAER;;UAGe;;;;;;;EAOf,SAAS;EACT,WAAW;;;;;;;EAOX;EACA;;;;;EAKA;EACA,YAAY,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/context.tsx","../src/use-field.ts","../src/use-repeater.ts","../src/use-wizard.ts","../src/use-submit.ts","../src/go-to-field.ts","../src/fields/internals.tsx","../src/form.tsx","../src/error-summary.tsx","../src/rich-text.tsx","../src/options-source.ts","../src/scanning.ts","../src/uploads.ts","../src/rich-text-editor.ts","../src/resume-notice.tsx"],"mappings":";;;;;wBAsBgB,mBACd,QACA,OACA;EAEA,QAAQ;;;;;;;EAOR,QAAQ;EACR,WAAW;oBACZ,IAAA;wBAsBe,iBAAiB;;;;;;;;;wBAkBjB,eAAe;;;UCvEd,qBAAqB;EACpC,SAAS;EACT;;EAEA,cAAc;;EAEd;IAAc;IAAY;;;EAE1B;IAAc;;;;;;;;;;;;;wBAaA,SAAS,eAAe,OAAO;;;UCrB9B;EACf;;EAEA;;EAEA;;EAEA;EACA;EACA,UAAU;;EAEV,QAAQ,cAAc;;;;;;;wBAQR,YAAY,eAAe,OAAO;;;UCrBjC;EACf;EACA;;;EAGA;EACA;;EAEA,QAAQ;EACR;;EAEA,KAAK;;;;;;;wBAQS,aAAa;;;;;;;;;;;wBCTb;EAAqB;EAAa,QAAQ;;;;;;;;;;;wBCD1C,iBAAiB;;;;;;;;;;;;;;;;UCYhB;EACf;EACA;;KAGU,iBAAiB,cAAc;UAE1B;EACf,SAAS,QAAQ,OAAO,WAAW;EACnC,SAAS,eAAe;;UAGT;EACf;EACA,QAAQ;;EAER;;UAGe;;;;;;;EAOf,SAAS;EACT,WAAW;;;;;;;EAOX;EACA;;;;;EAKA;EACA,YAAY,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;wBCNP,aAAa,OAAO,oCAAiB,IAAA;;;UCrDpC;EACf,SAAS;;;;;;;;;;;wBAYK,eAAe,UAAU,oCAAiB,IAAA;;;;;;;;;;;;;;;;;;;;wBCG1C,WAAW;EAAY;IAAmB;;;;;;;;;;UCZzC;;;;;EAKf;;EAEA;;EAEA;;EAEA;;EAEA;;;;;;;;;EASA;;;;;;;;EAQA;;EAEA,QAAQ;;;;;;;;;;;UAYO;;;;;;;;;;;;;EAaf,QAAQ,SAAS,iBAAiB,QAAQ;;EAE1C;;;;;;EAMA;;EAEA;;;;;;;;;;;;;KAcU,iBAAiB,SAAS,eAAe;qBAIxC,wCAAsB,SAAA,SAAA,eAAA;;;;;;;;;wBAUnB,qBAAqB;;;;;;;;;;;;UC9FpB;;EAEf;;EAEA;;;;;;;;;;;;;;;;;;;KAoBU,WAAW,SAAS,gBAAgB;qBAInC,iCAAe,SAAA;;;;;;;;wBASZ,cAAc;;;;;;;;;;;UC/Bb;;;;;EAKf;;EAEA,QAAQ;;EAER,WAAW,cAAc;;;;;;;;;;;;KAaf,YAAY,MAAM,MAAM,SAAS,kBAAkB,QAAQ;qBAI1D,kCAAgB,SAAA;;;;;;;;;wBAUb,eAAe;;;;;;;;;;;;;;;;;;;;;UChCd;;EAEf;;EAEA,WAAW;;;;;;;;;;;;;EAaX,MAAM,SAAS,aAAa;;EAE5B,WAAW,SAAS;EACpB;;UAGe;;WAEN,SAAS;;WAET;;WAEA,WAAW;WACX;;;;;;;;;;WAUA,YAAY,SAAS;;KAGpB,yBAAyB,OAAO,wBAAwB;qBAIvD,wCAAsB,SAAA;;;;;;;;;wBAUnB,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;UC9C3B;WACN;WACA,SAAS;aAAyB;aAAuB;;;UAGnD;;WAEN,YAAY;;WAEZ,SAAS,SAAS;;wBAGb,eAAe,WAAW,UAAU,oBAAoB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Fragment, createContext, useCallback, useContext, useEffect, useId, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
2
|
-
import { cancelUploads, fieldUploads, formatPath, inOptionOrder, parsePath, placedGroup, placedPage, thumbnailSize, ticked } from "@formancy/core";
|
|
3
|
-
import { answersToReview, countSentence, createFormText, errorSentence, optionsStatus } from "@formancy/core/words";
|
|
2
|
+
import { cancelUploads, fieldUploads, formatPath, hasReadOnlyControl, inOptionOrder, parsePath, placedGroup, placedPage, thumbnailSize, ticked } from "@formancy/core";
|
|
3
|
+
import { answerInWords, answersToReview, countSentence, createFormText, errorSentence, optionsStatus } from "@formancy/core/words";
|
|
4
4
|
import { LAYOUT_LEAF_KINDS, acceptRemoteAnswer, answerFromText, applyRichCommand, capRemoteAnswer, datagridColumns, editMasked, formatMasked, isImageSource, layoutChildren, layoutNodeShows, maskIsNumeric, maskPlaceholder, narrowOptionsByLabel, parseRichText, resolveText, resolvedLocale } from "@formancy/spec";
|
|
5
5
|
import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
|
|
6
6
|
import { flushSync } from "react-dom";
|
|
@@ -464,7 +464,10 @@ function Review({ onChange, children }) {
|
|
|
464
464
|
"data-formancy-part": "review-answer",
|
|
465
465
|
children: [
|
|
466
466
|
/* @__PURE__ */ jsx("dt", { children: answer.label }),
|
|
467
|
-
/* @__PURE__ */ jsx("dd", {
|
|
467
|
+
/* @__PURE__ */ jsx("dd", {
|
|
468
|
+
...answer.answered ? {} : { "data-formancy-part": "review-unanswered" },
|
|
469
|
+
children: answer.said
|
|
470
|
+
}),
|
|
468
471
|
/* @__PURE__ */ jsx("dd", { children: /* @__PURE__ */ jsxs("button", {
|
|
469
472
|
type: "button",
|
|
470
473
|
onClick: () => onChange(answer),
|
|
@@ -556,7 +559,8 @@ function useSourcedOptions(field, query, enabled = true) {
|
|
|
556
559
|
const debounceMs = source?.debounceMs ?? DEBOUNCE_MS;
|
|
557
560
|
const minQueryLength = source?.minQueryLength ?? MIN_QUERY;
|
|
558
561
|
const maxRows = source?.maxRows ?? MAX_ROWS;
|
|
559
|
-
const stored =
|
|
562
|
+
const stored = storedValues(field.value);
|
|
563
|
+
const storedKey = stored.join("\0");
|
|
560
564
|
const path = field.path;
|
|
561
565
|
const disabled = field.disabled;
|
|
562
566
|
const asked = useRef(0);
|
|
@@ -628,18 +632,19 @@ function useSourcedOptions(field, query, enabled = true) {
|
|
|
628
632
|
]);
|
|
629
633
|
const askedFor = useRef(/* @__PURE__ */ new Set());
|
|
630
634
|
useEffect(() => {
|
|
631
|
-
if (!enabled || source === void 0 ||
|
|
632
|
-
|
|
633
|
-
|
|
635
|
+
if (!enabled || source === void 0 || storedKey === "") return;
|
|
636
|
+
const unnamed = storedKey.split("\0").filter((value) => !named.has(value) && !askedFor.current.has(value));
|
|
637
|
+
if (unnamed.length === 0) return;
|
|
638
|
+
for (const value of unnamed) askedFor.current.add(value);
|
|
634
639
|
const controller = new AbortController();
|
|
635
640
|
source.resolve({
|
|
636
641
|
kind: "labels",
|
|
637
642
|
source: name ?? "",
|
|
638
643
|
path,
|
|
639
644
|
query: "",
|
|
640
|
-
values:
|
|
645
|
+
values: unnamed,
|
|
641
646
|
locale: engine.locale(),
|
|
642
|
-
limit:
|
|
647
|
+
limit: unnamed.length,
|
|
643
648
|
signal: controller.signal
|
|
644
649
|
}).then((answer) => {
|
|
645
650
|
const accepted = acceptRemoteAnswer(answer);
|
|
@@ -656,7 +661,7 @@ function useSourcedOptions(field, query, enabled = true) {
|
|
|
656
661
|
source,
|
|
657
662
|
name,
|
|
658
663
|
path,
|
|
659
|
-
|
|
664
|
+
storedKey,
|
|
660
665
|
named,
|
|
661
666
|
engine
|
|
662
667
|
]);
|
|
@@ -667,13 +672,11 @@ function useSourcedOptions(field, query, enabled = true) {
|
|
|
667
672
|
})),
|
|
668
673
|
remote: null
|
|
669
674
|
};
|
|
670
|
-
const offered = [...rows];
|
|
671
|
-
if (stored !== void 0 && !offered.some((row) => row.value === stored)) offered.unshift({
|
|
672
|
-
value: stored,
|
|
673
|
-
label: named.get(stored) ?? stored
|
|
674
|
-
});
|
|
675
675
|
return {
|
|
676
|
-
options:
|
|
676
|
+
options: [...stored.filter((value) => !rows.some((row) => row.value === value)).map((value) => ({
|
|
677
|
+
value,
|
|
678
|
+
label: named.get(value) ?? value
|
|
679
|
+
})), ...rows],
|
|
677
680
|
remote: {
|
|
678
681
|
unavailable: source === void 0,
|
|
679
682
|
busy,
|
|
@@ -684,6 +687,11 @@ function useSourcedOptions(field, query, enabled = true) {
|
|
|
684
687
|
}
|
|
685
688
|
};
|
|
686
689
|
}
|
|
690
|
+
function storedValues(value) {
|
|
691
|
+
if (typeof value === "string") return value === "" ? [] : [value];
|
|
692
|
+
if (!Array.isArray(value)) return [];
|
|
693
|
+
return value.filter((item) => typeof item === "string" && item !== "");
|
|
694
|
+
}
|
|
687
695
|
//#endregion
|
|
688
696
|
//#region src/uploads.ts
|
|
689
697
|
const UploaderContext = createContext(void 0);
|
|
@@ -1034,6 +1042,24 @@ function RadioGroupField({ path, label }) {
|
|
|
1034
1042
|
});
|
|
1035
1043
|
}
|
|
1036
1044
|
//#endregion
|
|
1045
|
+
//#region src/fields/computed-answer.tsx
|
|
1046
|
+
function ComputedAnswerField({ path, label }) {
|
|
1047
|
+
const field = useField(path);
|
|
1048
|
+
const engine = useFormEngine();
|
|
1049
|
+
const text = useFormText();
|
|
1050
|
+
return /* @__PURE__ */ jsx(FieldShell, {
|
|
1051
|
+
path,
|
|
1052
|
+
field,
|
|
1053
|
+
label,
|
|
1054
|
+
children: /* @__PURE__ */ jsx("input", {
|
|
1055
|
+
type: "text",
|
|
1056
|
+
readOnly: true,
|
|
1057
|
+
...field.controlProps,
|
|
1058
|
+
value: answerInWords(engine.schema(), field.def, field.value, text, engine.locale())
|
|
1059
|
+
})
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
//#endregion
|
|
1037
1063
|
//#region src/fields/file-field.tsx
|
|
1038
1064
|
function FileField({ path, label }) {
|
|
1039
1065
|
const field = useField(path);
|
|
@@ -1474,14 +1500,30 @@ function SelectBoxesSwitch(props) {
|
|
|
1474
1500
|
function TagPickerField({ path, label }) {
|
|
1475
1501
|
const field = useField(path);
|
|
1476
1502
|
const text = useFormText();
|
|
1477
|
-
const options = useResolvedOptions(field);
|
|
1478
1503
|
const chosen = Array.isArray(field.value) ? field.value.map(String) : [];
|
|
1479
1504
|
const [query, setQuery] = useState("");
|
|
1480
1505
|
const [open, setOpen] = useState(false);
|
|
1481
1506
|
const listboxId = `${field.ids.control}:listbox`;
|
|
1507
|
+
const written = useResolvedOptions(field);
|
|
1508
|
+
const sourced = useSourcedOptions({
|
|
1509
|
+
...field,
|
|
1510
|
+
path
|
|
1511
|
+
}, query);
|
|
1512
|
+
const remote = sourced.remote;
|
|
1513
|
+
const options = remote === null ? written : sourced.options;
|
|
1482
1514
|
const remaining = options.filter((option) => !chosen.includes(option.value));
|
|
1483
|
-
const matches = narrowOptionsByLabel(remaining, query);
|
|
1515
|
+
const matches = remote === null ? narrowOptionsByLabel(remaining, query) : remaining;
|
|
1484
1516
|
const expanded = open && !field.disabled && matches.length > 0;
|
|
1517
|
+
const said = remote === null ? "" : optionsStatus(text, {
|
|
1518
|
+
control: "typeahead",
|
|
1519
|
+
open: open && !field.disabled,
|
|
1520
|
+
disabled: field.disabled,
|
|
1521
|
+
failed: remote.failed,
|
|
1522
|
+
busy: remote.busy,
|
|
1523
|
+
needs: remote.needs,
|
|
1524
|
+
query,
|
|
1525
|
+
completeness: remote.completeness
|
|
1526
|
+
});
|
|
1485
1527
|
const add = (value) => {
|
|
1486
1528
|
field.setValue(ticked(field.def, chosen, value, true));
|
|
1487
1529
|
setQuery("");
|
|
@@ -1491,92 +1533,139 @@ function TagPickerField({ path, label }) {
|
|
|
1491
1533
|
field.setValue(chosen.filter((candidate) => candidate !== value));
|
|
1492
1534
|
};
|
|
1493
1535
|
const labelFor = (value) => options.find((option) => option.value === value)?.label ?? value;
|
|
1536
|
+
if (remote?.unavailable === true) return /* @__PURE__ */ jsx(FieldShell, {
|
|
1537
|
+
path,
|
|
1538
|
+
field,
|
|
1539
|
+
label,
|
|
1540
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
1541
|
+
"data-formancy-part": "options-unavailable",
|
|
1542
|
+
children: text("options.unavailable", { source: field.def.optionsSource ?? "" })
|
|
1543
|
+
})
|
|
1544
|
+
});
|
|
1494
1545
|
return /* @__PURE__ */ jsx(FieldShell, {
|
|
1495
1546
|
path,
|
|
1496
1547
|
field,
|
|
1497
1548
|
label,
|
|
1498
1549
|
children: /* @__PURE__ */ jsxs("div", {
|
|
1499
1550
|
"data-formancy-part": "tagpicker",
|
|
1500
|
-
children: [
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1551
|
+
children: [
|
|
1552
|
+
chosen.length === 0 ? null : /* @__PURE__ */ jsx("ul", {
|
|
1553
|
+
"data-formancy-part": "tagpicker-chips",
|
|
1554
|
+
"aria-label": text("tagpicker.chosen", { label }),
|
|
1555
|
+
children: chosen.map((value) => /* @__PURE__ */ jsxs("li", {
|
|
1556
|
+
"data-formancy-part": "tagpicker-chip",
|
|
1557
|
+
children: [labelFor(value), /* @__PURE__ */ jsx("button", {
|
|
1558
|
+
type: "button",
|
|
1559
|
+
"data-formancy-part": "tagpicker-remove",
|
|
1560
|
+
"aria-label": text("tagpicker.remove", { option: labelFor(value) }),
|
|
1561
|
+
disabled: field.disabled,
|
|
1562
|
+
onClick: () => remove(value),
|
|
1563
|
+
children: "×"
|
|
1564
|
+
})]
|
|
1565
|
+
}, value))
|
|
1566
|
+
}),
|
|
1567
|
+
/* @__PURE__ */ jsxs("div", {
|
|
1568
|
+
"data-formancy-part": "tagpicker-anchor",
|
|
1569
|
+
children: [/* @__PURE__ */ jsx("input", {
|
|
1570
|
+
type: "text",
|
|
1571
|
+
role: "combobox",
|
|
1572
|
+
...field.controlProps,
|
|
1573
|
+
"data-formancy-part": "tagpicker-input",
|
|
1574
|
+
autoComplete: "off",
|
|
1575
|
+
"aria-expanded": expanded,
|
|
1576
|
+
"aria-controls": listboxId,
|
|
1577
|
+
"aria-autocomplete": "list",
|
|
1578
|
+
"aria-busy": remote?.busy === true ? true : void 0,
|
|
1579
|
+
value: query,
|
|
1580
|
+
onChange: (event) => {
|
|
1581
|
+
setQuery(event.target.value);
|
|
1582
|
+
setOpen(true);
|
|
1583
|
+
},
|
|
1584
|
+
onClick: () => setOpen(true),
|
|
1585
|
+
onKeyDown: (event) => {
|
|
1586
|
+
if (event.key === "Escape") {
|
|
1587
|
+
setOpen(false);
|
|
1588
|
+
return;
|
|
1589
|
+
}
|
|
1590
|
+
if (event.key === "Enter" && expanded && matches[0] !== void 0) {
|
|
1591
|
+
event.preventDefault();
|
|
1592
|
+
add(matches[0].value);
|
|
1593
|
+
return;
|
|
1594
|
+
}
|
|
1595
|
+
if (event.key === "Backspace" && query === "" && chosen.length > 0) remove(chosen[chosen.length - 1]);
|
|
1596
|
+
},
|
|
1597
|
+
onBlur: () => {
|
|
1533
1598
|
setOpen(false);
|
|
1534
|
-
|
|
1535
|
-
}
|
|
1536
|
-
if (event.key === "Enter" && expanded && matches[0] !== void 0) {
|
|
1537
|
-
event.preventDefault();
|
|
1538
|
-
add(matches[0].value);
|
|
1539
|
-
return;
|
|
1599
|
+
field.touch();
|
|
1540
1600
|
}
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1601
|
+
}), /* @__PURE__ */ jsx("ul", {
|
|
1602
|
+
id: listboxId,
|
|
1603
|
+
role: "listbox",
|
|
1604
|
+
"aria-label": text("options.suggestions", { label }),
|
|
1605
|
+
"data-formancy-part": "tagpicker-listbox",
|
|
1606
|
+
hidden: !expanded,
|
|
1607
|
+
children: matches.map((option) => /* @__PURE__ */ jsx("li", {
|
|
1608
|
+
role: "option",
|
|
1609
|
+
"data-formancy-part": "tagpicker-option",
|
|
1610
|
+
"aria-selected": false,
|
|
1611
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
1612
|
+
onClick: () => add(option.value),
|
|
1613
|
+
children: option.label
|
|
1614
|
+
}, option.value))
|
|
1615
|
+
})]
|
|
1616
|
+
}),
|
|
1617
|
+
remote === null ? null : /* @__PURE__ */ jsx("p", {
|
|
1618
|
+
role: "status",
|
|
1619
|
+
"data-formancy-part": "tagpicker-status",
|
|
1620
|
+
"data-state": remote.failed ? "failed" : void 0,
|
|
1621
|
+
children: said
|
|
1622
|
+
})
|
|
1623
|
+
]
|
|
1563
1624
|
})
|
|
1564
1625
|
});
|
|
1565
1626
|
}
|
|
1566
1627
|
function SelectBoxesField({ path, label }) {
|
|
1567
1628
|
const field = useField(path);
|
|
1568
|
-
const
|
|
1629
|
+
const text = useFormText();
|
|
1630
|
+
const written = useResolvedOptions(field);
|
|
1631
|
+
const sourced = useSourcedOptions({
|
|
1632
|
+
...field,
|
|
1633
|
+
path
|
|
1634
|
+
}, "");
|
|
1635
|
+
const remote = sourced.remote;
|
|
1636
|
+
const options = remote === null ? written : sourced.options;
|
|
1569
1637
|
const showError = field.touched && field.errors.length > 0;
|
|
1570
1638
|
const chosen = Array.isArray(field.value) ? field.value : [];
|
|
1639
|
+
const group = useRef(null);
|
|
1640
|
+
const again = useRef(null);
|
|
1641
|
+
const [retrying, setRetrying] = useState(false);
|
|
1642
|
+
const settled = remote !== null && !remote.busy && !remote.failed;
|
|
1643
|
+
useEffect(() => {
|
|
1644
|
+
if (!retrying || !settled) return;
|
|
1645
|
+
setRetrying(false);
|
|
1646
|
+
if (document.activeElement === again.current) group.current?.querySelector("input[type=\"checkbox\"]")?.focus();
|
|
1647
|
+
}, [retrying, settled]);
|
|
1648
|
+
const said = remote === null ? "" : optionsStatus(text, {
|
|
1649
|
+
control: "ticks",
|
|
1650
|
+
open: true,
|
|
1651
|
+
disabled: field.disabled,
|
|
1652
|
+
failed: remote.failed,
|
|
1653
|
+
busy: remote.busy,
|
|
1654
|
+
needs: remote.needs,
|
|
1655
|
+
query: "",
|
|
1656
|
+
completeness: remote.completeness
|
|
1657
|
+
});
|
|
1571
1658
|
const toggle = (value, on) => {
|
|
1572
1659
|
field.setValue(ticked(field.def, chosen, value, on));
|
|
1573
1660
|
};
|
|
1574
1661
|
return /* @__PURE__ */ jsxs("fieldset", {
|
|
1662
|
+
ref: group,
|
|
1575
1663
|
id: field.ids.control,
|
|
1576
1664
|
"data-formancy-part": "field",
|
|
1577
1665
|
"data-formancy-field-path": path,
|
|
1578
1666
|
"data-state": showError ? "invalid" : "valid",
|
|
1579
1667
|
"aria-describedby": field.controlProps["aria-describedby"],
|
|
1668
|
+
"aria-busy": remote?.busy === true ? true : void 0,
|
|
1580
1669
|
children: [
|
|
1581
1670
|
/* @__PURE__ */ jsx("legend", {
|
|
1582
1671
|
"data-formancy-part": "label",
|
|
@@ -1584,6 +1673,10 @@ function SelectBoxesField({ path, label }) {
|
|
|
1584
1673
|
}),
|
|
1585
1674
|
/* @__PURE__ */ jsx(RequiredHint, { field }),
|
|
1586
1675
|
/* @__PURE__ */ jsx(Description, { field }),
|
|
1676
|
+
remote?.unavailable === true ? /* @__PURE__ */ jsx("p", {
|
|
1677
|
+
"data-formancy-part": "options-unavailable",
|
|
1678
|
+
children: text("options.unavailable", { source: field.def.optionsSource ?? "" })
|
|
1679
|
+
}) : null,
|
|
1587
1680
|
options.map((option) => {
|
|
1588
1681
|
const optionId = `${field.ids.control}:${option.value}`;
|
|
1589
1682
|
return /* @__PURE__ */ jsxs("span", {
|
|
@@ -1603,6 +1696,22 @@ function SelectBoxesField({ path, label }) {
|
|
|
1603
1696
|
})]
|
|
1604
1697
|
}, option.value);
|
|
1605
1698
|
}),
|
|
1699
|
+
remote === null || remote.unavailable ? null : /* @__PURE__ */ jsx("p", {
|
|
1700
|
+
role: "status",
|
|
1701
|
+
"data-formancy-part": "checkbox-status",
|
|
1702
|
+
"data-state": remote.failed ? "failed" : void 0,
|
|
1703
|
+
children: said
|
|
1704
|
+
}),
|
|
1705
|
+
remote !== null && (remote.failed || retrying) && !field.disabled ? /* @__PURE__ */ jsx("button", {
|
|
1706
|
+
ref: again,
|
|
1707
|
+
type: "button",
|
|
1708
|
+
"data-formancy-part": "checkbox-retry",
|
|
1709
|
+
onClick: () => {
|
|
1710
|
+
setRetrying(true);
|
|
1711
|
+
remote.retry();
|
|
1712
|
+
},
|
|
1713
|
+
children: text("options.retry")
|
|
1714
|
+
}) : null,
|
|
1606
1715
|
showError ? /* @__PURE__ */ jsx(ErrorText, { field }) : null
|
|
1607
1716
|
]
|
|
1608
1717
|
});
|
|
@@ -2324,7 +2433,7 @@ function FieldList({ labels, registry, page, layout }) {
|
|
|
2324
2433
|
function FieldSlot({ path, fallbackLabel, registry }) {
|
|
2325
2434
|
const field = useField(path);
|
|
2326
2435
|
if (!field.visible) return null;
|
|
2327
|
-
const Component = registry?.byPath?.[path] ?? registry?.byType?.[field.type] ?? DEFAULT_COMPONENTS[field.type];
|
|
2436
|
+
const Component = registry?.byPath?.[path] ?? (field.readOnly && !hasReadOnlyControl(field.def) ? ComputedAnswerField : void 0) ?? registry?.byType?.[field.type] ?? DEFAULT_COMPONENTS[field.type];
|
|
2328
2437
|
if (Component === null) return null;
|
|
2329
2438
|
const label = field.label ?? fallbackLabel ?? path;
|
|
2330
2439
|
return /* @__PURE__ */ jsx(Component, {
|