feat(i18n): expose localized text runtime primitive
Add a DOM-free LocalizedText component for MessageDescriptor values and export it from the runtime entry point.\n\nAlso expose provider detection so packages with a standalone fallback provider can avoid invoking Lingui hooks outside a provider. Cover localized rendering without an extra wrapper node.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import * as React from "react"
|
||||
import { useLingui } from "@lingui/react"
|
||||
import { LinguiContext, useLingui } from "@lingui/react"
|
||||
|
||||
import { I18nRuntimeContext } from "./context"
|
||||
import { createIntlFormatters } from "./intl-formatters"
|
||||
@@ -26,6 +26,14 @@ export function useTranslate(): TranslateFunction {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the component is nested in an I18nProvider without
|
||||
* invoking the provider-dependent Lingui hooks.
|
||||
*/
|
||||
export function useI18nProvider(): boolean {
|
||||
return React.useContext(LinguiContext) !== null
|
||||
}
|
||||
|
||||
export function useMessage(descriptor: MessageDescriptor): string
|
||||
export function useMessage(
|
||||
id: MessageId,
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
export { I18nProvider, type I18nProviderProps } from "./i18n-provider"
|
||||
export { LocalizedText, type LocalizedTextProps } from "./localized-text"
|
||||
export { Translate, type TranslateProps } from "./translate"
|
||||
export { createIntlFormatters } from "./intl-formatters"
|
||||
export { mergeMessageCatalogs, type MessageCatalogSource } from "./catalogs"
|
||||
export {
|
||||
useFormatters,
|
||||
useI18nProvider,
|
||||
useLocale,
|
||||
useLocaleDefinition,
|
||||
useLocales,
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { useMessage } from "./hooks"
|
||||
import type { MessageDescriptor } from "./types"
|
||||
|
||||
export interface LocalizedTextProps {
|
||||
message: MessageDescriptor
|
||||
}
|
||||
|
||||
/** Renders a message descriptor as localized text without adding a DOM node. */
|
||||
export function LocalizedText({ message }: LocalizedTextProps) {
|
||||
return useMessage(message)
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
useMessage,
|
||||
useTranslate,
|
||||
} from "./hooks"
|
||||
import { LocalizedText } from "./localized-text"
|
||||
import { Translate } from "./translate"
|
||||
|
||||
const catalogs = {
|
||||
@@ -96,6 +97,18 @@ describe("i18n runtime", () => {
|
||||
expect(container.innerHTML).toBe("<p>Hello</p>")
|
||||
})
|
||||
|
||||
it("renders localized text without adding a DOM element", () => {
|
||||
const { container } = render(
|
||||
<I18nProvider catalogs={catalogs} locale="zh-Hans">
|
||||
<p>
|
||||
<LocalizedText message={{ id: "greeting", message: "Fallback" }} />
|
||||
</p>
|
||||
</I18nProvider>
|
||||
)
|
||||
|
||||
expect(container.innerHTML).toBe("<p>你好</p>")
|
||||
})
|
||||
|
||||
it("infers right-to-left locale direction", () => {
|
||||
function DirectionProbe() {
|
||||
return <span>{useLocales()[0]?.direction}</span>
|
||||
|
||||
Reference in New Issue
Block a user