feat(i18n): expand catalog runtime and developer tooling

- add Intl-backed locale definitions, formatters, catalog loaders, and runtime hooks\n- compile hashed production catalogs from package-scoped catalog sources\n- drive Lingui extraction and compilation directly from project JSON config\n- redesign the devtool with localized controls, draggable persistence, settings, navigation, copy actions, ANSI output, and fullscreen support\n- extend repository APIs, CLI coverage, documentation, and runtime tests
This commit is contained in:
Maofeng
2026-07-30 14:47:42 +08:00
parent 0d0aad1d47
commit 0768e8fa29
55 changed files with 7553 additions and 495 deletions
+54 -21
View File
@@ -1,54 +1,87 @@
import * as React from "react"
import type { MessageDescriptor, MessageId, MessageOptions } from "@lingui/core"
import { useLingui } from "@lingui/react"
import { I18nRuntimeContext } from "./context"
import type { LocaleDefinition, TranslateFunction } from "./types"
import { createIntlFormatters } from "./intl-formatters"
import type {
IntlFormatters,
LocaleDefinition,
MessageDescriptor,
MessageId,
MessageOptions,
MessageValues,
TranslateFunction,
} from "./types"
export function useTranslate(): TranslateFunction {
return useLingui()._
const { i18n } = useLingui()
return React.useCallback(
(descriptor, values) =>
i18n._({
...descriptor,
values: values ?? descriptor.values,
}),
[i18n]
)
}
export function useMessage(descriptor: MessageDescriptor): string
export function useMessage(
id: MessageId,
values?: Record<string, unknown>,
values?: MessageValues,
options?: MessageOptions
): string
export function useMessage(
descriptorOrId: MessageDescriptor | MessageId,
values?: Record<string, unknown>,
values?: MessageValues,
options?: MessageOptions
) {
const translate = useTranslate()
const { i18n } = useLingui()
return React.useMemo(
() =>
typeof descriptorOrId === "string"
? translate(descriptorOrId, values, options)
: translate(descriptorOrId),
[descriptorOrId, options, translate, values]
? i18n._(descriptorOrId, values, options)
: i18n._({
...descriptorOrId,
values: values ?? descriptorOrId.values,
}),
[descriptorOrId, i18n, options, values]
)
}
export function useLocale(): string {
const runtime = React.useContext(I18nRuntimeContext)
const { i18n } = useLingui()
return runtime?.locale ?? i18n.locale
return useLocaleDefinition().locale
}
export function useLocales(): readonly LocaleDefinition[] {
export function useLocaleDefinition(): LocaleDefinition {
const runtime = React.useContext(I18nRuntimeContext)
const { i18n } = useLingui()
return (
runtime?.locales ?? [
{
direction: "ltr",
label: i18n.locale,
locale: i18n.locale,
},
]
runtime?.locale ?? {
label: i18n.locale,
languageTag: i18n.locale,
locale: i18n.locale,
}
)
}
export function useLocales(): readonly LocaleDefinition[] {
const runtime = React.useContext(I18nRuntimeContext)
const activeLocale = useLocaleDefinition()
return runtime?.locales ?? [activeLocale]
}
export function useFormatters(): IntlFormatters {
const runtime = React.useContext(I18nRuntimeContext)
const locale = useLocaleDefinition()
const fallbackFormatters = React.useMemo(
() => createIntlFormatters(locale.languageTag ?? locale.locale),
[locale.languageTag, locale.locale]
)
return runtime?.formatters ?? fallbackFormatters
}