diff --git a/packages/i18n/src/runtime/hooks.ts b/packages/i18n/src/runtime/hooks.ts index 44c67c4..7fa297c 100644 --- a/packages/i18n/src/runtime/hooks.ts +++ b/packages/i18n/src/runtime/hooks.ts @@ -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, diff --git a/packages/i18n/src/runtime/index.ts b/packages/i18n/src/runtime/index.ts index 1c53ed1..8fe7892 100644 --- a/packages/i18n/src/runtime/index.ts +++ b/packages/i18n/src/runtime/index.ts @@ -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, diff --git a/packages/i18n/src/runtime/localized-text.tsx b/packages/i18n/src/runtime/localized-text.tsx new file mode 100644 index 0000000..62f2f40 --- /dev/null +++ b/packages/i18n/src/runtime/localized-text.tsx @@ -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) +} diff --git a/packages/i18n/src/runtime/runtime.test.tsx b/packages/i18n/src/runtime/runtime.test.tsx index c400489..b4dd632 100644 --- a/packages/i18n/src/runtime/runtime.test.tsx +++ b/packages/i18n/src/runtime/runtime.test.tsx @@ -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("

Hello

") }) + it("renders localized text without adding a DOM element", () => { + const { container } = render( + +

+ +

+
+ ) + + expect(container.innerHTML).toBe("

你好

") + }) + it("infers right-to-left locale direction", () => { function DirectionProbe() { return {useLocales()[0]?.direction}