@form-engine-ts/react 2.9.1 → 2.9.3

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