From 707d692b5b6c4a845c4948bbc4a2afc11224aeae Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 6 Sep 2026 06:47:01 +0000 Subject: [PATCH] docs(i18n): compile the i18n README's 8 blocks and drop its ledger entry Every ts/tsx fence in packages/i18n/README.md now compiles --strict against the built dist/*.d.ts, so its UNGATED_DOCS entry in scripts/check-doc-snippet-types.mjs is removed (22 -> 21 entries; removals only, nothing else in that file changed). The 11 measured diagnostics decomposed into 7 TS2304 fragment-shape names and 4 real API drift. The formatting block documented a positional signature the package has never shipped: formatDate/formatCurrency/formatNumber take an options object second (DateFormatOptions / CurrencyFormatOptions / NumberFormatOptions), and formatRelativeTime takes (date, locale) and derives the unit itself -- so formatCurrency(99.99, 'USD', 'en') and formatRelativeTime(-3, 'days', 'en') were both uncopyable as written. Every replacement call was executed against the built package and its output comment is the real string. The three fragment blocks gain real imports plus `declare const` placeholders typed to the shipped surface, matching the existing spelling in packages/app-shell/README.md; the useObjectTranslation block now shows the hook inside a component rather than at module top level. No packages/** source is touched, no public type widened, no gate loosened, and no new FRAGMENT_MARKER declared -- all 8 blocks earn coverage by compiling. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_01MM7kaS4dPpYHV5BsMyu4tQ --- packages/i18n/README.md | 42 ++++++++++++++++++++++++----- scripts/check-doc-snippet-types.mjs | 2 -- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/packages/i18n/README.md b/packages/i18n/README.md index 79757ff7df..c7a901422b 100644 --- a/packages/i18n/README.md +++ b/packages/i18n/README.md @@ -55,9 +55,15 @@ function MyComponent() { Wraps your application with i18n context: ```tsx +import type { ReactNode } from 'react'; +import { I18nProvider } from '@object-ui/i18n'; + +// Your app supplies the tree being wrapped. +declare const App: () => ReactNode; + - +; ``` #### Language persistence @@ -75,11 +81,16 @@ app no longer offers (not a built-in pack, not in `config.resources`) is ignored translations. ```tsx +import type { ReactNode } from 'react'; +import { I18nProvider } from '@object-ui/i18n'; + +declare const Preview: () => ReactNode; + // Fixed-language surfaces (previews, demos, screenshot harnesses) opt out — // they neither restore nor write the preference. - +; ``` Bringing your own `instance`? Then its bootstrap language is yours to choose — @@ -91,7 +102,18 @@ Switching through such an instance is still persisted. Hook for translations and language management: ```tsx -const { t, language, changeLanguage, direction } = useObjectTranslation(); +import { useObjectTranslation } from '@object-ui/i18n'; + +function LanguageBar() { + const { t, language, changeLanguage, direction } = useObjectTranslation(); + + return ( +
+ {t('common.save')} — {language} + +
+ ); +} ``` ### createI18n @@ -109,13 +131,19 @@ i18n.t('common.cancel'); // "Abbrechen" Locale-aware formatting functions: +Each formatter takes the value first and an **options object** second; the +locale is a field on that object (`DateFormatOptions`, `CurrencyFormatOptions`, +`NumberFormatOptions`), never a positional argument. `formatRelativeTime` is the +one exception: it takes the locale directly, and derives the unit from how far +the date is from now. + ```tsx import { formatDate, formatCurrency, formatNumber, formatRelativeTime } from '@object-ui/i18n'; -formatDate(new Date(), 'en'); // "Jan 1, 2025" -formatCurrency(99.99, 'USD', 'en'); // "$99.99" -formatNumber(1234567, 'de'); // "1.234.567" -formatRelativeTime(-3, 'days', 'en'); // "3 days ago" +formatDate(new Date(2025, 0, 1), { locale: 'en' }); // "Jan 1, 2025" +formatCurrency(99.99, { currency: 'USD', locale: 'en' }); // "$99.99" +formatNumber(1234567, { locale: 'de' }); // "1.234.567" +formatRelativeTime(Date.now() - 3 * 86_400_000, 'en'); // "3 days ago" ``` ### Built-in Locales diff --git a/scripts/check-doc-snippet-types.mjs b/scripts/check-doc-snippet-types.mjs index 9f7afb122f..68dc6bc446 100644 --- a/scripts/check-doc-snippet-types.mjs +++ b/scripts/check-doc-snippet-types.mjs @@ -719,8 +719,6 @@ const UNGATED_DOCS = { 'self-contained or declared, plus a way to declare a block whose rejection IS the point.', 'packages/fields/README.md': '2 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; 1 unresolved-module diagnostic(s)', - 'packages/i18n/README.md': - '7 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; plus TS2554x2 TS2559x2 — candidate real defects, un-triaged', 'packages/layout/README.md': '3 undefined-name diagnostic(s) — blocks continue an earlier block, or use ambient names the page never defines; 3 unresolved-module diagnostic(s)', 'packages/permissions/README.md':