Initial Commit
This commit is contained in:
75
apps/testbed/src/client/pages/i18n/i18n-page.md
Normal file
75
apps/testbed/src/client/pages/i18n/i18n-page.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# I18nPage
|
||||
|
||||
<!-- begin:auto-docs -->
|
||||
_(no submodules)_
|
||||
<!-- end:auto-docs -->## Purpose
|
||||
|
||||
The `I18nPage` demonstrates the `@suaveplan/i18n` package's `MessageCatalog` and `PluralizationEngine` classes. It allows users to switch between four locales (English, French, German, Japanese) and adjust an item count to see how plural forms change per locale. The greeting message also switches locale to show the full translation catalog in action.
|
||||
|
||||
## Features
|
||||
|
||||
- `MessageCatalog` seeded with four locales: English, French, German, Japanese
|
||||
- `PluralizationEngine.resolve()` picks zero/one/other plural forms per locale
|
||||
- Item counter (+ and –) drives pluralization, starting at 1
|
||||
- Greeting message switches locale together with the plural form
|
||||
- `{n}` placeholder in plural templates is replaced with the live count
|
||||
- All required `data-testid` attributes for Playwright E2E testing
|
||||
- `data-testid="locale-select"` dropdown for Playwright locale-switching tests
|
||||
- Derived state memoised with `useMemo` to avoid unnecessary recalculation
|
||||
|
||||
## Usage: Basic Example
|
||||
|
||||
```tsx
|
||||
import React from "react";
|
||||
import { I18nPage } from "./i18n-page.js";
|
||||
|
||||
export function App() {
|
||||
return <I18nPage />;
|
||||
}
|
||||
```
|
||||
|
||||
## Usage: Advanced Example
|
||||
|
||||
You can extend the catalog with additional locales at runtime using `catalog.addMessages`:
|
||||
|
||||
```ts
|
||||
import { MessageCatalog, PluralizationEngine } from "@suaveplan/i18n";
|
||||
|
||||
const catalog = new MessageCatalog({
|
||||
defaultLocale: "en",
|
||||
messages: {
|
||||
en: { items_one: "1 item", items_other: "{n} items" },
|
||||
es: { items_one: "1 artículo", items_other: "{n} artículos" },
|
||||
},
|
||||
});
|
||||
|
||||
catalog.setLocale("es");
|
||||
const engine = new PluralizationEngine();
|
||||
const result = engine.resolve(3, { one: catalog.t("items_one"), other: catalog.t("items_other") }, { locale: "es" });
|
||||
console.log(result.message); // "3 artículos" (after {n} replacement)
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### `I18nPage(): React.JSX.Element`
|
||||
|
||||
No props.
|
||||
|
||||
**data-testid attributes:**
|
||||
|
||||
- `page-title` — the `<h1>` heading
|
||||
- `demo-card` — wraps the locale selector, counter, and output
|
||||
- `locale-select` — the locale dropdown (`<select>`)
|
||||
- `output` — displays the resolved plural message for the current count and locale
|
||||
- `console-panel` — bottom console section with implementation notes
|
||||
|
||||
**Interactive elements:**
|
||||
|
||||
- Locale select dropdown — switches `catalog.setLocale()` and re-derives messages
|
||||
- – button — decrements count (floor 0)
|
||||
- - button — increments count
|
||||
- Count display — shows the current integer
|
||||
|
||||
## Implementation Notes
|
||||
|
||||
The `MessageCatalog` and `PluralizationEngine` instances are created outside the component to avoid re-instantiation on every render. `catalog.setLocale()` is called inside the `useMemo` callback to keep the active locale in sync with React state. `PluralizationEngine.resolve()` takes a `PluralMessages` object (`{ zero?, one?, other? }`) and locale options (`{ locale: string }`). The `{n}` placeholder is replaced with a `String(count)` substitution after resolution, since the engine resolves the message template but does not perform interpolation itself.
|
||||
Reference in New Issue
Block a user