@form-engine-ts/react 4.8.0 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ import {
102
102
  DEFAULT_FIELD_TYPE_DEFINITIONS,
103
103
  populateSchemaTranslations
104
104
  } from "@form-engine-ts/core";
105
- import { Children, createContext, isValidElement, useContext, useState as useState2 } from "react";
105
+ import { Children, createContext as createContext2, isValidElement, useContext as useContext2, useState as useState2 } from "react";
106
106
 
107
107
  // src/hooks/useFormBuilder.ts
108
108
  import {
@@ -921,8 +921,42 @@ function resolveTranslation(key, aliases, adapter, defaultCatalog, params = {},
921
921
  return key;
922
922
  }
923
923
 
924
+ // src/i18n/provider.tsx
925
+ import { createFormEngineTranslator } from "@form-engine-ts/core";
926
+ import { createContext, useContext, useMemo as useMemo2 } from "react";
927
+ import { jsx } from "react/jsx-runtime";
928
+ var defaultTranslator = createFormEngineTranslator({ locale: "ja" });
929
+ var FormEngineI18nContext = createContext({
930
+ uiLocale: "ja",
931
+ translator: defaultTranslator
932
+ });
933
+ var FormEngineI18nProviderScopeContext = createContext(false);
934
+ function FormEngineI18nProvider({
935
+ locale = "ja",
936
+ fallbackLocale = "en",
937
+ messages,
938
+ customCatalogs,
939
+ translator: customTranslator,
940
+ children
941
+ }) {
942
+ const translator = useMemo2(() => {
943
+ if (customTranslator !== void 0) return customTranslator;
944
+ return createFormEngineTranslator({
945
+ locale,
946
+ fallbackLocale,
947
+ ...messages === void 0 ? {} : { messages },
948
+ ...customCatalogs === void 0 ? {} : { customCatalogs }
949
+ });
950
+ }, [customCatalogs, customTranslator, fallbackLocale, locale, messages]);
951
+ const value = useMemo2(() => ({ uiLocale: locale, translator }), [locale, translator]);
952
+ return /* @__PURE__ */ jsx(FormEngineI18nProviderScopeContext.Provider, { value: true, children: /* @__PURE__ */ jsx(FormEngineI18nContext.Provider, { value, children }) });
953
+ }
954
+ function useFormEngineI18n() {
955
+ return useContext(FormEngineI18nContext);
956
+ }
957
+
924
958
  // src/builder.tsx
925
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
959
+ import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
926
960
  function DefaultButton({
927
961
  id,
928
962
  className,
@@ -936,7 +970,7 @@ function DefaultButton({
936
970
  action,
937
971
  targetId
938
972
  }) {
939
- return /* @__PURE__ */ jsx(
973
+ return /* @__PURE__ */ jsx2(
940
974
  "button",
941
975
  {
942
976
  id,
@@ -955,7 +989,7 @@ function DefaultButton({
955
989
  );
956
990
  }
957
991
  function DefaultIconButton(props) {
958
- return /* @__PURE__ */ jsx(
992
+ return /* @__PURE__ */ jsx2(
959
993
  DefaultButton,
960
994
  {
961
995
  ...props.id === void 0 ? {} : { id: props.id },
@@ -1034,10 +1068,10 @@ function DefaultTextInput({
1034
1068
  max,
1035
1069
  step
1036
1070
  }) {
1037
- const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
1071
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx2("span", { children: label }) : /* @__PURE__ */ jsx2("label", { htmlFor: id, children: label });
1038
1072
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1039
1073
  labelElement,
1040
- /* @__PURE__ */ jsx(
1074
+ /* @__PURE__ */ jsx2(
1041
1075
  "input",
1042
1076
  {
1043
1077
  id,
@@ -1061,7 +1095,7 @@ function DefaultTextInput({
1061
1095
  onChange: (event) => onChange(event.currentTarget.value)
1062
1096
  }
1063
1097
  ),
1064
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
1098
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx2("small", { id: ariaDescribedBy, children: helperText })
1065
1099
  ] });
1066
1100
  }
1067
1101
  function DefaultTextArea({
@@ -1083,10 +1117,10 @@ function DefaultTextArea({
1083
1117
  placeholder,
1084
1118
  maxLength
1085
1119
  }) {
1086
- const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
1120
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx2("span", { children: label }) : /* @__PURE__ */ jsx2("label", { htmlFor: id, children: label });
1087
1121
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1088
1122
  labelElement,
1089
- /* @__PURE__ */ jsx(
1123
+ /* @__PURE__ */ jsx2(
1090
1124
  "textarea",
1091
1125
  {
1092
1126
  id,
@@ -1106,7 +1140,7 @@ function DefaultTextArea({
1106
1140
  onChange: (event) => onChange(event.currentTarget.value)
1107
1141
  }
1108
1142
  ),
1109
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
1143
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx2("small", { id: ariaDescribedBy, children: helperText })
1110
1144
  ] });
1111
1145
  }
1112
1146
  function DefaultSelect({
@@ -1132,10 +1166,10 @@ function DefaultSelect({
1132
1166
  (option) => typeof option === "string" ? { value: option, label: option } : option
1133
1167
  );
1134
1168
  const selectedOption = normalizedOptions.find((option) => option.value === value);
1135
- const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx("span", { children: label }) : /* @__PURE__ */ jsx("label", { htmlFor: id, children: label });
1169
+ const labelElement = label === void 0 ? null : id === void 0 ? /* @__PURE__ */ jsx2("span", { children: label }) : /* @__PURE__ */ jsx2("label", { htmlFor: id, children: label });
1136
1170
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1137
1171
  labelElement,
1138
- /* @__PURE__ */ jsx(
1172
+ /* @__PURE__ */ jsx2(
1139
1173
  "select",
1140
1174
  {
1141
1175
  id,
@@ -1150,11 +1184,11 @@ function DefaultSelect({
1150
1184
  value,
1151
1185
  onChange: (event) => onChange(event.currentTarget.value),
1152
1186
  onKeyDown,
1153
- children: normalizedOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, disabled: option.disabled, children: renderOption === void 0 ? option.label : renderOption(option) }, option.value))
1187
+ children: normalizedOptions.map((option) => /* @__PURE__ */ jsx2("option", { value: option.value, disabled: option.disabled, children: renderOption === void 0 ? option.label : renderOption(option) }, option.value))
1154
1188
  }
1155
1189
  ),
1156
- renderValue === void 0 ? null : /* @__PURE__ */ jsx("output", { children: renderValue(selectedOption) }),
1157
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
1190
+ renderValue === void 0 ? null : /* @__PURE__ */ jsx2("output", { children: renderValue(selectedOption) }),
1191
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx2("small", { id: ariaDescribedBy, children: helperText })
1158
1192
  ] });
1159
1193
  }
1160
1194
  function DefaultCheckbox({
@@ -1175,7 +1209,7 @@ function DefaultCheckbox({
1175
1209
  }) {
1176
1210
  return /* @__PURE__ */ jsxs(Fragment, { children: [
1177
1211
  /* @__PURE__ */ jsxs("label", { className, children: [
1178
- /* @__PURE__ */ jsx(
1212
+ /* @__PURE__ */ jsx2(
1179
1213
  "input",
1180
1214
  {
1181
1215
  id,
@@ -1193,7 +1227,7 @@ function DefaultCheckbox({
1193
1227
  ),
1194
1228
  label
1195
1229
  ] }),
1196
- helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx("small", { id: ariaDescribedBy, children: helperText })
1230
+ helperText === void 0 || helperText.length === 0 ? null : /* @__PURE__ */ jsx2("small", { id: ariaDescribedBy, children: helperText })
1197
1231
  ] });
1198
1232
  }
1199
1233
  function DefaultSection({
@@ -1215,8 +1249,8 @@ function DefaultSection({
1215
1249
  "aria-labelledby": title === void 0 ? void 0 : headingId,
1216
1250
  onClickCapture,
1217
1251
  children: [
1218
- title === void 0 ? null : /* @__PURE__ */ jsx("h2", { id: headingId, children: title }),
1219
- description === void 0 ? null : /* @__PURE__ */ jsx("p", { children: description }),
1252
+ title === void 0 ? null : /* @__PURE__ */ jsx2("h2", { id: headingId, children: title }),
1253
+ description === void 0 ? null : /* @__PURE__ */ jsx2("p", { children: description }),
1220
1254
  children
1221
1255
  ]
1222
1256
  }
@@ -1224,12 +1258,12 @@ function DefaultSection({
1224
1258
  }
1225
1259
  function DefaultFieldset({ className, legend, disabled, children }) {
1226
1260
  return /* @__PURE__ */ jsxs("fieldset", { className, disabled, children: [
1227
- legend === void 0 ? null : /* @__PURE__ */ jsx("legend", { children: legend }),
1261
+ legend === void 0 ? null : /* @__PURE__ */ jsx2("legend", { children: legend }),
1228
1262
  children
1229
1263
  ] });
1230
1264
  }
1231
1265
  function DefaultErrorMessage({ className, message }) {
1232
- return /* @__PURE__ */ jsx("p", { className, children: message });
1266
+ return /* @__PURE__ */ jsx2("p", { className, children: message });
1233
1267
  }
1234
1268
  var DEFAULT_COMPONENTS = {
1235
1269
  Button: DefaultButton,
@@ -1244,7 +1278,7 @@ var DEFAULT_COMPONENTS = {
1244
1278
  renderIcon: defaultIconFor,
1245
1279
  renderFieldTypeIcon: defaultFieldTypeIcon
1246
1280
  };
1247
- var BuilderPrimitiveContext = createContext({
1281
+ var BuilderPrimitiveContext = createContext2({
1248
1282
  components: DEFAULT_COMPONENTS,
1249
1283
  readOnly: false,
1250
1284
  unstyled: false
@@ -1258,9 +1292,9 @@ function primitiveClassName(className, defaultClassName, unstyled) {
1258
1292
  return [unstyled ? void 0 : defaultClassName, userClassName].filter((value) => value !== void 0).join(" ") || void 0;
1259
1293
  }
1260
1294
  function BuilderButton(props) {
1261
- const context = useContext(BuilderPrimitiveContext);
1295
+ const context = useContext2(BuilderPrimitiveContext);
1262
1296
  const Component = context.components.Button;
1263
- return /* @__PURE__ */ jsx(
1297
+ return /* @__PURE__ */ jsx2(
1264
1298
  Component,
1265
1299
  {
1266
1300
  ...props,
@@ -1271,10 +1305,10 @@ function BuilderButton(props) {
1271
1305
  );
1272
1306
  }
1273
1307
  function BuilderIconButton(props) {
1274
- const context = useContext(BuilderPrimitiveContext);
1308
+ const context = useContext2(BuilderPrimitiveContext);
1275
1309
  const Component = context.components.IconButton;
1276
1310
  const icon = props.actionType === void 0 ? props.icon ?? void 0 : context.components.renderIcon(props.actionType) ?? props.icon ?? defaultIconFor(props.actionType);
1277
- return /* @__PURE__ */ jsx(
1311
+ return /* @__PURE__ */ jsx2(
1278
1312
  Component,
1279
1313
  {
1280
1314
  ...props,
@@ -1286,9 +1320,9 @@ function BuilderIconButton(props) {
1286
1320
  );
1287
1321
  }
1288
1322
  function BuilderTextInput(props) {
1289
- const context = useContext(BuilderPrimitiveContext);
1323
+ const context = useContext2(BuilderPrimitiveContext);
1290
1324
  const Component = context.components.TextInput;
1291
- return /* @__PURE__ */ jsx(
1325
+ return /* @__PURE__ */ jsx2(
1292
1326
  Component,
1293
1327
  {
1294
1328
  ...props,
@@ -1299,9 +1333,9 @@ function BuilderTextInput(props) {
1299
1333
  );
1300
1334
  }
1301
1335
  function BuilderTextArea(props) {
1302
- const context = useContext(BuilderPrimitiveContext);
1336
+ const context = useContext2(BuilderPrimitiveContext);
1303
1337
  const Component = context.components.TextArea;
1304
- return /* @__PURE__ */ jsx(
1338
+ return /* @__PURE__ */ jsx2(
1305
1339
  Component,
1306
1340
  {
1307
1341
  ...props,
@@ -1312,9 +1346,9 @@ function BuilderTextArea(props) {
1312
1346
  );
1313
1347
  }
1314
1348
  function BuilderSelect(props) {
1315
- const context = useContext(BuilderPrimitiveContext);
1349
+ const context = useContext2(BuilderPrimitiveContext);
1316
1350
  const Component = context.components.Select;
1317
- return /* @__PURE__ */ jsx(
1351
+ return /* @__PURE__ */ jsx2(
1318
1352
  Component,
1319
1353
  {
1320
1354
  ...props,
@@ -1325,9 +1359,9 @@ function BuilderSelect(props) {
1325
1359
  );
1326
1360
  }
1327
1361
  function BuilderCheckbox(props) {
1328
- const context = useContext(BuilderPrimitiveContext);
1362
+ const context = useContext2(BuilderPrimitiveContext);
1329
1363
  const Component = context.components.Checkbox;
1330
- return /* @__PURE__ */ jsx(
1364
+ return /* @__PURE__ */ jsx2(
1331
1365
  Component,
1332
1366
  {
1333
1367
  ...props,
@@ -1338,18 +1372,18 @@ function BuilderCheckbox(props) {
1338
1372
  );
1339
1373
  }
1340
1374
  function BuilderSection(props) {
1341
- const Component = useContext(BuilderPrimitiveContext).components.Section;
1342
- return /* @__PURE__ */ jsx(Component, { ...props });
1375
+ const Component = useContext2(BuilderPrimitiveContext).components.Section;
1376
+ return /* @__PURE__ */ jsx2(Component, { ...props });
1343
1377
  }
1344
1378
  function BuilderFieldset(props) {
1345
- const context = useContext(BuilderPrimitiveContext);
1379
+ const context = useContext2(BuilderPrimitiveContext);
1346
1380
  const Component = context.components.Fieldset;
1347
- return /* @__PURE__ */ jsx(Component, { ...props, disabled: context.readOnly || props.disabled === true });
1381
+ return /* @__PURE__ */ jsx2(Component, { ...props, disabled: context.readOnly || props.disabled === true });
1348
1382
  }
1349
1383
  function BuilderErrorMessage(props) {
1350
- const context = useContext(BuilderPrimitiveContext);
1384
+ const context = useContext2(BuilderPrimitiveContext);
1351
1385
  const Component = context.components.ErrorMessage;
1352
- return /* @__PURE__ */ jsx("div", { className: primitiveClassName(props.className, "form-engine-builder__error", context.unstyled), children: /* @__PURE__ */ jsx(Component, { message: props.message }) });
1386
+ return /* @__PURE__ */ jsx2("div", { className: primitiveClassName(props.className, "form-engine-builder__error", context.unstyled), children: /* @__PURE__ */ jsx2(Component, { message: props.message }) });
1353
1387
  }
1354
1388
  var GUARDED_COMPONENTS = {
1355
1389
  Button: BuilderButton,
@@ -1615,7 +1649,7 @@ function ConditionValueEditor({
1615
1649
  if (condition.operator === "not_empty") return null;
1616
1650
  const update = (value) => onChange({ ...condition, value });
1617
1651
  if (source.type === "checkbox") {
1618
- return /* @__PURE__ */ jsx(
1652
+ return /* @__PURE__ */ jsx2(
1619
1653
  Select,
1620
1654
  {
1621
1655
  value: String(condition.value),
@@ -1628,7 +1662,7 @@ function ConditionValueEditor({
1628
1662
  );
1629
1663
  }
1630
1664
  if (source.type === "number" || source.type === "rating") {
1631
- return /* @__PURE__ */ jsx(
1665
+ return /* @__PURE__ */ jsx2(
1632
1666
  TextInput,
1633
1667
  {
1634
1668
  "aria-label": translate("builder.conditionValue"),
@@ -1639,7 +1673,7 @@ function ConditionValueEditor({
1639
1673
  );
1640
1674
  }
1641
1675
  if ("options" in source) {
1642
- return /* @__PURE__ */ jsx(
1676
+ return /* @__PURE__ */ jsx2(
1643
1677
  Select,
1644
1678
  {
1645
1679
  value: String(condition.value ?? ""),
@@ -1648,7 +1682,7 @@ function ConditionValueEditor({
1648
1682
  }
1649
1683
  );
1650
1684
  }
1651
- return /* @__PURE__ */ jsx(
1685
+ return /* @__PURE__ */ jsx2(
1652
1686
  TextInput,
1653
1687
  {
1654
1688
  "aria-label": translate("builder.conditionValue"),
@@ -1668,7 +1702,7 @@ function resolveInitialFieldType(defaultType, allowedTypes) {
1668
1702
  function FormBuilder({
1669
1703
  schema,
1670
1704
  onChange,
1671
- locale = "en",
1705
+ locale: explicitLocale,
1672
1706
  translator,
1673
1707
  translationAdapter,
1674
1708
  translationOptions,
@@ -1695,6 +1729,12 @@ function FormBuilder({
1695
1729
  onActiveFieldChange,
1696
1730
  submissionSettingsOptions
1697
1731
  }) {
1732
+ const i18n = useFormEngineI18n();
1733
+ const isProviderValue = useContext2(FormEngineI18nProviderScopeContext);
1734
+ const locale = explicitLocale ?? (isProviderValue ? i18n.uiLocale : "en");
1735
+ const resolvedTranslator = translator ?? (isProviderValue ? {
1736
+ translate: (key, _locale, params) => params === void 0 ? i18n.translator(key) : i18n.translator(key, { ...params })
1737
+ } : void 0);
1698
1738
  const resolvedComponents = { ...DEFAULT_COMPONENTS, ...componentOverrides };
1699
1739
  const components = {
1700
1740
  ...GUARDED_COMPONENTS,
@@ -1731,7 +1771,7 @@ function FormBuilder({
1731
1771
  const translate = (key, params = {}) => resolveTranslation(
1732
1772
  key,
1733
1773
  BUILDER_TRANSLATION_ALIASES[key] === void 0 ? [] : [BUILDER_TRANSLATION_ALIASES[key]],
1734
- translator,
1774
+ resolvedTranslator,
1735
1775
  BUILDER_DEFAULTS,
1736
1776
  params,
1737
1777
  locale
@@ -2000,11 +2040,11 @@ function FormBuilder({
2000
2040
  params: { locale: targetLocale }
2001
2041
  })
2002
2042
  };
2003
- return /* @__PURE__ */ jsx(
2043
+ return /* @__PURE__ */ jsx2(
2004
2044
  BuilderPrimitiveContext.Provider,
2005
2045
  {
2006
2046
  value: { components: resolvedComponents, readOnly, unstyled: defaultStylesDisabled },
2007
- children: /* @__PURE__ */ jsx(
2047
+ children: /* @__PURE__ */ jsx2(
2008
2048
  Section,
2009
2049
  {
2010
2050
  className: defaultStylesDisabled ? className || void 0 : `form-engine-builder ${className}`.trim(),
@@ -2024,15 +2064,15 @@ function FormBuilder({
2024
2064
  addOption(fieldId);
2025
2065
  }
2026
2066
  },
2027
- children: /* @__PURE__ */ jsx(Fieldset, { className: builderClass("form-engine-builder__controls"), disabled: readOnly, children: /* @__PURE__ */ jsxs(OrderedBuilderSections, { ...resolvedSectionOrder === void 0 ? {} : { order: resolvedSectionOrder }, children: [
2028
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "basicSettings", children: /* @__PURE__ */ jsx(
2067
+ children: /* @__PURE__ */ jsx2(Fieldset, { className: builderClass("form-engine-builder__controls"), disabled: readOnly, children: /* @__PURE__ */ jsxs(OrderedBuilderSections, { ...resolvedSectionOrder === void 0 ? {} : { order: resolvedSectionOrder }, children: [
2068
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "basicSettings", children: /* @__PURE__ */ jsx2(
2029
2069
  Section,
2030
2070
  {
2031
2071
  className: builderClass("form-engine-builder__basic-settings"),
2032
2072
  headingId: "builder-basic-settings-heading",
2033
2073
  title: translate("builder.basicSettings"),
2034
2074
  children: /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2035
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2075
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2036
2076
  TextInput,
2037
2077
  {
2038
2078
  id: "builder-form-title",
@@ -2046,7 +2086,7 @@ function FormBuilder({
2046
2086
  onChange: (value) => setSourceText({ kind: "form" }, "title", value)
2047
2087
  }
2048
2088
  ) }),
2049
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2089
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2050
2090
  TextArea,
2051
2091
  {
2052
2092
  id: "builder-form-description",
@@ -2060,13 +2100,13 @@ function FormBuilder({
2060
2100
  ] })
2061
2101
  }
2062
2102
  ) }),
2063
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "submissionSettings", children: submissionSettingsOptions?.enabled ? /* @__PURE__ */ jsxs(
2103
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "submissionSettings", children: submissionSettingsOptions?.enabled ? /* @__PURE__ */ jsxs(
2064
2104
  Section,
2065
2105
  {
2066
2106
  className: builderClass("form-engine-builder__submission-settings"),
2067
2107
  title: translate("builder.submissionSettings"),
2068
2108
  children: [
2069
- /* @__PURE__ */ jsx(
2109
+ /* @__PURE__ */ jsx2(
2070
2110
  Checkbox,
2071
2111
  {
2072
2112
  id: "builder-show-confirmation",
@@ -2078,7 +2118,7 @@ function FormBuilder({
2078
2118
  })
2079
2119
  }
2080
2120
  ),
2081
- /* @__PURE__ */ jsx(
2121
+ /* @__PURE__ */ jsx2(
2082
2122
  Select,
2083
2123
  {
2084
2124
  id: "builder-confirmation-render-mode",
@@ -2101,7 +2141,7 @@ function FormBuilder({
2101
2141
  ]
2102
2142
  }
2103
2143
  ) : null }),
2104
- resolvedSectionOrder === void 0 ? null : /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "completionMessage", children: /* @__PURE__ */ jsx(Section, { headingId: "builder-completion-message-heading", title: translate("builder.completionMessage"), children: /* @__PURE__ */ jsx(
2144
+ resolvedSectionOrder === void 0 ? null : /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "completionMessage", children: /* @__PURE__ */ jsx2(Section, { headingId: "builder-completion-message-heading", title: translate("builder.completionMessage"), children: /* @__PURE__ */ jsx2(
2105
2145
  TextInput,
2106
2146
  {
2107
2147
  id: "builder-completion-message",
@@ -2110,13 +2150,13 @@ function FormBuilder({
2110
2150
  onChange: (value) => setSourceText({ kind: "form" }, "completionMessage", value)
2111
2151
  }
2112
2152
  ) }) }),
2113
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "questions", children: pagesEnabled ? PagesSlot === void 0 ? /* @__PURE__ */ jsx(
2153
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "questions", children: pagesEnabled ? PagesSlot === void 0 ? /* @__PURE__ */ jsx2(
2114
2154
  Section,
2115
2155
  {
2116
2156
  className: builderClass("form-engine-builder__pages"),
2117
2157
  headingId: "builder-pages-heading",
2118
2158
  title: translate("builder.pages"),
2119
- children: schema.pages === void 0 ? /* @__PURE__ */ jsx(Button, { onClick: enablePages, children: translate("builder.enablePages") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2159
+ children: schema.pages === void 0 ? /* @__PURE__ */ jsx2(Button, { onClick: enablePages, children: translate("builder.enablePages") }) : /* @__PURE__ */ jsxs(Fragment, { children: [
2120
2160
  schema.pages.map((page, pageIndex) => {
2121
2161
  const priorQuestionIds = new Set(
2122
2162
  schema.pages?.slice(0, pageIndex).flatMap((item) => item.questionIds)
@@ -2129,8 +2169,8 @@ function FormBuilder({
2129
2169
  className: builderClass("form-engine-builder__page"),
2130
2170
  legend: page.title ?? `${translate("builder.newPage")} ${pageIndex + 1}`,
2131
2171
  children: [
2132
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2133
- /* @__PURE__ */ jsx(
2172
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2173
+ /* @__PURE__ */ jsx2(
2134
2174
  IconButton,
2135
2175
  {
2136
2176
  actionType: "moveUp",
@@ -2139,7 +2179,7 @@ function FormBuilder({
2139
2179
  onClick: () => movePage(pageIndex, -1)
2140
2180
  }
2141
2181
  ),
2142
- /* @__PURE__ */ jsx(
2182
+ /* @__PURE__ */ jsx2(
2143
2183
  IconButton,
2144
2184
  {
2145
2185
  actionType: "moveDown",
@@ -2148,7 +2188,7 @@ function FormBuilder({
2148
2188
  onClick: () => movePage(pageIndex, 1)
2149
2189
  }
2150
2190
  ),
2151
- /* @__PURE__ */ jsx(
2191
+ /* @__PURE__ */ jsx2(
2152
2192
  IconButton,
2153
2193
  {
2154
2194
  actionType: "delete",
@@ -2156,7 +2196,7 @@ function FormBuilder({
2156
2196
  onClick: () => removePage(pageIndex)
2157
2197
  }
2158
2198
  )
2159
- ] }) : /* @__PURE__ */ jsx(
2199
+ ] }) : /* @__PURE__ */ jsx2(
2160
2200
  ToolbarSlot,
2161
2201
  {
2162
2202
  schema,
@@ -2175,7 +2215,7 @@ function FormBuilder({
2175
2215
  }
2176
2216
  ) }),
2177
2217
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2178
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2218
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2179
2219
  TextInput,
2180
2220
  {
2181
2221
  id: `builder-page-${page.id}-title`,
@@ -2190,7 +2230,7 @@ function FormBuilder({
2190
2230
  }
2191
2231
  }
2192
2232
  ) }),
2193
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2233
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2194
2234
  TextInput,
2195
2235
  {
2196
2236
  id: `builder-page-${page.id}-description`,
@@ -2207,9 +2247,9 @@ function FormBuilder({
2207
2247
  ) })
2208
2248
  ] }),
2209
2249
  !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__translation-editor"), children: [
2210
- /* @__PURE__ */ jsx("strong", { children: editingLocale }),
2250
+ /* @__PURE__ */ jsx2("strong", { children: editingLocale }),
2211
2251
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2212
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2252
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2213
2253
  TextInput,
2214
2254
  {
2215
2255
  id: `builder-page-${page.id}-${editingLocale}-title`,
@@ -2228,7 +2268,7 @@ function FormBuilder({
2228
2268
  })
2229
2269
  }
2230
2270
  ) }),
2231
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2271
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2232
2272
  TextInput,
2233
2273
  {
2234
2274
  id: `builder-page-${page.id}-${editingLocale}-description`,
@@ -2250,7 +2290,7 @@ function FormBuilder({
2250
2290
  ] })
2251
2291
  ] }),
2252
2292
  conditionsEnabled ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__condition"), children: [
2253
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2293
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2254
2294
  Select,
2255
2295
  {
2256
2296
  id: `builder-page-${page.id}-condition`,
@@ -2280,7 +2320,7 @@ function FormBuilder({
2280
2320
  }
2281
2321
  ) }),
2282
2322
  page.displayCondition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2283
- /* @__PURE__ */ jsx(
2323
+ /* @__PURE__ */ jsx2(
2284
2324
  Select,
2285
2325
  {
2286
2326
  "aria-label": translate("builder.conditionOperator"),
@@ -2302,7 +2342,7 @@ function FormBuilder({
2302
2342
  }))
2303
2343
  }
2304
2344
  ),
2305
- /* @__PURE__ */ jsx(
2345
+ /* @__PURE__ */ jsx2(
2306
2346
  ConditionValueEditor,
2307
2347
  {
2308
2348
  source,
@@ -2323,7 +2363,7 @@ function FormBuilder({
2323
2363
  );
2324
2364
  }),
2325
2365
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__page-add"), children: [
2326
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2366
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2327
2367
  Select,
2328
2368
  {
2329
2369
  id: "builder-page-question",
@@ -2337,11 +2377,11 @@ function FormBuilder({
2337
2377
  ]
2338
2378
  }
2339
2379
  ) }),
2340
- /* @__PURE__ */ jsx(Button, { disabled: movablePageQuestions.length === 0, onClick: addPage, children: translate("builder.addPage") })
2380
+ /* @__PURE__ */ jsx2(Button, { disabled: movablePageQuestions.length === 0, onClick: addPage, children: translate("builder.addPage") })
2341
2381
  ] })
2342
2382
  ] })
2343
2383
  }
2344
- ) : /* @__PURE__ */ jsx(
2384
+ ) : /* @__PURE__ */ jsx2(
2345
2385
  PagesSlot,
2346
2386
  {
2347
2387
  schema,
@@ -2353,14 +2393,14 @@ function FormBuilder({
2353
2393
  components
2354
2394
  }
2355
2395
  ) : null }),
2356
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "localization", children: localizationEnabled ? LocalizationSlot === void 0 ? /* @__PURE__ */ jsxs(
2396
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "localization", children: localizationEnabled ? LocalizationSlot === void 0 ? /* @__PURE__ */ jsxs(
2357
2397
  Section,
2358
2398
  {
2359
2399
  className: builderClass("form-engine-builder__localization"),
2360
2400
  headingId: "builder-localization-heading",
2361
2401
  title: translate("builder.localization"),
2362
2402
  children: [
2363
- resolvedSectionOrder === void 0 ? /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2403
+ resolvedSectionOrder === void 0 ? /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2364
2404
  TextInput,
2365
2405
  {
2366
2406
  id: "builder-completion-message",
@@ -2370,7 +2410,7 @@ function FormBuilder({
2370
2410
  }
2371
2411
  ) }) : null,
2372
2412
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2373
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2413
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2374
2414
  TextInput,
2375
2415
  {
2376
2416
  id: "builder-default-locale",
@@ -2379,7 +2419,7 @@ function FormBuilder({
2379
2419
  onChange: setDefaultLocale
2380
2420
  }
2381
2421
  ) }),
2382
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx(
2422
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: availableAllowedLocales === void 0 ? /* @__PURE__ */ jsx2(
2383
2423
  TextInput,
2384
2424
  {
2385
2425
  id: "builder-new-locale",
@@ -2387,7 +2427,7 @@ function FormBuilder({
2387
2427
  value: newLocale,
2388
2428
  onChange: setNewLocale
2389
2429
  }
2390
- ) : /* @__PURE__ */ jsx(
2430
+ ) : /* @__PURE__ */ jsx2(
2391
2431
  Select,
2392
2432
  {
2393
2433
  id: "builder-new-locale",
@@ -2400,7 +2440,7 @@ function FormBuilder({
2400
2440
  ]
2401
2441
  }
2402
2442
  ) }),
2403
- /* @__PURE__ */ jsx(
2443
+ /* @__PURE__ */ jsx2(
2404
2444
  Button,
2405
2445
  {
2406
2446
  action: "addLocale",
@@ -2409,7 +2449,7 @@ function FormBuilder({
2409
2449
  children: translate("builder.addLocale")
2410
2450
  }
2411
2451
  ),
2412
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2452
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2413
2453
  Select,
2414
2454
  {
2415
2455
  id: "builder-edit-locale",
@@ -2422,14 +2462,14 @@ function FormBuilder({
2422
2462
  ]
2423
2463
  }
2424
2464
  ) }),
2425
- TranslationActionsSlot === void 0 ? /* @__PURE__ */ jsx(
2465
+ TranslationActionsSlot === void 0 ? /* @__PURE__ */ jsx2(
2426
2466
  Button,
2427
2467
  {
2428
2468
  disabled: translationAdapter === void 0 || editingLocale.length === 0 || isTranslating,
2429
2469
  onClick: () => void translateAll(),
2430
2470
  children: translate("builder.autoTranslate")
2431
2471
  }
2432
- ) : /* @__PURE__ */ jsx(
2472
+ ) : /* @__PURE__ */ jsx2(
2433
2473
  TranslationActionsSlot,
2434
2474
  {
2435
2475
  schema,
@@ -2447,10 +2487,10 @@ function FormBuilder({
2447
2487
  }
2448
2488
  )
2449
2489
  ] }),
2450
- translationAdapter === void 0 ? /* @__PURE__ */ jsx("p", { children: translate("builder.translationUnavailable") }) : null,
2451
- translationError === null ? null : /* @__PURE__ */ jsx(ErrorMessage, { message: translationError }),
2490
+ translationAdapter === void 0 ? /* @__PURE__ */ jsx2("p", { children: translate("builder.translationUnavailable") }) : null,
2491
+ translationError === null ? null : /* @__PURE__ */ jsx2(ErrorMessage, { message: translationError }),
2452
2492
  editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2453
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2493
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2454
2494
  TextInput,
2455
2495
  {
2456
2496
  id: `builder-${editingLocale}-form-title`,
@@ -2459,7 +2499,7 @@ function FormBuilder({
2459
2499
  onChange: (value) => updateFormTranslation("title", value)
2460
2500
  }
2461
2501
  ) }),
2462
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2502
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2463
2503
  TextInput,
2464
2504
  {
2465
2505
  id: `builder-${editingLocale}-form-description`,
@@ -2468,7 +2508,7 @@ function FormBuilder({
2468
2508
  onChange: (value) => updateFormTranslation("description", value)
2469
2509
  }
2470
2510
  ) }),
2471
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2511
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2472
2512
  TextInput,
2473
2513
  {
2474
2514
  id: `builder-${editingLocale}-completion-message`,
@@ -2480,7 +2520,7 @@ function FormBuilder({
2480
2520
  ] })
2481
2521
  ]
2482
2522
  }
2483
- ) : /* @__PURE__ */ jsx(
2523
+ ) : /* @__PURE__ */ jsx2(
2484
2524
  LocalizationSlot,
2485
2525
  {
2486
2526
  schema,
@@ -2497,7 +2537,7 @@ function FormBuilder({
2497
2537
  components
2498
2538
  }
2499
2539
  ) : null }),
2500
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "questions", children: /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__list"), children: schema.fields.map((field, index) => {
2540
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "questions", children: /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__list"), children: schema.fields.map((field, index) => {
2501
2541
  const controls = resolveFieldEditorControls(fieldEditorControls);
2502
2542
  const editorState = headless.getFieldEditorProps?.(field.id) ?? {
2503
2543
  isActive: true,
@@ -2508,18 +2548,18 @@ function FormBuilder({
2508
2548
  const source = condition === void 0 ? void 0 : schema.fields.find((item) => item.id === condition.questionId);
2509
2549
  const availableSources = schema.fields.slice(0, index);
2510
2550
  if (!editorState.isVisible) {
2511
- return /* @__PURE__ */ jsx(
2551
+ return /* @__PURE__ */ jsx2(
2512
2552
  "div",
2513
2553
  {
2514
2554
  className: builderClass("form-engine-builder__question-preview"),
2515
2555
  "data-field-id": field.id,
2516
- children: /* @__PURE__ */ jsx("button", { type: "button", onClick: editorState.onSelect, children: field.title })
2556
+ children: /* @__PURE__ */ jsx2("button", { type: "button", onClick: editorState.onSelect, children: field.title })
2517
2557
  },
2518
2558
  field.id
2519
2559
  );
2520
2560
  }
2521
2561
  if (FieldEditorSlot !== void 0) {
2522
- return /* @__PURE__ */ jsx(
2562
+ return /* @__PURE__ */ jsx2(
2523
2563
  FieldEditorSlot,
2524
2564
  {
2525
2565
  schema,
@@ -2545,8 +2585,8 @@ function FormBuilder({
2545
2585
  className: builderClass("form-engine-builder__question"),
2546
2586
  legend: field.title,
2547
2587
  children: [
2548
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2549
- /* @__PURE__ */ jsx(
2588
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__toolbar"), children: ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2589
+ /* @__PURE__ */ jsx2(
2550
2590
  IconButton,
2551
2591
  {
2552
2592
  actionType: "moveUp",
@@ -2555,7 +2595,7 @@ function FormBuilder({
2555
2595
  onClick: () => moveField(index, -1)
2556
2596
  }
2557
2597
  ),
2558
- /* @__PURE__ */ jsx(
2598
+ /* @__PURE__ */ jsx2(
2559
2599
  IconButton,
2560
2600
  {
2561
2601
  actionType: "moveDown",
@@ -2564,7 +2604,7 @@ function FormBuilder({
2564
2604
  onClick: () => moveField(index, 1)
2565
2605
  }
2566
2606
  ),
2567
- /* @__PURE__ */ jsx(
2607
+ /* @__PURE__ */ jsx2(
2568
2608
  IconButton,
2569
2609
  {
2570
2610
  actionType: "delete",
@@ -2574,7 +2614,7 @@ function FormBuilder({
2574
2614
  title: translate("builder.delete", { title: field.title })
2575
2615
  }
2576
2616
  )
2577
- ] }) : /* @__PURE__ */ jsx(
2617
+ ] }) : /* @__PURE__ */ jsx2(
2578
2618
  ToolbarSlot,
2579
2619
  {
2580
2620
  schema,
@@ -2593,7 +2633,7 @@ function FormBuilder({
2593
2633
  }
2594
2634
  ) }),
2595
2635
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2596
- controls.title === "hidden" ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2636
+ controls.title === "hidden" ? null : /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2597
2637
  TextInput,
2598
2638
  {
2599
2639
  id: `builder-field-${field.id}-title`,
@@ -2612,7 +2652,7 @@ function FormBuilder({
2612
2652
  }))
2613
2653
  }
2614
2654
  ) }),
2615
- controls.typeSelect === "hidden" ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2655
+ controls.typeSelect === "hidden" ? null : /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2616
2656
  Select,
2617
2657
  {
2618
2658
  id: `builder-field-${field.id}-type`,
@@ -2629,7 +2669,7 @@ function FormBuilder({
2629
2669
  )
2630
2670
  }
2631
2671
  ) }),
2632
- controls.required === "hidden" ? null : /* @__PURE__ */ jsx(
2672
+ controls.required === "hidden" ? null : /* @__PURE__ */ jsx2(
2633
2673
  Checkbox,
2634
2674
  {
2635
2675
  className: builderClass("form-engine-builder__check"),
@@ -2640,7 +2680,7 @@ function FormBuilder({
2640
2680
  }
2641
2681
  )
2642
2682
  ] }),
2643
- controls.description === "hidden" ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2683
+ controls.description === "hidden" ? null : /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2644
2684
  TextArea,
2645
2685
  {
2646
2686
  id: `builder-field-${field.id}-description`,
@@ -2655,7 +2695,7 @@ function FormBuilder({
2655
2695
  })
2656
2696
  }
2657
2697
  ) }),
2658
- !pagesEnabled || schema.pages === void 0 ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2698
+ !pagesEnabled || schema.pages === void 0 ? null : /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2659
2699
  Select,
2660
2700
  {
2661
2701
  id: `builder-field-${field.id}-page`,
@@ -2669,9 +2709,9 @@ function FormBuilder({
2669
2709
  }
2670
2710
  ) }),
2671
2711
  !localizationEnabled || editingLocale.length === 0 ? null : /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__translation-editor"), children: [
2672
- /* @__PURE__ */ jsx("strong", { children: editingLocale }),
2712
+ /* @__PURE__ */ jsx2("strong", { children: editingLocale }),
2673
2713
  /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2674
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2714
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2675
2715
  TextInput,
2676
2716
  {
2677
2717
  id: `builder-field-${field.id}-${editingLocale}-title`,
@@ -2690,7 +2730,7 @@ function FormBuilder({
2690
2730
  })
2691
2731
  }
2692
2732
  ) }),
2693
- controls.description === "hidden" ? null : /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2733
+ controls.description === "hidden" ? null : /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2694
2734
  TextInput,
2695
2735
  {
2696
2736
  id: `builder-field-${field.id}-${editingLocale}-description`,
@@ -2711,7 +2751,7 @@ function FormBuilder({
2711
2751
  }
2712
2752
  ) })
2713
2753
  ] }),
2714
- "options" in field ? field.options.map((option, optionIndex) => /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2754
+ "options" in field ? field.options.map((option, optionIndex) => /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2715
2755
  TextInput,
2716
2756
  {
2717
2757
  id: `builder-option-${option.id}-${editingLocale}`,
@@ -2732,7 +2772,7 @@ function FormBuilder({
2732
2772
  ) }, option.id)) : null
2733
2773
  ] }),
2734
2774
  field.type === "rating" && controls.ratingBounds !== "hidden" ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2735
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2775
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2736
2776
  TextInput,
2737
2777
  {
2738
2778
  id: `builder-field-${field.id}-minimum`,
@@ -2750,7 +2790,7 @@ function FormBuilder({
2750
2790
  }
2751
2791
  }
2752
2792
  ) }),
2753
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2793
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2754
2794
  TextInput,
2755
2795
  {
2756
2796
  id: `builder-field-${field.id}-maximum`,
@@ -2770,7 +2810,7 @@ function FormBuilder({
2770
2810
  ) })
2771
2811
  ] }) : null,
2772
2812
  (field.type === "text" || field.type === "textarea") && controls.textLimits !== "hidden" ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__grid"), children: [
2773
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2813
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2774
2814
  TextInput,
2775
2815
  {
2776
2816
  id: `builder-field-${field.id}-min-length`,
@@ -2785,7 +2825,7 @@ function FormBuilder({
2785
2825
  })
2786
2826
  }
2787
2827
  ) }),
2788
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2828
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2789
2829
  TextInput,
2790
2830
  {
2791
2831
  id: `builder-field-${field.id}-max-length`,
@@ -2800,7 +2840,7 @@ function FormBuilder({
2800
2840
  })
2801
2841
  }
2802
2842
  ) }),
2803
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2843
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2804
2844
  TextInput,
2805
2845
  {
2806
2846
  id: `builder-field-${field.id}-pattern`,
@@ -2814,7 +2854,7 @@ function FormBuilder({
2814
2854
  }
2815
2855
  ) })
2816
2856
  ] }) : null,
2817
- field.type === "number" && controls.numberLimits !== "hidden" ? /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__grid"), children: ["min", "max", "step"].map((property) => /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2857
+ field.type === "number" && controls.numberLimits !== "hidden" ? /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__grid"), children: ["min", "max", "step"].map((property) => /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2818
2858
  TextInput,
2819
2859
  {
2820
2860
  id: `builder-field-${field.id}-${property}`,
@@ -2836,10 +2876,10 @@ function FormBuilder({
2836
2876
  }
2837
2877
  ) }, property)) }) : null,
2838
2878
  "options" in field && controls.options !== "hidden" ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__options"), children: [
2839
- /* @__PURE__ */ jsx("strong", { children: translate("builder.options") }),
2879
+ /* @__PURE__ */ jsx2("strong", { children: translate("builder.options") }),
2840
2880
  field.options.map(
2841
2881
  (option, optionIndex) => OptionEditorSlot === void 0 ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__option"), children: [
2842
- /* @__PURE__ */ jsx(
2882
+ /* @__PURE__ */ jsx2(
2843
2883
  TextInput,
2844
2884
  {
2845
2885
  id: `builder-option-${option.id}`,
@@ -2851,7 +2891,7 @@ function FormBuilder({
2851
2891
  }
2852
2892
  ),
2853
2893
  ToolbarSlot === void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2854
- /* @__PURE__ */ jsx(
2894
+ /* @__PURE__ */ jsx2(
2855
2895
  IconButton,
2856
2896
  {
2857
2897
  actionType: "moveUp",
@@ -2860,7 +2900,7 @@ function FormBuilder({
2860
2900
  onClick: () => moveOption(field.id, option.id, optionIndex - 1)
2861
2901
  }
2862
2902
  ),
2863
- /* @__PURE__ */ jsx(
2903
+ /* @__PURE__ */ jsx2(
2864
2904
  IconButton,
2865
2905
  {
2866
2906
  actionType: "moveDown",
@@ -2869,7 +2909,7 @@ function FormBuilder({
2869
2909
  onClick: () => moveOption(field.id, option.id, optionIndex + 1)
2870
2910
  }
2871
2911
  ),
2872
- /* @__PURE__ */ jsx(
2912
+ /* @__PURE__ */ jsx2(
2873
2913
  IconButton,
2874
2914
  {
2875
2915
  actionType: "delete",
@@ -2878,7 +2918,7 @@ function FormBuilder({
2878
2918
  title: translate("builder.remove")
2879
2919
  }
2880
2920
  )
2881
- ] }) : /* @__PURE__ */ jsx(
2921
+ ] }) : /* @__PURE__ */ jsx2(
2882
2922
  ToolbarSlot,
2883
2923
  {
2884
2924
  schema,
@@ -2896,7 +2936,7 @@ function FormBuilder({
2896
2936
  components
2897
2937
  }
2898
2938
  )
2899
- ] }, option.id) : /* @__PURE__ */ jsx(
2939
+ ] }, option.id) : /* @__PURE__ */ jsx2(
2900
2940
  OptionEditorSlot,
2901
2941
  {
2902
2942
  schema,
@@ -2912,7 +2952,7 @@ function FormBuilder({
2912
2952
  option.id
2913
2953
  )
2914
2954
  ),
2915
- /* @__PURE__ */ jsx(
2955
+ /* @__PURE__ */ jsx2(
2916
2956
  Button,
2917
2957
  {
2918
2958
  action: "addOption",
@@ -2924,7 +2964,7 @@ function FormBuilder({
2924
2964
  )
2925
2965
  ] }) : null,
2926
2966
  conditionsEnabled && controls.displayConditions !== "hidden" ? /* @__PURE__ */ jsxs("div", { className: builderClass("form-engine-builder__condition"), children: [
2927
- /* @__PURE__ */ jsx("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx(
2967
+ /* @__PURE__ */ jsx2("div", { className: builderClass("form-engine-builder__field"), children: /* @__PURE__ */ jsx2(
2928
2968
  Select,
2929
2969
  {
2930
2970
  id: `builder-field-${field.id}-condition`,
@@ -2951,7 +2991,7 @@ function FormBuilder({
2951
2991
  }
2952
2992
  ) }),
2953
2993
  condition !== void 0 && source !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
2954
- /* @__PURE__ */ jsx(
2994
+ /* @__PURE__ */ jsx2(
2955
2995
  Select,
2956
2996
  {
2957
2997
  "aria-label": translate("builder.conditionOperator"),
@@ -2969,7 +3009,7 @@ function FormBuilder({
2969
3009
  }))
2970
3010
  }
2971
3011
  ),
2972
- /* @__PURE__ */ jsx(
3012
+ /* @__PURE__ */ jsx2(
2973
3013
  ConditionValueEditor,
2974
3014
  {
2975
3015
  source,
@@ -2986,7 +3026,7 @@ function FormBuilder({
2986
3026
  field.id
2987
3027
  );
2988
3028
  }) }) }),
2989
- /* @__PURE__ */ jsx(BuilderSectionGroup, { name: "addQuestion", children: /* @__PURE__ */ jsx(
3029
+ /* @__PURE__ */ jsx2(BuilderSectionGroup, { name: "addQuestion", children: /* @__PURE__ */ jsx2(
2990
3030
  Button,
2991
3031
  {
2992
3032
  className: builderClass("form-engine-builder__add"),
@@ -3013,7 +3053,7 @@ import {
3013
3053
  validateAnswers,
3014
3054
  validatePageAnswers
3015
3055
  } from "@form-engine-ts/core";
3016
- import { createContext as createContext2, useCallback as useCallback2, useContext as useContext2, useEffect, useMemo as useMemo2, useRef, useState as useState3 } from "react";
3056
+ import { createContext as createContext3, useCallback as useCallback2, useContext as useContext3, useEffect, useMemo as useMemo3, useRef, useState as useState3 } from "react";
3017
3057
 
3018
3058
  // src/types.ts
3019
3059
  var FormSubmissionError = class extends Error {
@@ -3026,8 +3066,8 @@ var FormSubmissionError = class extends Error {
3026
3066
  };
3027
3067
 
3028
3068
  // src/context.tsx
3029
- import { jsx as jsx2 } from "react/jsx-runtime";
3030
- var FormContext = createContext2(null);
3069
+ import { jsx as jsx3 } from "react/jsx-runtime";
3070
+ var FormContext = createContext3(null);
3031
3071
  function issuesByField(issues) {
3032
3072
  const result = {};
3033
3073
  for (const issue of issues) result[issue.fieldId] ??= issue;
@@ -3054,7 +3094,7 @@ function FormProvider({
3054
3094
  onSubmit,
3055
3095
  children
3056
3096
  }) {
3057
- const validSchema = useMemo2(() => {
3097
+ const validSchema = useMemo3(() => {
3058
3098
  assertValidFormSchema(schema);
3059
3099
  const localized = resolveLocalizedSchema(schema, locale);
3060
3100
  assertValidFormSchema(localized);
@@ -3066,8 +3106,8 @@ function FormProvider({
3066
3106
  const [submitError, setSubmitError] = useState3(null);
3067
3107
  const [validationPageIndex, setValidationPageIndex] = useState3(null);
3068
3108
  const submissionInFlight = useRef(false);
3069
- const visibility = useMemo2(() => calculateFieldVisibility(validSchema, values), [validSchema, values]);
3070
- const pageVisibility = useMemo2(() => calculatePageVisibility(validSchema, values), [validSchema, values]);
3109
+ const visibility = useMemo3(() => calculateFieldVisibility(validSchema, values), [validSchema, values]);
3110
+ const pageVisibility = useMemo3(() => calculatePageVisibility(validSchema, values), [validSchema, values]);
3071
3111
  useEffect(() => {
3072
3112
  const fieldIds = new Set(validSchema.fields.map((field) => field.id));
3073
3113
  setValues((current) => Object.fromEntries(Object.entries(current).filter(([fieldId]) => fieldIds.has(fieldId))));
@@ -3179,7 +3219,7 @@ function FormProvider({
3179
3219
  (key, params) => translator.translate(key, locale, params) ?? key,
3180
3220
  [locale, translator]
3181
3221
  );
3182
- const contextValue = useMemo2(
3222
+ const contextValue = useMemo3(
3183
3223
  () => ({
3184
3224
  schema: validSchema,
3185
3225
  locale,
@@ -3218,10 +3258,10 @@ function FormProvider({
3218
3258
  visibility
3219
3259
  ]
3220
3260
  );
3221
- return /* @__PURE__ */ jsx2(FormContext.Provider, { value: contextValue, children });
3261
+ return /* @__PURE__ */ jsx3(FormContext.Provider, { value: contextValue, children });
3222
3262
  }
3223
3263
  function useForm() {
3224
- const context = useContext2(FormContext);
3264
+ const context = useContext3(FormContext);
3225
3265
  if (context === null) throw new Error("useForm must be called inside a FormProvider.");
3226
3266
  return context;
3227
3267
  }
@@ -3242,7 +3282,7 @@ import {
3242
3282
  populateSchemaTranslations as populateSchemaTranslations2,
3243
3283
  removeLocaleFromSchema
3244
3284
  } from "@form-engine-ts/core";
3245
- import { useCallback as useCallback3, useMemo as useMemo3, useState as useState4 } from "react";
3285
+ import { useCallback as useCallback3, useMemo as useMemo4, useState as useState4 } from "react";
3246
3286
  function updateTranslationMap(translations, locale, property, text) {
3247
3287
  if (property === "label") return translations ?? {};
3248
3288
  const current = translations?.[locale];
@@ -3326,15 +3366,21 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
3326
3366
  }
3327
3367
  return { valid: true };
3328
3368
  };
3329
- function workspaceLocaleValidationMessage(validation) {
3330
- if (validation.error?.type === "locale_not_allowed") {
3331
- return validation.error.message.replace(" is not allowed by policy.", " is not allowed by the form policy.");
3369
+ function workspaceLocaleValidationError(validation, currentLocales, requestedLocale) {
3370
+ const error = validation.error;
3371
+ if (error === void 0) return { type: "invalid_locale_format", locale: requestedLocale };
3372
+ if (error.type === "locale_not_allowed") return { type: "locale_not_allowed", locale: requestedLocale };
3373
+ if (error.type === "locale_already_exists") {
3374
+ return { type: "locale_already_exists", locale: requestedLocale };
3332
3375
  }
3333
- if (validation.error?.type === "max_locales_exceeded") {
3334
- const maximum = validation.error.message.match(/\((\d+)\)/u)?.[1];
3335
- return maximum === void 0 ? validation.error.message : `At most ${maximum} locales are allowed by the form policy.`;
3376
+ if (error.type === "invalid_locale_format") {
3377
+ return { type: "invalid_locale_format", locale: requestedLocale };
3336
3378
  }
3337
- return validation.error?.message ?? "Locale is not valid.";
3379
+ if (error.type === "max_locales_exceeded") {
3380
+ const max = Number(error.message.match(/\((\d+)\)/u)?.[1] ?? 0);
3381
+ return { type: "max_locales_exceeded", max, current: currentLocales };
3382
+ }
3383
+ return { type: "custom_validation_failed", message: error.message };
3338
3384
  }
3339
3385
  function manualMetadata(sourceText, sourceLocale) {
3340
3386
  return {
@@ -3405,6 +3451,7 @@ function useTranslationWorkspace({
3405
3451
  translationAdapter,
3406
3452
  readOnly = false,
3407
3453
  policy,
3454
+ beforeRemoveLocale,
3408
3455
  validateLocale
3409
3456
  }) {
3410
3457
  const [draftSchema, setDraftSchema] = useState4(schema);
@@ -3412,18 +3459,18 @@ function useTranslationWorkspace({
3412
3459
  const [isTranslating, setIsTranslating] = useState4(false);
3413
3460
  const [error, setError] = useState4();
3414
3461
  const currentSchema = onChange === void 0 ? draftSchema : schema;
3415
- const targetLocales = useMemo3(() => {
3462
+ const targetLocales = useMemo4(() => {
3416
3463
  const locales = collectSchemaLocales2(currentSchema).allUniqueLocales;
3417
3464
  return [.../* @__PURE__ */ new Set([...currentSchema.supportedLocales ?? [], ...locales])].filter(
3418
3465
  (locale) => locale !== sourceLocale
3419
3466
  );
3420
3467
  }, [currentSchema, sourceLocale]);
3421
3468
  const activeLocale = selectedLocale.length > 0 ? selectedLocale : targetLocales[0] ?? "";
3422
- const slots = useMemo3(
3469
+ const slots = useMemo4(
3423
3470
  () => activeLocale.length === 0 ? [] : collectTranslationSlots(currentSchema, activeLocale),
3424
3471
  [activeLocale, currentSchema]
3425
3472
  );
3426
- const summary = useMemo3(() => {
3473
+ const summary = useMemo4(() => {
3427
3474
  const counts = {
3428
3475
  missing: 0,
3429
3476
  translated: 0,
@@ -3458,16 +3505,32 @@ function useTranslationWorkspace({
3458
3505
  );
3459
3506
  const addLocale = useCallback3(
3460
3507
  (locale) => {
3461
- if (readOnly) return { success: false, error: "Workspace is read-only." };
3508
+ if (readOnly) {
3509
+ const workspaceError = { type: "read_only_mode" };
3510
+ setError(workspaceError);
3511
+ return { success: false, error: workspaceError };
3512
+ }
3462
3513
  const normalized = normalizeLocale(locale);
3463
3514
  if (normalized === null) {
3464
- return {
3465
- success: false,
3466
- error: workspaceLocaleValidationMessage(validateLocalePipeline(locale, currentSchema, policy, validateLocale))
3467
- };
3515
+ const workspaceError = workspaceLocaleValidationError(
3516
+ validateLocalePipeline(locale, currentSchema, policy, validateLocale),
3517
+ collectSchemaLocales2(currentSchema).allUniqueLocales.size,
3518
+ locale
3519
+ );
3520
+ setError(workspaceError);
3521
+ return { success: false, error: workspaceError };
3468
3522
  }
3469
3523
  const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale);
3470
- if (!validation.valid) return { success: false, error: workspaceLocaleValidationMessage(validation) };
3524
+ if (!validation.valid) {
3525
+ const workspaceError = workspaceLocaleValidationError(
3526
+ validation,
3527
+ collectSchemaLocales2(currentSchema).allUniqueLocales.size,
3528
+ normalized
3529
+ );
3530
+ setError(workspaceError);
3531
+ return { success: false, error: workspaceError };
3532
+ }
3533
+ setError(void 0);
3471
3534
  commit({
3472
3535
  ...currentSchema,
3473
3536
  supportedLocales: [.../* @__PURE__ */ new Set([...currentSchema.supportedLocales ?? [], normalized])]
@@ -3488,16 +3551,57 @@ function useTranslationWorkspace({
3488
3551
  );
3489
3552
  const removeLocale = useCallback3(
3490
3553
  (locale) => {
3491
- if (readOnly || locale === sourceLocale || locale === currentSchema.defaultLocale) return;
3492
- commit(removeLocaleFromSchema(currentSchema, locale));
3493
- if (activeLocale === locale) setSelectedLocale("");
3554
+ if (readOnly || locale === sourceLocale || locale === currentSchema.defaultLocale) return false;
3555
+ const remove = () => {
3556
+ commit(removeLocaleFromSchema(currentSchema, locale));
3557
+ if (activeLocale === locale) setSelectedLocale("");
3558
+ };
3559
+ const slotCount = collectTranslationSlots(currentSchema, locale).length;
3560
+ if (beforeRemoveLocale === void 0) {
3561
+ remove();
3562
+ return true;
3563
+ }
3564
+ try {
3565
+ const decision = beforeRemoveLocale(locale, { slotCount });
3566
+ if (typeof decision === "boolean") {
3567
+ if (!decision) return false;
3568
+ remove();
3569
+ return true;
3570
+ }
3571
+ return decision.then((allowed) => {
3572
+ if (!allowed) return false;
3573
+ remove();
3574
+ return true;
3575
+ });
3576
+ } catch (cause) {
3577
+ const workspaceError = {
3578
+ type: "translation_failed",
3579
+ message: cause instanceof Error ? cause.message : String(cause),
3580
+ cause
3581
+ };
3582
+ setError(workspaceError);
3583
+ return Promise.reject(cause);
3584
+ }
3494
3585
  },
3495
- [activeLocale, commit, currentSchema, readOnly, sourceLocale]
3586
+ [activeLocale, beforeRemoveLocale, commit, currentSchema, readOnly, sourceLocale]
3496
3587
  );
3497
3588
  const translateAll = useCallback3(
3498
3589
  async (options = {}) => {
3499
- if (translationAdapter === void 0) throw new Error("A translation adapter is required.");
3500
- if (activeLocale.length === 0) throw new Error("A target locale is required.");
3590
+ if (readOnly) {
3591
+ const workspaceError = { type: "read_only_mode" };
3592
+ setError(workspaceError);
3593
+ return { success: false, error: workspaceError };
3594
+ }
3595
+ if (translationAdapter === void 0) {
3596
+ const workspaceError = { type: "adapter_not_configured" };
3597
+ setError(workspaceError);
3598
+ return { success: false, error: workspaceError };
3599
+ }
3600
+ if (activeLocale.length === 0) {
3601
+ const workspaceError = { type: "target_locale_missing" };
3602
+ setError(workspaceError);
3603
+ return { success: false, error: workspaceError };
3604
+ }
3501
3605
  setIsTranslating(true);
3502
3606
  setError(void 0);
3503
3607
  try {
@@ -3512,30 +3616,47 @@ function useTranslationWorkspace({
3512
3616
  }
3513
3617
  );
3514
3618
  commit(populated.schema);
3515
- return populated.report;
3619
+ return { success: true, report: populated.report };
3516
3620
  } catch (cause) {
3517
- const message = cause instanceof Error ? cause.message : String(cause);
3518
- setError(message);
3519
- throw cause;
3621
+ const workspaceError = {
3622
+ type: "translation_failed",
3623
+ message: cause instanceof Error ? cause.message : String(cause),
3624
+ cause
3625
+ };
3626
+ setError(workspaceError);
3627
+ return { success: false, error: workspaceError };
3520
3628
  } finally {
3521
3629
  setIsTranslating(false);
3522
3630
  }
3523
3631
  },
3524
- [activeLocale, commit, currentSchema, translationAdapter]
3632
+ [activeLocale, commit, currentSchema, readOnly, translationAdapter]
3525
3633
  );
3526
3634
  const translateSlot = useCallback3(
3527
3635
  async (slot) => {
3528
- if (translationAdapter === void 0) throw new Error("A translation adapter is required.");
3529
- if (readOnly) return;
3636
+ if (translationAdapter === void 0) {
3637
+ const workspaceError = { type: "adapter_not_configured" };
3638
+ setError(workspaceError);
3639
+ return { success: false, error: workspaceError };
3640
+ }
3641
+ if (readOnly) {
3642
+ const workspaceError = { type: "read_only_mode" };
3643
+ setError(workspaceError);
3644
+ return { success: false, error: workspaceError };
3645
+ }
3530
3646
  setIsTranslating(true);
3531
3647
  setError(void 0);
3532
3648
  try {
3533
3649
  const text = await asAsyncAdapter(translationAdapter).translateText(slot.sourceText, slot.locale, sourceLocale);
3534
3650
  commit(updateSchemaTranslation(currentSchema, slot, text, sourceLocale));
3651
+ return { success: true };
3535
3652
  } catch (cause) {
3536
- const message = cause instanceof Error ? cause.message : String(cause);
3537
- setError(message);
3538
- throw cause;
3653
+ const workspaceError = {
3654
+ type: "translation_failed",
3655
+ message: cause instanceof Error ? cause.message : String(cause),
3656
+ cause
3657
+ };
3658
+ setError(workspaceError);
3659
+ return { success: false, error: workspaceError };
3539
3660
  } finally {
3540
3661
  setIsTranslating(false);
3541
3662
  }
@@ -3561,7 +3682,7 @@ function useTranslationWorkspace({
3561
3682
  }
3562
3683
 
3563
3684
  // src/receipt.ts
3564
- import { useEffect as useEffect2, useMemo as useMemo4, useState as useState5 } from "react";
3685
+ import { useEffect as useEffect2, useMemo as useMemo5, useState as useState5 } from "react";
3565
3686
  function submissionReceiptQueryKey(formId, formVersion) {
3566
3687
  return `${formId}:v${formVersion}`;
3567
3688
  }
@@ -3632,7 +3753,7 @@ function createLocalStorageSubmissionReceiptStore(options = {}) {
3632
3753
  }
3633
3754
  function useSubmissionReceipts(store, queries) {
3634
3755
  const querySignature = JSON.stringify(queries.map(({ formId, formVersion }) => [formId, formVersion]));
3635
- const stableQueries = useMemo4(() => {
3756
+ const stableQueries = useMemo5(() => {
3636
3757
  const parsed = JSON.parse(querySignature);
3637
3758
  if (!Array.isArray(parsed)) return [];
3638
3759
  return parsed.flatMap(
@@ -3685,13 +3806,14 @@ import {
3685
3806
  import {
3686
3807
  Fragment as Fragment2,
3687
3808
  useCallback as useCallback4,
3809
+ useContext as useContext4,
3688
3810
  useEffect as useEffect3,
3689
3811
  useId,
3690
- useMemo as useMemo5,
3812
+ useMemo as useMemo6,
3691
3813
  useRef as useRef2,
3692
3814
  useState as useState6
3693
3815
  } from "react";
3694
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
3816
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
3695
3817
  var isChoiceFieldType = (type) => type === "radio" || type === "checkbox" || type === "multi-select" || type === "select";
3696
3818
  function resolveChoiceFieldLayout(type, appearance, groupedChoiceFieldsLegacy = false) {
3697
3819
  if (groupedChoiceFieldsLegacy) return "grouped";
@@ -3717,15 +3839,15 @@ function RequiredMark({
3717
3839
  }
3718
3840
  function FieldMessage({ props }) {
3719
3841
  return /* @__PURE__ */ jsxs2(Fragment3, { children: [
3720
- props.field.description === void 0 ? null : /* @__PURE__ */ jsx3("div", { id: props.helpId, className: "fe-help", children: props.field.description }),
3721
- props.error === void 0 ? null : /* @__PURE__ */ jsx3("div", { id: props.errorId, className: "fe-error", children: props.translate(props.error.messageKey, props.error.params) })
3842
+ props.field.description === void 0 ? null : /* @__PURE__ */ jsx4("div", { id: props.helpId, className: "fe-help", children: props.field.description }),
3843
+ props.error === void 0 ? null : /* @__PURE__ */ jsx4("div", { id: props.errorId, className: "fe-error", children: props.translate(props.error.messageKey, props.error.params) })
3722
3844
  ] });
3723
3845
  }
3724
3846
  function GroupedChoiceDescription({ props }) {
3725
- return props.field.description === void 0 ? null : /* @__PURE__ */ jsx3("div", { id: props.helpId, className: "fe-field-description", children: props.field.description });
3847
+ return props.field.description === void 0 ? null : /* @__PURE__ */ jsx4("div", { id: props.helpId, className: "fe-field-description", children: props.field.description });
3726
3848
  }
3727
3849
  function GroupedChoiceError({ props }) {
3728
- return props.error === void 0 ? null : /* @__PURE__ */ jsx3("div", { id: props.errorId, className: "fe-field-error", role: "alert", children: props.translate(props.error.messageKey, props.error.params) });
3850
+ return props.error === void 0 ? null : /* @__PURE__ */ jsx4("div", { id: props.errorId, className: "fe-field-error", role: "alert", children: props.translate(props.error.messageKey, props.error.params) });
3729
3851
  }
3730
3852
  function ChoiceGroupFrame({
3731
3853
  props,
@@ -3749,7 +3871,7 @@ function ChoiceGroupFrame({
3749
3871
  children,
3750
3872
  className
3751
3873
  };
3752
- if (renderChoiceGroup !== void 0) return /* @__PURE__ */ jsx3(Fragment3, { children: renderChoiceGroup(groupProps) });
3874
+ if (renderChoiceGroup !== void 0) return /* @__PURE__ */ jsx4(Fragment3, { children: renderChoiceGroup(groupProps) });
3753
3875
  return (
3754
3876
  // biome-ignore lint/a11y/useAriaPropsSupportedByRole: The grouped fieldset exposes the required state for the complete choice question.
3755
3877
  /* @__PURE__ */ jsxs2(
@@ -3765,11 +3887,11 @@ function ChoiceGroupFrame({
3765
3887
  children: [
3766
3888
  /* @__PURE__ */ jsxs2("legend", { className: "fe-choice-legend", children: [
3767
3889
  field.title,
3768
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required, className: "fe-required-badge" })
3890
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required, className: "fe-required-badge" })
3769
3891
  ] }),
3770
- /* @__PURE__ */ jsx3(GroupedChoiceDescription, { props }),
3892
+ /* @__PURE__ */ jsx4(GroupedChoiceDescription, { props }),
3771
3893
  children,
3772
- /* @__PURE__ */ jsx3(GroupedChoiceError, { props })
3894
+ /* @__PURE__ */ jsx4(GroupedChoiceError, { props })
3773
3895
  ]
3774
3896
  }
3775
3897
  )
@@ -3793,7 +3915,7 @@ function DefaultField({
3793
3915
  };
3794
3916
  if (field.type === "checkbox") {
3795
3917
  if (isGroupedChoiceField) {
3796
- return /* @__PURE__ */ jsx3(
3918
+ return /* @__PURE__ */ jsx4(
3797
3919
  ChoiceGroupFrame,
3798
3920
  {
3799
3921
  props,
@@ -3802,8 +3924,8 @@ function DefaultField({
3802
3924
  renderChoiceGroup,
3803
3925
  disabled,
3804
3926
  readOnly,
3805
- children: /* @__PURE__ */ jsx3("div", { className: "fe-choice-options", children: /* @__PURE__ */ jsxs2("label", { className: "fe-choice-option", htmlFor: inputId, children: [
3806
- /* @__PURE__ */ jsx3(
3927
+ children: /* @__PURE__ */ jsx4("div", { className: "fe-choice-options", children: /* @__PURE__ */ jsxs2("label", { className: "fe-choice-option", htmlFor: inputId, children: [
3928
+ /* @__PURE__ */ jsx4(
3807
3929
  "input",
3808
3930
  {
3809
3931
  id: inputId,
@@ -3816,14 +3938,14 @@ function DefaultField({
3816
3938
  onChange: (event) => setValue(event.currentTarget.checked)
3817
3939
  }
3818
3940
  ),
3819
- /* @__PURE__ */ jsx3("span", { children: field.title })
3941
+ /* @__PURE__ */ jsx4("span", { children: field.title })
3820
3942
  ] }) })
3821
3943
  }
3822
3944
  );
3823
3945
  }
3824
3946
  return /* @__PURE__ */ jsxs2("div", { className: "fe-field fe-field--checkbox", "data-field-id": field.id, children: [
3825
3947
  /* @__PURE__ */ jsxs2("label", { className: "fe-check-label", htmlFor: inputId, children: [
3826
- /* @__PURE__ */ jsx3(
3948
+ /* @__PURE__ */ jsx4(
3827
3949
  "input",
3828
3950
  {
3829
3951
  ...ariaProps,
@@ -3836,17 +3958,17 @@ function DefaultField({
3836
3958
  ),
3837
3959
  /* @__PURE__ */ jsxs2("span", { children: [
3838
3960
  field.title,
3839
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required })
3961
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required })
3840
3962
  ] })
3841
3963
  ] }),
3842
- /* @__PURE__ */ jsx3(FieldMessage, { props })
3964
+ /* @__PURE__ */ jsx4(FieldMessage, { props })
3843
3965
  ] });
3844
3966
  }
3845
3967
  if (field.type === "radio" || field.type === "multi-select") {
3846
3968
  const selected = Array.isArray(value) ? value : [];
3847
3969
  if (isGroupedChoiceField) {
3848
3970
  const isRadio = field.type === "radio";
3849
- return /* @__PURE__ */ jsx3(
3971
+ return /* @__PURE__ */ jsx4(
3850
3972
  ChoiceGroupFrame,
3851
3973
  {
3852
3974
  props,
@@ -3855,11 +3977,11 @@ function DefaultField({
3855
3977
  renderChoiceGroup,
3856
3978
  disabled,
3857
3979
  readOnly,
3858
- children: /* @__PURE__ */ jsx3("div", { className: "fe-choice-options", children: field.options.map((option, index) => {
3980
+ children: /* @__PURE__ */ jsx4("div", { className: "fe-choice-options", children: field.options.map((option, index) => {
3859
3981
  const optionId = `${inputId}-${index}`;
3860
3982
  const checked = isRadio ? value === option.id : selected.includes(option.id);
3861
3983
  return /* @__PURE__ */ jsxs2("label", { className: "fe-choice-option", htmlFor: optionId, children: [
3862
- /* @__PURE__ */ jsx3(
3984
+ /* @__PURE__ */ jsx4(
3863
3985
  "input",
3864
3986
  {
3865
3987
  id: optionId,
@@ -3889,7 +4011,7 @@ function DefaultField({
3889
4011
  }
3890
4012
  }
3891
4013
  ),
3892
- /* @__PURE__ */ jsx3("span", { children: option.label })
4014
+ /* @__PURE__ */ jsx4("span", { children: option.label })
3893
4015
  ] }, option.id);
3894
4016
  }) })
3895
4017
  }
@@ -3899,12 +4021,12 @@ function DefaultField({
3899
4021
  return /* @__PURE__ */ jsxs2("div", { className: "fe-field fe-field--radio", "data-field-id": field.id, children: [
3900
4022
  /* @__PURE__ */ jsxs2("div", { className: "fe-label", children: [
3901
4023
  field.title,
3902
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required })
4024
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required })
3903
4025
  ] }),
3904
4026
  field.options.map((option, index) => {
3905
4027
  const optionId = `${inputId}-${index}`;
3906
4028
  return /* @__PURE__ */ jsxs2("label", { className: "fe-check-label", htmlFor: optionId, children: [
3907
- /* @__PURE__ */ jsx3(
4029
+ /* @__PURE__ */ jsx4(
3908
4030
  "input",
3909
4031
  {
3910
4032
  ...ariaProps,
@@ -3916,22 +4038,22 @@ function DefaultField({
3916
4038
  onChange: () => setValue(option.id)
3917
4039
  }
3918
4040
  ),
3919
- /* @__PURE__ */ jsx3("span", { children: option.label })
4041
+ /* @__PURE__ */ jsx4("span", { children: option.label })
3920
4042
  ] }, option.id);
3921
4043
  }),
3922
- /* @__PURE__ */ jsx3(FieldMessage, { props })
4044
+ /* @__PURE__ */ jsx4(FieldMessage, { props })
3923
4045
  ] });
3924
4046
  }
3925
4047
  return /* @__PURE__ */ jsxs2("fieldset", { className: `fe-field fe-field--${field.type}`, "data-field-id": field.id, ...ariaProps, children: [
3926
4048
  /* @__PURE__ */ jsxs2("legend", { className: "fe-label", children: [
3927
4049
  field.title,
3928
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required })
4050
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required })
3929
4051
  ] }),
3930
4052
  field.options.map((option, index) => {
3931
4053
  const optionId = `${inputId}-${index}`;
3932
4054
  const checked = field.type === "radio" ? value === option.id : selected.includes(option.id);
3933
4055
  return /* @__PURE__ */ jsxs2("label", { className: "fe-check-label", htmlFor: optionId, children: [
3934
- /* @__PURE__ */ jsx3(
4056
+ /* @__PURE__ */ jsx4(
3935
4057
  "input",
3936
4058
  {
3937
4059
  id: optionId,
@@ -3948,10 +4070,10 @@ function DefaultField({
3948
4070
  }
3949
4071
  }
3950
4072
  ),
3951
- /* @__PURE__ */ jsx3("span", { children: option.label })
4073
+ /* @__PURE__ */ jsx4("span", { children: option.label })
3952
4074
  ] }, option.id);
3953
4075
  }),
3954
- /* @__PURE__ */ jsx3(FieldMessage, { props })
4076
+ /* @__PURE__ */ jsx4(FieldMessage, { props })
3955
4077
  ] });
3956
4078
  }
3957
4079
  if (field.type === "rating") {
@@ -3960,12 +4082,12 @@ function DefaultField({
3960
4082
  return /* @__PURE__ */ jsxs2("fieldset", { className: "fe-field fe-field--rating", "data-field-id": field.id, ...ariaProps, children: [
3961
4083
  /* @__PURE__ */ jsxs2("legend", { className: "fe-label", children: [
3962
4084
  field.title,
3963
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required })
4085
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required })
3964
4086
  ] }),
3965
- /* @__PURE__ */ jsx3("div", { className: "fe-rating-options", children: Array.from({ length: max - min + 1 }, (_, index) => min + index).map((rating) => {
4087
+ /* @__PURE__ */ jsx4("div", { className: "fe-rating-options", children: Array.from({ length: max - min + 1 }, (_, index) => min + index).map((rating) => {
3966
4088
  const optionId = `${inputId}-${rating}`;
3967
4089
  return /* @__PURE__ */ jsxs2("label", { className: "fe-rating-label", htmlFor: optionId, children: [
3968
- /* @__PURE__ */ jsx3(
4090
+ /* @__PURE__ */ jsx4(
3969
4091
  "input",
3970
4092
  {
3971
4093
  id: optionId,
@@ -3976,15 +4098,15 @@ function DefaultField({
3976
4098
  onChange: () => setValue(rating)
3977
4099
  }
3978
4100
  ),
3979
- /* @__PURE__ */ jsx3("span", { children: rating })
4101
+ /* @__PURE__ */ jsx4("span", { children: rating })
3980
4102
  ] }, rating);
3981
4103
  }) }),
3982
- /* @__PURE__ */ jsx3(FieldMessage, { props })
4104
+ /* @__PURE__ */ jsx4(FieldMessage, { props })
3983
4105
  ] });
3984
4106
  }
3985
4107
  const label = /* @__PURE__ */ jsxs2("label", { className: "fe-label", htmlFor: inputId, children: [
3986
4108
  field.title,
3987
- /* @__PURE__ */ jsx3(RequiredMark, { required: field.required })
4109
+ /* @__PURE__ */ jsx4(RequiredMark, { required: field.required })
3988
4110
  ] });
3989
4111
  let control;
3990
4112
  const textConstraints = field.type === "text" || field.type === "textarea" ? {
@@ -3993,7 +4115,7 @@ function DefaultField({
3993
4115
  ...field.pattern === void 0 ? {} : { pattern: field.pattern }
3994
4116
  } : {};
3995
4117
  if (field.type === "textarea") {
3996
- control = /* @__PURE__ */ jsx3(
4118
+ control = /* @__PURE__ */ jsx4(
3997
4119
  "textarea",
3998
4120
  {
3999
4121
  ...ariaProps,
@@ -4006,7 +4128,7 @@ function DefaultField({
4006
4128
  }
4007
4129
  );
4008
4130
  } else if (field.type === "number") {
4009
- control = /* @__PURE__ */ jsx3(
4131
+ control = /* @__PURE__ */ jsx4(
4010
4132
  "input",
4011
4133
  {
4012
4134
  ...ariaProps,
@@ -4033,14 +4155,14 @@ function DefaultField({
4033
4155
  value: typeof value === "string" ? value : "",
4034
4156
  onChange: (event) => setValue(event.currentTarget.value || void 0),
4035
4157
  children: [
4036
- /* @__PURE__ */ jsx3("option", { value: "", children: "\u2014" }),
4037
- field.options.map((option) => /* @__PURE__ */ jsx3("option", { value: option.id, children: option.label }, option.id))
4158
+ /* @__PURE__ */ jsx4("option", { value: "", children: "\u2014" }),
4159
+ field.options.map((option) => /* @__PURE__ */ jsx4("option", { value: option.id, children: option.label }, option.id))
4038
4160
  ]
4039
4161
  }
4040
4162
  );
4041
4163
  } else {
4042
4164
  const placeholderKey = "placeholderKey" in field ? field.placeholderKey : void 0;
4043
- control = /* @__PURE__ */ jsx3(
4165
+ control = /* @__PURE__ */ jsx4(
4044
4166
  "input",
4045
4167
  {
4046
4168
  ...ariaProps,
@@ -4054,7 +4176,7 @@ function DefaultField({
4054
4176
  );
4055
4177
  }
4056
4178
  if (isGroupedChoiceField) {
4057
- return /* @__PURE__ */ jsx3(
4179
+ return /* @__PURE__ */ jsx4(
4058
4180
  ChoiceGroupFrame,
4059
4181
  {
4060
4182
  props,
@@ -4063,7 +4185,7 @@ function DefaultField({
4063
4185
  renderChoiceGroup,
4064
4186
  disabled,
4065
4187
  readOnly,
4066
- children: /* @__PURE__ */ jsx3("div", { className: "fe-choice-options", children: control })
4188
+ children: /* @__PURE__ */ jsx4("div", { className: "fe-choice-options", children: control })
4067
4189
  }
4068
4190
  );
4069
4191
  }
@@ -4079,7 +4201,7 @@ function DefaultField({
4079
4201
  " / ",
4080
4202
  field.maxLength
4081
4203
  ] }) : null,
4082
- /* @__PURE__ */ jsx3(FieldMessage, { props })
4204
+ /* @__PURE__ */ jsx4(FieldMessage, { props })
4083
4205
  ] });
4084
4206
  }
4085
4207
  function isRecord(value) {
@@ -4201,6 +4323,8 @@ function ContextFormRenderer({
4201
4323
  slots = {}
4202
4324
  }) {
4203
4325
  const form = useForm();
4326
+ const i18n = useFormEngineI18n();
4327
+ const isProviderValue = useContext4(FormEngineI18nProviderScopeContext);
4204
4328
  const prefix = useId().replace(/:/g, "");
4205
4329
  const formRef = useRef2(null);
4206
4330
  const loadedDraftKey = useRef2(null);
@@ -4218,15 +4342,15 @@ function ContextFormRenderer({
4218
4342
  const completionRef = useRef2(null);
4219
4343
  const confirmationRef = useRef2(null);
4220
4344
  const pages = form.schema.pages;
4221
- const visiblePageIndexes = useMemo5(
4345
+ const visiblePageIndexes = useMemo6(
4222
4346
  () => pages === void 0 ? [] : pages.flatMap((page, index) => form.pageVisibility[page.id] === true ? [index] : []),
4223
4347
  [form.pageVisibility, pages]
4224
4348
  );
4225
4349
  const activePage = pages?.[currentPageIndex];
4226
4350
  const activeVisibleIndex = visiblePageIndexes.indexOf(currentPageIndex);
4227
4351
  const fieldIds = activePage === void 0 ? void 0 : new Set(activePage.questionIds);
4228
- const visibleValues = useMemo5(() => selectVisibleAnswers2(form.schema, form.values), [form.schema, form.values]);
4229
- const visibleItems = useMemo5(
4352
+ const visibleValues = useMemo6(() => selectVisibleAnswers2(form.schema, form.values), [form.schema, form.values]);
4353
+ const visibleItems = useMemo6(
4230
4354
  () => buildSubmittedItems(form.schema, form.values, form.visibility, (key) => form.translate(key), false),
4231
4355
  [form.schema, form.translate, form.values, form.visibility]
4232
4356
  );
@@ -4237,11 +4361,12 @@ function ContextFormRenderer({
4237
4361
  const isReplaceMode = successRenderMode === "replace" || hideFormOnSuccess;
4238
4362
  const resolveMessage = useCallback4(
4239
4363
  (key, fallback) => {
4240
- const defaultText = fallback ?? DEFAULT_RENDERER_MESSAGES[form.locale.toLowerCase().startsWith("ja") ? "ja" : "en"][key] ?? key;
4364
+ const providerDefault = isProviderValue ? i18n.translator(`renderer.${key}`) : void 0;
4365
+ const defaultText = fallback ?? (providerDefault === "" ? void 0 : providerDefault) ?? DEFAULT_RENDERER_MESSAGES[form.locale.toLowerCase().startsWith("ja") ? "ja" : "en"][key] ?? key;
4241
4366
  const configured = messages[key];
4242
4367
  return messageResolver?.(key, configured ?? defaultText) ?? configured ?? defaultText;
4243
4368
  },
4244
- [form.locale, messageResolver, messages]
4369
+ [form.locale, i18n, isProviderValue, messageResolver, messages]
4245
4370
  );
4246
4371
  const fieldTranslate = useCallback4(
4247
4372
  (key, params) => key === "validation.required" && (messages.requiredField !== void 0 || messageResolver !== void 0) ? resolveMessage("requiredField") : form.translate(key, params),
@@ -4550,7 +4675,7 @@ function ContextFormRenderer({
4550
4675
  onSubmit: () => void submitValues()
4551
4676
  };
4552
4677
  return slots.renderSubmitButton?.(submitButtonProps) ?? /* @__PURE__ */ jsxs2("button", { className: "fe-submit", type: "submit", disabled: submitButtonProps.disabled, children: [
4553
- submitState === "submitting" ? /* @__PURE__ */ jsx3("span", { className: "fe-spinner", "aria-hidden": "true" }) : null,
4678
+ submitState === "submitting" ? /* @__PURE__ */ jsx4("span", { className: "fe-spinner", "aria-hidden": "true" }) : null,
4554
4679
  submitState === "submitting" ? resolveMessage("submittingButton") : resolveMessage("submitButton", form.translate(form.schema.submitLabelKey ?? "form.submit"))
4555
4680
  ] });
4556
4681
  };
@@ -4574,10 +4699,10 @@ function ContextFormRenderer({
4574
4699
  onReset: form.reset
4575
4700
  };
4576
4701
  const completionRegion = /* @__PURE__ */ jsxs2("div", { ref: completionRef, className: "fe-completion", role: "status", "aria-live": "polite", tabIndex: -1, children: [
4577
- slots.renderCompletion?.(completionProps) ?? /* @__PURE__ */ jsx3("div", { children: completionMessage }),
4702
+ slots.renderCompletion?.(completionProps) ?? /* @__PURE__ */ jsx4("div", { children: completionMessage }),
4578
4703
  slots.renderSubmittedValues?.({ items: activeCompletionData.submittedItems, schema: form.schema })
4579
4704
  ] });
4580
- const confirmationContent = /* @__PURE__ */ jsx3(
4705
+ const confirmationContent = /* @__PURE__ */ jsx4(
4581
4706
  "div",
4582
4707
  {
4583
4708
  ref: confirmationRef,
@@ -4592,49 +4717,49 @@ function ContextFormRenderer({
4592
4717
  onConfirm: confirmSubmission,
4593
4718
  onCancel: cancelSubmission
4594
4719
  }) ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
4595
- /* @__PURE__ */ jsx3("h2", { children: confirmation?.generic === true ? form.locale.toLowerCase().startsWith("ja") ? "\u56DE\u7B54\u5185\u5BB9\u306E\u78BA\u8A8D" : "Review your answers" : resolveMessage("confirmSensitiveDataTitle") }),
4596
- /* @__PURE__ */ jsx3("p", { children: confirmation?.message ?? (confirmation?.generic === true ? form.locale.toLowerCase().startsWith("ja") ? "\u56DE\u7B54\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001\u9001\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : "Please review your answers before submitting." : resolveMessage("confirmSensitiveDataMessage", form.translate("form.confirmSensitiveData"))) }),
4597
- (confirmation?.findings ?? []).length === 0 ? null : /* @__PURE__ */ jsx3("ul", { children: (confirmation?.findings ?? []).map((finding, index) => {
4720
+ /* @__PURE__ */ jsx4("h2", { children: confirmation?.generic === true ? form.locale.toLowerCase().startsWith("ja") ? "\u56DE\u7B54\u5185\u5BB9\u306E\u78BA\u8A8D" : "Review your answers" : resolveMessage("confirmSensitiveDataTitle") }),
4721
+ /* @__PURE__ */ jsx4("p", { children: confirmation?.message ?? (confirmation?.generic === true ? form.locale.toLowerCase().startsWith("ja") ? "\u56DE\u7B54\u5185\u5BB9\u3092\u3054\u78BA\u8A8D\u306E\u3046\u3048\u3001\u9001\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\u3002" : "Please review your answers before submitting." : resolveMessage("confirmSensitiveDataMessage", form.translate("form.confirmSensitiveData"))) }),
4722
+ (confirmation?.findings ?? []).length === 0 ? null : /* @__PURE__ */ jsx4("ul", { children: (confirmation?.findings ?? []).map((finding, index) => {
4598
4723
  const field = form.schema.fields.find((candidate) => candidate.id === finding.fieldId);
4599
4724
  const typeLabels = form.locale.toLowerCase().startsWith("ja") ? { email: "\u30E1\u30FC\u30EB\u30A2\u30C9\u30EC\u30B9", phone: "\u96FB\u8A71\u756A\u53F7", url: "URL", postal_code: "\u90F5\u4FBF\u756A\u53F7" } : { email: "Email address", phone: "Phone number", url: "URL", postal_code: "Postal code" };
4600
4725
  const typeLabel = finding.typeLabel ?? typeLabels[finding.type] ?? finding.type;
4601
4726
  const value = maskSensitiveValue(finding);
4602
4727
  return /* @__PURE__ */ jsxs2("li", { children: [
4603
- /* @__PURE__ */ jsx3("span", { children: finding.fieldTitle ?? field?.title ?? finding.fieldId }),
4728
+ /* @__PURE__ */ jsx4("span", { children: finding.fieldTitle ?? field?.title ?? finding.fieldId }),
4604
4729
  " ",
4605
- /* @__PURE__ */ jsx3("span", { className: "fe-sensitive-type", children: typeLabel }),
4730
+ /* @__PURE__ */ jsx4("span", { className: "fe-sensitive-type", children: typeLabel }),
4606
4731
  value === void 0 ? null : /* @__PURE__ */ jsxs2("span", { className: "fe-sensitive-value", children: [
4607
4732
  " ",
4608
4733
  value
4609
4734
  ] })
4610
4735
  ] }, `${finding.fieldId}-${finding.type}-${finding.start ?? index}`);
4611
4736
  }) }),
4612
- confirmation?.generic === true ? /* @__PURE__ */ jsx3("ul", { className: "fe-submission-summary", children: visibleItems.map((item) => /* @__PURE__ */ jsxs2("li", { children: [
4613
- /* @__PURE__ */ jsx3("span", { children: item.title }),
4737
+ confirmation?.generic === true ? /* @__PURE__ */ jsx4("ul", { className: "fe-submission-summary", children: visibleItems.map((item) => /* @__PURE__ */ jsxs2("li", { children: [
4738
+ /* @__PURE__ */ jsx4("span", { children: item.title }),
4614
4739
  ": ",
4615
- /* @__PURE__ */ jsx3("span", { children: item.displayValue })
4740
+ /* @__PURE__ */ jsx4("span", { children: item.displayValue })
4616
4741
  ] }, item.fieldId)) }) : null,
4617
- /* @__PURE__ */ jsx3("button", { type: "button", "data-fe-confirm": "true", onClick: confirmSubmission, children: resolveMessage("confirmButton", form.translate("form.confirmSubmission")) }),
4618
- /* @__PURE__ */ jsx3("button", { type: "button", onClick: cancelSubmission, children: resolveMessage("cancelButton", form.translate("form.cancelSubmission")) })
4742
+ /* @__PURE__ */ jsx4("button", { type: "button", "data-fe-confirm": "true", onClick: confirmSubmission, children: resolveMessage("confirmButton", form.translate("form.confirmSubmission")) }),
4743
+ /* @__PURE__ */ jsx4("button", { type: "button", onClick: cancelSubmission, children: resolveMessage("cancelButton", form.translate("form.cancelSubmission")) })
4619
4744
  ] })
4620
4745
  }
4621
4746
  );
4622
4747
  if (!receiptLoaded) return null;
4623
4748
  if (receipt !== null) {
4624
- return /* @__PURE__ */ jsx3("div", { className: `fe-form fe-already-submitted ${className}`.trim(), children: slots.renderAlreadySubmitted?.({
4749
+ return /* @__PURE__ */ jsx4("div", { className: `fe-form fe-already-submitted ${className}`.trim(), children: slots.renderAlreadySubmitted?.({
4625
4750
  receipt,
4626
4751
  ...receiptStore === void 0 ? {} : { onReset: () => void resetReceipt() }
4627
4752
  }) ?? /* @__PURE__ */ jsxs2("div", { role: "status", children: [
4628
- /* @__PURE__ */ jsx3("h2", { children: resolveMessage("alreadySubmittedTitle") }),
4629
- /* @__PURE__ */ jsx3("p", { children: resolveMessage("alreadySubmittedMessage", form.translate("form.alreadySubmitted")) }),
4630
- receiptStore === void 0 ? null : /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => void resetReceipt(), children: resolveMessage("submitButton", form.translate("form.submitAnother")) })
4753
+ /* @__PURE__ */ jsx4("h2", { children: resolveMessage("alreadySubmittedTitle") }),
4754
+ /* @__PURE__ */ jsx4("p", { children: resolveMessage("alreadySubmittedMessage", form.translate("form.alreadySubmitted")) }),
4755
+ receiptStore === void 0 ? null : /* @__PURE__ */ jsx4("button", { type: "button", onClick: () => void resetReceipt(), children: resolveMessage("submitButton", form.translate("form.submitAnother")) })
4631
4756
  ] }) });
4632
4757
  }
4633
4758
  if (form.submitStatus === "success" && isReplaceMode) {
4634
- return /* @__PURE__ */ jsx3("div", { className: `fe-form ${className}`.trim(), children: completionRegion });
4759
+ return /* @__PURE__ */ jsx4("div", { className: `fe-form ${className}`.trim(), children: completionRegion });
4635
4760
  }
4636
4761
  if (confirmation !== null && confirmationRenderMode === "replace") {
4637
- return /* @__PURE__ */ jsx3("div", { className: `fe-form ${className}`.trim(), children: confirmationContent });
4762
+ return /* @__PURE__ */ jsx4("div", { className: `fe-form ${className}`.trim(), children: confirmationContent });
4638
4763
  }
4639
4764
  return /* @__PURE__ */ jsxs2(Fragment3, { children: [
4640
4765
  /* @__PURE__ */ jsxs2(
@@ -4650,10 +4775,10 @@ function ContextFormRenderer({
4650
4775
  title: form.schema.title,
4651
4776
  ...form.schema.description === void 0 ? {} : { description: form.schema.description }
4652
4777
  }) ?? /* @__PURE__ */ jsxs2("header", { className: "fe-header", children: [
4653
- /* @__PURE__ */ jsx3("h1", { children: form.schema.title }),
4654
- form.schema.description === void 0 ? null : /* @__PURE__ */ jsx3("p", { children: form.schema.description }),
4778
+ /* @__PURE__ */ jsx4("h1", { children: form.schema.title }),
4779
+ form.schema.description === void 0 ? null : /* @__PURE__ */ jsx4("p", { children: form.schema.description }),
4655
4780
  pages === void 0 ? null : /* @__PURE__ */ jsxs2("div", { className: "fe-progress", children: [
4656
- /* @__PURE__ */ jsx3(
4781
+ /* @__PURE__ */ jsx4(
4657
4782
  "div",
4658
4783
  {
4659
4784
  className: "form-progress-bar",
@@ -4661,7 +4786,7 @@ function ContextFormRenderer({
4661
4786
  "aria-valuemin": 1,
4662
4787
  "aria-valuemax": visiblePageIndexes.length,
4663
4788
  "aria-valuenow": activeVisibleIndex + 1,
4664
- children: /* @__PURE__ */ jsx3(
4789
+ children: /* @__PURE__ */ jsx4(
4665
4790
  "div",
4666
4791
  {
4667
4792
  className: "form-progress-fill",
@@ -4670,17 +4795,17 @@ function ContextFormRenderer({
4670
4795
  )
4671
4796
  }
4672
4797
  ),
4673
- /* @__PURE__ */ jsx3("span", { children: form.translate("form.step", { current: activeVisibleIndex + 1, total: visiblePageIndexes.length }) })
4798
+ /* @__PURE__ */ jsx4("span", { children: form.translate("form.step", { current: activeVisibleIndex + 1, total: visiblePageIndexes.length }) })
4674
4799
  ] }),
4675
- draftRestored ? /* @__PURE__ */ jsx3("span", { className: "form-draft-badge", children: form.translate("form.draftRestored") }) : null
4800
+ draftRestored ? /* @__PURE__ */ jsx4("span", { className: "form-draft-badge", children: form.translate("form.draftRestored") }) : null
4676
4801
  ] }),
4677
4802
  activePage === void 0 ? null : slots.renderPageHeader?.({
4678
4803
  page: activePage,
4679
4804
  pageIndex: activeVisibleIndex,
4680
4805
  totalPages: visiblePageIndexes.length
4681
4806
  }) ?? /* @__PURE__ */ jsxs2("div", { className: "fe-page-header", children: [
4682
- activePage.title === void 0 ? null : /* @__PURE__ */ jsx3("h2", { className: "fe-page-title", children: activePage.title }),
4683
- activePage.description === void 0 ? null : /* @__PURE__ */ jsx3("p", { className: "fe-page-description", children: activePage.description })
4807
+ activePage.title === void 0 ? null : /* @__PURE__ */ jsx4("h2", { className: "fe-page-title", children: activePage.title }),
4808
+ activePage.description === void 0 ? null : /* @__PURE__ */ jsx4("p", { className: "fe-page-description", children: activePage.description })
4684
4809
  ] }),
4685
4810
  (() => {
4686
4811
  const fieldChildren = form.schema.fields.filter((field) => form.visibility[field.id] === true && (fieldIds === void 0 || fieldIds.has(field.id))).map((field) => {
@@ -4697,7 +4822,7 @@ function ContextFormRenderer({
4697
4822
  ...slots.renderCharacterCount === void 0 ? {} : { renderCharacterCount: slots.renderCharacterCount }
4698
4823
  };
4699
4824
  if (slots.renderField !== void 0) {
4700
- return /* @__PURE__ */ jsx3(Fragment2, { children: slots.renderField({
4825
+ return /* @__PURE__ */ jsx4(Fragment2, { children: slots.renderField({
4701
4826
  question: field,
4702
4827
  value: form.values[field.id],
4703
4828
  onChange: (value) => {
@@ -4707,7 +4832,7 @@ function ContextFormRenderer({
4707
4832
  }) }, field.id);
4708
4833
  }
4709
4834
  const Component = components[field.type];
4710
- return Component === void 0 ? /* @__PURE__ */ jsx3(
4835
+ return Component === void 0 ? /* @__PURE__ */ jsx4(
4711
4836
  DefaultField,
4712
4837
  {
4713
4838
  ...props,
@@ -4718,12 +4843,12 @@ function ContextFormRenderer({
4718
4843
  disabled: interactionLocked
4719
4844
  },
4720
4845
  field.id
4721
- ) : /* @__PURE__ */ jsx3(Component, { ...props }, field.id);
4846
+ ) : /* @__PURE__ */ jsx4(Component, { ...props }, field.id);
4722
4847
  });
4723
4848
  const fieldClassName = `fe-fields${fieldsClassName === void 0 ? "" : ` ${fieldsClassName}`}`;
4724
- return slots.renderFields?.({ children: fieldChildren, className: fieldClassName }) ?? /* @__PURE__ */ jsx3("div", { className: fieldClassName, children: fieldChildren });
4849
+ return slots.renderFields?.({ children: fieldChildren, className: fieldClassName }) ?? /* @__PURE__ */ jsx4("div", { className: fieldClassName, children: fieldChildren });
4725
4850
  })(),
4726
- guardMessage === null ? null : /* @__PURE__ */ jsx3("div", { role: "alert", children: guardMessage }),
4851
+ guardMessage === null ? null : /* @__PURE__ */ jsx4("div", { role: "alert", children: guardMessage }),
4727
4852
  confirmation !== null && confirmationRenderMode === "inline" ? confirmationContent : null,
4728
4853
  validationIssues.length === 0 ? null : slots.renderValidationSummary?.({ issues: validationIssues }) ?? /* @__PURE__ */ jsxs2("div", { className: "fe-validation-summary", role: "alert", children: [
4729
4854
  validationIssues.length,
@@ -4752,7 +4877,7 @@ function ContextFormRenderer({
4752
4877
  },
4753
4878
  onNext: handleNext
4754
4879
  }) ?? /* @__PURE__ */ jsxs2(Fragment3, { children: [
4755
- canPrev ? /* @__PURE__ */ jsx3(
4880
+ canPrev ? /* @__PURE__ */ jsx4(
4756
4881
  "button",
4757
4882
  {
4758
4883
  className: "btn-prev",
@@ -4762,7 +4887,7 @@ function ContextFormRenderer({
4762
4887
  children: form.translate("form.back")
4763
4888
  }
4764
4889
  ) : null,
4765
- canNext ? /* @__PURE__ */ jsx3("button", { className: "btn-next", type: "button", disabled: interactionLocked, onClick: handleNext, children: form.translate("form.next") }) : null
4890
+ canNext ? /* @__PURE__ */ jsx4("button", { className: "btn-next", type: "button", disabled: interactionLocked, onClick: handleNext, children: form.translate("form.next") }) : null
4766
4891
  ] }),
4767
4892
  canNext ? null : renderSubmitButton()
4768
4893
  ] }),
@@ -4770,16 +4895,16 @@ function ContextFormRenderer({
4770
4895
  form.submitStatus === "success" ? completionRegion : null,
4771
4896
  form.submitStatus === "error" && form.submitError !== null ? slots.renderSubmitError?.({ error: form.submitError, onRetry: () => void submitValues() }) ?? (form.submitError instanceof FormSubmissionError && form.submitError.payload.formError !== void 0 ? /* @__PURE__ */ jsxs2("div", { role: "alert", children: [
4772
4897
  form.submitError.payload.formError,
4773
- /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => void submitValues(), children: resolveMessage("retryButton") })
4898
+ /* @__PURE__ */ jsx4("button", { type: "button", onClick: () => void submitValues(), children: resolveMessage("retryButton") })
4774
4899
  ] }) : /* @__PURE__ */ jsxs2("div", { role: "alert", children: [
4775
4900
  errorMessageKey === void 0 ? resolveMessage("serverErrorSummary") : form.translate(errorMessageKey),
4776
- /* @__PURE__ */ jsx3("button", { type: "button", onClick: () => void submitValues(), children: resolveMessage("retryButton") })
4901
+ /* @__PURE__ */ jsx4("button", { type: "button", onClick: () => void submitValues(), children: resolveMessage("retryButton") })
4777
4902
  ] })) : null
4778
4903
  ] })
4779
4904
  ]
4780
4905
  }
4781
4906
  ),
4782
- confirmation !== null && confirmationRenderMode === "dialog" ? /* @__PURE__ */ jsx3("div", { className: "fe-confirmation-dialog-backdrop", role: "dialog", "aria-modal": "true", children: confirmationContent }) : null
4907
+ confirmation !== null && confirmationRenderMode === "dialog" ? /* @__PURE__ */ jsx4("div", { className: "fe-confirmation-dialog-backdrop", role: "dialog", "aria-modal": "true", children: confirmationContent }) : null
4783
4908
  ] });
4784
4909
  }
4785
4910
  var RENDERER_MESSAGES = {
@@ -4824,17 +4949,22 @@ var defaultRendererTranslator = {
4824
4949
  }
4825
4950
  };
4826
4951
  function FormRenderer(props) {
4827
- if (!("schema" in props)) return /* @__PURE__ */ jsx3(ContextFormRenderer, { ...props });
4952
+ const i18n = useFormEngineI18n();
4953
+ const isProviderValue = useContext4(FormEngineI18nProviderScopeContext);
4954
+ if (!("schema" in props)) return /* @__PURE__ */ jsx4(ContextFormRenderer, { ...props });
4828
4955
  const {
4829
4956
  schema,
4830
4957
  locale = schema.defaultLocale ?? "en",
4831
- translator = defaultRendererTranslator,
4958
+ translator: explicitTranslator,
4832
4959
  initialValues,
4833
4960
  resetOnSuccess,
4834
4961
  onSubmit,
4835
4962
  ...rendererProps
4836
4963
  } = props;
4837
- return /* @__PURE__ */ jsx3(
4964
+ const translator = explicitTranslator ?? (isProviderValue ? {
4965
+ translate: (key, _locale, params) => params === void 0 ? i18n.translator(key) : i18n.translator(key, { ...params })
4966
+ } : defaultRendererTranslator);
4967
+ return /* @__PURE__ */ jsx4(
4838
4968
  FormProvider,
4839
4969
  {
4840
4970
  schema,
@@ -4843,7 +4973,7 @@ function FormRenderer(props) {
4843
4973
  onSubmit,
4844
4974
  ...initialValues === void 0 ? {} : { initialValues },
4845
4975
  ...resetOnSuccess === void 0 ? {} : { resetOnSuccess },
4846
- children: /* @__PURE__ */ jsx3(ContextFormRenderer, { ...rendererProps })
4976
+ children: /* @__PURE__ */ jsx4(ContextFormRenderer, { ...rendererProps })
4847
4977
  }
4848
4978
  );
4849
4979
  }
@@ -4851,6 +4981,8 @@ export {
4851
4981
  BUILDER_TRANSLATION_ALIASES,
4852
4982
  BUILDER_TRANSLATION_KEYS,
4853
4983
  FormBuilder,
4984
+ FormEngineI18nContext,
4985
+ FormEngineI18nProvider,
4854
4986
  FormProvider,
4855
4987
  FormRenderer,
4856
4988
  FormSubmissionError,
@@ -4866,6 +4998,7 @@ export {
4866
4998
  useField,
4867
4999
  useForm,
4868
5000
  useFormBuilder,
5001
+ useFormEngineI18n,
4869
5002
  useSubmissionReceipts,
4870
5003
  useTranslationWorkspace,
4871
5004
  validateLocalePipeline