34 lines
1.5 KiB
TypeScript
34 lines
1.5 KiB
TypeScript
"use client";
|
|
|
|
import { createContext, useCallback, useContext, useEffect, useSyncExternalStore, type ReactNode } from "react";
|
|
import { createLocaleStore } from "@/lib/i18n/locale-store";
|
|
import { defaultLocale, type Locale } from "@/lib/i18n/locales";
|
|
import { translate, type MessageParams } from "@/lib/i18n/messages";
|
|
import { exportText, type ExportMessageKey } from "@/lib/guides/export-text";
|
|
|
|
// This store contains a browser preference only; server rendering always uses Thai.
|
|
const store = createLocaleStore(() => typeof window === "undefined" ? undefined : window.localStorage);
|
|
const LocaleContext = createContext<Locale>(defaultLocale);
|
|
|
|
export function LocaleProvider({ children }: { children: ReactNode }) {
|
|
const locale = useSyncExternalStore(store.subscribe, store.getSnapshot, store.getServerSnapshot);
|
|
useEffect(() => { document.documentElement.lang = locale; }, [locale]);
|
|
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>;
|
|
}
|
|
|
|
export function LocaleBoundary({ locale, children }: { locale: Locale; children: ReactNode }) {
|
|
return <LocaleContext.Provider value={locale}>{children}</LocaleContext.Provider>;
|
|
}
|
|
|
|
export function useTranslation() {
|
|
const locale = useContext(LocaleContext);
|
|
const t = useCallback((message: string, params?: MessageParams) => translate(message, params, locale), [locale]);
|
|
const e = useCallback((key: ExportMessageKey, params?: MessageParams) => exportText(key, params, locale), [locale]);
|
|
return {
|
|
locale,
|
|
setLocale: store.setLocale,
|
|
t,
|
|
e,
|
|
};
|
|
}
|