diff --git a/CHANGELOG.md b/CHANGELOG.md index 31916d97..6c315207 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this p * Auto-collapse items after resize if the final size is less than `minSize` for that item; * Prevent toggle buttons on `WorkspaceLayoutRow` children from being partially hidden when corresponding item is collapsed. - Export `TranslationProvider` and `DefaultTranslation` to be able to use `useTranslation()` outside the workspace component: + * Export default (fallback) bundle for `en` language: `DefaultTranslationBundle`. * Remove deprecated `Translation.formatIri()` method (use `DataLocaleProvider.formatIri()` instead). - Extend `CommandBatch.discard()` to accept `revert` option to be able to revert the batch without storing it first. - Always display ungroup buttons on `StandardGroup` when the element is single-selected. diff --git a/examples/i18n.tsx b/examples/i18n.tsx index ac56494d..d1c6d99b 100644 --- a/examples/i18n.tsx +++ b/examples/i18n.tsx @@ -38,7 +38,8 @@ function I18nExample() { 'toolbar_action': { 'layout.label': 'Layout the graph', }, - } + }, + Reactodia.DefaultTranslationBundle, ], }), defaultLayout, diff --git a/src/diagram/locale.tsx b/src/diagram/locale.tsx index 145e0429..0cd44fac 100644 --- a/src/diagram/locale.tsx +++ b/src/diagram/locale.tsx @@ -8,33 +8,33 @@ import { import * as Rdf from '../data/rdf/rdfModel'; +/** + * Default (fallback) translation bundle `en` language. + * + * @category Constants + */ export const DefaultTranslationBundle: TranslationBundle = DefaultBundle; /** * Default built-in implementation for i18n strings interpolation and other * methods from {@link Translation} interface. + * + * @category Core */ -export class DefaultTranslation implements Translation { +export class DefaultTranslation implements Translation { protected readonly bundles: ReadonlyArray>; private readonly _selectLabel: LabelLanguageSelector; constructor(options?: { /** - * Additional translation bundles for UI text strings in the workspace + * Translation bundles for UI text strings in the workspace * in order from higher to lower priority. * * @default [] - * @see {@link useDefaultTranslation} + * @see {@link DefaultTranslationBundle} */ bundles?: ReadonlyArray>; - /** - * If set, disables translation fallback which (with default `en` language). - * - * @default true - * @see {@link translations} - */ - useDefaultBundle?: boolean; /** * Overrides how a single label gets selected from multiple of them based on target language. */ @@ -42,18 +42,13 @@ export class DefaultTranslation implements Translation { }) { const { bundles = [], - useDefaultBundle = true, selectLabel = defaultSelectLabel, } = options ?? {}; - const translationBundles: Partial[] = [...bundles]; - if (useDefaultBundle) { - translationBundles.push(DefaultTranslationBundle); - } - this.bundles = translationBundles; + this.bundles = bundles; this._selectLabel = selectLabel; } - private getString(key: TranslationKey): string | undefined { + private getString(key: K): string | undefined { const dotIndex = key.indexOf('.'); if (!(dotIndex > 0 && dotIndex < key.length)) { throw new Error(`Reactodia: Invalid translation key: ${key}`); @@ -69,12 +64,12 @@ export class DefaultTranslation implements Translation { return undefined; } - text(key: TranslationKey, placeholders?: Record): string { + text(key: K, placeholders?: Record): string { return this.textOptional(key, placeholders) ?? key; } textOptional( - key: TranslationKey, + key: K, placeholders?: Record ): string | undefined { const template = this.getString(key); @@ -84,7 +79,7 @@ export class DefaultTranslation implements Translation { return formatPlaceholders(template, placeholders); } - template(key: TranslationKey, parts: Record): React.ReactNode { + template(key: K, parts: Record): React.ReactNode { const template = this.getString(key) ?? key; return templatePlaceholders(template, parts); } diff --git a/src/workspace.ts b/src/workspace.ts index 3a660404..bc1a176e 100644 --- a/src/workspace.ts +++ b/src/workspace.ts @@ -102,7 +102,7 @@ export { LinkVertices, type LinkVerticesProps, } from './diagram/linkLayer'; export { DefaultLinkRouter, type DefaultLinkRouterOptions } from './diagram/linkRouter'; -export { DefaultTranslation } from './diagram/locale'; +export { DefaultTranslation, DefaultTranslationBundle } from './diagram/locale'; export { type DiagramModel, type DiagramModelEvents, type GraphStructure } from './diagram/model'; export { CanvasPlaceAt, type CanvasPlaceAtLayer } from './diagram/placeLayer'; export { diff --git a/src/workspace/workspaceProvider.tsx b/src/workspace/workspaceProvider.tsx index e5dc0982..4dcf0545 100644 --- a/src/workspace/workspaceProvider.tsx +++ b/src/workspace/workspaceProvider.tsx @@ -18,7 +18,7 @@ import { CommandHistory, InMemoryHistory } from '../diagram/history'; import { CalculatedLayout, LayoutFunction, LayoutTypeProvider, calculateLayout, applyLayout, } from '../diagram/layout'; -import { DefaultTranslation } from '../diagram/locale'; +import { DefaultTranslation, DefaultTranslationBundle } from '../diagram/locale'; import { RenameLinkToLinkStateProvider, SharedCanvasState } from '../diagram/sharedCanvasState'; import { AnnotationElement, AnnotationLink } from '../editor/annotationCells'; @@ -52,7 +52,8 @@ export interface CreateWorkspaceParams { /** * Overrides default i18n (translation) implementation. * - * By default, {@link DefaultTranslation} instance is used. + * By default, {@link DefaultTranslation} instance with a single + * {@link DefaultTranslationBundle} is used. */ translation?: Translation; /** @@ -224,7 +225,9 @@ class RefCountedWorkspaceContext implements WorkspaceContext { constructor(params: CreateWorkspaceParams) { const { - translation = new DefaultTranslation(), + translation = new DefaultTranslation({ + bundles: [DefaultTranslationBundle], + }), history = new InMemoryHistory(), dialogSettingsProvider = new DefaultDialogSettingsProvider(), metadataProvider, diff --git a/src/workspace/workspaceWrapper.tsx b/src/workspace/workspaceWrapper.tsx index 175a9a6c..087fe36f 100644 --- a/src/workspace/workspaceWrapper.tsx +++ b/src/workspace/workspaceWrapper.tsx @@ -12,7 +12,7 @@ import { TypeStyleResolver, RenameLinkProvider } from '../diagram/customization' import { Element } from '../diagram/elements'; import { CommandHistory, InMemoryHistory } from '../diagram/history'; import { LayoutFunction } from '../diagram/layout'; -import { DefaultTranslation } from '../diagram/locale'; +import { DefaultTranslation, DefaultTranslationBundle } from '../diagram/locale'; import { EntityElement } from '../editor/dataElements'; import { @@ -151,10 +151,13 @@ export class Workspace extends React.Component { onWorkspaceEvent, } = this.props; + let bundles = translations; + if (useDefaultTranslation) { + bundles = [...translations, DefaultTranslationBundle]; + } this._workspace = createWorkspace({ translation: this.context ?? new DefaultTranslation({ - bundles: translations, - useDefaultBundle: useDefaultTranslation, + bundles, selectLabel: selectLabelLanguage, }), history,