@form-engine-ts/mui 4.4.0 → 4.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
+ ConditionEditor: () => ConditionEditor,
23
24
  DEFAULT_MUI_SECTION_ORDER: () => DEFAULT_MUI_SECTION_ORDER,
24
25
  MUI_LOCALIZATION_SECTION_ORDERS: () => MUI_LOCALIZATION_SECTION_ORDERS,
25
26
  MuiButtonAdapter: () => MuiButtonAdapter,
@@ -38,6 +39,7 @@ __export(index_exports, {
38
39
  MuiTextAreaAdapter: () => MuiTextAreaAdapter,
39
40
  MuiTextInputAdapter: () => MuiTextInputAdapter,
40
41
  MuiToolbarSlot: () => MuiToolbarSlot,
42
+ TranslationWorkspace: () => TranslationWorkspace,
41
43
  createMuiBuilderComponents: () => createMuiBuilderComponents,
42
44
  createMuiBuilderProps: () => createMuiBuilderProps,
43
45
  createMuiBuilderSlots: () => createMuiBuilderSlots,
@@ -792,11 +794,189 @@ function createMuiBuilderComponents(optionsOrOverrides = {}, customOverrides) {
792
794
  // src/slots/FieldEditor.tsx
793
795
  var import_core = require("@form-engine-ts/core");
794
796
  var import_react2 = require("@form-engine-ts/react");
795
- var import_material12 = require("@mui/material");
797
+ var import_material13 = require("@mui/material");
796
798
 
797
- // src/slots/OptionEditor.tsx
799
+ // src/slots/ConditionEditor.tsx
798
800
  var import_material10 = require("@mui/material");
799
801
  var import_jsx_runtime11 = require("react/jsx-runtime");
802
+ var OPERATORS = [
803
+ "equals",
804
+ "not_equals",
805
+ "contains",
806
+ "not_contains",
807
+ "is_empty",
808
+ "is_not_empty",
809
+ "greater_than",
810
+ "less_than"
811
+ ];
812
+ function sourceIds(field) {
813
+ if (field.displayRule === void 0)
814
+ return field.displayCondition?.questionId === void 0 ? [] : [field.displayCondition.questionId];
815
+ const ids = [];
816
+ const visit = (group) => {
817
+ for (const condition of group.conditions) {
818
+ if ("logic" in condition) visit(condition);
819
+ else ids.push(condition.fieldId);
820
+ }
821
+ };
822
+ visit(field.displayRule.condition);
823
+ return ids;
824
+ }
825
+ function dependsOn(schema, startId, targetId, visited = /* @__PURE__ */ new Set()) {
826
+ if (startId === targetId) return true;
827
+ if (visited.has(startId)) return false;
828
+ visited.add(startId);
829
+ const field = schema.fields.find((candidate) => candidate.id === startId);
830
+ return field !== void 0 && sourceIds(field).some((sourceId) => dependsOn(schema, sourceId, targetId, visited));
831
+ }
832
+ function operatorsFor(field) {
833
+ if (field === void 0) return [];
834
+ if (field.type === "checkbox" || field.type === "multi-select")
835
+ return ["contains", "not_contains", "is_empty", "is_not_empty"];
836
+ if (field.type === "text" || field.type === "textarea")
837
+ return OPERATORS.filter(
838
+ (operator) => ["equals", "not_equals", "contains", "not_contains", "is_empty", "is_not_empty"].includes(operator)
839
+ );
840
+ if (field.type === "number" || field.type === "rating")
841
+ return ["equals", "not_equals", "greater_than", "less_than", "is_empty", "is_not_empty"];
842
+ return ["equals", "not_equals", "is_empty", "is_not_empty"];
843
+ }
844
+ function conditionGroup(rule) {
845
+ return rule?.condition ?? { logic: "all", conditions: [] };
846
+ }
847
+ function conditionValue(field, condition, onChange) {
848
+ if (["is_empty", "is_not_empty"].includes(condition.operator)) return null;
849
+ if (field !== void 0 && "options" in field) {
850
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.FormControl, { fullWidth: true, size: "small", children: [
851
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.InputLabel, { children: "Value" }),
852
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.Select, { label: "Value", value: String(condition.value ?? ""), onChange: (event) => onChange(event.target.value), children: field.options.map((option) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.MenuItem, { value: option.id, children: option.label }, option.id)) })
853
+ ] });
854
+ }
855
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
856
+ import_material10.TextField,
857
+ {
858
+ label: "Value",
859
+ type: field?.type === "number" || field?.type === "rating" ? "number" : "text",
860
+ value: condition.value === void 0 ? "" : String(condition.value),
861
+ onChange: (event) => onChange(field?.type === "number" || field?.type === "rating" ? Number(event.target.value) : event.target.value),
862
+ fullWidth: true,
863
+ size: "small"
864
+ }
865
+ );
866
+ }
867
+ function ConditionEditor({ schema, fieldId, value, onChange, readOnly = false }) {
868
+ const group = conditionGroup(value);
869
+ const candidates = schema.fields.filter((field) => field.id !== fieldId && !dependsOn(schema, field.id, fieldId));
870
+ const updateGroup = (nextGroup) => onChange({ action: value?.action ?? "show", condition: nextGroup });
871
+ const updateCondition = (index, nextCondition) => {
872
+ const conditions = group.conditions.map(
873
+ (condition, conditionIndex) => conditionIndex === index ? nextCondition : condition
874
+ );
875
+ updateGroup({ ...group, conditions });
876
+ };
877
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.Stack, { spacing: 1.5, "data-testid": `condition-editor-${fieldId}`, children: [
878
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
879
+ import_material10.ToggleButtonGroup,
880
+ {
881
+ exclusive: true,
882
+ value: group.logic,
883
+ onChange: (_event, logic) => logic === null ? void 0 : updateGroup({ ...group, logic }),
884
+ disabled: readOnly,
885
+ size: "small",
886
+ children: [
887
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.ToggleButton, { value: "all", children: "All (AND)" }),
888
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.ToggleButton, { value: "any", children: "Any (OR)" })
889
+ ]
890
+ }
891
+ ),
892
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.FormControl, { fullWidth: true, size: "small", children: [
893
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.InputLabel, { children: "Action" }),
894
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
895
+ import_material10.Select,
896
+ {
897
+ label: "Action",
898
+ value: value?.action ?? "show",
899
+ onChange: (event) => onChange({ action: event.target.value, condition: group }),
900
+ disabled: readOnly,
901
+ children: [
902
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.MenuItem, { value: "show", children: "Show when matched" }),
903
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.MenuItem, { value: "hide", children: "Hide when matched" })
904
+ ]
905
+ }
906
+ )
907
+ ] }),
908
+ group.conditions.map((condition, index) => {
909
+ if ("logic" in condition) return null;
910
+ const source = schema.fields.find((field) => field.id === condition.fieldId);
911
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.Stack, { direction: { xs: "column", md: "row" }, spacing: 1, children: [
912
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.FormControl, { fullWidth: true, size: "small", children: [
913
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.InputLabel, { children: "Question" }),
914
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
915
+ import_material10.Select,
916
+ {
917
+ label: "Question",
918
+ value: condition.fieldId,
919
+ onChange: (event) => {
920
+ const nextSource = schema.fields.find((field) => field.id === event.target.value);
921
+ const nextOperator = operatorsFor(nextSource)[0] ?? "equals";
922
+ updateCondition(index, { fieldId: event.target.value, operator: nextOperator });
923
+ },
924
+ disabled: readOnly,
925
+ children: candidates.map((candidate) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.MenuItem, { value: candidate.id, children: candidate.title }, candidate.id))
926
+ }
927
+ )
928
+ ] }),
929
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.FormControl, { fullWidth: true, size: "small", children: [
930
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.InputLabel, { children: "Operator" }),
931
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
932
+ import_material10.Select,
933
+ {
934
+ label: "Operator",
935
+ value: condition.operator,
936
+ onChange: (event) => updateCondition(index, { ...condition, operator: event.target.value }),
937
+ disabled: readOnly,
938
+ children: operatorsFor(source).map((operator) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_material10.MenuItem, { value: operator, children: operator }, operator))
939
+ }
940
+ )
941
+ ] }),
942
+ conditionValue(
943
+ source,
944
+ condition,
945
+ (nextValue) => updateCondition(index, { ...condition, value: nextValue })
946
+ ),
947
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
948
+ import_material10.Button,
949
+ {
950
+ onClick: () => updateGroup({
951
+ ...group,
952
+ conditions: group.conditions.filter((_item, itemIndex) => itemIndex !== index)
953
+ }),
954
+ disabled: readOnly,
955
+ children: "Remove"
956
+ }
957
+ )
958
+ ] }, `${condition.fieldId}-${condition.operator}`);
959
+ }),
960
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
961
+ import_material10.Button,
962
+ {
963
+ variant: "outlined",
964
+ disabled: readOnly || candidates.length === 0,
965
+ onClick: () => {
966
+ const source = candidates[0];
967
+ if (source === void 0) return;
968
+ const operator = operatorsFor(source)[0] ?? "equals";
969
+ updateGroup({ ...group, conditions: [...group.conditions, { fieldId: source.id, operator }] });
970
+ },
971
+ children: "Add condition"
972
+ }
973
+ )
974
+ ] });
975
+ }
976
+
977
+ // src/slots/OptionEditor.tsx
978
+ var import_material11 = require("@mui/material");
979
+ var import_jsx_runtime12 = require("react/jsx-runtime");
800
980
  function createMuiOptionEditorSlot(options) {
801
981
  return function MuiOptionEditor({
802
982
  field,
@@ -811,9 +991,9 @@ function createMuiOptionEditorSlot(options) {
811
991
  const resolved = useResolvedMuiAdapterOptions(options);
812
992
  const { IconButton: IconButton2, TextInput } = components;
813
993
  const describedBy = option.label.trim().length === 0 ? `mui-option-${option.id}-error` : void 0;
814
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.Stack, { ...resolved.muiSlotProps?.stack, "data-mui-slot": "option-editor", spacing: resolved.dense ? 0.75 : 1, children: [
815
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, alignItems: { sm: "flex-start" }, children: [
816
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
994
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material11.Stack, { ...resolved.muiSlotProps?.stack, "data-mui-slot": "option-editor", spacing: resolved.dense ? 0.75 : 1, children: [
995
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material11.Stack, { direction: { xs: "column", sm: "row" }, spacing: 1, alignItems: { sm: "flex-start" }, children: [
996
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
817
997
  TextInput,
818
998
  {
819
999
  id: `mui-option-${option.id}`,
@@ -827,8 +1007,8 @@ function createMuiOptionEditorSlot(options) {
827
1007
  onChange: (value) => actions.updateOption(field.id, option.id, (current) => ({ ...current, label: value }))
828
1008
  }
829
1009
  ),
830
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_material10.Stack, { direction: "row", spacing: 0.5, children: [
831
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1010
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_material11.Stack, { direction: "row", spacing: 0.5, children: [
1011
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
832
1012
  IconButton2,
833
1013
  {
834
1014
  actionType: "moveUp",
@@ -837,7 +1017,7 @@ function createMuiOptionEditorSlot(options) {
837
1017
  onClick: () => actions.moveOption(field.id, option.id, index - 1)
838
1018
  }
839
1019
  ),
840
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1020
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
841
1021
  IconButton2,
842
1022
  {
843
1023
  actionType: "moveDown",
@@ -846,7 +1026,7 @@ function createMuiOptionEditorSlot(options) {
846
1026
  onClick: () => actions.moveOption(field.id, option.id, index + 1)
847
1027
  }
848
1028
  ),
849
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1029
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
850
1030
  IconButton2,
851
1031
  {
852
1032
  actionType: "delete",
@@ -857,7 +1037,7 @@ function createMuiOptionEditorSlot(options) {
857
1037
  )
858
1038
  ] })
859
1039
  ] }),
860
- currentLocale.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1040
+ currentLocale.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
861
1041
  TextInput,
862
1042
  {
863
1043
  id: `mui-option-${option.id}-${currentLocale}`,
@@ -875,8 +1055,8 @@ function createMuiOptionEditorSlot(options) {
875
1055
  var MuiOptionEditorSlot = createMuiOptionEditorSlot();
876
1056
 
877
1057
  // src/slots/Toolbar.tsx
878
- var import_material11 = require("@mui/material");
879
- var import_jsx_runtime12 = require("react/jsx-runtime");
1058
+ var import_material12 = require("@mui/material");
1059
+ var import_jsx_runtime13 = require("react/jsx-runtime");
880
1060
  function createMuiToolbarSlot(options) {
881
1061
  return function MuiToolbar({
882
1062
  kind,
@@ -892,8 +1072,8 @@ function createMuiToolbarSlot(options) {
892
1072
  }) {
893
1073
  const resolved = useResolvedMuiAdapterOptions(options);
894
1074
  const { IconButton: IconButton2 } = components;
895
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
896
- import_material11.Stack,
1075
+ return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1076
+ import_material12.Stack,
897
1077
  {
898
1078
  ...resolved.muiSlotProps?.stack,
899
1079
  "data-mui-slot": "toolbar",
@@ -902,7 +1082,7 @@ function createMuiToolbarSlot(options) {
902
1082
  alignItems: "center",
903
1083
  sx: resolved.muiSlotProps?.stack?.sx ?? { mb: resolved.dense ? 1 : 2 },
904
1084
  children: [
905
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1085
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
906
1086
  IconButton2,
907
1087
  {
908
1088
  actionType: "moveUp",
@@ -911,7 +1091,7 @@ function createMuiToolbarSlot(options) {
911
1091
  onClick: onMoveUp
912
1092
  }
913
1093
  ),
914
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1094
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
915
1095
  IconButton2,
916
1096
  {
917
1097
  actionType: "moveDown",
@@ -920,7 +1100,7 @@ function createMuiToolbarSlot(options) {
920
1100
  onClick: onMoveDown
921
1101
  }
922
1102
  ),
923
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1103
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
924
1104
  IconButton2,
925
1105
  {
926
1106
  actionType: "delete",
@@ -937,7 +1117,7 @@ function createMuiToolbarSlot(options) {
937
1117
  var MuiToolbarSlot = createMuiToolbarSlot();
938
1118
 
939
1119
  // src/slots/FieldEditor.tsx
940
- var import_jsx_runtime13 = require("react/jsx-runtime");
1120
+ var import_jsx_runtime14 = require("react/jsx-runtime");
941
1121
  var FIELD_TYPES = import_core.DEFAULT_FIELD_TYPE_DEFINITIONS.map((definition) => definition.type);
942
1122
  function isFieldType(value) {
943
1123
  return FIELD_TYPES.some((type) => type === value);
@@ -990,7 +1170,7 @@ function createMuiFieldEditorSlot(options) {
990
1170
  fieldTypeOptions: fieldTypeOptionsConfig
991
1171
  }) {
992
1172
  const resolved = useResolvedMuiAdapterOptions(options);
993
- const { Button: Button2, Checkbox: Checkbox2, Select: Select2, TextArea, TextInput } = components;
1173
+ const { Button: Button4, Checkbox: Checkbox2, Select: Select3, TextArea, TextInput } = components;
994
1174
  const allowedTypes = policy?.allowedFieldTypes ?? FIELD_TYPES;
995
1175
  const pageId = schema.pages?.find((page) => page.questionIds.includes(field.id))?.id ?? "";
996
1176
  const condition = field.displayCondition;
@@ -1034,16 +1214,16 @@ function createMuiFieldEditorSlot(options) {
1034
1214
  const changeFieldType = (nextType) => {
1035
1215
  if (allowedTypes.includes(nextType)) actions.changeFieldType(field.id, nextType);
1036
1216
  };
1037
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
1038
- import_material12.Card,
1217
+ return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1218
+ import_material13.Card,
1039
1219
  {
1040
1220
  ...resolved.muiSlotProps?.card,
1041
1221
  "data-mui-slot": "field-editor",
1042
1222
  variant: "outlined",
1043
1223
  sx: resolved.muiSlotProps?.card?.sx ?? { mb: resolved.dense ? 1 : 2, p: resolved.dense ? 1.5 : 2 },
1044
1224
  children: [
1045
- FieldEditorHeader === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1046
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1225
+ FieldEditorHeader === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1226
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1047
1227
  Toolbar,
1048
1228
  {
1049
1229
  schema,
@@ -1061,11 +1241,11 @@ function createMuiFieldEditorSlot(options) {
1061
1241
  components
1062
1242
  }
1063
1243
  ),
1064
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material12.Typography, { variant: "subtitle1", fontWeight: "bold", children: field.title })
1065
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(FieldEditorHeader, { field, index, totalFields: schema.fields.length, actions }),
1066
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { ...resolved.muiSlotProps?.stack, spacing: resolved.dense ? 1 : 2, children: [
1067
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1068
- controls.title === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1244
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "subtitle1", fontWeight: "bold", children: field.title })
1245
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(FieldEditorHeader, { field, index, totalFields: schema.fields.length, actions }),
1246
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { ...resolved.muiSlotProps?.stack, spacing: resolved.dense ? 1 : 2, children: [
1247
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1248
+ controls.title === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1069
1249
  TextInput,
1070
1250
  {
1071
1251
  id: `mui-field-${field.id}-title`,
@@ -1080,8 +1260,8 @@ function createMuiFieldEditorSlot(options) {
1080
1260
  onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "title", value)
1081
1261
  }
1082
1262
  ),
1083
- controls.typeSelect === "hidden" ? null : FieldTypeSelect === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1084
- Select2,
1263
+ controls.typeSelect === "hidden" ? null : FieldTypeSelect === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1264
+ Select3,
1085
1265
  {
1086
1266
  id: fieldTypeSelectId,
1087
1267
  name: `fields.${field.id}.type`,
@@ -1093,7 +1273,7 @@ function createMuiFieldEditorSlot(options) {
1093
1273
  if (isFieldType(value)) changeFieldType(value);
1094
1274
  }
1095
1275
  }
1096
- ) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1276
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1097
1277
  FieldTypeSelect,
1098
1278
  {
1099
1279
  id: fieldTypeSelectId,
@@ -1110,7 +1290,7 @@ function createMuiFieldEditorSlot(options) {
1110
1290
  }
1111
1291
  )
1112
1292
  ] }),
1113
- controls.description === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1293
+ controls.description === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1114
1294
  TextArea,
1115
1295
  {
1116
1296
  id: `mui-field-${field.id}-description`,
@@ -1123,7 +1303,7 @@ function createMuiFieldEditorSlot(options) {
1123
1303
  onChange: (value) => actions.setSourceText({ kind: "field", id: field.id }, "description", value)
1124
1304
  }
1125
1305
  ),
1126
- controls.required === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1306
+ controls.required === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1127
1307
  Checkbox2,
1128
1308
  {
1129
1309
  id: `mui-field-${field.id}-required`,
@@ -1134,8 +1314,8 @@ function createMuiFieldEditorSlot(options) {
1134
1314
  onChange: (checked) => actions.updateField(field.id, (current) => ({ ...current, required: checked }))
1135
1315
  }
1136
1316
  ),
1137
- features?.pages === false || schema.pages === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1138
- Select2,
1317
+ features?.pages === false || schema.pages === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1318
+ Select3,
1139
1319
  {
1140
1320
  id: `mui-field-${field.id}-page`,
1141
1321
  label: translate("builder.questionPage"),
@@ -1148,8 +1328,8 @@ function createMuiFieldEditorSlot(options) {
1148
1328
  onChange: (value) => actions.assignFieldToPage(field.id, value.length === 0 ? null : value)
1149
1329
  }
1150
1330
  ),
1151
- field.type === "number" || field.type === "rating" ? (field.type === "number" ? controls.numberLimits : controls.ratingBounds) === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1152
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1331
+ field.type === "number" || field.type === "rating" ? (field.type === "number" ? controls.numberLimits : controls.ratingBounds) === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1332
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1153
1333
  TextInput,
1154
1334
  {
1155
1335
  id: `mui-field-${field.id}-minimum`,
@@ -1160,7 +1340,7 @@ function createMuiFieldEditorSlot(options) {
1160
1340
  onChange: (value) => actions.updateField(field.id, (current) => updateBound(current, "min", value))
1161
1341
  }
1162
1342
  ),
1163
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1343
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1164
1344
  TextInput,
1165
1345
  {
1166
1346
  id: `mui-field-${field.id}-maximum`,
@@ -1172,7 +1352,7 @@ function createMuiFieldEditorSlot(options) {
1172
1352
  }
1173
1353
  )
1174
1354
  ] }) : null,
1175
- field.type === "number" && controls.numberLimits !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1355
+ field.type === "number" && controls.numberLimits !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1176
1356
  TextInput,
1177
1357
  {
1178
1358
  id: `mui-field-${field.id}-step`,
@@ -1183,8 +1363,8 @@ function createMuiFieldEditorSlot(options) {
1183
1363
  onChange: (value) => actions.updateField(field.id, (current) => updateNumberProperty(current, "step", value))
1184
1364
  }
1185
1365
  ) : null,
1186
- (field.type === "text" || field.type === "textarea") && controls.textLimits !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1187
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1366
+ (field.type === "text" || field.type === "textarea") && controls.textLimits !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { direction: { xs: "column", sm: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1367
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1188
1368
  TextInput,
1189
1369
  {
1190
1370
  id: `mui-field-${field.id}-min-length`,
@@ -1199,7 +1379,7 @@ function createMuiFieldEditorSlot(options) {
1199
1379
  })
1200
1380
  }
1201
1381
  ),
1202
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1382
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1203
1383
  TextInput,
1204
1384
  {
1205
1385
  id: `mui-field-${field.id}-max-length`,
@@ -1214,7 +1394,7 @@ function createMuiFieldEditorSlot(options) {
1214
1394
  })
1215
1395
  }
1216
1396
  ),
1217
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1397
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1218
1398
  TextInput,
1219
1399
  {
1220
1400
  id: `mui-field-${field.id}-pattern`,
@@ -1228,9 +1408,25 @@ function createMuiFieldEditorSlot(options) {
1228
1408
  }
1229
1409
  )
1230
1410
  ] }) : null,
1231
- features?.conditions === false || conditionSources.length === 0 || controls.displayConditions === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1232
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1233
- Select2,
1411
+ features?.conditions === false || conditionSources.length === 0 || controls.displayConditions === "hidden" ? null : field.displayRule !== void 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1412
+ ConditionEditor,
1413
+ {
1414
+ schema,
1415
+ fieldId: field.id,
1416
+ value: field.displayRule,
1417
+ readOnly: readOnly || controls.displayConditions === "readOnly",
1418
+ onChange: (displayRule) => actions.updateField(field.id, (current) => {
1419
+ const { displayCondition: _displayCondition, ...withoutLegacyCondition } = current;
1420
+ if (displayRule === void 0) {
1421
+ const { displayRule: _displayRule, ...withoutRules } = withoutLegacyCondition;
1422
+ return withoutRules;
1423
+ }
1424
+ return { ...withoutLegacyCondition, displayRule };
1425
+ })
1426
+ }
1427
+ ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { direction: { xs: "column", md: "row" }, spacing: resolved.dense ? 1 : 2, children: [
1428
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1429
+ Select3,
1234
1430
  {
1235
1431
  id: `mui-field-${field.id}-condition-source`,
1236
1432
  label: translate("builder.displayCondition"),
@@ -1246,9 +1442,9 @@ function createMuiFieldEditorSlot(options) {
1246
1442
  )
1247
1443
  }
1248
1444
  ),
1249
- condition === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_jsx_runtime13.Fragment, { children: [
1250
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1251
- Select2,
1445
+ condition === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_jsx_runtime14.Fragment, { children: [
1446
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1447
+ Select3,
1252
1448
  {
1253
1449
  id: `mui-field-${field.id}-condition-operator`,
1254
1450
  label: translate("builder.conditionOperator"),
@@ -1266,7 +1462,7 @@ function createMuiFieldEditorSlot(options) {
1266
1462
  }
1267
1463
  }
1268
1464
  ),
1269
- condition.operator === "not_empty" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1465
+ condition.operator === "not_empty" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1270
1466
  TextInput,
1271
1467
  {
1272
1468
  id: `mui-field-${field.id}-condition-value`,
@@ -1278,11 +1474,11 @@ function createMuiFieldEditorSlot(options) {
1278
1474
  )
1279
1475
  ] })
1280
1476
  ] }),
1281
- currentLocale.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { spacing: resolved.dense ? 1 : 2, children: [
1282
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material12.Typography, { variant: "subtitle2", children: translate("builder.translation", {
1477
+ currentLocale.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { spacing: resolved.dense ? 1 : 2, children: [
1478
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "subtitle2", children: translate("builder.translation", {
1283
1479
  locale: resolved.getLocaleLabel?.(currentLocale) ?? currentLocale
1284
1480
  }) }),
1285
- controls.title === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1481
+ controls.title === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1286
1482
  TextInput,
1287
1483
  {
1288
1484
  id: `mui-field-${field.id}-${currentLocale}-title`,
@@ -1292,7 +1488,7 @@ function createMuiFieldEditorSlot(options) {
1292
1488
  onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "field", id: field.id }, "title", value)
1293
1489
  }
1294
1490
  ),
1295
- controls.description === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1491
+ controls.description === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1296
1492
  TextArea,
1297
1493
  {
1298
1494
  id: `mui-field-${field.id}-${currentLocale}-description`,
@@ -1304,9 +1500,9 @@ function createMuiFieldEditorSlot(options) {
1304
1500
  }
1305
1501
  )
1306
1502
  ] }),
1307
- "options" in field && controls.options !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(import_material12.Stack, { "data-mui-slot": "options", spacing: resolved.dense ? 1 : 2, children: [
1308
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_material12.Typography, { variant: "subtitle2", children: translate("builder.options") }),
1309
- field.options.map((option, optionIndex) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1503
+ "options" in field && controls.options !== "hidden" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { "data-mui-slot": "options", spacing: resolved.dense ? 1 : 2, children: [
1504
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "subtitle2", children: translate("builder.options") }),
1505
+ field.options.map((option, optionIndex) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1310
1506
  OptionEditor,
1311
1507
  {
1312
1508
  schema,
@@ -1321,8 +1517,8 @@ function createMuiFieldEditorSlot(options) {
1321
1517
  },
1322
1518
  option.id
1323
1519
  )),
1324
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1325
- Button2,
1520
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1521
+ Button4,
1326
1522
  {
1327
1523
  action: "addOption",
1328
1524
  targetId: field.id,
@@ -1342,9 +1538,9 @@ var MuiFieldEditorSlot = createMuiFieldEditorSlot();
1342
1538
 
1343
1539
  // src/slots/Localization.tsx
1344
1540
  var import_icons_material2 = require("@mui/icons-material");
1345
- var import_material13 = require("@mui/material");
1541
+ var import_material14 = require("@mui/material");
1346
1542
  var import_react3 = require("react");
1347
- var import_jsx_runtime14 = require("react/jsx-runtime");
1543
+ var import_jsx_runtime15 = require("react/jsx-runtime");
1348
1544
  var DEFAULT_EMPTY_STATE_MESSAGE = "No translation locales have been added yet. Select a language from the dropdown above to add one.";
1349
1545
  function normalizeLocaleOptions(options, getLocaleLabel) {
1350
1546
  const seen = /* @__PURE__ */ new Set();
@@ -1373,7 +1569,7 @@ function createMuiLocalizationSlot(options) {
1373
1569
  translate
1374
1570
  }) {
1375
1571
  const resolved = useResolvedMuiAdapterOptions(options);
1376
- const { Button: Button2, ErrorMessage, Select: Select2, TextArea, TextInput } = components;
1572
+ const { Button: Button4, ErrorMessage, Select: Select3, TextArea, TextInput } = components;
1377
1573
  const [newLocale, setNewLocale] = (0, import_react3.useState)("");
1378
1574
  const [pendingFocusLocale, setPendingFocusLocale] = (0, import_react3.useState)(null);
1379
1575
  const locales = Array.from(
@@ -1438,13 +1634,13 @@ function createMuiLocalizationSlot(options) {
1438
1634
  supportedLocales: schema.supportedLocales ?? [],
1439
1635
  totalLocales: registeredLocales.size
1440
1636
  };
1441
- const summary = localizationOptions.renderSummary === void 0 ? localizationOptions.showSummary ? configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Alert, { severity: "success", sx: { mb: 2 }, children: translate("builder.localization.localesConfiguredSummary", {
1637
+ const summary = localizationOptions.renderSummary === void 0 ? localizationOptions.showSummary ? configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Alert, { severity: "success", sx: { mb: 2 }, children: translate("builder.localization.localesConfiguredSummary", {
1442
1638
  count: schema.supportedLocales?.length ?? 0
1443
- }) }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Alert, { severity: "info", sx: { mb: 2 }, children: translate("builder.localization.noLocalesConfigured") }) : null : localizationOptions.renderSummary(summaryContext);
1444
- const title = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { alignItems: "center", direction: "row", spacing: 1, children: [
1445
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }),
1446
- localizationOptions.renderSummary === void 0 && localizationOptions.showSummary && configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1447
- import_material13.Chip,
1639
+ }) }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Alert, { severity: "info", sx: { mb: 2 }, children: translate("builder.localization.noLocalesConfigured") }) : null : localizationOptions.renderSummary(summaryContext);
1640
+ const title = /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.Stack, { alignItems: "center", direction: "row", spacing: 1, children: [
1641
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Typography, { variant: "subtitle1", fontWeight: "bold", children: translate("builder.localization") }),
1642
+ localizationOptions.renderSummary === void 0 && localizationOptions.showSummary && configuredTranslationLocales.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1643
+ import_material14.Chip,
1448
1644
  {
1449
1645
  label: legacySummaryLabel,
1450
1646
  size: "small",
@@ -1455,11 +1651,11 @@ function createMuiLocalizationSlot(options) {
1455
1651
  ] });
1456
1652
  const noCandidateLocales = hasLocaleSelector && filteredAvailableLocales.length === 0;
1457
1653
  const candidateHelperText = localeLimitReached ? void 0 : noCandidateLocales ? translate("builder.localization.allLocalesAdded") : void 0;
1458
- const content = /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1654
+ const content = /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.Stack, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1459
1655
  !collapsible ? title : null,
1460
1656
  summary,
1461
- /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(
1462
- import_material13.Stack,
1657
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(
1658
+ import_material14.Stack,
1463
1659
  {
1464
1660
  ...stackProps,
1465
1661
  direction: { xs: "column", sm: "row" },
@@ -1467,16 +1663,16 @@ function createMuiLocalizationSlot(options) {
1467
1663
  spacing: resolved.dense ? 1 : 2,
1468
1664
  sx: { mt: 1 },
1469
1665
  children: [
1470
- defaultLocaleControl === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } }, children: defaultLocaleControl === "readOnly" ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { spacing: 0.5, children: [
1471
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "caption", color: "text.secondary", children: translate("builder.defaultLocale") }),
1472
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1473
- import_material13.Chip,
1666
+ defaultLocaleControl === "hidden" ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } }, children: defaultLocaleControl === "readOnly" ? /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.Stack, { spacing: 0.5, children: [
1667
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Typography, { variant: "caption", color: "text.secondary", children: translate("builder.defaultLocale") }),
1668
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1669
+ import_material14.Chip,
1474
1670
  {
1475
1671
  label: resolved.getLocaleLabel?.(schema.defaultLocale ?? "") ?? schema.defaultLocale ?? "",
1476
1672
  size: resolved.size
1477
1673
  }
1478
1674
  )
1479
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1675
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1480
1676
  TextInput,
1481
1677
  {
1482
1678
  id: "mui-builder-default-locale",
@@ -1489,8 +1685,8 @@ function createMuiLocalizationSlot(options) {
1489
1685
  }
1490
1686
  }
1491
1687
  ) }),
1492
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } }, onKeyDownCapture: handleAddKeyDown, children: hasLocaleSelector ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1493
- Select2,
1688
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Box, { sx: { flexGrow: 1, minWidth: 0, width: { xs: "100%", sm: "auto" } }, onKeyDownCapture: handleAddKeyDown, children: hasLocaleSelector ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1689
+ Select3,
1494
1690
  {
1495
1691
  id: "mui-builder-new-locale",
1496
1692
  label: translate("builder.localization.selectLocaleToAdd"),
@@ -1500,7 +1696,7 @@ function createMuiLocalizationSlot(options) {
1500
1696
  disabled: readOnly || localeLimitReached || noCandidateLocales,
1501
1697
  onChange: setNewLocale
1502
1698
  }
1503
- ) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1699
+ ) : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1504
1700
  TextInput,
1505
1701
  {
1506
1702
  id: "mui-builder-new-locale",
@@ -1510,16 +1706,16 @@ function createMuiLocalizationSlot(options) {
1510
1706
  onChange: setNewLocale
1511
1707
  }
1512
1708
  ) }),
1513
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1514
- import_material13.Box,
1709
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1710
+ import_material14.Box,
1515
1711
  {
1516
1712
  sx: {
1517
1713
  flexShrink: 0,
1518
1714
  minWidth: "max-content",
1519
1715
  ...localizationOptions.noWrapActions ?? true ? { whiteSpace: "nowrap" } : {}
1520
1716
  },
1521
- children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1522
- Button2,
1717
+ children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1718
+ Button4,
1523
1719
  {
1524
1720
  variant: "primary",
1525
1721
  action: "addLocale",
@@ -1534,17 +1730,17 @@ function createMuiLocalizationSlot(options) {
1534
1730
  ]
1535
1731
  }
1536
1732
  ),
1537
- localeLimitReached ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "body2", color: "text.secondary", children: translate("builder.localization.maxLocalesReached", { max: policy?.maxLocales ?? 0 }) }) : null,
1538
- locales.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1539
- import_material13.Tabs,
1733
+ localeLimitReached ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Typography, { variant: "body2", color: "text.secondary", children: translate("builder.localization.maxLocalesReached", { max: policy?.maxLocales ?? 0 }) }) : null,
1734
+ locales.length === 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1735
+ import_material14.Tabs,
1540
1736
  {
1541
1737
  value: editingLocaleConfigured ? currentLocale : false,
1542
1738
  onChange: handleTabChange,
1543
1739
  variant: "scrollable",
1544
1740
  scrollButtons: "auto",
1545
1741
  "aria-label": translate("builder.translationLocale"),
1546
- children: locales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1547
- import_material13.Tab,
1742
+ children: locales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1743
+ import_material14.Tab,
1548
1744
  {
1549
1745
  id: `mui-builder-locale-tab-${locale}`,
1550
1746
  value: locale,
@@ -1556,8 +1752,8 @@ function createMuiLocalizationSlot(options) {
1556
1752
  ))
1557
1753
  }
1558
1754
  ),
1559
- !translationAdapterAvailable ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Box, { sx: { minWidth: "max-content", whiteSpace: "nowrap" }, children: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1560
- Button2,
1755
+ !translationAdapterAvailable ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Box, { sx: { minWidth: "max-content", whiteSpace: "nowrap" }, children: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1756
+ Button4,
1561
1757
  {
1562
1758
  variant: "secondary",
1563
1759
  noWrap: localizationOptions.noWrapActions ?? true,
@@ -1566,9 +1762,9 @@ function createMuiLocalizationSlot(options) {
1566
1762
  children: isTranslating ? translate("builder.translating") : translate("builder.autoTranslate")
1567
1763
  }
1568
1764
  ) }),
1569
- translationError === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(ErrorMessage, { message: translationError }),
1570
- !editingLocaleConfigured ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.Typography, { variant: "body2", color: "text.secondary", children: locales.length === 0 ? emptyStateMessage : translate("builder.selectLocale") }) : /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Stack, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1571
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1765
+ translationError === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(ErrorMessage, { message: translationError }),
1766
+ !editingLocaleConfigured ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.Typography, { variant: "body2", color: "text.secondary", children: locales.length === 0 ? emptyStateMessage : translate("builder.selectLocale") }) : /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.Stack, { ...stackProps, spacing: resolved.dense ? 1 : 2, children: [
1767
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1572
1768
  TextInput,
1573
1769
  {
1574
1770
  id: `mui-builder-${currentLocale}-form-title`,
@@ -1578,7 +1774,7 @@ function createMuiLocalizationSlot(options) {
1578
1774
  onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "form" }, "title", value)
1579
1775
  }
1580
1776
  ),
1581
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1777
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1582
1778
  TextArea,
1583
1779
  {
1584
1780
  id: `mui-builder-${currentLocale}-form-description`,
@@ -1588,7 +1784,7 @@ function createMuiLocalizationSlot(options) {
1588
1784
  onChange: (value) => actions.setManualTranslation(currentLocale, { kind: "form" }, "description", value)
1589
1785
  }
1590
1786
  ),
1591
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1787
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1592
1788
  TextInput,
1593
1789
  {
1594
1790
  id: `mui-builder-${currentLocale}-completion-message`,
@@ -1603,13 +1799,13 @@ function createMuiLocalizationSlot(options) {
1603
1799
  const configured = locales.length > 0;
1604
1800
  const defaultExpanded = localizationOptions.defaultExpanded === "when-configured" ? configured : localizationOptions.defaultExpanded === "always" ? true : localizationOptions.defaultExpanded ?? false;
1605
1801
  if (collapsible) {
1606
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)(import_material13.Accordion, { ...resolved.muiSlotProps?.accordion, "data-mui-slot": "localization", defaultExpanded, children: [
1607
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.AccordionSummary, { expandIcon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_icons_material2.ExpandMore, {}), children: title }),
1608
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_material13.AccordionDetails, { children: content })
1802
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.Accordion, { ...resolved.muiSlotProps?.accordion, "data-mui-slot": "localization", defaultExpanded, children: [
1803
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.AccordionSummary, { expandIcon: /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_icons_material2.ExpandMore, {}), children: title }),
1804
+ /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.AccordionDetails, { children: content })
1609
1805
  ] });
1610
1806
  }
1611
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1612
- import_material13.Box,
1807
+ return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1808
+ import_material14.Box,
1613
1809
  {
1614
1810
  "data-mui-slot": "localization",
1615
1811
  sx: {
@@ -1627,8 +1823,8 @@ function createMuiLocalizationSlot(options) {
1627
1823
  var MuiLocalizationSlot = createMuiLocalizationSlot();
1628
1824
 
1629
1825
  // src/slots/MuiChoiceGroupSlot.tsx
1630
- var import_material14 = require("@mui/material");
1631
- var import_jsx_runtime15 = require("react/jsx-runtime");
1826
+ var import_material15 = require("@mui/material");
1827
+ var import_jsx_runtime16 = require("react/jsx-runtime");
1632
1828
  function MuiChoiceGroupSlot({
1633
1829
  title,
1634
1830
  description,
@@ -1638,8 +1834,8 @@ function MuiChoiceGroupSlot({
1638
1834
  children,
1639
1835
  className
1640
1836
  }) {
1641
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1642
- import_material14.Paper,
1837
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1838
+ import_material15.Paper,
1643
1839
  {
1644
1840
  className,
1645
1841
  variant: "outlined",
@@ -1649,11 +1845,11 @@ function MuiChoiceGroupSlot({
1649
1845
  mb: 2,
1650
1846
  p: 2
1651
1847
  },
1652
- children: /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_material14.FormControl, { component: "fieldset", error: error !== void 0, fullWidth: true, required, disabled, children: [
1653
- /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.FormLabel, { component: "legend", sx: { fontWeight: "bold", mb: description === void 0 ? 1 : 0.5 }, children: title }),
1654
- description === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.FormHelperText, { sx: { mt: 0, mb: 1 }, children: description }),
1848
+ children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_material15.FormControl, { component: "fieldset", error: error !== void 0, fullWidth: true, required, disabled, children: [
1849
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material15.FormLabel, { component: "legend", sx: { fontWeight: "bold", mb: description === void 0 ? 1 : 0.5 }, children: title }),
1850
+ description === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material15.FormHelperText, { sx: { mt: 0, mb: 1 }, children: description }),
1655
1851
  children,
1656
- error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_material14.FormHelperText, { error: true, children: error.message })
1852
+ error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_material15.FormHelperText, { error: true, children: error.message })
1657
1853
  ] })
1658
1854
  }
1659
1855
  );
@@ -1690,11 +1886,12 @@ function createMuiBuilderProps(options, overrides = {}) {
1690
1886
  // src/MuiFormBuilder.tsx
1691
1887
  var import_react4 = require("@form-engine-ts/react");
1692
1888
  var import_react5 = require("react");
1693
- var import_jsx_runtime16 = require("react/jsx-runtime");
1889
+ var import_jsx_runtime17 = require("react/jsx-runtime");
1694
1890
  function MuiFormBuilder({
1695
1891
  muiOptions,
1696
1892
  layoutOptions,
1697
1893
  localizationOptions,
1894
+ submissionSettingsOptions,
1698
1895
  muiSlotProps,
1699
1896
  components: customComponents,
1700
1897
  slots: customSlots,
@@ -1713,20 +1910,170 @@ function MuiFormBuilder({
1713
1910
  const components = (0, import_react5.useMemo)(() => ({ ...muiBuilderComponents, ...customComponents }), [customComponents]);
1714
1911
  const slots = (0, import_react5.useMemo)(() => ({ ...muiBuilderSlots, ...customSlots }), [customSlots]);
1715
1912
  const placement = contextOptions.localizationOptions?.placement;
1716
- const resolvedSectionOrder = sectionOrder ?? (placement === void 0 ? contextOptions.layoutOptions?.sectionOrder : MUI_LOCALIZATION_SECTION_ORDERS[placement]);
1717
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(MuiFormBuilderContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
1913
+ const baseSectionOrder = sectionOrder ?? (placement === void 0 ? contextOptions.layoutOptions?.sectionOrder : MUI_LOCALIZATION_SECTION_ORDERS[placement]);
1914
+ const resolvedSectionOrder = (() => {
1915
+ if (submissionSettingsOptions?.enabled !== true) return baseSectionOrder;
1916
+ const order = [
1917
+ ...baseSectionOrder ?? DEFAULT_MUI_SECTION_ORDER
1918
+ ].filter((name) => name !== "submissionSettings");
1919
+ const settingsPlacement = submissionSettingsOptions.placement ?? "bottom";
1920
+ const target = settingsPlacement === "beforeQuestions" ? "questions" : settingsPlacement === "afterQuestions" ? "addQuestion" : void 0;
1921
+ if (target === void 0) return [...order, "submissionSettings"];
1922
+ const index = order.indexOf(target);
1923
+ order.splice(
1924
+ index < 0 ? order.length : index + (settingsPlacement === "afterQuestions" ? 1 : 0),
1925
+ 0,
1926
+ "submissionSettings"
1927
+ );
1928
+ return order;
1929
+ })();
1930
+ return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(MuiFormBuilderContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
1718
1931
  import_react4.FormBuilder,
1719
1932
  {
1720
1933
  ...props,
1721
1934
  components,
1722
1935
  disableDefaultStyles: true,
1723
1936
  slots,
1724
- ...resolvedSectionOrder === void 0 ? {} : { sectionOrder: resolvedSectionOrder }
1937
+ ...resolvedSectionOrder === void 0 ? {} : { sectionOrder: resolvedSectionOrder },
1938
+ ...submissionSettingsOptions === void 0 ? {} : { submissionSettingsOptions }
1725
1939
  }
1726
1940
  ) });
1727
1941
  }
1942
+
1943
+ // src/workspace/TranslationWorkspace.tsx
1944
+ var import_react6 = require("@form-engine-ts/react");
1945
+ var import_material16 = require("@mui/material");
1946
+ var import_react7 = require("react");
1947
+ var import_jsx_runtime18 = require("react/jsx-runtime");
1948
+ var statusLabel = {
1949
+ missing: "Missing",
1950
+ translated: "Translated",
1951
+ stale: "Source changed",
1952
+ manual: "Manual",
1953
+ "manual-stale": "Manual / source changed"
1954
+ };
1955
+ function SlotCard({
1956
+ slot,
1957
+ readOnly,
1958
+ onChange,
1959
+ onTranslate
1960
+ }) {
1961
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Card, { variant: "outlined", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.CardContent, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Stack, { spacing: 1.5, children: [
1962
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Stack, { direction: "row", justifyContent: "space-between", alignItems: "center", children: [
1963
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Typography, { variant: "subtitle2", children: slot.path }),
1964
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Chip, { size: "small", label: statusLabel[slot.status ?? "missing"] })
1965
+ ] }),
1966
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1967
+ import_material16.TextField,
1968
+ {
1969
+ label: "Source",
1970
+ value: slot.sourceText,
1971
+ multiline: true,
1972
+ fullWidth: true,
1973
+ slotProps: { input: { readOnly: true } }
1974
+ }
1975
+ ),
1976
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
1977
+ import_material16.TextField,
1978
+ {
1979
+ label: "Translation",
1980
+ value: slot.existingText ?? "",
1981
+ multiline: true,
1982
+ fullWidth: true,
1983
+ disabled: readOnly,
1984
+ onChange: (event) => onChange(event.target.value)
1985
+ }
1986
+ ),
1987
+ slot.status === "stale" || slot.status === "manual-stale" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Typography, { color: "warning.main", variant: "body2", children: "The source text has changed since this translation was created." }) : null,
1988
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Button, { variant: "outlined", onClick: onTranslate, disabled: readOnly, children: "Translate this slot" })
1989
+ ] }) }) });
1990
+ }
1991
+ function TranslationWorkspace({
1992
+ schema,
1993
+ onChange,
1994
+ sourceLocale,
1995
+ targetLocale,
1996
+ translationAdapter,
1997
+ readOnly = false
1998
+ }) {
1999
+ const workspace = (0, import_react6.useTranslationWorkspace)({
2000
+ schema,
2001
+ ...onChange === void 0 ? {} : { onChange },
2002
+ ...sourceLocale === void 0 ? {} : { sourceLocale },
2003
+ ...targetLocale === void 0 ? {} : { targetLocale },
2004
+ ...translationAdapter === void 0 ? {} : { translationAdapter },
2005
+ readOnly
2006
+ });
2007
+ const [newLocale, setNewLocale] = (0, import_react7.useState)("");
2008
+ return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Stack, { spacing: 2, "data-testid": "translation-workspace", children: [
2009
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Stack, { direction: { xs: "column", sm: "row" }, spacing: 2, alignItems: { sm: "center" }, children: [
2010
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Typography, { variant: "h6", children: "Translations" }),
2011
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Typography, { variant: "body2", children: [
2012
+ workspace.summary.completionPercentage,
2013
+ "% complete (",
2014
+ workspace.summary.translatedCount,
2015
+ "/",
2016
+ workspace.summary.totalSlots,
2017
+ ")"
2018
+ ] }),
2019
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2020
+ import_material16.Button,
2021
+ {
2022
+ variant: "contained",
2023
+ onClick: () => void workspace.translateAll(),
2024
+ disabled: readOnly || workspace.isTranslating,
2025
+ children: "Translate all"
2026
+ }
2027
+ )
2028
+ ] }),
2029
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.LinearProgress, { variant: "determinate", value: workspace.summary.completionPercentage }),
2030
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_material16.Stack, { direction: "row", spacing: 1, alignItems: "center", children: [
2031
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2032
+ import_material16.Tabs,
2033
+ {
2034
+ value: workspace.targetLocale,
2035
+ onChange: (_event, value) => workspace.setTargetLocale(value),
2036
+ "aria-label": "Translation locales",
2037
+ children: workspace.targetLocales.map((locale) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Tab, { value: locale, label: locale }, locale))
2038
+ }
2039
+ ),
2040
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2041
+ import_material16.TextField,
2042
+ {
2043
+ size: "small",
2044
+ label: "Add locale",
2045
+ value: newLocale,
2046
+ onChange: (event) => setNewLocale(event.target.value)
2047
+ }
2048
+ ),
2049
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2050
+ import_material16.Button,
2051
+ {
2052
+ onClick: () => {
2053
+ workspace.addLocale(newLocale);
2054
+ setNewLocale("");
2055
+ },
2056
+ disabled: readOnly,
2057
+ children: "Add"
2058
+ }
2059
+ )
2060
+ ] }),
2061
+ workspace.error === void 0 ? null : /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Typography, { color: "error", children: workspace.error }),
2062
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_material16.Stack, { spacing: 1.5, children: workspace.slots.map((slot) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2063
+ SlotCard,
2064
+ {
2065
+ slot,
2066
+ readOnly,
2067
+ onChange: (text) => workspace.setTranslation(slot, text),
2068
+ onTranslate: () => void workspace.translateSlot(slot)
2069
+ },
2070
+ slot.path
2071
+ )) })
2072
+ ] });
2073
+ }
1728
2074
  // Annotate the CommonJS export names for ESM import in node:
1729
2075
  0 && (module.exports = {
2076
+ ConditionEditor,
1730
2077
  DEFAULT_MUI_SECTION_ORDER,
1731
2078
  MUI_LOCALIZATION_SECTION_ORDERS,
1732
2079
  MuiButtonAdapter,
@@ -1745,6 +2092,7 @@ function MuiFormBuilder({
1745
2092
  MuiTextAreaAdapter,
1746
2093
  MuiTextInputAdapter,
1747
2094
  MuiToolbarSlot,
2095
+ TranslationWorkspace,
1748
2096
  createMuiBuilderComponents,
1749
2097
  createMuiBuilderProps,
1750
2098
  createMuiBuilderSlots,