@form-engine-ts/react 2.9.1 → 2.9.2

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.js CHANGED
@@ -750,6 +750,8 @@ function DefaultButton({
750
750
  className,
751
751
  disabled,
752
752
  "aria-label": ariaLabel,
753
+ "aria-describedby": ariaDescribedBy,
754
+ "aria-labelledby": ariaLabelledBy,
753
755
  onClick,
754
756
  children,
755
757
  title,
@@ -764,6 +766,8 @@ function DefaultButton({
764
766
  type: "button",
765
767
  disabled,
766
768
  "aria-label": ariaLabel,
769
+ "aria-describedby": ariaDescribedBy,
770
+ "aria-labelledby": ariaLabelledBy,
767
771
  title,
768
772
  "data-builder-action": action,
769
773
  "data-target-id": targetId,
@@ -780,17 +784,43 @@ function DefaultIconButton(props) {
780
784
  ...props.className === void 0 ? {} : { className: props.className },
781
785
  ...props.disabled === void 0 ? {} : { disabled: props.disabled },
782
786
  "aria-label": props["aria-label"] ?? props.title,
787
+ "aria-describedby": props["aria-describedby"],
788
+ "aria-labelledby": props["aria-labelledby"],
789
+ ...props.title === void 0 ? {} : { title: props.title },
783
790
  ...props.onClick === void 0 ? {} : { onClick: props.onClick },
784
791
  children: props.icon
785
792
  }
786
793
  );
787
794
  }
795
+ function defaultIconFor(actionType) {
796
+ switch (actionType) {
797
+ case "moveUp":
798
+ return "\u2191";
799
+ case "moveDown":
800
+ return "\u2193";
801
+ case "delete":
802
+ case "close":
803
+ return "\xD7";
804
+ case "add":
805
+ return "+";
806
+ case "dragHandle":
807
+ return "\u283F";
808
+ case "edit":
809
+ return "\u270E";
810
+ case "settings":
811
+ return "\u2699";
812
+ case "translate":
813
+ return "\u6587";
814
+ }
815
+ }
788
816
  function DefaultTextInput({
789
817
  id,
790
818
  className,
791
819
  disabled,
792
820
  readOnly,
793
821
  "aria-label": ariaLabel,
822
+ "aria-describedby": ariaDescribedBy,
823
+ "aria-labelledby": ariaLabelledBy,
794
824
  name,
795
825
  label,
796
826
  required,
@@ -806,7 +836,9 @@ function DefaultTextInput({
806
836
  max,
807
837
  step
808
838
  }) {
839
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
809
840
  return /* @__PURE__ */ jsxs(Fragment, { children: [
841
+ labelElement,
810
842
  /* @__PURE__ */ jsx(
811
843
  "input",
812
844
  {
@@ -816,7 +848,9 @@ function DefaultTextInput({
816
848
  disabled,
817
849
  readOnly,
818
850
  required,
819
- "aria-label": ariaLabel ?? label,
851
+ "aria-label": ariaLabel,
852
+ "aria-describedby": ariaDescribedBy,
853
+ "aria-labelledby": ariaLabelledBy,
820
854
  "aria-invalid": error === true ? true : void 0,
821
855
  type: type === "text" ? void 0 : type,
822
856
  inputMode,
@@ -829,7 +863,7 @@ function DefaultTextInput({
829
863
  onChange: (event) => onChange(event.currentTarget.value)
830
864
  }
831
865
  ),
832
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { children: helperText })
866
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
833
867
  ] });
834
868
  }
835
869
  function DefaultTextArea({
@@ -838,6 +872,8 @@ function DefaultTextArea({
838
872
  disabled,
839
873
  readOnly,
840
874
  "aria-label": ariaLabel,
875
+ "aria-describedby": ariaDescribedBy,
876
+ "aria-labelledby": ariaLabelledBy,
841
877
  name,
842
878
  label,
843
879
  required,
@@ -849,7 +885,9 @@ function DefaultTextArea({
849
885
  placeholder,
850
886
  maxLength
851
887
  }) {
888
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
852
889
  return /* @__PURE__ */ jsxs(Fragment, { children: [
890
+ labelElement,
853
891
  /* @__PURE__ */ jsx(
854
892
  "textarea",
855
893
  {
@@ -859,7 +897,9 @@ function DefaultTextArea({
859
897
  disabled,
860
898
  readOnly,
861
899
  required,
862
- "aria-label": ariaLabel ?? label,
900
+ "aria-label": ariaLabel,
901
+ "aria-describedby": ariaDescribedBy,
902
+ "aria-labelledby": ariaLabelledBy,
863
903
  "aria-invalid": error === true ? true : void 0,
864
904
  value,
865
905
  rows,
@@ -868,7 +908,7 @@ function DefaultTextArea({
868
908
  onChange: (event) => onChange(event.currentTarget.value)
869
909
  }
870
910
  ),
871
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { children: helperText })
911
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
872
912
  ] });
873
913
  }
874
914
  function DefaultSelect({
@@ -876,6 +916,8 @@ function DefaultSelect({
876
916
  className,
877
917
  disabled,
878
918
  "aria-label": ariaLabel,
919
+ "aria-describedby": ariaDescribedBy,
920
+ "aria-labelledby": ariaLabelledBy,
879
921
  name,
880
922
  label,
881
923
  required,
@@ -885,7 +927,9 @@ function DefaultSelect({
885
927
  onChange,
886
928
  options
887
929
  }) {
930
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
888
931
  return /* @__PURE__ */ jsxs(Fragment, { children: [
932
+ labelElement,
889
933
  /* @__PURE__ */ jsx(
890
934
  "select",
891
935
  {
@@ -894,14 +938,16 @@ function DefaultSelect({
894
938
  className,
895
939
  disabled,
896
940
  required,
897
- "aria-label": ariaLabel ?? label,
941
+ "aria-label": ariaLabel,
942
+ "aria-describedby": ariaDescribedBy,
943
+ "aria-labelledby": ariaLabelledBy,
898
944
  "aria-invalid": error === true ? true : void 0,
899
945
  value,
900
946
  onChange: (event) => onChange(event.currentTarget.value),
901
947
  children: options.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, disabled: option.disabled, children: option.label }, option.value))
902
948
  }
903
949
  ),
904
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { children: helperText })
950
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
905
951
  ] });
906
952
  }
907
953
  function DefaultCheckbox({
@@ -960,8 +1006,8 @@ function DefaultFieldset({ className, legend, disabled, children }) {
960
1006
  children
961
1007
  ] });
962
1008
  }
963
- function DefaultErrorMessage({ message }) {
964
- return /* @__PURE__ */ jsx("p", { className: "form-engine-builder__error", children: message });
1009
+ function DefaultErrorMessage({ className, message }) {
1010
+ return /* @__PURE__ */ jsx("p", { className, children: message });
965
1011
  }
966
1012
  var DEFAULT_COMPONENTS = {
967
1013
  Button: DefaultButton,
@@ -972,41 +1018,101 @@ var DEFAULT_COMPONENTS = {
972
1018
  Checkbox: DefaultCheckbox,
973
1019
  Section: DefaultSection,
974
1020
  Fieldset: DefaultFieldset,
975
- ErrorMessage: DefaultErrorMessage
1021
+ ErrorMessage: DefaultErrorMessage,
1022
+ renderIcon: defaultIconFor
976
1023
  };
977
1024
  var BuilderPrimitiveContext = createContext({
978
1025
  components: DEFAULT_COMPONENTS,
979
- readOnly: false
1026
+ readOnly: false,
1027
+ unstyled: false
980
1028
  });
1029
+ function withoutDefaultStyleClasses(className) {
1030
+ const filtered = className?.split(/\s+/u).filter((name) => name.length > 0 && !name.startsWith("form-engine-builder") && !name.startsWith("feb-")).join(" ");
1031
+ return filtered === void 0 || filtered.length === 0 ? void 0 : filtered;
1032
+ }
1033
+ function primitiveClassName(className, defaultClassName, unstyled) {
1034
+ const userClassName = unstyled ? withoutDefaultStyleClasses(className) : className;
1035
+ return [unstyled ? void 0 : defaultClassName, userClassName].filter((value) => value !== void 0).join(" ") || void 0;
1036
+ }
981
1037
  function BuilderButton(props) {
982
1038
  const context = useContext(BuilderPrimitiveContext);
983
1039
  const Component = context.components.Button;
984
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1040
+ return /* @__PURE__ */ jsx(
1041
+ Component,
1042
+ {
1043
+ ...props,
1044
+ className: primitiveClassName(props.className, "feb-button", context.unstyled),
1045
+ disabled: context.readOnly || props.disabled === true,
1046
+ readOnly: context.readOnly
1047
+ }
1048
+ );
985
1049
  }
986
1050
  function BuilderIconButton(props) {
987
1051
  const context = useContext(BuilderPrimitiveContext);
988
1052
  const Component = context.components.IconButton;
989
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1053
+ const icon = props.actionType === void 0 ? props.icon ?? void 0 : context.components.renderIcon(props.actionType) ?? props.icon ?? defaultIconFor(props.actionType);
1054
+ return /* @__PURE__ */ jsx(
1055
+ Component,
1056
+ {
1057
+ ...props,
1058
+ icon,
1059
+ className: primitiveClassName(props.className, "feb-icon-button", context.unstyled),
1060
+ disabled: context.readOnly || props.disabled === true,
1061
+ readOnly: context.readOnly
1062
+ }
1063
+ );
990
1064
  }
991
1065
  function BuilderTextInput(props) {
992
1066
  const context = useContext(BuilderPrimitiveContext);
993
1067
  const Component = context.components.TextInput;
994
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1068
+ return /* @__PURE__ */ jsx(
1069
+ Component,
1070
+ {
1071
+ ...props,
1072
+ className: primitiveClassName(props.className, "feb-input", context.unstyled),
1073
+ disabled: context.readOnly || props.disabled === true,
1074
+ readOnly: context.readOnly
1075
+ }
1076
+ );
995
1077
  }
996
1078
  function BuilderTextArea(props) {
997
1079
  const context = useContext(BuilderPrimitiveContext);
998
1080
  const Component = context.components.TextArea;
999
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1081
+ return /* @__PURE__ */ jsx(
1082
+ Component,
1083
+ {
1084
+ ...props,
1085
+ className: primitiveClassName(props.className, "feb-textarea", context.unstyled),
1086
+ disabled: context.readOnly || props.disabled === true,
1087
+ readOnly: context.readOnly
1088
+ }
1089
+ );
1000
1090
  }
1001
1091
  function BuilderSelect(props) {
1002
1092
  const context = useContext(BuilderPrimitiveContext);
1003
1093
  const Component = context.components.Select;
1004
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1094
+ return /* @__PURE__ */ jsx(
1095
+ Component,
1096
+ {
1097
+ ...props,
1098
+ className: primitiveClassName(props.className, "feb-select", context.unstyled),
1099
+ disabled: context.readOnly || props.disabled === true,
1100
+ readOnly: context.readOnly
1101
+ }
1102
+ );
1005
1103
  }
1006
1104
  function BuilderCheckbox(props) {
1007
1105
  const context = useContext(BuilderPrimitiveContext);
1008
1106
  const Component = context.components.Checkbox;
1009
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true, readOnly: context.readOnly });
1107
+ return /* @__PURE__ */ jsx(
1108
+ Component,
1109
+ {
1110
+ ...props,
1111
+ className: primitiveClassName(props.className, "feb-checkbox", context.unstyled),
1112
+ disabled: context.readOnly || props.disabled === true,
1113
+ readOnly: context.readOnly
1114
+ }
1115
+ );
1010
1116
  }
1011
1117
  function BuilderSection(props) {
1012
1118
  const Component = useContext(BuilderPrimitiveContext).components.Section;
@@ -1018,8 +1124,9 @@ function BuilderFieldset(props) {
1018
1124
  return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true });
1019
1125
  }
1020
1126
  function BuilderErrorMessage(props) {
1021
- const Component = useContext(BuilderPrimitiveContext).components.ErrorMessage;
1022
- return /* @__PURE__ */ jsx(Component, { ...props });
1127
+ const context = useContext(BuilderPrimitiveContext);
1128
+ const Component = context.components.ErrorMessage;
1129
+ return /* @__PURE__ */ jsx("div", { className: primitiveClassName(props.className, "form-engine-builder__error", context.unstyled), children: /* @__PURE__ */ jsx(Component, { message: props.message }) });
1023
1130
  }
1024
1131
  var GUARDED_COMPONENTS = {
1025
1132
  Button: BuilderButton,
@@ -1208,10 +1315,17 @@ function FormBuilder({
1208
1315
  readOnly = false,
1209
1316
  features,
1210
1317
  components: componentOverrides,
1211
- slots
1318
+ slots,
1319
+ disableDefaultStyles = false,
1320
+ unstyled = false
1212
1321
  }) {
1213
1322
  const resolvedComponents = { ...DEFAULT_COMPONENTS, ...componentOverrides };
1214
- const components = GUARDED_COMPONENTS;
1323
+ const components = {
1324
+ ...GUARDED_COMPONENTS,
1325
+ renderIcon: resolvedComponents.renderIcon
1326
+ };
1327
+ const defaultStylesDisabled = disableDefaultStyles || unstyled;
1328
+ const builderClass = (value) => defaultStylesDisabled ? void 0 : value;
1215
1329
  const { Button, Checkbox, ErrorMessage, Fieldset, IconButton, Section, Select, TextArea, TextInput } = components;
1216
1330
  const ToolbarSlot = slots?.toolbar;
1217
1331
  const FieldEditorSlot = slots?.fieldEditor;
@@ -1494,817 +1608,818 @@ function FormBuilder({
1494
1608
  params: { locale: targetLocale }
1495
1609
  })
1496
1610
  };
1497
- return /* @__PURE__ */ jsx(BuilderPrimitiveContext.Provider, { value: { components: resolvedComponents, readOnly }, children: /* @__PURE__ */ jsx(
1498
- Section,
1611
+ return /* @__PURE__ */ jsx(
1612
+ BuilderPrimitiveContext.Provider,
1499
1613
  {
1500
- className: `form-engine-builder ${className}`.trim(),
1501
- "aria-label": translate("builder.formBuilder"),
1502
- onClickCapture: (event) => {
1503
- if (readOnly) return;
1504
- if (!(event.target instanceof HTMLElement)) return;
1505
- const actionTarget = event.target.closest("[data-builder-action]");
1506
- if (actionTarget?.dataset.builderAction === "addField" && maxFieldsReached && initialFieldType !== null)
1507
- addField();
1508
- if (actionTarget?.dataset.builderAction === "addLocale" && localeLimitReached && newLocale.trim().length > 0)
1509
- addLocale();
1510
- if (actionTarget?.dataset.builderAction !== "addOption") return;
1511
- const fieldId = actionTarget.dataset.targetId;
1512
- const field = schema.fields.find((candidate) => candidate.id === fieldId);
1513
- if (fieldId !== void 0 && field !== void 0 && "options" in field && policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField) {
1514
- addOption(fieldId);
1515
- }
1516
- },
1517
- children: /* @__PURE__ */ jsxs(Fieldset, { className: "form-engine-builder__controls", disabled: readOnly, children: [
1518
- /* @__PURE__ */ jsx(
1519
- Section,
1520
- {
1521
- className: "form-engine-builder__basic-settings",
1522
- headingId: "builder-basic-settings-heading",
1523
- title: translate("builder.basicSettings"),
1524
- children: /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1525
- /* @__PURE__ */ jsxs("label", { children: [
1526
- translate("builder.formTitle"),
1527
- /* @__PURE__ */ jsx(
1528
- TextInput,
1529
- {
1530
- name: "title",
1531
- required: true,
1532
- error: schema.title.trim().length === 0,
1533
- helperText: schema.title.trim().length === 0 ? translate("builder.required") : "",
1534
- value: schema.title,
1535
- onChange: (value) => setSourceText({ kind: "form" }, "title", value)
1536
- }
1537
- )
1538
- ] }),
1539
- /* @__PURE__ */ jsxs("label", { children: [
1540
- translate("builder.formDescription"),
1541
- /* @__PURE__ */ jsx(
1542
- TextArea,
1543
- {
1544
- name: "description",
1545
- rows: 3,
1546
- value: schema.description ?? "",
1547
- onChange: (value) => setSourceText({ kind: "form" }, "description", value)
1548
- }
1549
- )
1550
- ] })
1551
- ] })
1552
- }
1553
- ),
1554
- pagesEnabled ? PagesSlot === void 0 ? /* @__PURE__ */ jsx(
1555
- Section,
1556
- {
1557
- className: "form-engine-builder__pages",
1558
- headingId: "builder-pages-heading",
1559
- title: translate("builder.pages"),
1560
- children: schema.pages === void 0 ? /* @__PURE__ */ jsx(Button, { onClick: enablePages, children: translate("builder.enablePages") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1561
- schema.pages.map((page, pageIndex) => {
1562
- const priorQuestionIds = new Set(
1563
- schema.pages?.slice(0, pageIndex).flatMap((item) => item.questionIds)
1564
- );
1565
- const availableSources = schema.fields.filter((field) => priorQuestionIds.has(field.id));
1566
- const source = schema.fields.find((field) => field.id === page.displayCondition?.questionId);
1567
- return /* @__PURE__ */ jsxs(
1568
- Fieldset,
1569
- {
1570
- className: "form-engine-builder__page",
1571
- legend: page.title ?? `${translate("builder.newPage")} ${pageIndex + 1}`,
1572
- children: [
1573
- /* @__PURE__ */ jsx("div", { className: "form-engine-builder__toolbar", children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1574
- /* @__PURE__ */ jsx(
1575
- IconButton,
1576
- {
1577
- icon: "\u2191",
1578
- title: translate("builder.moveUp", { title: page.title ?? page.id }),
1579
- disabled: pageIndex === 0,
1580
- onClick: () => movePage(pageIndex, -1)
1581
- }
1582
- ),
1583
- /* @__PURE__ */ jsx(
1584
- IconButton,
1585
- {
1586
- icon: "\u2193",
1587
- title: translate("builder.moveDown", { title: page.title ?? page.id }),
1588
- disabled: pageIndex === (schema.pages?.length ?? 0) - 1,
1589
- onClick: () => movePage(pageIndex, 1)
1590
- }
1591
- ),
1592
- /* @__PURE__ */ jsx(Button, { onClick: () => removePage(pageIndex), variant: "danger", children: translate("builder.deleteAction") })
1593
- ] }) : /* @__PURE__ */ jsx(
1594
- ToolbarSlot,
1595
- {
1596
- schema,
1597
- kind: "page",
1598
- targetId: page.id,
1599
- index: pageIndex,
1600
- total: schema.pages?.length ?? 0,
1601
- title: page.title ?? page.id,
1602
- onMoveUp: () => movePage(pageIndex, -1),
1603
- onMoveDown: () => movePage(pageIndex, 1),
1604
- onRemove: () => removePage(pageIndex),
1605
- readOnly,
1606
- actions,
1607
- components
1608
- }
1609
- ) }),
1610
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1611
- /* @__PURE__ */ jsxs("label", { children: [
1612
- translate("builder.pageTitle"),
1613
- /* @__PURE__ */ jsx(
1614
- TextInput,
1615
- {
1616
- value: page.title ?? "",
1617
- onChange: (value) => {
1618
- updatePage(page.id, (current) => {
1619
- if (value.length > 0) return { ...current, title: value };
1620
- const { title: _title, ...withoutTitle } = current;
1621
- return withoutTitle;
1622
- });
1623
- }
1624
- }
1625
- )
1626
- ] }),
1627
- /* @__PURE__ */ jsxs("label", { children: [
1628
- translate("builder.pageDescription"),
1629
- /* @__PURE__ */ jsx(
1630
- TextInput,
1631
- {
1632
- value: page.description ?? "",
1633
- onChange: (value) => {
1634
- updatePage(page.id, (current) => {
1635
- if (value.length > 0) return { ...current, description: value };
1636
- const { description: _description, ...withoutDescription } = current;
1637
- return withoutDescription;
1638
- });
1614
+ value: { components: resolvedComponents, readOnly, unstyled: defaultStylesDisabled },
1615
+ children: /* @__PURE__ */ jsx(
1616
+ Section,
1617
+ {
1618
+ className: defaultStylesDisabled ? className || void 0 : `form-engine-builder ${className}`.trim(),
1619
+ "aria-label": translate("builder.formBuilder"),
1620
+ onClickCapture: (event) => {
1621
+ if (readOnly) return;
1622
+ if (!(event.target instanceof HTMLElement)) return;
1623
+ const actionTarget = event.target.closest("[data-builder-action]");
1624
+ if (actionTarget?.dataset.builderAction === "addField" && maxFieldsReached && initialFieldType !== null)
1625
+ addField();
1626
+ if (actionTarget?.dataset.builderAction === "addLocale" && localeLimitReached && newLocale.trim().length > 0)
1627
+ addLocale();
1628
+ if (actionTarget?.dataset.builderAction !== "addOption") return;
1629
+ const fieldId = actionTarget.dataset.targetId;
1630
+ const field = schema.fields.find((candidate) => candidate.id === fieldId);
1631
+ if (fieldId !== void 0 && field !== void 0 && "options" in field && policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField) {
1632
+ addOption(fieldId);
1633
+ }
1634
+ },
1635
+ children: /* @__PURE__ */ jsxs(Fieldset, { className: builderClass("form-engine-builder__controls"), disabled: readOnly, children: [
1636
+ /* @__PURE__ */ jsx(
1637
+ Section,
1638
+ {
1639
+ className: builderClass("form-engine-builder__basic-settings"),
1640
+ headingId: "builder-basic-settings-heading",
1641
+ title: translate("builder.basicSettings"),
1642
+ children: /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
1643
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1644
+ TextInput,
1645
+ {
1646
+ id: "builder-form-title",
1647
+ name: "title",
1648
+ label: translate("builder.formTitle"),
1649
+ required: true,
1650
+ error: schema.title.trim().length === 0,
1651
+ helperText: schema.title.trim().length === 0 ? translate("builder.required") : "",
1652
+ "aria-describedby": schema.title.trim().length === 0 ? "builder-form-title-error" : void 0,
1653
+ value: schema.title,
1654
+ onChange: (value) => setSourceText({ kind: "form" }, "title", value)
1655
+ }
1656
+ ) }),
1657
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1658
+ TextArea,
1659
+ {
1660
+ id: "builder-form-description",
1661
+ name: "description",
1662
+ label: translate("builder.formDescription"),
1663
+ rows: 3,
1664
+ value: schema.description ?? "",
1665
+ onChange: (value) => setSourceText({ kind: "form" }, "description", value)
1666
+ }
1667
+ ) })
1668
+ ] })
1669
+ }
1670
+ ),
1671
+ pagesEnabled ? PagesSlot === void 0 ? /* @__PURE__ */ jsx(
1672
+ Section,
1673
+ {
1674
+ className: builderClass("form-engine-builder__pages"),
1675
+ headingId: "builder-pages-heading",
1676
+ title: translate("builder.pages"),
1677
+ children: schema.pages === void 0 ? /* @__PURE__ */ jsx(Button, { onClick: enablePages, children: translate("builder.enablePages") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
1678
+ schema.pages.map((page, pageIndex) => {
1679
+ const priorQuestionIds = new Set(
1680
+ schema.pages?.slice(0, pageIndex).flatMap((item) => item.questionIds)
1681
+ );
1682
+ const availableSources = schema.fields.filter((field) => priorQuestionIds.has(field.id));
1683
+ const source = schema.fields.find((field) => field.id === page.displayCondition?.questionId);
1684
+ return /* @__PURE__ */ jsxs(
1685
+ Fieldset,
1686
+ {
1687
+ className: builderClass("form-engine-builder__page"),
1688
+ legend: page.title ?? `${translate("builder.newPage")} ${pageIndex + 1}`,
1689
+ children: [
1690
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1691
+ /* @__PURE__ */ jsx(
1692
+ IconButton,
1693
+ {
1694
+ actionType: "moveUp",
1695
+ title: translate("builder.moveUp", { title: page.title ?? page.id }),
1696
+ disabled: pageIndex === 0,
1697
+ onClick: () => movePage(pageIndex, -1)
1639
1698
  }
1640
- }
1641
- )
1642
- ] })
1643
- ] }),
1644
- !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__translation-editor", children: [
1645
- /* @__PURE__ */ jsx("strong", { children: editingLocale }),
1646
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1647
- /* @__PURE__ */ jsxs("label", { children: [
1648
- translate("builder.pageTitle"),
1699
+ ),
1649
1700
  /* @__PURE__ */ jsx(
1650
- TextInput,
1701
+ IconButton,
1651
1702
  {
1652
- value: page.translations?.[editingLocale]?.title ?? "",
1653
- onChange: (value) => updateManualTranslation({
1654
- locale: editingLocale,
1655
- kind: "page",
1656
- nodeId: page.id,
1657
- property: "title",
1658
- sourceText: page.title ?? "",
1659
- translatedText: value,
1660
- ...page.translationMetadata?.[editingLocale]?.title === void 0 ? {} : {
1661
- existingTranslationMetadata: page.translationMetadata[editingLocale]?.title
1662
- }
1663
- })
1703
+ actionType: "moveDown",
1704
+ title: translate("builder.moveDown", { title: page.title ?? page.id }),
1705
+ disabled: pageIndex === (schema.pages?.length ?? 0) - 1,
1706
+ onClick: () => movePage(pageIndex, 1)
1664
1707
  }
1665
- )
1666
- ] }),
1667
- /* @__PURE__ */ jsxs("label", { children: [
1668
- translate("builder.pageDescription"),
1708
+ ),
1669
1709
  /* @__PURE__ */ jsx(
1670
- TextInput,
1710
+ IconButton,
1671
1711
  {
1672
- value: page.translations?.[editingLocale]?.description ?? "",
1673
- onChange: (value) => updateManualTranslation({
1674
- locale: editingLocale,
1675
- kind: "page",
1676
- nodeId: page.id,
1677
- property: "description",
1678
- sourceText: page.description ?? "",
1679
- translatedText: value,
1680
- ...page.translationMetadata?.[editingLocale]?.description === void 0 ? {} : {
1681
- existingTranslationMetadata: page.translationMetadata[editingLocale]?.description
1682
- }
1683
- })
1712
+ actionType: "delete",
1713
+ title: translate("builder.delete", { title: page.title ?? page.id }),
1714
+ onClick: () => removePage(pageIndex)
1684
1715
  }
1685
1716
  )
1686
- ] })
1687
- ] })
1688
- ] }),
1689
- conditionsEnabled ? /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__condition", children: [
1690
- /* @__PURE__ */ jsxs("label", { children: [
1691
- translate("builder.pageCondition"),
1692
- /* @__PURE__ */ jsx(
1693
- Select,
1694
- {
1695
- value: page.displayCondition?.questionId ?? "",
1696
- onChange: (value) => {
1697
- const selected = schema.fields.find((field) => field.id === value);
1698
- updatePage(page.id, (current) => {
1699
- if (selected === void 0) {
1700
- const { displayCondition: _condition, ...withoutCondition } = current;
1701
- return withoutCondition;
1702
- }
1703
- return {
1704
- ...current,
1705
- displayCondition: conditionWithValue(
1706
- selected.id,
1707
- conditionOperators(selected)[0] ?? "not_empty",
1708
- defaultConditionValue(selected)
1709
- )
1710
- };
1711
- });
1712
- },
1713
- options: [
1714
- { value: "", label: translate("builder.alwaysVisible") },
1715
- ...availableSources.map((field) => ({ value: field.id, label: field.title }))
1716
- ]
1717
- }
1718
- )
1719
- ] }),
1720
- page.displayCondition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1721
- /* @__PURE__ */ jsx(
1722
- Select,
1723
- {
1724
- "aria-label": translate("builder.conditionOperator"),
1725
- value: page.displayCondition.operator,
1726
- onChange: (value) => {
1727
- const operator = value;
1728
- updatePage(page.id, (current) => ({
1729
- ...current,
1730
- displayCondition: conditionWithValue(
1731
- source.id,
1732
- operator,
1733
- defaultConditionValue(source)
1734
- )
1735
- }));
1736
- },
1737
- options: conditionOperators(source).map((operator) => ({
1738
- value: operator,
1739
- label: translate(operatorKey(operator))
1740
- }))
1741
- }
1742
- ),
1743
- /* @__PURE__ */ jsx(
1744
- ConditionValueEditor,
1717
+ ] }) : /* @__PURE__ */ jsx(
1718
+ ToolbarSlot,
1745
1719
  {
1746
- source,
1747
- condition: page.displayCondition,
1748
- onChange: (condition) => updatePage(page.id, (current) => ({ ...current, displayCondition: condition })),
1749
- translate,
1720
+ schema,
1721
+ kind: "page",
1722
+ targetId: page.id,
1723
+ index: pageIndex,
1724
+ total: schema.pages?.length ?? 0,
1725
+ title: page.title ?? page.id,
1726
+ onMoveUp: () => movePage(pageIndex, -1),
1727
+ onMoveDown: () => movePage(pageIndex, 1),
1728
+ onRemove: () => removePage(pageIndex),
1729
+ readOnly,
1730
+ actions,
1750
1731
  components
1751
1732
  }
1752
- )
1753
- ] }) : null
1754
- ] }) : null
1755
- ]
1733
+ ) }),
1734
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
1735
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1736
+ TextInput,
1737
+ {
1738
+ id: `builder-page-${page.id}-title`,
1739
+ label: translate("builder.pageTitle"),
1740
+ value: page.title ?? "",
1741
+ onChange: (value) => {
1742
+ updatePage(page.id, (current) => {
1743
+ if (value.length > 0) return { ...current, title: value };
1744
+ const { title: _title, ...withoutTitle } = current;
1745
+ return withoutTitle;
1746
+ });
1747
+ }
1748
+ }
1749
+ ) }),
1750
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1751
+ TextInput,
1752
+ {
1753
+ id: `builder-page-${page.id}-description`,
1754
+ label: translate("builder.pageDescription"),
1755
+ value: page.description ?? "",
1756
+ onChange: (value) => {
1757
+ updatePage(page.id, (current) => {
1758
+ if (value.length > 0) return { ...current, description: value };
1759
+ const { description: _description, ...withoutDescription } = current;
1760
+ return withoutDescription;
1761
+ });
1762
+ }
1763
+ }
1764
+ ) })
1765
+ ] }),
1766
+ !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__translation-editor"), children: [
1767
+ /* @__PURE__ */ jsx("strong", { children: editingLocale }),
1768
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
1769
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1770
+ TextInput,
1771
+ {
1772
+ id: `builder-page-${page.id}-${editingLocale}-title`,
1773
+ label: translate("builder.pageTitle"),
1774
+ value: page.translations?.[editingLocale]?.title ?? "",
1775
+ onChange: (value) => updateManualTranslation({
1776
+ locale: editingLocale,
1777
+ kind: "page",
1778
+ nodeId: page.id,
1779
+ property: "title",
1780
+ sourceText: page.title ?? "",
1781
+ translatedText: value,
1782
+ ...page.translationMetadata?.[editingLocale]?.title === void 0 ? {} : {
1783
+ existingTranslationMetadata: page.translationMetadata[editingLocale]?.title
1784
+ }
1785
+ })
1786
+ }
1787
+ ) }),
1788
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1789
+ TextInput,
1790
+ {
1791
+ id: `builder-page-${page.id}-${editingLocale}-description`,
1792
+ label: translate("builder.pageDescription"),
1793
+ value: page.translations?.[editingLocale]?.description ?? "",
1794
+ onChange: (value) => updateManualTranslation({
1795
+ locale: editingLocale,
1796
+ kind: "page",
1797
+ nodeId: page.id,
1798
+ property: "description",
1799
+ sourceText: page.description ?? "",
1800
+ translatedText: value,
1801
+ ...page.translationMetadata?.[editingLocale]?.description === void 0 ? {} : {
1802
+ existingTranslationMetadata: page.translationMetadata[editingLocale]?.description
1803
+ }
1804
+ })
1805
+ }
1806
+ ) })
1807
+ ] })
1808
+ ] }),
1809
+ conditionsEnabled ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__condition"), children: [
1810
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1811
+ Select,
1812
+ {
1813
+ id: `builder-page-${page.id}-condition`,
1814
+ label: translate("builder.pageCondition"),
1815
+ value: page.displayCondition?.questionId ?? "",
1816
+ onChange: (value) => {
1817
+ const selected = schema.fields.find((field) => field.id === value);
1818
+ updatePage(page.id, (current) => {
1819
+ if (selected === void 0) {
1820
+ const { displayCondition: _condition, ...withoutCondition } = current;
1821
+ return withoutCondition;
1822
+ }
1823
+ return {
1824
+ ...current,
1825
+ displayCondition: conditionWithValue(
1826
+ selected.id,
1827
+ conditionOperators(selected)[0] ?? "not_empty",
1828
+ defaultConditionValue(selected)
1829
+ )
1830
+ };
1831
+ });
1832
+ },
1833
+ options: [
1834
+ { value: "", label: translate("builder.alwaysVisible") },
1835
+ ...availableSources.map((field) => ({ value: field.id, label: field.title }))
1836
+ ]
1837
+ }
1838
+ ) }),
1839
+ page.displayCondition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1840
+ /* @__PURE__ */ jsx(
1841
+ Select,
1842
+ {
1843
+ "aria-label": translate("builder.conditionOperator"),
1844
+ value: page.displayCondition.operator,
1845
+ onChange: (value) => {
1846
+ const operator = value;
1847
+ updatePage(page.id, (current) => ({
1848
+ ...current,
1849
+ displayCondition: conditionWithValue(
1850
+ source.id,
1851
+ operator,
1852
+ defaultConditionValue(source)
1853
+ )
1854
+ }));
1855
+ },
1856
+ options: conditionOperators(source).map((operator) => ({
1857
+ value: operator,
1858
+ label: translate(operatorKey(operator))
1859
+ }))
1860
+ }
1861
+ ),
1862
+ /* @__PURE__ */ jsx(
1863
+ ConditionValueEditor,
1864
+ {
1865
+ source,
1866
+ condition: page.displayCondition,
1867
+ onChange: (condition) => updatePage(page.id, (current) => ({ ...current, displayCondition: condition })),
1868
+ translate,
1869
+ components
1870
+ }
1871
+ )
1872
+ ] }) : null
1873
+ ] }) : null
1874
+ ]
1875
+ },
1876
+ page.id
1877
+ );
1878
+ }),
1879
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__page-add"), children: [
1880
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1881
+ Select,
1882
+ {
1883
+ id: "builder-page-question",
1884
+ label: translate("builder.pageQuestion"),
1885
+ value: newPageQuestionId,
1886
+ disabled: movablePageQuestions.length === 0,
1887
+ onChange: setNewPageQuestionId,
1888
+ options: [
1889
+ { value: "", label: "\u2014" },
1890
+ ...schema.fields.filter((field) => movablePageQuestions.includes(field.id)).map((field) => ({ value: field.id, label: field.title }))
1891
+ ]
1892
+ }
1893
+ ) }),
1894
+ /* @__PURE__ */ jsx(Button, { disabled: movablePageQuestions.length === 0, onClick: addPage, children: translate("builder.addPage") })
1895
+ ] })
1896
+ ] })
1897
+ }
1898
+ ) : /* @__PURE__ */ jsx(
1899
+ PagesSlot,
1900
+ {
1901
+ schema,
1902
+ currentLocale: editingLocale,
1903
+ readOnly,
1904
+ actions,
1905
+ components
1906
+ }
1907
+ ) : null,
1908
+ localizationEnabled ? LocalizationSlot === void 0 ? /* @__PURE__ */ jsxs(
1909
+ Section,
1910
+ {
1911
+ className: builderClass("form-engine-builder__localization"),
1912
+ headingId: "builder-localization-heading",
1913
+ title: translate("builder.localization"),
1914
+ children: [
1915
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1916
+ TextInput,
1917
+ {
1918
+ id: "builder-completion-message",
1919
+ label: translate("builder.completionMessage"),
1920
+ value: schema.completionMessage ?? "",
1921
+ onChange: (value) => setSourceText({ kind: "form" }, "completionMessage", value)
1922
+ }
1923
+ ) }),
1924
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
1925
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1926
+ TextInput,
1927
+ {
1928
+ id: "builder-default-locale",
1929
+ label: translate("builder.defaultLocale"),
1930
+ value: schema.defaultLocale ?? "",
1931
+ onChange: setDefaultLocale
1932
+ }
1933
+ ) }),
1934
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx(
1935
+ TextInput,
1936
+ {
1937
+ id: "builder-new-locale",
1938
+ label: translate("builder.addLocale"),
1939
+ value: newLocale,
1940
+ onChange: setNewLocale
1941
+ }
1942
+ ) : /* @__PURE__ */ jsx(
1943
+ Select,
1944
+ {
1945
+ id: "builder-new-locale",
1946
+ label: translate("builder.addLocale"),
1947
+ value: newLocale,
1948
+ onChange: setNewLocale,
1949
+ options: [
1950
+ { value: "", label: "\u2014" },
1951
+ ...availableAllowedLocales.map((candidate) => ({ value: candidate, label: candidate }))
1952
+ ]
1953
+ }
1954
+ ) }),
1955
+ /* @__PURE__ */ jsx(
1956
+ Button,
1957
+ {
1958
+ action: "addLocale",
1959
+ disabled: newLocale.trim().length === 0 || localeLimitReached,
1960
+ onClick: addLocale,
1961
+ children: translate("builder.addLocale")
1962
+ }
1963
+ ),
1964
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1965
+ Select,
1966
+ {
1967
+ id: "builder-edit-locale",
1968
+ label: translate("builder.editLocale"),
1969
+ value: editingLocale,
1970
+ onChange: setEditingLocale,
1971
+ options: [
1972
+ { value: "", label: "\u2014" },
1973
+ ...(schema.supportedLocales ?? []).filter((item) => item !== schema.defaultLocale).map((item) => ({ value: item, label: item }))
1974
+ ]
1975
+ }
1976
+ ) }),
1977
+ TranslationActionsSlot === void 0 ? /* @__PURE__ */ jsx(
1978
+ Button,
1979
+ {
1980
+ disabled: translationAdapter === void 0 || editingLocale.length === 0 || isTranslating,
1981
+ onClick: () => void translateAll(),
1982
+ children: translate("builder.autoTranslate")
1983
+ }
1984
+ ) : /* @__PURE__ */ jsx(
1985
+ TranslationActionsSlot,
1986
+ {
1987
+ schema,
1988
+ currentLocale: editingLocale,
1989
+ onAutoTranslate: () => void translateAll(),
1990
+ isTranslating,
1991
+ ...translationError === null ? {} : { translationError },
1992
+ ...translationReport === void 0 ? {} : { translationReport },
1993
+ onClearTranslationError: () => setTranslationError(null),
1994
+ readOnly,
1995
+ actions,
1996
+ components
1997
+ }
1998
+ )
1999
+ ] }),
2000
+ translationAdapter === void 0 ? /* @__PURE__ */ jsx("p", { children: translate("builder.translationUnavailable") }) : null,
2001
+ translationError === null ? null : /* @__PURE__ */ jsx(ErrorMessage, { message: translationError }),
2002
+ editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2003
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2004
+ TextInput,
2005
+ {
2006
+ id: `builder-${editingLocale}-form-title`,
2007
+ label: translate("builder.questionTitle"),
2008
+ value: schema.translations?.[editingLocale]?.title ?? "",
2009
+ onChange: (value) => updateFormTranslation("title", value)
2010
+ }
2011
+ ) }),
2012
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2013
+ TextInput,
2014
+ {
2015
+ id: `builder-${editingLocale}-form-description`,
2016
+ label: translate("builder.pageDescription"),
2017
+ value: schema.translations?.[editingLocale]?.description ?? "",
2018
+ onChange: (value) => updateFormTranslation("description", value)
2019
+ }
2020
+ ) }),
2021
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2022
+ TextInput,
2023
+ {
2024
+ id: `builder-${editingLocale}-completion-message`,
2025
+ label: translate("builder.completionMessage"),
2026
+ value: schema.translations?.[editingLocale]?.completionMessage ?? "",
2027
+ onChange: (value) => updateFormTranslation("completionMessage", value)
2028
+ }
2029
+ ) })
2030
+ ] })
2031
+ ]
2032
+ }
2033
+ ) : /* @__PURE__ */ jsx(
2034
+ LocalizationSlot,
2035
+ {
2036
+ schema,
2037
+ currentLocale: editingLocale,
2038
+ onCurrentLocaleChange: setEditingLocale,
2039
+ onAutoTranslate: () => void translateAll(),
2040
+ isTranslating,
2041
+ ...translationError === null ? {} : { translationError },
2042
+ readOnly,
2043
+ actions,
2044
+ components
2045
+ }
2046
+ ) : null,
2047
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__list"), children: schema.fields.map((field, index) => {
2048
+ const condition = field.displayCondition;
2049
+ const source = condition === void 0 ? void 0 : schema.fields.find((item) => item.id === condition.questionId);
2050
+ const availableSources = schema.fields.slice(0, index);
2051
+ if (FieldEditorSlot !== void 0) {
2052
+ return /* @__PURE__ */ jsx(
2053
+ FieldEditorSlot,
2054
+ {
2055
+ schema,
2056
+ field,
2057
+ index,
2058
+ currentLocale: editingLocale,
2059
+ ...policy === void 0 ? {} : { policy },
2060
+ readOnly,
2061
+ actions,
2062
+ components
1756
2063
  },
1757
- page.id
2064
+ field.id
1758
2065
  );
1759
- }),
1760
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__page-add", children: [
1761
- /* @__PURE__ */ jsxs("label", { children: [
1762
- translate("builder.pageQuestion"),
2066
+ }
2067
+ return /* @__PURE__ */ jsxs(Fieldset, { className: builderClass("form-engine-builder__question"), legend: field.title, children: [
2068
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1763
2069
  /* @__PURE__ */ jsx(
1764
- Select,
2070
+ IconButton,
1765
2071
  {
1766
- value: newPageQuestionId,
1767
- disabled: movablePageQuestions.length === 0,
1768
- onChange: setNewPageQuestionId,
1769
- options: [
1770
- { value: "", label: "\u2014" },
1771
- ...schema.fields.filter((field) => movablePageQuestions.includes(field.id)).map((field) => ({ value: field.id, label: field.title }))
1772
- ]
2072
+ actionType: "moveUp",
2073
+ title: translate("builder.moveUp", { title: field.title }),
2074
+ disabled: index === 0,
2075
+ onClick: () => moveField(index, -1)
1773
2076
  }
1774
- )
1775
- ] }),
1776
- /* @__PURE__ */ jsx(Button, { disabled: movablePageQuestions.length === 0, onClick: addPage, children: translate("builder.addPage") })
1777
- ] })
1778
- ] })
1779
- }
1780
- ) : /* @__PURE__ */ jsx(
1781
- PagesSlot,
1782
- {
1783
- schema,
1784
- currentLocale: editingLocale,
1785
- readOnly,
1786
- actions,
1787
- components
1788
- }
1789
- ) : null,
1790
- localizationEnabled ? LocalizationSlot === void 0 ? /* @__PURE__ */ jsxs(
1791
- Section,
1792
- {
1793
- className: "form-engine-builder__localization",
1794
- headingId: "builder-localization-heading",
1795
- title: translate("builder.localization"),
1796
- children: [
1797
- /* @__PURE__ */ jsxs("label", { children: [
1798
- translate("builder.completionMessage"),
1799
- /* @__PURE__ */ jsx(
1800
- TextInput,
1801
- {
1802
- value: schema.completionMessage ?? "",
1803
- onChange: (value) => setSourceText({ kind: "form" }, "completionMessage", value)
1804
- }
1805
- )
1806
- ] }),
1807
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1808
- /* @__PURE__ */ jsxs("label", { children: [
1809
- translate("builder.defaultLocale"),
1810
- /* @__PURE__ */ jsx(TextInput, { value: schema.defaultLocale ?? "", onChange: setDefaultLocale })
1811
- ] }),
1812
- /* @__PURE__ */ jsxs("label", { htmlFor: "builder-new-locale", children: [
1813
- translate("builder.addLocale"),
1814
- availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx(TextInput, { id: "builder-new-locale", value: newLocale, onChange: setNewLocale }) : /* @__PURE__ */ jsx(
1815
- Select,
2077
+ ),
2078
+ /* @__PURE__ */ jsx(
2079
+ IconButton,
1816
2080
  {
1817
- id: "builder-new-locale",
1818
- value: newLocale,
1819
- onChange: setNewLocale,
1820
- options: [
1821
- { value: "", label: "\u2014" },
1822
- ...availableAllowedLocales.map((candidate) => ({ value: candidate, label: candidate }))
1823
- ]
2081
+ actionType: "moveDown",
2082
+ title: translate("builder.moveDown", { title: field.title }),
2083
+ disabled: index === schema.fields.length - 1,
2084
+ onClick: () => moveField(index, 1)
1824
2085
  }
1825
- )
1826
- ] }),
1827
- /* @__PURE__ */ jsx(
1828
- Button,
1829
- {
1830
- action: "addLocale",
1831
- disabled: newLocale.trim().length === 0 || localeLimitReached,
1832
- onClick: addLocale,
1833
- children: translate("builder.addLocale")
1834
- }
1835
- ),
1836
- /* @__PURE__ */ jsxs("label", { children: [
1837
- translate("builder.editLocale"),
2086
+ ),
1838
2087
  /* @__PURE__ */ jsx(
1839
- Select,
2088
+ IconButton,
1840
2089
  {
1841
- value: editingLocale,
1842
- onChange: setEditingLocale,
1843
- options: [
1844
- { value: "", label: "\u2014" },
1845
- ...(schema.supportedLocales ?? []).filter((item) => item !== schema.defaultLocale).map((item) => ({ value: item, label: item }))
1846
- ]
2090
+ actionType: "delete",
2091
+ disabled: schema.fields.length === 1,
2092
+ onClick: () => removeField(field.id),
2093
+ "aria-label": translate("builder.delete", { title: field.title }),
2094
+ title: translate("builder.delete", { title: field.title })
1847
2095
  }
1848
2096
  )
1849
- ] }),
1850
- TranslationActionsSlot === void 0 ? /* @__PURE__ */ jsx(
1851
- Button,
1852
- {
1853
- disabled: translationAdapter === void 0 || editingLocale.length === 0 || isTranslating,
1854
- onClick: () => void translateAll(),
1855
- children: translate("builder.autoTranslate")
1856
- }
1857
- ) : /* @__PURE__ */ jsx(
1858
- TranslationActionsSlot,
2097
+ ] }) : /* @__PURE__ */ jsx(
2098
+ ToolbarSlot,
1859
2099
  {
1860
2100
  schema,
1861
- currentLocale: editingLocale,
1862
- onAutoTranslate: () => void translateAll(),
1863
- isTranslating,
1864
- ...translationError === null ? {} : { translationError },
1865
- ...translationReport === void 0 ? {} : { translationReport },
1866
- onClearTranslationError: () => setTranslationError(null),
2101
+ kind: "field",
2102
+ targetId: field.id,
2103
+ index,
2104
+ total: schema.fields.length,
2105
+ title: field.title,
2106
+ onMoveUp: () => moveField(index, -1),
2107
+ onMoveDown: () => moveField(index, 1),
2108
+ onRemove: () => removeField(field.id),
1867
2109
  readOnly,
1868
2110
  actions,
1869
2111
  components
1870
2112
  }
1871
- )
1872
- ] }),
1873
- translationAdapter === void 0 ? /* @__PURE__ */ jsx("p", { children: translate("builder.translationUnavailable") }) : null,
1874
- translationError === null ? null : /* @__PURE__ */ jsx(ErrorMessage, { message: translationError }),
1875
- editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1876
- /* @__PURE__ */ jsxs("label", { children: [
1877
- translate("builder.questionTitle"),
1878
- /* @__PURE__ */ jsx(
2113
+ ) }),
2114
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2115
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
1879
2116
  TextInput,
1880
2117
  {
1881
- value: schema.translations?.[editingLocale]?.title ?? "",
1882
- onChange: (value) => updateFormTranslation("title", value)
2118
+ id: `builder-field-${field.id}-title`,
2119
+ name: `fields.${field.id}.title`,
2120
+ label: translate("builder.questionTitle"),
2121
+ required: true,
2122
+ error: field.title.trim().length === 0,
2123
+ helperText: field.title.trim().length === 0 ? translate("builder.required") : "",
2124
+ "aria-describedby": field.title.trim().length === 0 ? `builder-field-${field.id}-title-error` : void 0,
2125
+ value: field.title,
2126
+ placeholder: translate("builder.questionTitlePlaceholder"),
2127
+ onChange: (value) => updateField(field.id, (current) => ({
2128
+ ...current,
2129
+ title: value.trim().length === 0 ? current.title : value
2130
+ }))
1883
2131
  }
1884
- )
1885
- ] }),
1886
- /* @__PURE__ */ jsxs("label", { children: [
1887
- translate("builder.pageDescription"),
1888
- /* @__PURE__ */ jsx(
1889
- TextInput,
2132
+ ) }),
2133
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2134
+ Select,
1890
2135
  {
1891
- value: schema.translations?.[editingLocale]?.description ?? "",
1892
- onChange: (value) => updateFormTranslation("description", value)
2136
+ id: `builder-field-${field.id}-type`,
2137
+ label: translate("builder.type"),
2138
+ value: field.type,
2139
+ onChange: (value) => changeType(field.id, value),
2140
+ options: FIELD_TYPES.filter(
2141
+ (type) => policy?.allowedFieldTypes === void 0 || policy.allowedFieldTypes.includes(type)
2142
+ ).map((type) => ({ value: type, label: translate(fieldTypeKey(type)) }))
1893
2143
  }
1894
- )
1895
- ] }),
1896
- /* @__PURE__ */ jsxs("label", { children: [
1897
- translate("builder.completionMessage"),
2144
+ ) }),
1898
2145
  /* @__PURE__ */ jsx(
1899
- TextInput,
2146
+ Checkbox,
1900
2147
  {
1901
- value: schema.translations?.[editingLocale]?.completionMessage ?? "",
1902
- onChange: (value) => updateFormTranslation("completionMessage", value)
2148
+ className: builderClass("form-engine-builder__check"),
2149
+ checked: field.required === true,
2150
+ onChange: (checked) => updateField(field.id, (current) => ({ ...current, required: checked })),
2151
+ label: translate("builder.required")
1903
2152
  }
1904
2153
  )
1905
- ] })
1906
- ] })
1907
- ]
1908
- }
1909
- ) : /* @__PURE__ */ jsx(
1910
- LocalizationSlot,
1911
- {
1912
- schema,
1913
- currentLocale: editingLocale,
1914
- onCurrentLocaleChange: setEditingLocale,
1915
- onAutoTranslate: () => void translateAll(),
1916
- isTranslating,
1917
- ...translationError === null ? {} : { translationError },
1918
- readOnly,
1919
- actions,
1920
- components
1921
- }
1922
- ) : null,
1923
- /* @__PURE__ */ jsx("div", { className: "form-engine-builder__list", children: schema.fields.map((field, index) => {
1924
- const condition = field.displayCondition;
1925
- const source = condition === void 0 ? void 0 : schema.fields.find((item) => item.id === condition.questionId);
1926
- const availableSources = schema.fields.slice(0, index);
1927
- if (FieldEditorSlot !== void 0) {
1928
- return /* @__PURE__ */ jsx(
1929
- FieldEditorSlot,
1930
- {
1931
- schema,
1932
- field,
1933
- index,
1934
- currentLocale: editingLocale,
1935
- ...policy === void 0 ? {} : { policy },
1936
- readOnly,
1937
- actions,
1938
- components
1939
- },
1940
- field.id
1941
- );
1942
- }
1943
- return /* @__PURE__ */ jsxs(Fieldset, { className: "form-engine-builder__question", legend: field.title, children: [
1944
- /* @__PURE__ */ jsx("div", { className: "form-engine-builder__toolbar", children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
1945
- /* @__PURE__ */ jsx(
1946
- IconButton,
1947
- {
1948
- icon: "\u2191",
1949
- title: translate("builder.moveUp", { title: field.title }),
1950
- disabled: index === 0,
1951
- onClick: () => moveField(index, -1)
1952
- }
1953
- ),
1954
- /* @__PURE__ */ jsx(
1955
- IconButton,
1956
- {
1957
- icon: "\u2193",
1958
- title: translate("builder.moveDown", { title: field.title }),
1959
- disabled: index === schema.fields.length - 1,
1960
- onClick: () => moveField(index, 1)
1961
- }
1962
- ),
1963
- /* @__PURE__ */ jsx(
1964
- Button,
1965
- {
1966
- disabled: schema.fields.length === 1,
1967
- onClick: () => removeField(field.id),
1968
- "aria-label": translate("builder.delete", { title: field.title }),
1969
- variant: "danger",
1970
- children: translate("builder.deleteAction")
1971
- }
1972
- )
1973
- ] }) : /* @__PURE__ */ jsx(
1974
- ToolbarSlot,
1975
- {
1976
- schema,
1977
- kind: "field",
1978
- targetId: field.id,
1979
- index,
1980
- total: schema.fields.length,
1981
- title: field.title,
1982
- onMoveUp: () => moveField(index, -1),
1983
- onMoveDown: () => moveField(index, 1),
1984
- onRemove: () => removeField(field.id),
1985
- readOnly,
1986
- actions,
1987
- components
1988
- }
1989
- ) }),
1990
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
1991
- /* @__PURE__ */ jsxs("label", { children: [
1992
- translate("builder.questionTitle"),
1993
- /* @__PURE__ */ jsx(
1994
- TextInput,
1995
- {
1996
- name: `fields.${field.id}.title`,
1997
- label: translate("builder.questionTitle"),
1998
- required: true,
1999
- error: field.title.trim().length === 0,
2000
- helperText: field.title.trim().length === 0 ? translate("builder.required") : "",
2001
- value: field.title,
2002
- placeholder: translate("builder.questionTitlePlaceholder"),
2003
- onChange: (value) => updateField(field.id, (current) => ({
2004
- ...current,
2005
- title: value.trim().length === 0 ? current.title : value
2006
- }))
2007
- }
2008
- )
2009
- ] }),
2010
- /* @__PURE__ */ jsxs("label", { children: [
2011
- translate("builder.type"),
2012
- /* @__PURE__ */ jsx(
2154
+ ] }),
2155
+ !pagesEnabled || schema.pages === void 0 ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2013
2156
  Select,
2014
2157
  {
2015
- value: field.type,
2016
- onChange: (value) => changeType(field.id, value),
2017
- options: FIELD_TYPES.filter(
2018
- (type) => policy?.allowedFieldTypes === void 0 || policy.allowedFieldTypes.includes(type)
2019
- ).map((type) => ({ value: type, label: translate(fieldTypeKey(type)) }))
2158
+ id: `builder-field-${field.id}-page`,
2159
+ label: translate("builder.questionPage"),
2160
+ value: pageForField(field.id)?.id ?? "",
2161
+ onChange: (value) => assignFieldToPage(field.id, value),
2162
+ options: schema.pages.map((page, pageIndex) => ({
2163
+ value: page.id,
2164
+ label: page.title ?? `${translate("builder.newPage")} ${pageIndex + 1}`
2165
+ }))
2020
2166
  }
2021
- )
2022
- ] }),
2023
- /* @__PURE__ */ jsx(
2024
- Checkbox,
2025
- {
2026
- className: "form-engine-builder__check",
2027
- checked: field.required === true,
2028
- onChange: (checked) => updateField(field.id, (current) => ({ ...current, required: checked })),
2029
- label: translate("builder.required")
2030
- }
2031
- )
2032
- ] }),
2033
- !pagesEnabled || schema.pages === void 0 ? null : /* @__PURE__ */ jsxs("label", { children: [
2034
- translate("builder.questionPage"),
2035
- /* @__PURE__ */ jsx(
2036
- Select,
2037
- {
2038
- value: pageForField(field.id)?.id ?? "",
2039
- onChange: (value) => assignFieldToPage(field.id, value),
2040
- options: schema.pages.map((page, pageIndex) => ({
2041
- value: page.id,
2042
- label: page.title ?? `${translate("builder.newPage")} ${pageIndex + 1}`
2043
- }))
2044
- }
2045
- )
2046
- ] }),
2047
- !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__translation-editor", children: [
2048
- /* @__PURE__ */ jsx("strong", { children: editingLocale }),
2049
- /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
2050
- /* @__PURE__ */ jsxs("label", { children: [
2051
- translate("builder.questionTitle"),
2052
- /* @__PURE__ */ jsx(
2167
+ ) }),
2168
+ !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__translation-editor"), children: [
2169
+ /* @__PURE__ */ jsx("strong", { children: editingLocale }),
2170
+ /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2171
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2172
+ TextInput,
2173
+ {
2174
+ id: `builder-field-${field.id}-${editingLocale}-title`,
2175
+ label: translate("builder.questionTitle"),
2176
+ value: field.translations?.[editingLocale]?.title ?? "",
2177
+ onChange: (value) => updateManualTranslation({
2178
+ locale: editingLocale,
2179
+ kind: "field",
2180
+ nodeId: field.id,
2181
+ property: "title",
2182
+ sourceText: field.title,
2183
+ translatedText: value,
2184
+ ...field.translationMetadata?.[editingLocale]?.title === void 0 ? {} : {
2185
+ existingTranslationMetadata: field.translationMetadata[editingLocale]?.title
2186
+ }
2187
+ })
2188
+ }
2189
+ ) }),
2190
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2191
+ TextInput,
2192
+ {
2193
+ id: `builder-field-${field.id}-${editingLocale}-description`,
2194
+ label: translate("builder.pageDescription"),
2195
+ value: field.translations?.[editingLocale]?.description ?? "",
2196
+ onChange: (value) => updateManualTranslation({
2197
+ locale: editingLocale,
2198
+ kind: "field",
2199
+ nodeId: field.id,
2200
+ property: "description",
2201
+ sourceText: field.description ?? "",
2202
+ translatedText: value,
2203
+ ...field.translationMetadata?.[editingLocale]?.description === void 0 ? {} : {
2204
+ existingTranslationMetadata: field.translationMetadata[editingLocale]?.description
2205
+ }
2206
+ })
2207
+ }
2208
+ ) })
2209
+ ] }),
2210
+ "options" in field ? field.options.map((option, optionIndex) => /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2053
2211
  TextInput,
2054
2212
  {
2055
- value: field.translations?.[editingLocale]?.title ?? "",
2213
+ id: `builder-option-${option.id}-${editingLocale}`,
2214
+ label: `${translate("builder.optionLabel", { index: optionIndex + 1 })} (${editingLocale})`,
2215
+ value: option.translations?.[editingLocale] ?? "",
2056
2216
  onChange: (value) => updateManualTranslation({
2057
2217
  locale: editingLocale,
2058
- kind: "field",
2059
- nodeId: field.id,
2060
- property: "title",
2061
- sourceText: field.title,
2218
+ kind: "option",
2219
+ nodeId: option.id,
2220
+ property: "label",
2221
+ sourceText: option.label,
2062
2222
  translatedText: value,
2063
- ...field.translationMetadata?.[editingLocale]?.title === void 0 ? {} : {
2064
- existingTranslationMetadata: field.translationMetadata[editingLocale]?.title
2223
+ ...option.translationMetadata?.[editingLocale]?.label === void 0 ? {} : {
2224
+ existingTranslationMetadata: option.translationMetadata[editingLocale]?.label
2065
2225
  }
2066
2226
  })
2067
2227
  }
2068
- )
2228
+ ) }, option.id)) : null
2069
2229
  ] }),
2070
- /* @__PURE__ */ jsxs("label", { children: [
2071
- translate("builder.pageDescription"),
2072
- /* @__PURE__ */ jsx(
2230
+ field.type === "rating" ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2231
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2073
2232
  TextInput,
2074
2233
  {
2075
- value: field.translations?.[editingLocale]?.description ?? "",
2076
- onChange: (value) => updateManualTranslation({
2077
- locale: editingLocale,
2078
- kind: "field",
2079
- nodeId: field.id,
2080
- property: "description",
2081
- sourceText: field.description ?? "",
2082
- translatedText: value,
2083
- ...field.translationMetadata?.[editingLocale]?.description === void 0 ? {} : {
2084
- existingTranslationMetadata: field.translationMetadata[editingLocale]?.description
2085
- }
2086
- })
2087
- }
2088
- )
2089
- ] })
2090
- ] }),
2091
- "options" in field ? field.options.map((option, optionIndex) => /* @__PURE__ */ jsxs("label", { children: [
2092
- translate("builder.optionLabel", { index: optionIndex + 1 }),
2093
- " (",
2094
- editingLocale,
2095
- ")",
2096
- /* @__PURE__ */ jsx(
2097
- TextInput,
2098
- {
2099
- value: option.translations?.[editingLocale] ?? "",
2100
- onChange: (value) => updateManualTranslation({
2101
- locale: editingLocale,
2102
- kind: "option",
2103
- nodeId: option.id,
2104
- property: "label",
2105
- sourceText: option.label,
2106
- translatedText: value,
2107
- ...option.translationMetadata?.[editingLocale]?.label === void 0 ? {} : {
2108
- existingTranslationMetadata: option.translationMetadata[editingLocale]?.label
2234
+ id: `builder-field-${field.id}-minimum`,
2235
+ label: translate("builder.minimum"),
2236
+ type: "number",
2237
+ value: String(field.min ?? 1),
2238
+ onChange: (value) => {
2239
+ const min = Number(value);
2240
+ if (!Number.isInteger(min)) return;
2241
+ updateField(
2242
+ field.id,
2243
+ (current) => current.type === "rating" ? { ...current, min, max: Math.max(min, current.max ?? 5) } : current
2244
+ );
2109
2245
  }
2110
- })
2111
- }
2112
- )
2113
- ] }, option.id)) : null
2114
- ] }),
2115
- field.type === "rating" ? /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__grid", children: [
2116
- /* @__PURE__ */ jsxs("label", { children: [
2117
- translate("builder.minimum"),
2118
- /* @__PURE__ */ jsx(
2119
- TextInput,
2120
- {
2121
- type: "number",
2122
- value: String(field.min ?? 1),
2123
- onChange: (value) => {
2124
- const min = Number(value);
2125
- if (!Number.isInteger(min)) return;
2126
- updateField(
2127
- field.id,
2128
- (current) => current.type === "rating" ? { ...current, min, max: Math.max(min, current.max ?? 5) } : current
2129
- );
2130
2246
  }
2131
- }
2132
- )
2133
- ] }),
2134
- /* @__PURE__ */ jsxs("label", { children: [
2135
- translate("builder.maximum"),
2136
- /* @__PURE__ */ jsx(
2137
- TextInput,
2138
- {
2139
- type: "number",
2140
- value: String(field.max ?? 5),
2141
- onChange: (value) => {
2142
- const max = Number(value);
2143
- if (!Number.isInteger(max)) return;
2144
- updateField(
2145
- field.id,
2146
- (current) => current.type === "rating" ? { ...current, min: Math.min(current.min ?? 1, max), max } : current
2147
- );
2148
- }
2149
- }
2150
- )
2151
- ] })
2152
- ] }) : null,
2153
- "options" in field ? /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__options", children: [
2154
- /* @__PURE__ */ jsx("strong", { children: translate("builder.options") }),
2155
- field.options.map(
2156
- (option, optionIndex) => OptionEditorSlot === void 0 ? /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__option", children: [
2157
- /* @__PURE__ */ jsx(
2247
+ ) }),
2248
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2158
2249
  TextInput,
2159
2250
  {
2160
- "aria-label": translate("builder.optionLabel", { index: optionIndex + 1 }),
2161
- value: option.label,
2162
- placeholder: translate("builder.optionLabelPlaceholder"),
2163
- onChange: (value) => value.trim().length === 0 ? void 0 : updateOption(field.id, option.id, value)
2251
+ id: `builder-field-${field.id}-maximum`,
2252
+ label: translate("builder.maximum"),
2253
+ type: "number",
2254
+ value: String(field.max ?? 5),
2255
+ onChange: (value) => {
2256
+ const max = Number(value);
2257
+ if (!Number.isInteger(max)) return;
2258
+ updateField(
2259
+ field.id,
2260
+ (current) => current.type === "rating" ? { ...current, min: Math.min(current.min ?? 1, max), max } : current
2261
+ );
2262
+ }
2164
2263
  }
2165
- ),
2166
- ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2167
- /* @__PURE__ */ jsx(
2168
- IconButton,
2264
+ ) })
2265
+ ] }) : null,
2266
+ "options" in field ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__options"), children: [
2267
+ /* @__PURE__ */ jsx("strong", { children: translate("builder.options") }),
2268
+ field.options.map(
2269
+ (option, optionIndex) => OptionEditorSlot === void 0 ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__option"), children: [
2270
+ /* @__PURE__ */ jsx(
2271
+ TextInput,
2272
+ {
2273
+ id: `builder-option-${option.id}`,
2274
+ label: translate("builder.optionLabel", { index: optionIndex + 1 }),
2275
+ value: option.label,
2276
+ placeholder: translate("builder.optionLabelPlaceholder"),
2277
+ onChange: (value) => value.trim().length === 0 ? void 0 : updateOption(field.id, option.id, value)
2278
+ }
2279
+ ),
2280
+ ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2281
+ /* @__PURE__ */ jsx(
2282
+ IconButton,
2283
+ {
2284
+ actionType: "moveUp",
2285
+ title: translate("builder.moveUp", { title: option.label }),
2286
+ disabled: optionIndex === 0,
2287
+ onClick: () => moveOption(field.id, option.id, optionIndex - 1)
2288
+ }
2289
+ ),
2290
+ /* @__PURE__ */ jsx(
2291
+ IconButton,
2292
+ {
2293
+ actionType: "moveDown",
2294
+ title: translate("builder.moveDown", { title: option.label }),
2295
+ disabled: optionIndex === field.options.length - 1,
2296
+ onClick: () => moveOption(field.id, option.id, optionIndex + 1)
2297
+ }
2298
+ ),
2299
+ /* @__PURE__ */ jsx(
2300
+ IconButton,
2301
+ {
2302
+ actionType: "delete",
2303
+ disabled: field.options.length === 1,
2304
+ onClick: () => removeOption(field.id, option.id),
2305
+ title: translate("builder.remove")
2306
+ }
2307
+ )
2308
+ ] }) : /* @__PURE__ */ jsx(
2309
+ ToolbarSlot,
2310
+ {
2311
+ schema,
2312
+ kind: "option",
2313
+ targetId: option.id,
2314
+ index: optionIndex,
2315
+ total: field.options.length,
2316
+ title: option.label,
2317
+ onMoveUp: () => moveOption(field.id, option.id, optionIndex - 1),
2318
+ onMoveDown: () => moveOption(field.id, option.id, optionIndex + 1),
2319
+ onRemove: () => removeOption(field.id, option.id),
2320
+ readOnly,
2321
+ actions,
2322
+ components
2323
+ }
2324
+ )
2325
+ ] }, option.id) : /* @__PURE__ */ jsx(
2326
+ OptionEditorSlot,
2169
2327
  {
2170
- icon: "\u2191",
2171
- title: translate("builder.moveUp", { title: option.label }),
2172
- disabled: optionIndex === 0,
2173
- onClick: () => moveOption(field.id, option.id, optionIndex - 1)
2174
- }
2175
- ),
2328
+ schema,
2329
+ field,
2330
+ option,
2331
+ index: optionIndex,
2332
+ currentLocale: editingLocale,
2333
+ readOnly,
2334
+ actions,
2335
+ components
2336
+ },
2337
+ option.id
2338
+ )
2339
+ ),
2340
+ /* @__PURE__ */ jsx(
2341
+ Button,
2342
+ {
2343
+ action: "addOption",
2344
+ targetId: field.id,
2345
+ disabled: policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField,
2346
+ onClick: () => addOption(field.id),
2347
+ children: translate("builder.addOption")
2348
+ }
2349
+ )
2350
+ ] }) : null,
2351
+ conditionsEnabled ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__condition"), children: [
2352
+ /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2353
+ Select,
2354
+ {
2355
+ id: `builder-field-${field.id}-condition`,
2356
+ label: translate("builder.displayCondition"),
2357
+ value: condition?.questionId ?? "",
2358
+ onChange: (value) => {
2359
+ const selected = schema.fields.find((item) => item.id === value);
2360
+ setDisplayCondition(
2361
+ field.id,
2362
+ selected === void 0 ? void 0 : conditionWithValue(
2363
+ selected.id,
2364
+ conditionOperators(selected)[0] ?? "not_empty",
2365
+ defaultConditionValue(selected)
2366
+ )
2367
+ );
2368
+ },
2369
+ options: [
2370
+ { value: "", label: translate("builder.alwaysVisible") },
2371
+ ...availableSources.map((candidate) => ({ value: candidate.id, label: candidate.title }))
2372
+ ]
2373
+ }
2374
+ ) }),
2375
+ condition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2176
2376
  /* @__PURE__ */ jsx(
2177
- IconButton,
2377
+ Select,
2178
2378
  {
2179
- icon: "\u2193",
2180
- title: translate("builder.moveDown", { title: option.label }),
2181
- disabled: optionIndex === field.options.length - 1,
2182
- onClick: () => moveOption(field.id, option.id, optionIndex + 1)
2379
+ "aria-label": translate("builder.conditionOperator"),
2380
+ value: condition.operator,
2381
+ onChange: (value) => {
2382
+ const operator = value;
2383
+ setDisplayCondition(
2384
+ field.id,
2385
+ conditionWithValue(source.id, operator, defaultConditionValue(source))
2386
+ );
2387
+ },
2388
+ options: conditionOperators(source).map((operator) => ({
2389
+ value: operator,
2390
+ label: translate(operatorKey(operator))
2391
+ }))
2183
2392
  }
2184
2393
  ),
2185
2394
  /* @__PURE__ */ jsx(
2186
- Button,
2395
+ ConditionValueEditor,
2187
2396
  {
2188
- disabled: field.options.length === 1,
2189
- onClick: () => removeOption(field.id, option.id),
2190
- variant: "danger",
2191
- children: translate("builder.remove")
2397
+ source,
2398
+ condition,
2399
+ onChange: (next) => setDisplayCondition(field.id, next),
2400
+ translate,
2401
+ components
2192
2402
  }
2193
2403
  )
2194
- ] }) : /* @__PURE__ */ jsx(
2195
- ToolbarSlot,
2196
- {
2197
- schema,
2198
- kind: "option",
2199
- targetId: option.id,
2200
- index: optionIndex,
2201
- total: field.options.length,
2202
- title: option.label,
2203
- onMoveUp: () => moveOption(field.id, option.id, optionIndex - 1),
2204
- onMoveDown: () => moveOption(field.id, option.id, optionIndex + 1),
2205
- onRemove: () => removeOption(field.id, option.id),
2206
- readOnly,
2207
- actions,
2208
- components
2209
- }
2210
- )
2211
- ] }, option.id) : /* @__PURE__ */ jsx(
2212
- OptionEditorSlot,
2213
- {
2214
- schema,
2215
- field,
2216
- option,
2217
- index: optionIndex,
2218
- currentLocale: editingLocale,
2219
- readOnly,
2220
- actions,
2221
- components
2222
- },
2223
- option.id
2224
- )
2225
- ),
2226
- /* @__PURE__ */ jsx(
2227
- Button,
2228
- {
2229
- action: "addOption",
2230
- targetId: field.id,
2231
- disabled: policy?.maxOptionsPerField !== void 0 && field.options.length >= policy.maxOptionsPerField,
2232
- onClick: () => addOption(field.id),
2233
- children: translate("builder.addOption")
2234
- }
2235
- )
2236
- ] }) : null,
2237
- conditionsEnabled ? /* @__PURE__ */ jsxs("div", { className: "form-engine-builder__condition", children: [
2238
- /* @__PURE__ */ jsxs("label", { children: [
2239
- translate("builder.displayCondition"),
2240
- /* @__PURE__ */ jsx(
2241
- Select,
2242
- {
2243
- value: condition?.questionId ?? "",
2244
- onChange: (value) => {
2245
- const selected = schema.fields.find((item) => item.id === value);
2246
- setDisplayCondition(
2247
- field.id,
2248
- selected === void 0 ? void 0 : conditionWithValue(
2249
- selected.id,
2250
- conditionOperators(selected)[0] ?? "not_empty",
2251
- defaultConditionValue(selected)
2252
- )
2253
- );
2254
- },
2255
- options: [
2256
- { value: "", label: translate("builder.alwaysVisible") },
2257
- ...availableSources.map((candidate) => ({ value: candidate.id, label: candidate.title }))
2258
- ]
2259
- }
2260
- )
2261
- ] }),
2262
- condition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2263
- /* @__PURE__ */ jsx(
2264
- Select,
2265
- {
2266
- "aria-label": translate("builder.conditionOperator"),
2267
- value: condition.operator,
2268
- onChange: (value) => {
2269
- const operator = value;
2270
- setDisplayCondition(
2271
- field.id,
2272
- conditionWithValue(source.id, operator, defaultConditionValue(source))
2273
- );
2274
- },
2275
- options: conditionOperators(source).map((operator) => ({
2276
- value: operator,
2277
- label: translate(operatorKey(operator))
2278
- }))
2279
- }
2280
- ),
2281
- /* @__PURE__ */ jsx(
2282
- ConditionValueEditor,
2283
- {
2284
- source,
2285
- condition,
2286
- onChange: (next) => setDisplayCondition(field.id, next),
2287
- translate,
2288
- components
2289
- }
2290
- )
2291
- ] }) : null
2292
- ] }) : null
2293
- ] }, field.id);
2294
- }) }),
2295
- /* @__PURE__ */ jsx(
2296
- Button,
2297
- {
2298
- className: "form-engine-builder__add",
2299
- action: "addField",
2300
- disabled: initialFieldType === null || maxFieldsReached,
2301
- onClick: addField,
2302
- children: translate("builder.addQuestion")
2303
- }
2304
- )
2305
- ] })
2404
+ ] }) : null
2405
+ ] }) : null
2406
+ ] }, field.id);
2407
+ }) }),
2408
+ /* @__PURE__ */ jsx(
2409
+ Button,
2410
+ {
2411
+ className: builderClass("form-engine-builder__add"),
2412
+ action: "addField",
2413
+ disabled: initialFieldType === null || maxFieldsReached,
2414
+ onClick: addField,
2415
+ children: translate("builder.addQuestion")
2416
+ }
2417
+ )
2418
+ ] })
2419
+ }
2420
+ )
2306
2421
  }
2307
- ) });
2422
+ );
2308
2423
  }
2309
2424
 
2310
2425
  // src/context.tsx