@intl-party/react 1.1.0 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,342 @@
1
+ # @intl-party/react
2
+
3
+ React integration for IntlParty - hooks, context, and components for type-safe internationalization in React applications.
4
+
5
+ ## Features
6
+
7
+ - ⚛️ **React hooks** - `useTranslations`, `useLocale`, `useNamespace`
8
+ - 🎯 **Context provider** - `I18nProvider` for app-wide i18n state
9
+ - 🧩 **Components** - `Trans`, `LocaleSelector` for declarative translations
10
+ - 🔄 **Real-time updates** - Automatic re-renders when locale changes
11
+ - 📱 **SSR support** - Server-side rendering compatible
12
+ - 🎨 **Type safety** - Full TypeScript support with typed hooks
13
+
14
+ ## Installation
15
+
16
+ ```bash
17
+ npm install @intl-party/react @intl-party/core
18
+ # or
19
+ pnpm add @intl-party/react @intl-party/core
20
+ # or
21
+ yarn add @intl-party/react @intl-party/core
22
+ ```
23
+
24
+ ## Quick Start
25
+
26
+ ```tsx
27
+ import React from "react";
28
+ import { I18nProvider, useTranslations, useLocale } from "@intl-party/react";
29
+ import { createI18n } from "@intl-party/core";
30
+
31
+ // Create i18n instance
32
+ const i18n = createI18n({
33
+ locales: ["en", "es", "fr"],
34
+ defaultLocale: "en",
35
+ namespaces: ["common"],
36
+ });
37
+
38
+ // Add translations
39
+ i18n.addTranslations("en", "common", {
40
+ welcome: "Welcome!",
41
+ greeting: "Hello, {{name}}!",
42
+ });
43
+
44
+ i18n.addTranslations("es", "common", {
45
+ welcome: "¡Bienvenido!",
46
+ greeting: "¡Hola, {{name}}!",
47
+ });
48
+
49
+ function App() {
50
+ return (
51
+ <I18nProvider i18n={i18n}>
52
+ <HomePage />
53
+ </I18nProvider>
54
+ );
55
+ }
56
+
57
+ function HomePage() {
58
+ const t = useTranslations("common");
59
+ const { locale, setLocale } = useLocale();
60
+
61
+ return (
62
+ <div>
63
+ <h1>{t("welcome")}</h1>
64
+ <p>{t("greeting", { interpolation: { name: "John" } })}</p>
65
+
66
+ <button onClick={() => setLocale("es")}>Español</button>
67
+ <button onClick={() => setLocale("en")}>English</button>
68
+
69
+ <p>Current locale: {locale}</p>
70
+ </div>
71
+ );
72
+ }
73
+ ```
74
+
75
+ ## Hooks
76
+
77
+ ### useTranslations
78
+
79
+ Get a translation function for a specific namespace:
80
+
81
+ ```tsx
82
+ import { useTranslations } from "@intl-party/react";
83
+
84
+ function MyComponent() {
85
+ const t = useTranslations("common");
86
+
87
+ return (
88
+ <div>
89
+ <h1>{t("title")}</h1>
90
+ <p>
91
+ {t("description", {
92
+ interpolation: { name: "User" },
93
+ count: 5,
94
+ })}
95
+ </p>
96
+ </div>
97
+ );
98
+ }
99
+
100
+ // With fallback namespace
101
+ function MyComponent() {
102
+ const t = useTranslations(["common", "fallback"]);
103
+ return <h1>{t("title")}</h1>;
104
+ }
105
+ ```
106
+
107
+ ### useLocale
108
+
109
+ Manage the current locale:
110
+
111
+ ```tsx
112
+ import { useLocale } from "@intl-party/react";
113
+
114
+ function LocaleSwitcher() {
115
+ const { locale, setLocale, availableLocales } = useLocale();
116
+
117
+ return (
118
+ <select value={locale} onChange={(e) => setLocale(e.target.value)}>
119
+ {availableLocales.map((loc) => (
120
+ <option key={loc} value={loc}>
121
+ {loc}
122
+ </option>
123
+ ))}
124
+ </select>
125
+ );
126
+ }
127
+ ```
128
+
129
+ ### useNamespace
130
+
131
+ Manage the current namespace:
132
+
133
+ ```tsx
134
+ import { useNamespace } from "@intl-party/react";
135
+
136
+ function NamespaceSwitcher() {
137
+ const { namespace, setNamespace, availableNamespaces } = useNamespace();
138
+
139
+ return (
140
+ <div>
141
+ <p>Current namespace: {namespace}</p>
142
+ {availableNamespaces.map((ns) => (
143
+ <button key={ns} onClick={() => setNamespace(ns)}>
144
+ {ns}
145
+ </button>
146
+ ))}
147
+ </div>
148
+ );
149
+ }
150
+ ```
151
+
152
+ ### useI18nContext
153
+
154
+ Access the full i18n context:
155
+
156
+ ```tsx
157
+ import { useI18nContext } from "@intl-party/react";
158
+
159
+ function AdvancedComponent() {
160
+ const { i18n, locale, namespace } = useI18nContext();
161
+
162
+ // Direct access to i18n instance
163
+ const hasTranslation = i18n.hasTranslation("some.key");
164
+
165
+ return <div>...</div>;
166
+ }
167
+ ```
168
+
169
+ ## Components
170
+
171
+ ### Trans Component
172
+
173
+ Declarative translation with JSX interpolation:
174
+
175
+ ```tsx
176
+ import { Trans } from "@intl-party/react";
177
+
178
+ function MyComponent() {
179
+ return (
180
+ <Trans
181
+ namespace="common"
182
+ i18nKey="welcome.message"
183
+ values={{ name: "John", count: 5 }}
184
+ components={{
185
+ bold: <strong />,
186
+ link: <a href="/profile" />,
187
+ }}
188
+ />
189
+ );
190
+ }
191
+ ```
192
+
193
+ Translation file:
194
+
195
+ ```json
196
+ {
197
+ "welcome": {
198
+ "message": "Hello <bold>{{name}}</bold>! You have <link>{{count}} messages</link>."
199
+ }
200
+ }
201
+ ```
202
+
203
+ ### LocaleSelector Component
204
+
205
+ Pre-built locale selector:
206
+
207
+ ```tsx
208
+ import { LocaleSelector } from "@intl-party/react";
209
+
210
+ function Header() {
211
+ return (
212
+ <header>
213
+ <h1>My App</h1>
214
+ <LocaleSelector
215
+ className="locale-selector"
216
+ showFlags={true}
217
+ onChange={(locale) => console.log("Locale changed to:", locale)}
218
+ />
219
+ </header>
220
+ );
221
+ }
222
+ ```
223
+
224
+ ## Provider Configuration
225
+
226
+ ### I18nProvider
227
+
228
+ ```tsx
229
+ import { I18nProvider } from "@intl-party/react";
230
+
231
+ function App() {
232
+ return (
233
+ <I18nProvider
234
+ i18n={i18nInstance}
235
+ fallback={<div>Loading translations...</div>}
236
+ >
237
+ <YourApp />
238
+ </I18nProvider>
239
+ );
240
+ }
241
+ ```
242
+
243
+ ### Server-Side Rendering
244
+
245
+ For SSR compatibility, initialize with server-detected locale:
246
+
247
+ ```tsx
248
+ // Server-side
249
+ import { createI18n } from "@intl-party/core";
250
+
251
+ function createServerI18n(locale: string) {
252
+ const i18n = createI18n({
253
+ locales: ["en", "es", "fr"],
254
+ defaultLocale: "en",
255
+ namespaces: ["common"],
256
+ });
257
+
258
+ i18n.setLocale(locale);
259
+ return i18n;
260
+ }
261
+
262
+ // In your SSR setup
263
+ const i18n = createServerI18n(detectedLocale);
264
+ ```
265
+
266
+ ## TypeScript Support
267
+
268
+ Create typed hooks for better developer experience:
269
+
270
+ ```tsx
271
+ interface MyTranslations {
272
+ common: {
273
+ welcome: string;
274
+ user: {
275
+ profile: string;
276
+ settings: string;
277
+ };
278
+ };
279
+ navigation: {
280
+ home: string;
281
+ about: string;
282
+ };
283
+ }
284
+
285
+ // Type the hooks
286
+ const useTypedTranslations = useTranslations as <
287
+ T extends keyof MyTranslations,
288
+ >(
289
+ namespace: T,
290
+ ) => (key: string) => string;
291
+
292
+ function TypedComponent() {
293
+ const t = useTypedTranslations("common");
294
+ // Now t() has autocomplete for keys in 'common' namespace
295
+ return <h1>{t("welcome")}</h1>;
296
+ }
297
+ ```
298
+
299
+ ## Advanced Usage
300
+
301
+ ### Dynamic namespace loading
302
+
303
+ ```tsx
304
+ import { useTranslations, useI18nContext } from "@intl-party/react";
305
+
306
+ function DynamicComponent() {
307
+ const { i18n } = useI18nContext();
308
+ const t = useTranslations("dynamic");
309
+
310
+ useEffect(() => {
311
+ // Load translations dynamically
312
+ import(`./translations/${i18n.locale}/dynamic.json`).then(
313
+ (translations) => {
314
+ i18n.addTranslations(i18n.locale, "dynamic", translations.default);
315
+ },
316
+ );
317
+ }, [i18n.locale]);
318
+
319
+ return <div>{t("content")}</div>;
320
+ }
321
+ ```
322
+
323
+ ### Custom hook for scoped translations
324
+
325
+ ```tsx
326
+ function usePageTranslations(page: string) {
327
+ const { i18n } = useI18nContext();
328
+ return useMemo(
329
+ () => i18n.createScopedTranslator(`pages.${page}`),
330
+ [i18n, page],
331
+ );
332
+ }
333
+
334
+ function ContactPage() {
335
+ const t = usePageTranslations("contact");
336
+ return <h1>{t("title")}</h1>; // translates 'pages.contact.title'
337
+ }
338
+ ```
339
+
340
+ ## License
341
+
342
+ MIT © IntlParty
@@ -0,0 +1,196 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as _intl_party_core from '@intl-party/core';
3
+ import { I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TypedTranslationFunction, TranslationKey, TranslationOptions } from '@intl-party/core';
4
+ export { DeepKeyOf, I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TranslationKey, TranslationOptions, TranslationValue, Translations, TypedI18nInstance, TypedTranslationFunction } from '@intl-party/core';
5
+ import React, { ReactNode } from 'react';
6
+
7
+ interface I18nContextValue {
8
+ i18n: I18nInstance;
9
+ locale: Locale;
10
+ namespace: Namespace;
11
+ t: TranslationFunction;
12
+ setLocale: (locale: Locale) => void;
13
+ setNamespace: (namespace: Namespace) => void;
14
+ isLoading: boolean;
15
+ }
16
+ interface TypedI18nContextValue<T extends Record<string, any> = Record<string, any>> extends Omit<I18nContextValue, "t"> {
17
+ t: TypedTranslationFunction<T>;
18
+ }
19
+ interface I18nProviderProps {
20
+ children: ReactNode;
21
+ config?: I18nConfig;
22
+ i18n?: I18nInstance;
23
+ initialLocale?: Locale;
24
+ initialNamespace?: Namespace;
25
+ loadingComponent?: ReactNode;
26
+ fallbackComponent?: ReactNode;
27
+ onLocaleChange?: (locale: Locale) => void;
28
+ onNamespaceChange?: (namespace: Namespace) => void;
29
+ onError?: (error: Error) => void;
30
+ }
31
+ declare function I18nProvider({ children, config, i18n: externalI18n, initialLocale, initialNamespace, loadingComponent, fallbackComponent, onLocaleChange, onNamespaceChange, onError, }: I18nProviderProps): react_jsx_runtime.JSX.Element;
32
+ declare function useI18nContext(): I18nContextValue;
33
+ interface TypedI18nProviderProps<T extends Record<string, any>> extends Omit<I18nProviderProps, "i18n"> {
34
+ i18n?: I18nInstance;
35
+ }
36
+ declare function TypedI18nProvider<T extends Record<string, any>>({ children, ...props }: TypedI18nProviderProps<T>): react_jsx_runtime.JSX.Element;
37
+ declare function useTypedI18nContext<T extends Record<string, any>>(): TypedI18nContextValue<T>;
38
+ interface WithI18nProps {
39
+ i18n: I18nContextValue;
40
+ }
41
+ declare function withI18n<P extends object>(Component: React.ComponentType<P & WithI18nProps>): React.ComponentType<P>;
42
+ interface ScopedI18nProviderProps {
43
+ children: ReactNode;
44
+ namespace: Namespace;
45
+ locale?: Locale;
46
+ }
47
+ declare function ScopedI18nProvider({ children, namespace, locale, }: ScopedI18nProviderProps): react_jsx_runtime.JSX.Element;
48
+
49
+ declare function useTranslations(namespace?: Namespace): TranslationFunction;
50
+ declare function useTypedTranslations<T extends Record<string, any>>(namespace?: Namespace): TypedTranslationFunction<T>;
51
+ declare const useT: typeof useTranslations;
52
+ declare const useTypedT: typeof useTypedTranslations;
53
+ declare function useScopedTranslations(namespace: Namespace): TranslationFunction;
54
+ declare function useMultipleTranslations(namespaces: Namespace[]): Record<Namespace, TranslationFunction>;
55
+ declare function useOptionalTranslation(key: TranslationKey, namespace?: Namespace, options?: TranslationOptions): string | undefined;
56
+ declare function useTranslationWithFallback(key: TranslationKey, fallback: string, namespace?: Namespace, options?: TranslationOptions): string;
57
+ declare function useHasTranslation(): (key: TranslationKey, namespace?: Namespace) => boolean;
58
+ declare function useTranslationValue(): (key: TranslationKey, namespace?: Namespace) => any;
59
+ declare function useInterpolatedTranslation(key: TranslationKey, variables: Record<string, any>, namespace?: Namespace): string;
60
+ declare function usePluralization(key: TranslationKey, count: number, namespace?: Namespace, additionalOptions?: Omit<TranslationOptions, "count">): string;
61
+
62
+ declare function useLocale(): [Locale, (locale: Locale) => void];
63
+ declare function useLocaleInfo(): {
64
+ current: string;
65
+ available: string[];
66
+ fallbackChain: string[];
67
+ isRTL: boolean;
68
+ direction: string;
69
+ };
70
+ declare function useLocaleSwitch(): {
71
+ switchLocale: (locale: Locale) => void;
72
+ isLocaleAvailable: (locale: Locale) => boolean;
73
+ availableLocales: string[];
74
+ };
75
+ declare function useBrowserLocale(): {
76
+ detected: string;
77
+ browser: string;
78
+ supported: boolean;
79
+ } | null;
80
+ declare function useLocalePreference(): {
81
+ current: string;
82
+ save: (newLocale: Locale) => void;
83
+ load: () => string | null;
84
+ clear: () => void;
85
+ };
86
+ declare function useDirection(): "ltr" | "rtl";
87
+ declare function useFormatting(): {
88
+ formatDate: (date: Date, options?: Intl.DateTimeFormatOptions) => string;
89
+ formatNumber: (number: number, options?: Intl.NumberFormatOptions) => string;
90
+ formatCurrency: (amount: number, currency: string, options?: Intl.NumberFormatOptions) => string;
91
+ formatRelativeTime: (value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions) => string;
92
+ };
93
+
94
+ declare function useNamespace(): [Namespace, (namespace: Namespace) => void];
95
+ declare function useNamespaceInfo(): {
96
+ current: string;
97
+ available: string[];
98
+ isAvailable: boolean;
99
+ };
100
+ declare function useNamespaceSwitch(): {
101
+ switchNamespace: (namespace: Namespace) => void;
102
+ isNamespaceAvailable: (namespace: Namespace) => boolean;
103
+ availableNamespaces: string[];
104
+ };
105
+ declare function useMultipleNamespaces(namespaces: Namespace[]): {
106
+ translators: Record<string, _intl_party_core.TranslationFunction>;
107
+ isAllAvailable: boolean;
108
+ getMissingNamespaces: () => string[];
109
+ };
110
+ declare function useNamespacePreloading(): {
111
+ preloadNamespace: (namespace: Namespace) => Promise<void>;
112
+ preloadNamespaces: (namespaces: Namespace[]) => Promise<void>;
113
+ };
114
+
115
+ interface TransProps {
116
+ i18nKey: TranslationKey;
117
+ namespace?: Namespace;
118
+ values?: Record<string, any>;
119
+ components?: Record<string, ReactNode>;
120
+ count?: number;
121
+ fallback?: string;
122
+ children?: ReactNode;
123
+ }
124
+ declare function Trans({ i18nKey, namespace, values, components, count, fallback, children, }: TransProps): react_jsx_runtime.JSX.Element;
125
+ interface ConditionalTransProps extends TransProps {
126
+ when?: boolean;
127
+ fallbackComponent?: ReactNode;
128
+ }
129
+ declare function ConditionalTrans({ when, fallbackComponent, ...transProps }: ConditionalTransProps): react_jsx_runtime.JSX.Element;
130
+ interface PluralTransProps extends Omit<TransProps, "count"> {
131
+ count: number;
132
+ zero?: TranslationKey;
133
+ one?: TranslationKey;
134
+ other?: TranslationKey;
135
+ }
136
+ declare function PluralTrans({ count, zero, one, other, i18nKey, ...props }: PluralTransProps): react_jsx_runtime.JSX.Element;
137
+ interface RichTransProps extends TransProps {
138
+ allowedTags?: string[];
139
+ sanitize?: boolean;
140
+ }
141
+ declare function RichTrans({ allowedTags, sanitize, ...transProps }: RichTransProps): react_jsx_runtime.JSX.Element;
142
+
143
+ interface LocaleSelectorProps {
144
+ className?: string;
145
+ style?: React.CSSProperties;
146
+ placeholder?: string;
147
+ disabled?: boolean;
148
+ showNativeNames?: boolean;
149
+ filterLocales?: (locale: Locale) => boolean;
150
+ formatLocale?: (locale: Locale) => string;
151
+ onLocaleChange?: (locale: Locale) => void;
152
+ variant?: "select" | "buttons" | "dropdown";
153
+ }
154
+ declare function LocaleSelector({ className, style, placeholder, disabled, showNativeNames, filterLocales, formatLocale, onLocaleChange, variant, }: LocaleSelectorProps): react_jsx_runtime.JSX.Element | null;
155
+ interface FlagLocaleSelectorProps extends Omit<LocaleSelectorProps, "showNativeNames"> {
156
+ flagMap?: Record<Locale, string>;
157
+ showFlags?: boolean;
158
+ showLabels?: boolean;
159
+ }
160
+ declare function FlagLocaleSelector({ flagMap, showFlags, showLabels, variant, ...props }: FlagLocaleSelectorProps): react_jsx_runtime.JSX.Element;
161
+ interface CompactLocaleSelectorProps extends LocaleSelectorProps {
162
+ maxVisibleLocales?: number;
163
+ }
164
+ declare function CompactLocaleSelector({ maxVisibleLocales, ...props }: CompactLocaleSelectorProps): react_jsx_runtime.JSX.Element;
165
+ interface AccessibleLocaleSelectorProps extends LocaleSelectorProps {
166
+ ariaLabel?: string;
167
+ ariaDescribedBy?: string;
168
+ }
169
+ declare function AccessibleLocaleSelector({ ariaLabel, ariaDescribedBy, ...props }: AccessibleLocaleSelectorProps): react_jsx_runtime.JSX.Element;
170
+
171
+ declare const VERSION = "0.1.0";
172
+ declare function createI18nHook<T extends Record<string, any>>(): {
173
+ useTranslations: (namespace?: _intl_party_core.Namespace) => _intl_party_core.TypedTranslationFunction<T>;
174
+ useT: (namespace?: _intl_party_core.Namespace) => _intl_party_core.TypedTranslationFunction<T>;
175
+ };
176
+ declare function createNamespaceHOC(namespace: string): <P extends object>(Component: React.ComponentType<P>) => React.ComponentType<P>;
177
+ declare class I18nErrorBoundary extends React.Component<{
178
+ children: React.ReactNode;
179
+ fallback?: React.ComponentType<{
180
+ error: Error;
181
+ }>;
182
+ onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
183
+ }, {
184
+ hasError: boolean;
185
+ error?: Error;
186
+ }> {
187
+ constructor(props: any);
188
+ static getDerivedStateFromError(error: Error): {
189
+ hasError: boolean;
190
+ error: Error;
191
+ };
192
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
193
+ render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
194
+ }
195
+
196
+ export { AccessibleLocaleSelector, type AccessibleLocaleSelectorProps, CompactLocaleSelector, type CompactLocaleSelectorProps, ConditionalTrans, type ConditionalTransProps, FlagLocaleSelector, type FlagLocaleSelectorProps, type I18nContextValue, I18nErrorBoundary, I18nProvider, type I18nProviderProps, LocaleSelector, type LocaleSelectorProps, PluralTrans, type PluralTransProps, RichTrans, type RichTransProps, ScopedI18nProvider, type ScopedI18nProviderProps, Trans, type TransProps, type TypedI18nContextValue, TypedI18nProvider, type TypedI18nProviderProps, VERSION, type WithI18nProps, createI18nHook, createNamespaceHOC, useBrowserLocale, useDirection, useFormatting, useHasTranslation, useI18nContext, useInterpolatedTranslation, useLocale, useLocaleInfo, useLocalePreference, useLocaleSwitch, useMultipleNamespaces, useMultipleTranslations, useNamespace, useNamespaceInfo, useNamespacePreloading, useNamespaceSwitch, useOptionalTranslation, usePluralization, useScopedTranslations, useT, useTranslationValue, useTranslationWithFallback, useTranslations, useTypedI18nContext, useTypedT, useTypedTranslations, withI18n };
@@ -0,0 +1,196 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import * as _intl_party_core from '@intl-party/core';
3
+ import { I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TypedTranslationFunction, TranslationKey, TranslationOptions } from '@intl-party/core';
4
+ export { DeepKeyOf, I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TranslationKey, TranslationOptions, TranslationValue, Translations, TypedI18nInstance, TypedTranslationFunction } from '@intl-party/core';
5
+ import React, { ReactNode } from 'react';
6
+
7
+ interface I18nContextValue {
8
+ i18n: I18nInstance;
9
+ locale: Locale;
10
+ namespace: Namespace;
11
+ t: TranslationFunction;
12
+ setLocale: (locale: Locale) => void;
13
+ setNamespace: (namespace: Namespace) => void;
14
+ isLoading: boolean;
15
+ }
16
+ interface TypedI18nContextValue<T extends Record<string, any> = Record<string, any>> extends Omit<I18nContextValue, "t"> {
17
+ t: TypedTranslationFunction<T>;
18
+ }
19
+ interface I18nProviderProps {
20
+ children: ReactNode;
21
+ config?: I18nConfig;
22
+ i18n?: I18nInstance;
23
+ initialLocale?: Locale;
24
+ initialNamespace?: Namespace;
25
+ loadingComponent?: ReactNode;
26
+ fallbackComponent?: ReactNode;
27
+ onLocaleChange?: (locale: Locale) => void;
28
+ onNamespaceChange?: (namespace: Namespace) => void;
29
+ onError?: (error: Error) => void;
30
+ }
31
+ declare function I18nProvider({ children, config, i18n: externalI18n, initialLocale, initialNamespace, loadingComponent, fallbackComponent, onLocaleChange, onNamespaceChange, onError, }: I18nProviderProps): react_jsx_runtime.JSX.Element;
32
+ declare function useI18nContext(): I18nContextValue;
33
+ interface TypedI18nProviderProps<T extends Record<string, any>> extends Omit<I18nProviderProps, "i18n"> {
34
+ i18n?: I18nInstance;
35
+ }
36
+ declare function TypedI18nProvider<T extends Record<string, any>>({ children, ...props }: TypedI18nProviderProps<T>): react_jsx_runtime.JSX.Element;
37
+ declare function useTypedI18nContext<T extends Record<string, any>>(): TypedI18nContextValue<T>;
38
+ interface WithI18nProps {
39
+ i18n: I18nContextValue;
40
+ }
41
+ declare function withI18n<P extends object>(Component: React.ComponentType<P & WithI18nProps>): React.ComponentType<P>;
42
+ interface ScopedI18nProviderProps {
43
+ children: ReactNode;
44
+ namespace: Namespace;
45
+ locale?: Locale;
46
+ }
47
+ declare function ScopedI18nProvider({ children, namespace, locale, }: ScopedI18nProviderProps): react_jsx_runtime.JSX.Element;
48
+
49
+ declare function useTranslations(namespace?: Namespace): TranslationFunction;
50
+ declare function useTypedTranslations<T extends Record<string, any>>(namespace?: Namespace): TypedTranslationFunction<T>;
51
+ declare const useT: typeof useTranslations;
52
+ declare const useTypedT: typeof useTypedTranslations;
53
+ declare function useScopedTranslations(namespace: Namespace): TranslationFunction;
54
+ declare function useMultipleTranslations(namespaces: Namespace[]): Record<Namespace, TranslationFunction>;
55
+ declare function useOptionalTranslation(key: TranslationKey, namespace?: Namespace, options?: TranslationOptions): string | undefined;
56
+ declare function useTranslationWithFallback(key: TranslationKey, fallback: string, namespace?: Namespace, options?: TranslationOptions): string;
57
+ declare function useHasTranslation(): (key: TranslationKey, namespace?: Namespace) => boolean;
58
+ declare function useTranslationValue(): (key: TranslationKey, namespace?: Namespace) => any;
59
+ declare function useInterpolatedTranslation(key: TranslationKey, variables: Record<string, any>, namespace?: Namespace): string;
60
+ declare function usePluralization(key: TranslationKey, count: number, namespace?: Namespace, additionalOptions?: Omit<TranslationOptions, "count">): string;
61
+
62
+ declare function useLocale(): [Locale, (locale: Locale) => void];
63
+ declare function useLocaleInfo(): {
64
+ current: string;
65
+ available: string[];
66
+ fallbackChain: string[];
67
+ isRTL: boolean;
68
+ direction: string;
69
+ };
70
+ declare function useLocaleSwitch(): {
71
+ switchLocale: (locale: Locale) => void;
72
+ isLocaleAvailable: (locale: Locale) => boolean;
73
+ availableLocales: string[];
74
+ };
75
+ declare function useBrowserLocale(): {
76
+ detected: string;
77
+ browser: string;
78
+ supported: boolean;
79
+ } | null;
80
+ declare function useLocalePreference(): {
81
+ current: string;
82
+ save: (newLocale: Locale) => void;
83
+ load: () => string | null;
84
+ clear: () => void;
85
+ };
86
+ declare function useDirection(): "ltr" | "rtl";
87
+ declare function useFormatting(): {
88
+ formatDate: (date: Date, options?: Intl.DateTimeFormatOptions) => string;
89
+ formatNumber: (number: number, options?: Intl.NumberFormatOptions) => string;
90
+ formatCurrency: (amount: number, currency: string, options?: Intl.NumberFormatOptions) => string;
91
+ formatRelativeTime: (value: number, unit: Intl.RelativeTimeFormatUnit, options?: Intl.RelativeTimeFormatOptions) => string;
92
+ };
93
+
94
+ declare function useNamespace(): [Namespace, (namespace: Namespace) => void];
95
+ declare function useNamespaceInfo(): {
96
+ current: string;
97
+ available: string[];
98
+ isAvailable: boolean;
99
+ };
100
+ declare function useNamespaceSwitch(): {
101
+ switchNamespace: (namespace: Namespace) => void;
102
+ isNamespaceAvailable: (namespace: Namespace) => boolean;
103
+ availableNamespaces: string[];
104
+ };
105
+ declare function useMultipleNamespaces(namespaces: Namespace[]): {
106
+ translators: Record<string, _intl_party_core.TranslationFunction>;
107
+ isAllAvailable: boolean;
108
+ getMissingNamespaces: () => string[];
109
+ };
110
+ declare function useNamespacePreloading(): {
111
+ preloadNamespace: (namespace: Namespace) => Promise<void>;
112
+ preloadNamespaces: (namespaces: Namespace[]) => Promise<void>;
113
+ };
114
+
115
+ interface TransProps {
116
+ i18nKey: TranslationKey;
117
+ namespace?: Namespace;
118
+ values?: Record<string, any>;
119
+ components?: Record<string, ReactNode>;
120
+ count?: number;
121
+ fallback?: string;
122
+ children?: ReactNode;
123
+ }
124
+ declare function Trans({ i18nKey, namespace, values, components, count, fallback, children, }: TransProps): react_jsx_runtime.JSX.Element;
125
+ interface ConditionalTransProps extends TransProps {
126
+ when?: boolean;
127
+ fallbackComponent?: ReactNode;
128
+ }
129
+ declare function ConditionalTrans({ when, fallbackComponent, ...transProps }: ConditionalTransProps): react_jsx_runtime.JSX.Element;
130
+ interface PluralTransProps extends Omit<TransProps, "count"> {
131
+ count: number;
132
+ zero?: TranslationKey;
133
+ one?: TranslationKey;
134
+ other?: TranslationKey;
135
+ }
136
+ declare function PluralTrans({ count, zero, one, other, i18nKey, ...props }: PluralTransProps): react_jsx_runtime.JSX.Element;
137
+ interface RichTransProps extends TransProps {
138
+ allowedTags?: string[];
139
+ sanitize?: boolean;
140
+ }
141
+ declare function RichTrans({ allowedTags, sanitize, ...transProps }: RichTransProps): react_jsx_runtime.JSX.Element;
142
+
143
+ interface LocaleSelectorProps {
144
+ className?: string;
145
+ style?: React.CSSProperties;
146
+ placeholder?: string;
147
+ disabled?: boolean;
148
+ showNativeNames?: boolean;
149
+ filterLocales?: (locale: Locale) => boolean;
150
+ formatLocale?: (locale: Locale) => string;
151
+ onLocaleChange?: (locale: Locale) => void;
152
+ variant?: "select" | "buttons" | "dropdown";
153
+ }
154
+ declare function LocaleSelector({ className, style, placeholder, disabled, showNativeNames, filterLocales, formatLocale, onLocaleChange, variant, }: LocaleSelectorProps): react_jsx_runtime.JSX.Element | null;
155
+ interface FlagLocaleSelectorProps extends Omit<LocaleSelectorProps, "showNativeNames"> {
156
+ flagMap?: Record<Locale, string>;
157
+ showFlags?: boolean;
158
+ showLabels?: boolean;
159
+ }
160
+ declare function FlagLocaleSelector({ flagMap, showFlags, showLabels, variant, ...props }: FlagLocaleSelectorProps): react_jsx_runtime.JSX.Element;
161
+ interface CompactLocaleSelectorProps extends LocaleSelectorProps {
162
+ maxVisibleLocales?: number;
163
+ }
164
+ declare function CompactLocaleSelector({ maxVisibleLocales, ...props }: CompactLocaleSelectorProps): react_jsx_runtime.JSX.Element;
165
+ interface AccessibleLocaleSelectorProps extends LocaleSelectorProps {
166
+ ariaLabel?: string;
167
+ ariaDescribedBy?: string;
168
+ }
169
+ declare function AccessibleLocaleSelector({ ariaLabel, ariaDescribedBy, ...props }: AccessibleLocaleSelectorProps): react_jsx_runtime.JSX.Element;
170
+
171
+ declare const VERSION = "0.1.0";
172
+ declare function createI18nHook<T extends Record<string, any>>(): {
173
+ useTranslations: (namespace?: _intl_party_core.Namespace) => _intl_party_core.TypedTranslationFunction<T>;
174
+ useT: (namespace?: _intl_party_core.Namespace) => _intl_party_core.TypedTranslationFunction<T>;
175
+ };
176
+ declare function createNamespaceHOC(namespace: string): <P extends object>(Component: React.ComponentType<P>) => React.ComponentType<P>;
177
+ declare class I18nErrorBoundary extends React.Component<{
178
+ children: React.ReactNode;
179
+ fallback?: React.ComponentType<{
180
+ error: Error;
181
+ }>;
182
+ onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
183
+ }, {
184
+ hasError: boolean;
185
+ error?: Error;
186
+ }> {
187
+ constructor(props: any);
188
+ static getDerivedStateFromError(error: Error): {
189
+ hasError: boolean;
190
+ error: Error;
191
+ };
192
+ componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
193
+ render(): string | number | boolean | Iterable<React.ReactNode> | react_jsx_runtime.JSX.Element | null | undefined;
194
+ }
195
+
196
+ export { AccessibleLocaleSelector, type AccessibleLocaleSelectorProps, CompactLocaleSelector, type CompactLocaleSelectorProps, ConditionalTrans, type ConditionalTransProps, FlagLocaleSelector, type FlagLocaleSelectorProps, type I18nContextValue, I18nErrorBoundary, I18nProvider, type I18nProviderProps, LocaleSelector, type LocaleSelectorProps, PluralTrans, type PluralTransProps, RichTrans, type RichTransProps, ScopedI18nProvider, type ScopedI18nProviderProps, Trans, type TransProps, type TypedI18nContextValue, TypedI18nProvider, type TypedI18nProviderProps, VERSION, type WithI18nProps, createI18nHook, createNamespaceHOC, useBrowserLocale, useDirection, useFormatting, useHasTranslation, useI18nContext, useInterpolatedTranslation, useLocale, useLocaleInfo, useLocalePreference, useLocaleSwitch, useMultipleNamespaces, useMultipleTranslations, useNamespace, useNamespaceInfo, useNamespacePreloading, useNamespaceSwitch, useOptionalTranslation, usePluralization, useScopedTranslations, useT, useTranslationValue, useTranslationWithFallback, useTranslations, useTypedI18nContext, useTypedT, useTypedTranslations, withI18n };
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  "use strict";
2
+ "use client";
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -194,6 +195,24 @@ function I18nProvider({
194
195
  function useI18nContext() {
195
196
  const context = (0, import_react.useContext)(I18nContext);
196
197
  if (!context) {
198
+ if (typeof window === "undefined") {
199
+ const fallbackI18n = (0, import_core.createI18n)({
200
+ locales: ["en"],
201
+ defaultLocale: "en",
202
+ namespaces: ["common"]
203
+ });
204
+ return {
205
+ i18n: fallbackI18n,
206
+ locale: "en",
207
+ namespace: "common",
208
+ t: fallbackI18n.t,
209
+ setLocale: () => {
210
+ },
211
+ setNamespace: () => {
212
+ },
213
+ isLoading: false
214
+ };
215
+ }
197
216
  throw new Error("useI18nContext must be used within an I18nProvider");
198
217
  }
199
218
  return context;
@@ -228,6 +247,24 @@ function useTypedI18nContext() {
228
247
  TypedI18nContext
229
248
  );
230
249
  if (!context) {
250
+ if (typeof window === "undefined") {
251
+ const fallbackI18n = (0, import_core.createI18n)({
252
+ locales: ["en"],
253
+ defaultLocale: "en",
254
+ namespaces: ["common"]
255
+ });
256
+ return {
257
+ i18n: fallbackI18n,
258
+ locale: "en",
259
+ namespace: "common",
260
+ t: fallbackI18n.t,
261
+ setLocale: () => {
262
+ },
263
+ setNamespace: () => {
264
+ },
265
+ isLoading: false
266
+ };
267
+ }
231
268
  throw new Error(
232
269
  "useTypedI18nContext must be used within a TypedI18nProvider"
233
270
  );
package/dist/index.mjs CHANGED
@@ -1,3 +1,5 @@
1
+ "use client";
2
+
1
3
  // src/index.tsx
2
4
  import React4 from "react";
3
5
 
@@ -127,6 +129,24 @@ function I18nProvider({
127
129
  function useI18nContext() {
128
130
  const context = useContext(I18nContext);
129
131
  if (!context) {
132
+ if (typeof window === "undefined") {
133
+ const fallbackI18n = createI18n({
134
+ locales: ["en"],
135
+ defaultLocale: "en",
136
+ namespaces: ["common"]
137
+ });
138
+ return {
139
+ i18n: fallbackI18n,
140
+ locale: "en",
141
+ namespace: "common",
142
+ t: fallbackI18n.t,
143
+ setLocale: () => {
144
+ },
145
+ setNamespace: () => {
146
+ },
147
+ isLoading: false
148
+ };
149
+ }
130
150
  throw new Error("useI18nContext must be used within an I18nProvider");
131
151
  }
132
152
  return context;
@@ -161,6 +181,24 @@ function useTypedI18nContext() {
161
181
  TypedI18nContext
162
182
  );
163
183
  if (!context) {
184
+ if (typeof window === "undefined") {
185
+ const fallbackI18n = createI18n({
186
+ locales: ["en"],
187
+ defaultLocale: "en",
188
+ namespaces: ["common"]
189
+ });
190
+ return {
191
+ i18n: fallbackI18n,
192
+ locale: "en",
193
+ namespace: "common",
194
+ t: fallbackI18n.t,
195
+ setLocale: () => {
196
+ },
197
+ setNamespace: () => {
198
+ },
199
+ isLoading: false
200
+ };
201
+ }
164
202
  throw new Error(
165
203
  "useTypedI18nContext must be used within a TypedI18nProvider"
166
204
  );
@@ -0,0 +1,7 @@
1
+ export { I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TranslationKey, TranslationOptions, TranslationValue } from '@intl-party/core';
2
+
3
+ declare function useTranslations(): never;
4
+ declare function useLocale(): never;
5
+ declare function I18nProvider(): never;
6
+
7
+ export { I18nProvider, useLocale, useTranslations };
@@ -0,0 +1,7 @@
1
+ export { I18nConfig, I18nInstance, Locale, Namespace, TranslationFunction, TranslationKey, TranslationOptions, TranslationValue } from '@intl-party/core';
2
+
3
+ declare function useTranslations(): never;
4
+ declare function useLocale(): never;
5
+ declare function I18nProvider(): never;
6
+
7
+ export { I18nProvider, useLocale, useTranslations };
package/dist/server.js ADDED
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/server.ts
21
+ var server_exports = {};
22
+ __export(server_exports, {
23
+ I18nProvider: () => I18nProvider,
24
+ useLocale: () => useLocale,
25
+ useTranslations: () => useTranslations
26
+ });
27
+ module.exports = __toCommonJS(server_exports);
28
+ function useTranslations() {
29
+ throw new Error(
30
+ "useTranslations() is a client-side hook and cannot be used in Server Components. Use getServerTranslations() from @intl-party/nextjs/server instead."
31
+ );
32
+ }
33
+ function useLocale() {
34
+ throw new Error(
35
+ "useLocale() is a client-side hook and cannot be used in Server Components. Use getLocale() from @intl-party/nextjs/server instead."
36
+ );
37
+ }
38
+ function I18nProvider() {
39
+ throw new Error(
40
+ "I18nProvider is a client component and cannot be used in Server Components. Use AppI18nProvider from @intl-party/nextjs in a client component instead."
41
+ );
42
+ }
43
+ // Annotate the CommonJS export names for ESM import in node:
44
+ 0 && (module.exports = {
45
+ I18nProvider,
46
+ useLocale,
47
+ useTranslations
48
+ });
@@ -0,0 +1,21 @@
1
+ // src/server.ts
2
+ function useTranslations() {
3
+ throw new Error(
4
+ "useTranslations() is a client-side hook and cannot be used in Server Components. Use getServerTranslations() from @intl-party/nextjs/server instead."
5
+ );
6
+ }
7
+ function useLocale() {
8
+ throw new Error(
9
+ "useLocale() is a client-side hook and cannot be used in Server Components. Use getLocale() from @intl-party/nextjs/server instead."
10
+ );
11
+ }
12
+ function I18nProvider() {
13
+ throw new Error(
14
+ "I18nProvider is a client component and cannot be used in Server Components. Use AppI18nProvider from @intl-party/nextjs in a client component instead."
15
+ );
16
+ }
17
+ export {
18
+ I18nProvider,
19
+ useLocale,
20
+ useTranslations
21
+ };
package/package.json CHANGED
@@ -1,15 +1,16 @@
1
1
  {
2
2
  "name": "@intl-party/react",
3
- "version": "1.1.0",
3
+ "version": "1.1.3",
4
4
  "description": "React integration for IntlParty - hooks, context, and components for type-safe i18n",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
+ "react-server": "./dist/server.js",
11
+ "types": "./dist/index.d.ts",
10
12
  "import": "./dist/index.mjs",
11
- "require": "./dist/index.js",
12
- "types": "./dist/index.d.ts"
13
+ "require": "./dist/index.js"
13
14
  }
14
15
  },
15
16
  "files": [
@@ -26,7 +27,7 @@
26
27
  "author": "IntlParty Team",
27
28
  "license": "MIT",
28
29
  "dependencies": {
29
- "@intl-party/core": "1.0.0"
30
+ "@intl-party/core": "1.0.2"
30
31
  },
31
32
  "devDependencies": {
32
33
  "@testing-library/jest-dom": "^6.1.4",
@@ -52,10 +53,10 @@
52
53
  "directory": "packages/react"
53
54
  },
54
55
  "scripts": {
55
- "build": "tsup src/index.tsx --format cjs,esm --external react,react-dom",
56
+ "build": "tsup src/index.tsx src/server.ts --format cjs,esm --dts --external react,react-dom",
56
57
  "dev": "tsup src/index.tsx --format cjs,esm --external react,react-dom --watch",
57
- "test": "vitest",
58
- "test:watch": "vitest --watch",
58
+ "test": "vitest --run",
59
+ "test:watch": "vitest",
59
60
  "lint": "eslint src --ext .ts,.tsx",
60
61
  "typecheck": "tsc --noEmit",
61
62
  "clean": "rm -rf dist"