feat(composables/i18n): add signal-based translation library#4
Open
feat(composables/i18n): add signal-based translation library#4
Conversation
Adds a new `@homj/composables/i18n` secondary entry point that provides
a signal-based i18n system backed by Angular's resource API.
Key features:
- `provideTranslation(loader?)` — registers the global translation store
and optional global loader at environment level
- `provideTranslationScope(scope, loader)` — registers a local scope loader
at component level; the resource is created lazily in the store
- `useTranslation()` — returns a reactive `TranslateFn` that reads from
signal-backed resources; falls back to the key while loading
- Translation keys follow the format `'key'` (global) or `'scope:key'`
(scoped, e.g. `'my-component:foo'`)
- `{{ paramName }}` placeholder interpolation via optional params argument
- Each scope is backed by a single `resource()` instance; subsequent calls
to `ensureScope` with the same scope are no-ops
https://claude.ai/code/session_017w3dyuKpzdFHjg7ng5SeJD
- Extend @homj/composables/i18n with CURRENT_LANGUAGE signal token so any component can switch the active language reactively; all resource scopes reload automatically via the resource request signal - Change TranslationLoader signature to (lang: string) => Promise<TranslationData> so loaders can serve the correct language file - Add defaultLang parameter to provideTranslation (defaults to 'en') - Export CURRENT_LANGUAGE from public API - Update specs to provide CURRENT_LANGUAGE in TestBed and use the new loader signature; add a language-switching integration test - Refactor AppComponent to a shell (header nav + router-outlet); extract ButtonsDemoComponent for the existing button demo - Add /i18n route with I18nDemoComponent that demonstrates: * Global scope translations (EN/DE, with interpolation) * Custom scope via ScopedDemoComponent (user-card scope) * Lazy-loaded scope via LazyDemoComponent inside @defer (on interaction) * Error / fallback cases for missing key and unknown scope * Language switcher button (EN / DE) wired to CURRENT_LANGUAGE https://claude.ai/code/session_017w3dyuKpzdFHjg7ng5SeJD
Introduce a TranslationParser type and TRANSLATION_PARSER injection token
so the string-formatting step can be swapped out per application.
Built-in parsers
- interpolationParser (default, no extra deps) — replaces {{ name }}
placeholders; extracted from the store so it is independently testable
- withMessageFormat(MessageFormatCtor) — factory that wraps any
MessageFormat-compatible library (e.g. @messageformat/core) with
per-language compiler instances and a lang+pattern cache
API changes
- provideTranslation() gains an optional third parameter `parser`
(defaults to interpolationParser, fully backward-compatible)
- TRANSLATION_PARSER token is exported so advanced setups can provide
a parser directly via DI
- TranslationParser and MessageFormatLike types are exported from the
public API
TranslationStore now injects TRANSLATION_PARSER (optional, falls back to
interpolationParser) and passes (pattern, lang, params) to the parser on
every translate() call when params are present.
https://claude.ai/code/session_017w3dyuKpzdFHjg7ng5SeJD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a new
@homj/composables/i18nsecondary entry point that providesa signal-based i18n system backed by Angular's resource API.
Key features:
provideTranslation(loader?)— registers the global translation storeand optional global loader at environment level
provideTranslationScope(scope, loader)— registers a local scope loaderat component level; the resource is created lazily in the store
useTranslation()— returns a reactiveTranslateFnthat reads fromsignal-backed resources; falls back to the key while loading
'key'(global) or'scope:key'(scoped, e.g.
'my-component:foo'){{ paramName }}placeholder interpolation via optional params argumentresource()instance; subsequent callsto
ensureScopewith the same scope are no-opshttps://claude.ai/code/session_017w3dyuKpzdFHjg7ng5SeJD