@form-engine-ts/react 5.0.1 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3325,7 +3325,7 @@ function asAsyncAdapter(adapter) {
3325
3325
  )
3326
3326
  };
3327
3327
  }
3328
- var validateLocalePipeline = (locale, schema, policy, customValidator) => {
3328
+ var validateLocalePipeline = (locale, schema, policy, customValidator, availableLocales) => {
3329
3329
  const canonicalLocale = (0, import_core5.normalizeLocale)(locale);
3330
3330
  if (canonicalLocale === null) {
3331
3331
  return {
@@ -3338,6 +3338,18 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
3338
3338
  }
3339
3339
  const currentLocales = (schema.supportedLocales ?? []).map((candidate) => (0, import_core5.normalizeLocale)(candidate) ?? candidate);
3340
3340
  const defaultLocale = schema.defaultLocale === void 0 ? "" : (0, import_core5.normalizeLocale)(schema.defaultLocale) ?? schema.defaultLocale;
3341
+ if (availableLocales !== void 0 && !availableLocales.some((candidate) => {
3342
+ const value = typeof candidate === "string" ? candidate : candidate.locale;
3343
+ return (0, import_core5.normalizeLocale)(value) === canonicalLocale;
3344
+ })) {
3345
+ return {
3346
+ valid: false,
3347
+ error: {
3348
+ type: "locale_not_allowed",
3349
+ message: `Locale "${canonicalLocale}" is not available in the locale catalog.`
3350
+ }
3351
+ };
3352
+ }
3341
3353
  if (canonicalLocale === defaultLocale || currentLocales.includes(canonicalLocale)) {
3342
3354
  return {
3343
3355
  valid: false,
@@ -3478,11 +3490,15 @@ function useTranslationWorkspace({
3478
3490
  translationAdapter,
3479
3491
  readOnly = false,
3480
3492
  policy,
3493
+ availableLocales,
3494
+ onLocaleAdded,
3495
+ onLocaleRemoved,
3496
+ onLocaleChange,
3481
3497
  beforeRemoveLocale,
3482
3498
  validateLocale
3483
3499
  }) {
3484
3500
  const [draftSchema, setDraftSchema] = (0, import_react5.useState)(schema);
3485
- const [selectedLocale, setSelectedLocale] = (0, import_react5.useState)(targetLocale ?? "");
3501
+ const [selectedLocale, setSelectedLocale] = (0, import_react5.useState)((0, import_core5.normalizeLocale)(targetLocale ?? "") ?? targetLocale ?? "");
3486
3502
  const [isTranslating, setIsTranslating] = (0, import_react5.useState)(false);
3487
3503
  const [error, setError] = (0, import_react5.useState)();
3488
3504
  const currentSchema = onChange === void 0 ? draftSchema : schema;
@@ -3493,6 +3509,15 @@ function useTranslationWorkspace({
3493
3509
  );
3494
3510
  }, [currentSchema, sourceLocale]);
3495
3511
  const activeLocale = selectedLocale.length > 0 ? selectedLocale : targetLocales[0] ?? "";
3512
+ const localeOptions = (0, import_react5.useMemo)(() => {
3513
+ if (availableLocales === void 0) {
3514
+ return targetLocales.map((locale) => ({ locale, label: locale }));
3515
+ }
3516
+ return availableLocales.map((candidate) => {
3517
+ if (typeof candidate !== "string") return candidate;
3518
+ return { locale: (0, import_core5.normalizeLocale)(candidate) ?? candidate, label: candidate };
3519
+ });
3520
+ }, [availableLocales, targetLocales]);
3496
3521
  const slots = (0, import_react5.useMemo)(
3497
3522
  () => activeLocale.length === 0 ? [] : (0, import_core5.collectTranslationSlots)(currentSchema, activeLocale),
3498
3523
  [activeLocale, currentSchema]
@@ -3540,14 +3565,14 @@ function useTranslationWorkspace({
3540
3565
  const normalized = (0, import_core5.normalizeLocale)(locale);
3541
3566
  if (normalized === null) {
3542
3567
  const workspaceError = workspaceLocaleValidationError(
3543
- validateLocalePipeline(locale, currentSchema, policy, validateLocale),
3568
+ validateLocalePipeline(locale, currentSchema, policy, validateLocale, availableLocales),
3544
3569
  (0, import_core5.collectSchemaLocales)(currentSchema).allUniqueLocales.size,
3545
3570
  locale
3546
3571
  );
3547
3572
  setError(workspaceError);
3548
3573
  return { success: false, error: workspaceError };
3549
3574
  }
3550
- const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale);
3575
+ const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale, availableLocales);
3551
3576
  if (!validation.valid) {
3552
3577
  const workspaceError = workspaceLocaleValidationError(
3553
3578
  validation,
@@ -3563,33 +3588,38 @@ function useTranslationWorkspace({
3563
3588
  supportedLocales: [.../* @__PURE__ */ new Set([...currentSchema.supportedLocales ?? [], normalized])]
3564
3589
  });
3565
3590
  setSelectedLocale(normalized);
3591
+ onLocaleAdded?.(normalized);
3566
3592
  return { success: true };
3567
3593
  },
3568
- [commit, currentSchema, policy, readOnly, validateLocale]
3594
+ [availableLocales, commit, currentSchema, onLocaleAdded, policy, readOnly, validateLocale]
3569
3595
  );
3570
3596
  const isAddLocaleAllowed = (0, import_react5.useCallback)(
3571
3597
  (locale) => {
3572
3598
  if (readOnly) return false;
3573
3599
  const normalized = (0, import_core5.normalizeLocale)(locale);
3574
3600
  if (normalized === null) return false;
3575
- return validateLocalePipeline(normalized, currentSchema, policy, validateLocale).valid;
3601
+ return validateLocalePipeline(normalized, currentSchema, policy, validateLocale, availableLocales).valid;
3576
3602
  },
3577
- [currentSchema, policy, readOnly, validateLocale]
3603
+ [availableLocales, currentSchema, policy, readOnly, validateLocale]
3578
3604
  );
3579
3605
  const removeLocale = (0, import_react5.useCallback)(
3580
3606
  (locale) => {
3581
- if (readOnly || locale === sourceLocale || locale === currentSchema.defaultLocale) return false;
3607
+ const normalized = (0, import_core5.normalizeLocale)(locale) ?? locale;
3608
+ const normalizedSourceLocale = (0, import_core5.normalizeLocale)(sourceLocale) ?? sourceLocale;
3609
+ const normalizedDefaultLocale = currentSchema.defaultLocale === void 0 ? void 0 : (0, import_core5.normalizeLocale)(currentSchema.defaultLocale) ?? currentSchema.defaultLocale;
3610
+ if (readOnly || normalized === normalizedSourceLocale || normalized === normalizedDefaultLocale) return false;
3582
3611
  const remove = () => {
3583
- commit((0, import_core5.removeLocaleFromSchema)(currentSchema, locale));
3584
- if (activeLocale === locale) setSelectedLocale("");
3612
+ commit((0, import_core5.removeLocaleFromSchema)(currentSchema, normalized));
3613
+ if (activeLocale === normalized) setSelectedLocale("");
3614
+ onLocaleRemoved?.(normalized);
3585
3615
  };
3586
- const slotCount = (0, import_core5.collectTranslationSlots)(currentSchema, locale).length;
3616
+ const slotCount = (0, import_core5.collectTranslationSlots)(currentSchema, normalized).length;
3587
3617
  if (beforeRemoveLocale === void 0) {
3588
3618
  remove();
3589
3619
  return true;
3590
3620
  }
3591
3621
  try {
3592
- const decision = beforeRemoveLocale(locale, { slotCount });
3622
+ const decision = beforeRemoveLocale(normalized, { slotCount });
3593
3623
  if (typeof decision === "boolean") {
3594
3624
  if (!decision) return false;
3595
3625
  remove();
@@ -3610,7 +3640,7 @@ function useTranslationWorkspace({
3610
3640
  return Promise.reject(cause);
3611
3641
  }
3612
3642
  },
3613
- [activeLocale, beforeRemoveLocale, commit, currentSchema, readOnly, sourceLocale]
3643
+ [activeLocale, beforeRemoveLocale, commit, currentSchema, onLocaleRemoved, readOnly, sourceLocale]
3614
3644
  );
3615
3645
  const translateAll = (0, import_react5.useCallback)(
3616
3646
  async (options = {}) => {
@@ -3629,6 +3659,23 @@ function useTranslationWorkspace({
3629
3659
  setError(workspaceError);
3630
3660
  return { success: false, error: workspaceError };
3631
3661
  }
3662
+ const selectedLocaleOption = localeOptions.find(
3663
+ (option) => ((0, import_core5.normalizeLocale)(option.locale) ?? option.locale) === activeLocale
3664
+ );
3665
+ if (selectedLocaleOption?.translatable === false) {
3666
+ setError(void 0);
3667
+ return {
3668
+ success: true,
3669
+ report: {
3670
+ updatedSlots: [],
3671
+ skippedSlots: slots,
3672
+ staleSlots: [],
3673
+ skippedReasons: Object.fromEntries(
3674
+ slots.map((slot) => [slot.path ?? `${slot.kind}.${slot.nodeId}.${slot.property}`, "unsupported"])
3675
+ )
3676
+ }
3677
+ };
3678
+ }
3632
3679
  setIsTranslating(true);
3633
3680
  setError(void 0);
3634
3681
  try {
@@ -3656,7 +3703,7 @@ function useTranslationWorkspace({
3656
3703
  setIsTranslating(false);
3657
3704
  }
3658
3705
  },
3659
- [activeLocale, commit, currentSchema, readOnly, translationAdapter]
3706
+ [activeLocale, commit, currentSchema, localeOptions, readOnly, slots, translationAdapter]
3660
3707
  );
3661
3708
  const translateSlot = (0, import_react5.useCallback)(
3662
3709
  async (slot) => {
@@ -3694,7 +3741,12 @@ function useTranslationWorkspace({
3694
3741
  sourceLocale,
3695
3742
  targetLocale: activeLocale,
3696
3743
  targetLocales,
3697
- setTargetLocale: setSelectedLocale,
3744
+ localeOptions,
3745
+ setTargetLocale: (locale) => {
3746
+ const normalized = (0, import_core5.normalizeLocale)(locale) ?? locale;
3747
+ setSelectedLocale(normalized);
3748
+ onLocaleChange?.(normalized);
3749
+ },
3698
3750
  slots,
3699
3751
  summary,
3700
3752
  addLocale,
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
- import { QuestionType, FormField, ChoiceOption, FormPage, FormSchema, DisplayCondition, JsonValue, SchemaIssue, FormPolicy, Question, FieldOption, TranslationReport, ValidationIssue, ValidationError, FormValues, TranslationAdapter, AsyncTranslationAdapter, PopulateTranslationOptions, FormValue, AnswerValidationResult, TranslationSlot, FormEngineTranslator, FormEngineMessages, FieldType } from '@form-engine-ts/core';
1
+ import * as _form_engine_ts_core from '@form-engine-ts/core';
2
+ import { QuestionType, FormField, ChoiceOption, FormPage, FormSchema, DisplayCondition, JsonValue, SchemaIssue, FormPolicy, Question, FieldOption, TranslationReport, ValidationIssue, ValidationError, FormValues, LocaleOption, TranslationAdapter, AsyncTranslationAdapter, PopulateTranslationOptions, FormValue, AnswerValidationResult, TranslationSlot, FormEngineTranslator, FormEngineMessages, FieldType } from '@form-engine-ts/core';
2
3
  export { QuestionType } from '@form-engine-ts/core';
3
4
  import * as react from 'react';
4
5
  import { ReactNode, ComponentType, KeyboardEvent, MouseEvent, CSSProperties } from 'react';
@@ -379,6 +380,52 @@ interface BuilderLocalizationSlotProps extends BuilderSlotBaseProps {
379
380
  readonly policy?: FormPolicy;
380
381
  readonly translationAdapterAvailable?: boolean;
381
382
  }
383
+ interface TranslationWorkspaceHeaderProps {
384
+ readonly schema: FormSchema;
385
+ readonly sourceLocale: string;
386
+ readonly targetLocale: string;
387
+ readonly summary: {
388
+ readonly totalSlots: number;
389
+ readonly translatedCount: number;
390
+ readonly missingCount: number;
391
+ readonly staleCount: number;
392
+ readonly manualCount: number;
393
+ readonly completionPercentage: number;
394
+ };
395
+ readonly onTranslateAll: () => void;
396
+ readonly isTranslating: boolean;
397
+ readonly readOnly: boolean;
398
+ }
399
+ interface TranslationSlotRowProps {
400
+ readonly slot: _form_engine_ts_core.TranslationSlot;
401
+ readonly readOnly: boolean;
402
+ readonly onChange: (text: string) => void;
403
+ readonly onTranslate: () => void;
404
+ }
405
+ interface LocaleSelectorProps {
406
+ readonly targetLocale: string;
407
+ readonly targetLocales: readonly string[];
408
+ readonly localeOptions: readonly LocaleOption[];
409
+ readonly newLocale: string;
410
+ readonly readOnly: boolean;
411
+ readonly onTargetLocaleChange: (locale: string) => void;
412
+ readonly onNewLocaleChange: (locale: string) => void;
413
+ readonly onAddLocale: () => void;
414
+ }
415
+ interface TranslationWorkspaceActionsProps {
416
+ readonly onTranslateAll: () => void;
417
+ readonly isTranslating: boolean;
418
+ readonly readOnly: boolean;
419
+ }
420
+ interface TranslationWorkspaceSlots {
421
+ readonly renderHeader?: (props: TranslationWorkspaceHeaderProps) => ReactNode;
422
+ readonly renderSlotRow?: (props: TranslationSlotRowProps) => ReactNode;
423
+ readonly renderLocaleSelector?: (props: LocaleSelectorProps) => ReactNode;
424
+ readonly renderStatusBadge?: (props: {
425
+ readonly status: _form_engine_ts_core.TranslationStatus;
426
+ }) => ReactNode;
427
+ readonly renderActions?: (props: TranslationWorkspaceActionsProps) => ReactNode;
428
+ }
382
429
  interface LocalizationSummaryContext {
383
430
  readonly defaultLocale: string;
384
431
  readonly supportedLocales: readonly string[];
@@ -708,6 +755,10 @@ interface UseTranslationWorkspaceOptions {
708
755
  readonly translationAdapter?: TranslationAdapter | AsyncTranslationAdapter;
709
756
  readonly readOnly?: boolean;
710
757
  readonly policy?: FormPolicy;
758
+ readonly availableLocales?: readonly (string | LocaleOption)[];
759
+ readonly onLocaleAdded?: (locale: string) => void;
760
+ readonly onLocaleRemoved?: (locale: string) => void;
761
+ readonly onLocaleChange?: (targetLocale: string) => void;
711
762
  readonly beforeRemoveLocale?: (locale: string, context: {
712
763
  readonly slotCount: number;
713
764
  }) => Promise<boolean> | boolean;
@@ -766,6 +817,7 @@ interface UseTranslationWorkspaceResult {
766
817
  readonly sourceLocale: string;
767
818
  readonly targetLocale: string;
768
819
  readonly targetLocales: readonly string[];
820
+ readonly localeOptions: readonly LocaleOption[];
769
821
  readonly setTargetLocale: (locale: string) => void;
770
822
  readonly slots: readonly TranslationSlot[];
771
823
  readonly summary: TranslationSummary;
@@ -788,8 +840,8 @@ interface UseTranslationWorkspaceResult {
788
840
  readonly isTranslating: boolean;
789
841
  readonly error?: TranslationWorkspaceError;
790
842
  }
791
- declare const validateLocalePipeline: (locale: string, schema: FormSchema, policy?: FormPolicy, customValidator?: ((locale: string, currentLocales: readonly string[]) => LocaleValidationResult) | CustomLocaleValidator) => LocaleValidationResult;
792
- declare function useTranslationWorkspace({ schema, onChange, sourceLocale, targetLocale, translationAdapter, readOnly, policy, beforeRemoveLocale, validateLocale }: UseTranslationWorkspaceOptions): UseTranslationWorkspaceResult;
843
+ declare const validateLocalePipeline: (locale: string, schema: FormSchema, policy?: FormPolicy, customValidator?: ((locale: string, currentLocales: readonly string[]) => LocaleValidationResult) | CustomLocaleValidator, availableLocales?: readonly (string | LocaleOption)[]) => LocaleValidationResult;
844
+ declare function useTranslationWorkspace({ schema, onChange, sourceLocale, targetLocale, translationAdapter, readOnly, policy, availableLocales, onLocaleAdded, onLocaleRemoved, onLocaleChange, beforeRemoveLocale, validateLocale }: UseTranslationWorkspaceOptions): UseTranslationWorkspaceResult;
793
845
 
794
846
  declare const BUILDER_TRANSLATION_KEYS: {
795
847
  readonly ADD_FIELD: "builder.actions.addField";
@@ -879,4 +931,4 @@ interface StandaloneFormRendererProps extends FormRendererPresentationProps {
879
931
  type FormRendererProps = FormRendererPresentationProps | StandaloneFormRendererProps;
880
932
  declare function FormRenderer(props: FormRendererProps): react.JSX.Element;
881
933
 
882
- export { BUILDER_TRANSLATION_ALIASES, BUILDER_TRANSLATION_KEYS, type BeforeSubmit, type BuilderActionContext, type BuilderActionError, type BuilderActionIconType, type BuilderActionResult, type BuilderButtonProps, type BuilderCheckboxProps, type BuilderErrorMessageProps, type BuilderFactories, type BuilderFieldEditorSlotProps, type BuilderFieldsetProps, type BuilderIconButtonProps, type BuilderIdKind, type BuilderLocalizationSlotProps, type BuilderOptionEditorSlotProps, type BuilderPagesSlotProps, type BuilderPolicy, type BuilderSectionProps, type BuilderSelectOption, type BuilderSelectProps, type BuilderSlotActions, type BuilderTextAreaProps, type BuilderTextInputProps, type BuilderTextTarget, type BuilderToolbarSlotProps, type BuilderTranslationActionsSlotProps, type BuilderTranslationKey, type ChoiceFieldLayoutMode, type ChoiceFieldTypeLayoutMap, type ChoiceGroupSlotProps, type ComponentBaseProps, type CustomLocaleValidator, type FieldComponentProps, type FieldComponents, type FieldEditorControlsConfig, type FieldEditorHeaderSlotProps, type FieldEditorMode, type FieldError, type FieldPropertyControlMode, type FieldState, type FieldTypeSelectOptionsConfig, type FieldTypeSelectOptionsContext, type FieldTypeSelectOptionsSorter, type FieldTypeSelectOptionsTransformer, type FieldTypeSelectSlotProps, FormBuilder, type FormBuilderActions, type FormBuilderComponents, type FormBuilderFeatures, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormBuilderSectionName, type FormBuilderSlots, type FormBuilderSubmissionSettingsOptions, type FormCompletionSlotProps, type FormContextValue, FormEngineI18nContext, type FormEngineI18nContextValue, FormEngineI18nProvider, type FormEngineI18nProviderProps, type FormFieldsSlotProps, FormProvider, type FormProviderProps, FormRenderer, type FormRendererAppearance, type FormRendererMessages, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlotProps, type FormRendererSlots, type FormServerErrorPayload, FormSubmissionError, type FormSubmitHandler, type FormSubmitState, type FormSubmitStatus, type FormSubmittedAnswerItem, type FormSuccessRenderMode, type IconButtonProps, type InputComponentProps, type LocaleValidationContext, type LocaleValidationResult, type LocalizationSummaryContext, type ManualTranslationContext, type ManualTranslationTarget, type RenderSubmitButtonProps, type SelectComponentProps, type StandaloneFormRendererProps, type SubmissionAttempt, type SubmissionAttemptStore, type SubmissionConfirmationOptions, type SubmissionConfirmationRenderMode, type SubmissionConfirmationSlotProps, type SubmissionGuard, type SubmissionGuardResult, type SubmissionProtectionProps, type SubmissionReceipt, type SubmissionReceiptQuery, type SubmissionReceiptStore, type SubmitContext, type SubmitResponse, type SubmitResult, type SubmitStatus, type TranslationSummary, type TranslationWorkspaceError, type UseFormBuilderOptions, type UseFormBuilderResult, type UseSubmissionReceiptsResult, type UseTranslationWorkspaceOptions, type UseTranslationWorkspaceResult, createLocalStorageSubmissionAttemptStore, createLocalStorageSubmissionReceiptStore, isTranslationUnresolved, resolveChoiceFieldLayout, resolveFieldEditorControls, resolveFieldTypeSelectOptions, resolveInitialFieldType, resolveTranslation, submissionReceiptQueryKey, useField, useForm, useFormBuilder, useFormEngineI18n, useSubmissionReceipts, useTranslationWorkspace, validateLocalePipeline };
934
+ export { BUILDER_TRANSLATION_ALIASES, BUILDER_TRANSLATION_KEYS, type BeforeSubmit, type BuilderActionContext, type BuilderActionError, type BuilderActionIconType, type BuilderActionResult, type BuilderButtonProps, type BuilderCheckboxProps, type BuilderErrorMessageProps, type BuilderFactories, type BuilderFieldEditorSlotProps, type BuilderFieldsetProps, type BuilderIconButtonProps, type BuilderIdKind, type BuilderLocalizationSlotProps, type BuilderOptionEditorSlotProps, type BuilderPagesSlotProps, type BuilderPolicy, type BuilderSectionProps, type BuilderSelectOption, type BuilderSelectProps, type BuilderSlotActions, type BuilderTextAreaProps, type BuilderTextInputProps, type BuilderTextTarget, type BuilderToolbarSlotProps, type BuilderTranslationActionsSlotProps, type BuilderTranslationKey, type ChoiceFieldLayoutMode, type ChoiceFieldTypeLayoutMap, type ChoiceGroupSlotProps, type ComponentBaseProps, type CustomLocaleValidator, type FieldComponentProps, type FieldComponents, type FieldEditorControlsConfig, type FieldEditorHeaderSlotProps, type FieldEditorMode, type FieldError, type FieldPropertyControlMode, type FieldState, type FieldTypeSelectOptionsConfig, type FieldTypeSelectOptionsContext, type FieldTypeSelectOptionsSorter, type FieldTypeSelectOptionsTransformer, type FieldTypeSelectSlotProps, FormBuilder, type FormBuilderActions, type FormBuilderComponents, type FormBuilderFeatures, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormBuilderSectionName, type FormBuilderSlots, type FormBuilderSubmissionSettingsOptions, type FormCompletionSlotProps, type FormContextValue, FormEngineI18nContext, type FormEngineI18nContextValue, FormEngineI18nProvider, type FormEngineI18nProviderProps, type FormFieldsSlotProps, FormProvider, type FormProviderProps, FormRenderer, type FormRendererAppearance, type FormRendererMessages, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlotProps, type FormRendererSlots, type FormServerErrorPayload, FormSubmissionError, type FormSubmitHandler, type FormSubmitState, type FormSubmitStatus, type FormSubmittedAnswerItem, type FormSuccessRenderMode, type IconButtonProps, type InputComponentProps, type LocaleSelectorProps, type LocaleValidationContext, type LocaleValidationResult, type LocalizationSummaryContext, type ManualTranslationContext, type ManualTranslationTarget, type RenderSubmitButtonProps, type SelectComponentProps, type StandaloneFormRendererProps, type SubmissionAttempt, type SubmissionAttemptStore, type SubmissionConfirmationOptions, type SubmissionConfirmationRenderMode, type SubmissionConfirmationSlotProps, type SubmissionGuard, type SubmissionGuardResult, type SubmissionProtectionProps, type SubmissionReceipt, type SubmissionReceiptQuery, type SubmissionReceiptStore, type SubmitContext, type SubmitResponse, type SubmitResult, type SubmitStatus, type TranslationSlotRowProps, type TranslationSummary, type TranslationWorkspaceActionsProps, type TranslationWorkspaceError, type TranslationWorkspaceHeaderProps, type TranslationWorkspaceSlots, type UseFormBuilderOptions, type UseFormBuilderResult, type UseSubmissionReceiptsResult, type UseTranslationWorkspaceOptions, type UseTranslationWorkspaceResult, createLocalStorageSubmissionAttemptStore, createLocalStorageSubmissionReceiptStore, isTranslationUnresolved, resolveChoiceFieldLayout, resolveFieldEditorControls, resolveFieldTypeSelectOptions, resolveInitialFieldType, resolveTranslation, submissionReceiptQueryKey, useField, useForm, useFormBuilder, useFormEngineI18n, useSubmissionReceipts, useTranslationWorkspace, validateLocalePipeline };
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
- import { QuestionType, FormField, ChoiceOption, FormPage, FormSchema, DisplayCondition, JsonValue, SchemaIssue, FormPolicy, Question, FieldOption, TranslationReport, ValidationIssue, ValidationError, FormValues, TranslationAdapter, AsyncTranslationAdapter, PopulateTranslationOptions, FormValue, AnswerValidationResult, TranslationSlot, FormEngineTranslator, FormEngineMessages, FieldType } from '@form-engine-ts/core';
1
+ import * as _form_engine_ts_core from '@form-engine-ts/core';
2
+ import { QuestionType, FormField, ChoiceOption, FormPage, FormSchema, DisplayCondition, JsonValue, SchemaIssue, FormPolicy, Question, FieldOption, TranslationReport, ValidationIssue, ValidationError, FormValues, LocaleOption, TranslationAdapter, AsyncTranslationAdapter, PopulateTranslationOptions, FormValue, AnswerValidationResult, TranslationSlot, FormEngineTranslator, FormEngineMessages, FieldType } from '@form-engine-ts/core';
2
3
  export { QuestionType } from '@form-engine-ts/core';
3
4
  import * as react from 'react';
4
5
  import { ReactNode, ComponentType, KeyboardEvent, MouseEvent, CSSProperties } from 'react';
@@ -379,6 +380,52 @@ interface BuilderLocalizationSlotProps extends BuilderSlotBaseProps {
379
380
  readonly policy?: FormPolicy;
380
381
  readonly translationAdapterAvailable?: boolean;
381
382
  }
383
+ interface TranslationWorkspaceHeaderProps {
384
+ readonly schema: FormSchema;
385
+ readonly sourceLocale: string;
386
+ readonly targetLocale: string;
387
+ readonly summary: {
388
+ readonly totalSlots: number;
389
+ readonly translatedCount: number;
390
+ readonly missingCount: number;
391
+ readonly staleCount: number;
392
+ readonly manualCount: number;
393
+ readonly completionPercentage: number;
394
+ };
395
+ readonly onTranslateAll: () => void;
396
+ readonly isTranslating: boolean;
397
+ readonly readOnly: boolean;
398
+ }
399
+ interface TranslationSlotRowProps {
400
+ readonly slot: _form_engine_ts_core.TranslationSlot;
401
+ readonly readOnly: boolean;
402
+ readonly onChange: (text: string) => void;
403
+ readonly onTranslate: () => void;
404
+ }
405
+ interface LocaleSelectorProps {
406
+ readonly targetLocale: string;
407
+ readonly targetLocales: readonly string[];
408
+ readonly localeOptions: readonly LocaleOption[];
409
+ readonly newLocale: string;
410
+ readonly readOnly: boolean;
411
+ readonly onTargetLocaleChange: (locale: string) => void;
412
+ readonly onNewLocaleChange: (locale: string) => void;
413
+ readonly onAddLocale: () => void;
414
+ }
415
+ interface TranslationWorkspaceActionsProps {
416
+ readonly onTranslateAll: () => void;
417
+ readonly isTranslating: boolean;
418
+ readonly readOnly: boolean;
419
+ }
420
+ interface TranslationWorkspaceSlots {
421
+ readonly renderHeader?: (props: TranslationWorkspaceHeaderProps) => ReactNode;
422
+ readonly renderSlotRow?: (props: TranslationSlotRowProps) => ReactNode;
423
+ readonly renderLocaleSelector?: (props: LocaleSelectorProps) => ReactNode;
424
+ readonly renderStatusBadge?: (props: {
425
+ readonly status: _form_engine_ts_core.TranslationStatus;
426
+ }) => ReactNode;
427
+ readonly renderActions?: (props: TranslationWorkspaceActionsProps) => ReactNode;
428
+ }
382
429
  interface LocalizationSummaryContext {
383
430
  readonly defaultLocale: string;
384
431
  readonly supportedLocales: readonly string[];
@@ -708,6 +755,10 @@ interface UseTranslationWorkspaceOptions {
708
755
  readonly translationAdapter?: TranslationAdapter | AsyncTranslationAdapter;
709
756
  readonly readOnly?: boolean;
710
757
  readonly policy?: FormPolicy;
758
+ readonly availableLocales?: readonly (string | LocaleOption)[];
759
+ readonly onLocaleAdded?: (locale: string) => void;
760
+ readonly onLocaleRemoved?: (locale: string) => void;
761
+ readonly onLocaleChange?: (targetLocale: string) => void;
711
762
  readonly beforeRemoveLocale?: (locale: string, context: {
712
763
  readonly slotCount: number;
713
764
  }) => Promise<boolean> | boolean;
@@ -766,6 +817,7 @@ interface UseTranslationWorkspaceResult {
766
817
  readonly sourceLocale: string;
767
818
  readonly targetLocale: string;
768
819
  readonly targetLocales: readonly string[];
820
+ readonly localeOptions: readonly LocaleOption[];
769
821
  readonly setTargetLocale: (locale: string) => void;
770
822
  readonly slots: readonly TranslationSlot[];
771
823
  readonly summary: TranslationSummary;
@@ -788,8 +840,8 @@ interface UseTranslationWorkspaceResult {
788
840
  readonly isTranslating: boolean;
789
841
  readonly error?: TranslationWorkspaceError;
790
842
  }
791
- declare const validateLocalePipeline: (locale: string, schema: FormSchema, policy?: FormPolicy, customValidator?: ((locale: string, currentLocales: readonly string[]) => LocaleValidationResult) | CustomLocaleValidator) => LocaleValidationResult;
792
- declare function useTranslationWorkspace({ schema, onChange, sourceLocale, targetLocale, translationAdapter, readOnly, policy, beforeRemoveLocale, validateLocale }: UseTranslationWorkspaceOptions): UseTranslationWorkspaceResult;
843
+ declare const validateLocalePipeline: (locale: string, schema: FormSchema, policy?: FormPolicy, customValidator?: ((locale: string, currentLocales: readonly string[]) => LocaleValidationResult) | CustomLocaleValidator, availableLocales?: readonly (string | LocaleOption)[]) => LocaleValidationResult;
844
+ declare function useTranslationWorkspace({ schema, onChange, sourceLocale, targetLocale, translationAdapter, readOnly, policy, availableLocales, onLocaleAdded, onLocaleRemoved, onLocaleChange, beforeRemoveLocale, validateLocale }: UseTranslationWorkspaceOptions): UseTranslationWorkspaceResult;
793
845
 
794
846
  declare const BUILDER_TRANSLATION_KEYS: {
795
847
  readonly ADD_FIELD: "builder.actions.addField";
@@ -879,4 +931,4 @@ interface StandaloneFormRendererProps extends FormRendererPresentationProps {
879
931
  type FormRendererProps = FormRendererPresentationProps | StandaloneFormRendererProps;
880
932
  declare function FormRenderer(props: FormRendererProps): react.JSX.Element;
881
933
 
882
- export { BUILDER_TRANSLATION_ALIASES, BUILDER_TRANSLATION_KEYS, type BeforeSubmit, type BuilderActionContext, type BuilderActionError, type BuilderActionIconType, type BuilderActionResult, type BuilderButtonProps, type BuilderCheckboxProps, type BuilderErrorMessageProps, type BuilderFactories, type BuilderFieldEditorSlotProps, type BuilderFieldsetProps, type BuilderIconButtonProps, type BuilderIdKind, type BuilderLocalizationSlotProps, type BuilderOptionEditorSlotProps, type BuilderPagesSlotProps, type BuilderPolicy, type BuilderSectionProps, type BuilderSelectOption, type BuilderSelectProps, type BuilderSlotActions, type BuilderTextAreaProps, type BuilderTextInputProps, type BuilderTextTarget, type BuilderToolbarSlotProps, type BuilderTranslationActionsSlotProps, type BuilderTranslationKey, type ChoiceFieldLayoutMode, type ChoiceFieldTypeLayoutMap, type ChoiceGroupSlotProps, type ComponentBaseProps, type CustomLocaleValidator, type FieldComponentProps, type FieldComponents, type FieldEditorControlsConfig, type FieldEditorHeaderSlotProps, type FieldEditorMode, type FieldError, type FieldPropertyControlMode, type FieldState, type FieldTypeSelectOptionsConfig, type FieldTypeSelectOptionsContext, type FieldTypeSelectOptionsSorter, type FieldTypeSelectOptionsTransformer, type FieldTypeSelectSlotProps, FormBuilder, type FormBuilderActions, type FormBuilderComponents, type FormBuilderFeatures, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormBuilderSectionName, type FormBuilderSlots, type FormBuilderSubmissionSettingsOptions, type FormCompletionSlotProps, type FormContextValue, FormEngineI18nContext, type FormEngineI18nContextValue, FormEngineI18nProvider, type FormEngineI18nProviderProps, type FormFieldsSlotProps, FormProvider, type FormProviderProps, FormRenderer, type FormRendererAppearance, type FormRendererMessages, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlotProps, type FormRendererSlots, type FormServerErrorPayload, FormSubmissionError, type FormSubmitHandler, type FormSubmitState, type FormSubmitStatus, type FormSubmittedAnswerItem, type FormSuccessRenderMode, type IconButtonProps, type InputComponentProps, type LocaleValidationContext, type LocaleValidationResult, type LocalizationSummaryContext, type ManualTranslationContext, type ManualTranslationTarget, type RenderSubmitButtonProps, type SelectComponentProps, type StandaloneFormRendererProps, type SubmissionAttempt, type SubmissionAttemptStore, type SubmissionConfirmationOptions, type SubmissionConfirmationRenderMode, type SubmissionConfirmationSlotProps, type SubmissionGuard, type SubmissionGuardResult, type SubmissionProtectionProps, type SubmissionReceipt, type SubmissionReceiptQuery, type SubmissionReceiptStore, type SubmitContext, type SubmitResponse, type SubmitResult, type SubmitStatus, type TranslationSummary, type TranslationWorkspaceError, type UseFormBuilderOptions, type UseFormBuilderResult, type UseSubmissionReceiptsResult, type UseTranslationWorkspaceOptions, type UseTranslationWorkspaceResult, createLocalStorageSubmissionAttemptStore, createLocalStorageSubmissionReceiptStore, isTranslationUnresolved, resolveChoiceFieldLayout, resolveFieldEditorControls, resolveFieldTypeSelectOptions, resolveInitialFieldType, resolveTranslation, submissionReceiptQueryKey, useField, useForm, useFormBuilder, useFormEngineI18n, useSubmissionReceipts, useTranslationWorkspace, validateLocalePipeline };
934
+ export { BUILDER_TRANSLATION_ALIASES, BUILDER_TRANSLATION_KEYS, type BeforeSubmit, type BuilderActionContext, type BuilderActionError, type BuilderActionIconType, type BuilderActionResult, type BuilderButtonProps, type BuilderCheckboxProps, type BuilderErrorMessageProps, type BuilderFactories, type BuilderFieldEditorSlotProps, type BuilderFieldsetProps, type BuilderIconButtonProps, type BuilderIdKind, type BuilderLocalizationSlotProps, type BuilderOptionEditorSlotProps, type BuilderPagesSlotProps, type BuilderPolicy, type BuilderSectionProps, type BuilderSelectOption, type BuilderSelectProps, type BuilderSlotActions, type BuilderTextAreaProps, type BuilderTextInputProps, type BuilderTextTarget, type BuilderToolbarSlotProps, type BuilderTranslationActionsSlotProps, type BuilderTranslationKey, type ChoiceFieldLayoutMode, type ChoiceFieldTypeLayoutMap, type ChoiceGroupSlotProps, type ComponentBaseProps, type CustomLocaleValidator, type FieldComponentProps, type FieldComponents, type FieldEditorControlsConfig, type FieldEditorHeaderSlotProps, type FieldEditorMode, type FieldError, type FieldPropertyControlMode, type FieldState, type FieldTypeSelectOptionsConfig, type FieldTypeSelectOptionsContext, type FieldTypeSelectOptionsSorter, type FieldTypeSelectOptionsTransformer, type FieldTypeSelectSlotProps, FormBuilder, type FormBuilderActions, type FormBuilderComponents, type FormBuilderFeatures, type FormBuilderOptions, type FormBuilderProps, type FormBuilderResult, type FormBuilderSectionName, type FormBuilderSlots, type FormBuilderSubmissionSettingsOptions, type FormCompletionSlotProps, type FormContextValue, FormEngineI18nContext, type FormEngineI18nContextValue, FormEngineI18nProvider, type FormEngineI18nProviderProps, type FormFieldsSlotProps, FormProvider, type FormProviderProps, FormRenderer, type FormRendererAppearance, type FormRendererMessages, type FormRendererPresentationProps, type FormRendererProps, type FormRendererSlotProps, type FormRendererSlots, type FormServerErrorPayload, FormSubmissionError, type FormSubmitHandler, type FormSubmitState, type FormSubmitStatus, type FormSubmittedAnswerItem, type FormSuccessRenderMode, type IconButtonProps, type InputComponentProps, type LocaleSelectorProps, type LocaleValidationContext, type LocaleValidationResult, type LocalizationSummaryContext, type ManualTranslationContext, type ManualTranslationTarget, type RenderSubmitButtonProps, type SelectComponentProps, type StandaloneFormRendererProps, type SubmissionAttempt, type SubmissionAttemptStore, type SubmissionConfirmationOptions, type SubmissionConfirmationRenderMode, type SubmissionConfirmationSlotProps, type SubmissionGuard, type SubmissionGuardResult, type SubmissionProtectionProps, type SubmissionReceipt, type SubmissionReceiptQuery, type SubmissionReceiptStore, type SubmitContext, type SubmitResponse, type SubmitResult, type SubmitStatus, type TranslationSlotRowProps, type TranslationSummary, type TranslationWorkspaceActionsProps, type TranslationWorkspaceError, type TranslationWorkspaceHeaderProps, type TranslationWorkspaceSlots, type UseFormBuilderOptions, type UseFormBuilderResult, type UseSubmissionReceiptsResult, type UseTranslationWorkspaceOptions, type UseTranslationWorkspaceResult, createLocalStorageSubmissionAttemptStore, createLocalStorageSubmissionReceiptStore, isTranslationUnresolved, resolveChoiceFieldLayout, resolveFieldEditorControls, resolveFieldTypeSelectOptions, resolveInitialFieldType, resolveTranslation, submissionReceiptQueryKey, useField, useForm, useFormBuilder, useFormEngineI18n, useSubmissionReceipts, useTranslationWorkspace, validateLocalePipeline };
package/dist/index.js CHANGED
@@ -3298,7 +3298,7 @@ function asAsyncAdapter(adapter) {
3298
3298
  )
3299
3299
  };
3300
3300
  }
3301
- var validateLocalePipeline = (locale, schema, policy, customValidator) => {
3301
+ var validateLocalePipeline = (locale, schema, policy, customValidator, availableLocales) => {
3302
3302
  const canonicalLocale = normalizeLocale(locale);
3303
3303
  if (canonicalLocale === null) {
3304
3304
  return {
@@ -3311,6 +3311,18 @@ var validateLocalePipeline = (locale, schema, policy, customValidator) => {
3311
3311
  }
3312
3312
  const currentLocales = (schema.supportedLocales ?? []).map((candidate) => normalizeLocale(candidate) ?? candidate);
3313
3313
  const defaultLocale = schema.defaultLocale === void 0 ? "" : normalizeLocale(schema.defaultLocale) ?? schema.defaultLocale;
3314
+ if (availableLocales !== void 0 && !availableLocales.some((candidate) => {
3315
+ const value = typeof candidate === "string" ? candidate : candidate.locale;
3316
+ return normalizeLocale(value) === canonicalLocale;
3317
+ })) {
3318
+ return {
3319
+ valid: false,
3320
+ error: {
3321
+ type: "locale_not_allowed",
3322
+ message: `Locale "${canonicalLocale}" is not available in the locale catalog.`
3323
+ }
3324
+ };
3325
+ }
3314
3326
  if (canonicalLocale === defaultLocale || currentLocales.includes(canonicalLocale)) {
3315
3327
  return {
3316
3328
  valid: false,
@@ -3451,11 +3463,15 @@ function useTranslationWorkspace({
3451
3463
  translationAdapter,
3452
3464
  readOnly = false,
3453
3465
  policy,
3466
+ availableLocales,
3467
+ onLocaleAdded,
3468
+ onLocaleRemoved,
3469
+ onLocaleChange,
3454
3470
  beforeRemoveLocale,
3455
3471
  validateLocale
3456
3472
  }) {
3457
3473
  const [draftSchema, setDraftSchema] = useState4(schema);
3458
- const [selectedLocale, setSelectedLocale] = useState4(targetLocale ?? "");
3474
+ const [selectedLocale, setSelectedLocale] = useState4(normalizeLocale(targetLocale ?? "") ?? targetLocale ?? "");
3459
3475
  const [isTranslating, setIsTranslating] = useState4(false);
3460
3476
  const [error, setError] = useState4();
3461
3477
  const currentSchema = onChange === void 0 ? draftSchema : schema;
@@ -3466,6 +3482,15 @@ function useTranslationWorkspace({
3466
3482
  );
3467
3483
  }, [currentSchema, sourceLocale]);
3468
3484
  const activeLocale = selectedLocale.length > 0 ? selectedLocale : targetLocales[0] ?? "";
3485
+ const localeOptions = useMemo4(() => {
3486
+ if (availableLocales === void 0) {
3487
+ return targetLocales.map((locale) => ({ locale, label: locale }));
3488
+ }
3489
+ return availableLocales.map((candidate) => {
3490
+ if (typeof candidate !== "string") return candidate;
3491
+ return { locale: normalizeLocale(candidate) ?? candidate, label: candidate };
3492
+ });
3493
+ }, [availableLocales, targetLocales]);
3469
3494
  const slots = useMemo4(
3470
3495
  () => activeLocale.length === 0 ? [] : collectTranslationSlots(currentSchema, activeLocale),
3471
3496
  [activeLocale, currentSchema]
@@ -3513,14 +3538,14 @@ function useTranslationWorkspace({
3513
3538
  const normalized = normalizeLocale(locale);
3514
3539
  if (normalized === null) {
3515
3540
  const workspaceError = workspaceLocaleValidationError(
3516
- validateLocalePipeline(locale, currentSchema, policy, validateLocale),
3541
+ validateLocalePipeline(locale, currentSchema, policy, validateLocale, availableLocales),
3517
3542
  collectSchemaLocales2(currentSchema).allUniqueLocales.size,
3518
3543
  locale
3519
3544
  );
3520
3545
  setError(workspaceError);
3521
3546
  return { success: false, error: workspaceError };
3522
3547
  }
3523
- const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale);
3548
+ const validation = validateLocalePipeline(normalized, currentSchema, policy, validateLocale, availableLocales);
3524
3549
  if (!validation.valid) {
3525
3550
  const workspaceError = workspaceLocaleValidationError(
3526
3551
  validation,
@@ -3536,33 +3561,38 @@ function useTranslationWorkspace({
3536
3561
  supportedLocales: [.../* @__PURE__ */ new Set([...currentSchema.supportedLocales ?? [], normalized])]
3537
3562
  });
3538
3563
  setSelectedLocale(normalized);
3564
+ onLocaleAdded?.(normalized);
3539
3565
  return { success: true };
3540
3566
  },
3541
- [commit, currentSchema, policy, readOnly, validateLocale]
3567
+ [availableLocales, commit, currentSchema, onLocaleAdded, policy, readOnly, validateLocale]
3542
3568
  );
3543
3569
  const isAddLocaleAllowed = useCallback3(
3544
3570
  (locale) => {
3545
3571
  if (readOnly) return false;
3546
3572
  const normalized = normalizeLocale(locale);
3547
3573
  if (normalized === null) return false;
3548
- return validateLocalePipeline(normalized, currentSchema, policy, validateLocale).valid;
3574
+ return validateLocalePipeline(normalized, currentSchema, policy, validateLocale, availableLocales).valid;
3549
3575
  },
3550
- [currentSchema, policy, readOnly, validateLocale]
3576
+ [availableLocales, currentSchema, policy, readOnly, validateLocale]
3551
3577
  );
3552
3578
  const removeLocale = useCallback3(
3553
3579
  (locale) => {
3554
- if (readOnly || locale === sourceLocale || locale === currentSchema.defaultLocale) return false;
3580
+ const normalized = normalizeLocale(locale) ?? locale;
3581
+ const normalizedSourceLocale = normalizeLocale(sourceLocale) ?? sourceLocale;
3582
+ const normalizedDefaultLocale = currentSchema.defaultLocale === void 0 ? void 0 : normalizeLocale(currentSchema.defaultLocale) ?? currentSchema.defaultLocale;
3583
+ if (readOnly || normalized === normalizedSourceLocale || normalized === normalizedDefaultLocale) return false;
3555
3584
  const remove = () => {
3556
- commit(removeLocaleFromSchema(currentSchema, locale));
3557
- if (activeLocale === locale) setSelectedLocale("");
3585
+ commit(removeLocaleFromSchema(currentSchema, normalized));
3586
+ if (activeLocale === normalized) setSelectedLocale("");
3587
+ onLocaleRemoved?.(normalized);
3558
3588
  };
3559
- const slotCount = collectTranslationSlots(currentSchema, locale).length;
3589
+ const slotCount = collectTranslationSlots(currentSchema, normalized).length;
3560
3590
  if (beforeRemoveLocale === void 0) {
3561
3591
  remove();
3562
3592
  return true;
3563
3593
  }
3564
3594
  try {
3565
- const decision = beforeRemoveLocale(locale, { slotCount });
3595
+ const decision = beforeRemoveLocale(normalized, { slotCount });
3566
3596
  if (typeof decision === "boolean") {
3567
3597
  if (!decision) return false;
3568
3598
  remove();
@@ -3583,7 +3613,7 @@ function useTranslationWorkspace({
3583
3613
  return Promise.reject(cause);
3584
3614
  }
3585
3615
  },
3586
- [activeLocale, beforeRemoveLocale, commit, currentSchema, readOnly, sourceLocale]
3616
+ [activeLocale, beforeRemoveLocale, commit, currentSchema, onLocaleRemoved, readOnly, sourceLocale]
3587
3617
  );
3588
3618
  const translateAll = useCallback3(
3589
3619
  async (options = {}) => {
@@ -3602,6 +3632,23 @@ function useTranslationWorkspace({
3602
3632
  setError(workspaceError);
3603
3633
  return { success: false, error: workspaceError };
3604
3634
  }
3635
+ const selectedLocaleOption = localeOptions.find(
3636
+ (option) => (normalizeLocale(option.locale) ?? option.locale) === activeLocale
3637
+ );
3638
+ if (selectedLocaleOption?.translatable === false) {
3639
+ setError(void 0);
3640
+ return {
3641
+ success: true,
3642
+ report: {
3643
+ updatedSlots: [],
3644
+ skippedSlots: slots,
3645
+ staleSlots: [],
3646
+ skippedReasons: Object.fromEntries(
3647
+ slots.map((slot) => [slot.path ?? `${slot.kind}.${slot.nodeId}.${slot.property}`, "unsupported"])
3648
+ )
3649
+ }
3650
+ };
3651
+ }
3605
3652
  setIsTranslating(true);
3606
3653
  setError(void 0);
3607
3654
  try {
@@ -3629,7 +3676,7 @@ function useTranslationWorkspace({
3629
3676
  setIsTranslating(false);
3630
3677
  }
3631
3678
  },
3632
- [activeLocale, commit, currentSchema, readOnly, translationAdapter]
3679
+ [activeLocale, commit, currentSchema, localeOptions, readOnly, slots, translationAdapter]
3633
3680
  );
3634
3681
  const translateSlot = useCallback3(
3635
3682
  async (slot) => {
@@ -3667,7 +3714,12 @@ function useTranslationWorkspace({
3667
3714
  sourceLocale,
3668
3715
  targetLocale: activeLocale,
3669
3716
  targetLocales,
3670
- setTargetLocale: setSelectedLocale,
3717
+ localeOptions,
3718
+ setTargetLocale: (locale) => {
3719
+ const normalized = normalizeLocale(locale) ?? locale;
3720
+ setSelectedLocale(normalized);
3721
+ onLocaleChange?.(normalized);
3722
+ },
3671
3723
  slots,
3672
3724
  summary,
3673
3725
  addLocale,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@form-engine-ts/react",
3
- "version": "5.0.1",
3
+ "version": "5.1.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -42,8 +42,8 @@
42
42
  "typescript"
43
43
  ],
44
44
  "dependencies": {
45
- "@form-engine-ts/core": "5.0.1",
46
- "@form-engine-ts/privacy": "5.0.1"
45
+ "@form-engine-ts/core": "5.1.0",
46
+ "@form-engine-ts/privacy": "5.1.0"
47
47
  },
48
48
  "peerDependencies": {
49
49
  "react": ">=18.2 <20",