@valfuse-node/react 0.2.0
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/LICENSE +22 -0
- package/README.md +620 -0
- package/dist/index.d.mts +446 -0
- package/dist/index.d.ts +446 -0
- package/dist/index.js +986 -0
- package/dist/index.mjs +957 -0
- package/package.json +48 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
import React$1, { ChangeEvent, PropsWithChildren } from 'react';
|
|
2
|
+
import { ValfuseSchema, ValfuseFieldErrors } from '@valfuse-node/form';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
import * as _valfuse_node_localization from '@valfuse-node/localization';
|
|
5
|
+
import { RuntimeManifest } from '@valfuse-node/localization';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Controls when validation is triggered — mirrors react-hook-form's `mode` option:
|
|
9
|
+
*
|
|
10
|
+
* | Mode | Behaviour |
|
|
11
|
+
* |--------------|-------------------------------------------------------------------------|
|
|
12
|
+
* | `onSubmit` | Validate only when the form is submitted (default) |
|
|
13
|
+
* | `onBlur` | Validate when a field loses focus |
|
|
14
|
+
* | `onChange` | Validate on every keystroke / value change |
|
|
15
|
+
* | `onTouched` | Validate on the first blur; after that validate on every change |
|
|
16
|
+
* | `all` | Validate on both `onChange` and `onBlur` |
|
|
17
|
+
*/
|
|
18
|
+
type ValfuseFormMode = "onSubmit" | "onBlur" | "onChange" | "onTouched" | "all";
|
|
19
|
+
/** A single field error — extends the core error with a required `type` field */
|
|
20
|
+
type ValfuseFieldError = {
|
|
21
|
+
message: string;
|
|
22
|
+
/** Error originator: "validation" | "server" | "manual" | "custom" */
|
|
23
|
+
type: string;
|
|
24
|
+
/** Optional semantic code (e.g. "email.required", "auth.not_found") */
|
|
25
|
+
code?: string;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
};
|
|
28
|
+
type ValfuseFormErrors<TFieldValues extends Record<string, unknown>> = {
|
|
29
|
+
[K in keyof TFieldValues]?: ValfuseFieldError;
|
|
30
|
+
};
|
|
31
|
+
type ValfuseDirtyFields<TFieldValues extends Record<string, unknown>> = {
|
|
32
|
+
[K in keyof TFieldValues]?: boolean;
|
|
33
|
+
};
|
|
34
|
+
type ValfuseTouchedFields<TFieldValues extends Record<string, unknown>> = {
|
|
35
|
+
[K in keyof TFieldValues]?: boolean;
|
|
36
|
+
};
|
|
37
|
+
type ValfuseFormState<TFieldValues extends Record<string, unknown>> = {
|
|
38
|
+
/** All current field validation errors */
|
|
39
|
+
readonly errors: ValfuseFormErrors<TFieldValues>;
|
|
40
|
+
/** `true` while an async submit handler is running — never `undefined` */
|
|
41
|
+
readonly isSubmitting: boolean;
|
|
42
|
+
/** `true` after the form has been submitted at least once — never `undefined` */
|
|
43
|
+
readonly isSubmitted: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* `true` if the most recent submission completed without validation errors
|
|
46
|
+
* and the `onValid` handler finished successfully — never `undefined`.
|
|
47
|
+
*/
|
|
48
|
+
readonly isSubmitSuccessful: boolean;
|
|
49
|
+
/** Total number of submit attempts (resets on `reset()`) — never `undefined` */
|
|
50
|
+
readonly submitCount: number;
|
|
51
|
+
/** `true` if any field value differs from its default value — never `undefined` */
|
|
52
|
+
readonly isDirty: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* `true` if current values pass schema validation and there are no active errors.
|
|
55
|
+
* Computed directly from the schema — accurate from the very first render.
|
|
56
|
+
*/
|
|
57
|
+
readonly isValid: boolean;
|
|
58
|
+
/** Map of fields whose current value differs from the default (`{ email: true }`) */
|
|
59
|
+
readonly dirtyFields: ValfuseDirtyFields<TFieldValues>;
|
|
60
|
+
/** Map of fields the user has interacted with (focused + blurred) */
|
|
61
|
+
readonly touchedFields: ValfuseTouchedFields<TFieldValues>;
|
|
62
|
+
/** The `defaultValues` that were passed to `useValfuseForm` */
|
|
63
|
+
readonly defaultValues: Readonly<TFieldValues>;
|
|
64
|
+
};
|
|
65
|
+
/**
|
|
66
|
+
* Callback passed to `form.watch(callback)`.
|
|
67
|
+
* Called every time any field value changes.
|
|
68
|
+
*/
|
|
69
|
+
type ValfuseWatchCallback<TFieldValues extends Record<string, unknown>> = (values: TFieldValues, info: {
|
|
70
|
+
name?: string;
|
|
71
|
+
type?: string;
|
|
72
|
+
}) => void;
|
|
73
|
+
/**
|
|
74
|
+
* Callable type for `form.watch` — mirrors react-hook-form overloads:
|
|
75
|
+
*
|
|
76
|
+
* ```ts
|
|
77
|
+
* form.watch() // → TFieldValues (all values)
|
|
78
|
+
* form.watch("email") // → TFieldValues["email"]
|
|
79
|
+
* form.watch(["email", "name"]) // → Array of values in the same order
|
|
80
|
+
* form.watch((values, info) => void) // → () => void (unsubscribe)
|
|
81
|
+
* ```
|
|
82
|
+
*/
|
|
83
|
+
interface ValfuseWatchFunction<TFieldValues extends Record<string, unknown>> {
|
|
84
|
+
(): TFieldValues;
|
|
85
|
+
<TName extends keyof TFieldValues & string>(name: TName): TFieldValues[TName];
|
|
86
|
+
(names: Array<keyof TFieldValues & string>): Array<TFieldValues[keyof TFieldValues]>;
|
|
87
|
+
(callback: ValfuseWatchCallback<TFieldValues>): () => void;
|
|
88
|
+
}
|
|
89
|
+
/** Props returned by `form.register(name)` — spread directly onto `<input>` */
|
|
90
|
+
type ValfuseRegisterReturn = {
|
|
91
|
+
name: string;
|
|
92
|
+
/** Current field value — compatible with HTML input `value` prop */
|
|
93
|
+
value: string | number | readonly string[] | undefined;
|
|
94
|
+
onChange: (e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => void;
|
|
95
|
+
onBlur: () => void;
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* Opaque control object — passed to `<ValfuseController control={...} />`.
|
|
99
|
+
* Internal fields are prefixed with `_` and not part of the public API.
|
|
100
|
+
*/
|
|
101
|
+
type ValfuseFormControl<TFieldValues extends Record<string, unknown>> = {
|
|
102
|
+
/** @internal Current field values */
|
|
103
|
+
_values: TFieldValues;
|
|
104
|
+
/** @internal Current validation errors */
|
|
105
|
+
_errors: ValfuseFormErrors<TFieldValues>;
|
|
106
|
+
/** @internal Update a single field value */
|
|
107
|
+
_updateField: <TName extends keyof TFieldValues & string>(name: TName, value: TFieldValues[TName]) => void;
|
|
108
|
+
/** @internal Mark a field as touched (triggers onBlur validation) */
|
|
109
|
+
_touchField: (name: string) => void;
|
|
110
|
+
/** @internal Set of names of fields the user has interacted with */
|
|
111
|
+
_touchedFields: ReadonlySet<string>;
|
|
112
|
+
};
|
|
113
|
+
type UseValfuseFormProps<TFieldValues extends Record<string, unknown>> = {
|
|
114
|
+
schema: ValfuseSchema;
|
|
115
|
+
defaultValues: TFieldValues;
|
|
116
|
+
/**
|
|
117
|
+
* When validation runs:
|
|
118
|
+
* - `"onSubmit"` (default) — only on form submission
|
|
119
|
+
* - `"onBlur"` — when a field loses focus
|
|
120
|
+
* - `"onChange"` — on every keystroke
|
|
121
|
+
* - `"onTouched"` — on first blur, then on every change after that
|
|
122
|
+
* - `"all"` — on both onChange and onBlur
|
|
123
|
+
*/
|
|
124
|
+
mode?: ValfuseFormMode;
|
|
125
|
+
};
|
|
126
|
+
type UseValfuseFormReturn<TFieldValues extends Record<string, unknown>> = {
|
|
127
|
+
/** Registers an input field — spread the return value onto `<input>` */
|
|
128
|
+
register: <TName extends keyof TFieldValues & string>(name: TName) => ValfuseRegisterReturn;
|
|
129
|
+
/** Passed to `<ValfuseController control={...} />` */
|
|
130
|
+
control: ValfuseFormControl<TFieldValues>;
|
|
131
|
+
/** Wraps form submission: validates first, then calls `onValid` */
|
|
132
|
+
handleSubmit: (onValid: (values: TFieldValues) => void | Promise<void>) => (e?: React.FormEvent | {
|
|
133
|
+
preventDefault?: () => void;
|
|
134
|
+
}) => Promise<void>;
|
|
135
|
+
/**
|
|
136
|
+
* Reactive form state.
|
|
137
|
+
* Includes: errors, isSubmitting, isSubmitted, isSubmitSuccessful,
|
|
138
|
+
* submitCount, isDirty, isValid, dirtyFields, touchedFields, defaultValues.
|
|
139
|
+
*/
|
|
140
|
+
formState: ValfuseFormState<TFieldValues>;
|
|
141
|
+
/** Inject external errors (e.g. from API responses) */
|
|
142
|
+
setErrors: (errors: ValfuseFieldErrors<Extract<keyof TFieldValues, string>>) => void;
|
|
143
|
+
/** Clear one, many, or all field errors */
|
|
144
|
+
clearErrors: (name?: keyof TFieldValues | Array<keyof TFieldValues>) => void;
|
|
145
|
+
/**
|
|
146
|
+
* Programmatically set a field value.
|
|
147
|
+
* Pass `{ shouldValidate: true }` to run validation immediately after setting.
|
|
148
|
+
*/
|
|
149
|
+
setValue: <TName extends keyof TFieldValues>(name: TName, value: TFieldValues[TName], options?: {
|
|
150
|
+
shouldValidate?: boolean;
|
|
151
|
+
}) => void;
|
|
152
|
+
/**
|
|
153
|
+
* Manually trigger validation.
|
|
154
|
+
* - No argument → validate all fields
|
|
155
|
+
* - Single name → validate one field
|
|
156
|
+
* - Array of names → validate those fields
|
|
157
|
+
*
|
|
158
|
+
* Returns `true` if all triggered fields are valid, `false` otherwise.
|
|
159
|
+
*/
|
|
160
|
+
trigger: (name?: keyof TFieldValues & string | Array<keyof TFieldValues & string>) => boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Watch field values — mirrors react-hook-form's `watch`:
|
|
163
|
+
*
|
|
164
|
+
* ```ts
|
|
165
|
+
* form.watch() // all current values
|
|
166
|
+
* form.watch("email") // single field value
|
|
167
|
+
* form.watch(["email", "name"]) // array of values
|
|
168
|
+
* const unsub = form.watch((values, info) => { ... }); // subscribe
|
|
169
|
+
* unsub(); // unsubscribe
|
|
170
|
+
* ```
|
|
171
|
+
*/
|
|
172
|
+
watch: ValfuseWatchFunction<TFieldValues>;
|
|
173
|
+
/** Reset the form to default values (or provided partial values) */
|
|
174
|
+
reset: (values?: Partial<TFieldValues>) => void;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
declare function useValfuseForm<TFieldValues extends Record<string, unknown>>(props: UseValfuseFormProps<TFieldValues>): UseValfuseFormReturn<TFieldValues>;
|
|
178
|
+
|
|
179
|
+
type ValfuseControllerFieldState = {
|
|
180
|
+
error?: ValfuseFieldError;
|
|
181
|
+
isTouched: boolean;
|
|
182
|
+
};
|
|
183
|
+
type ValfuseControllerField<TValue> = {
|
|
184
|
+
name: string;
|
|
185
|
+
value: TValue;
|
|
186
|
+
/** Receives the raw value — not a DOM event */
|
|
187
|
+
onChange: (value: TValue) => void;
|
|
188
|
+
onBlur: () => void;
|
|
189
|
+
};
|
|
190
|
+
type ValfuseControllerRenderProps<TFieldValues extends Record<string, unknown>, TName extends keyof TFieldValues & string> = {
|
|
191
|
+
field: ValfuseControllerField<TFieldValues[TName]>;
|
|
192
|
+
fieldState: ValfuseControllerFieldState;
|
|
193
|
+
};
|
|
194
|
+
type ValfuseControllerProps<TFieldValues extends Record<string, unknown>, TName extends keyof TFieldValues & string = keyof TFieldValues & string> = {
|
|
195
|
+
control: ValfuseFormControl<TFieldValues>;
|
|
196
|
+
name: TName;
|
|
197
|
+
render: (props: ValfuseControllerRenderProps<TFieldValues, TName>) => React$1.ReactElement;
|
|
198
|
+
};
|
|
199
|
+
/**
|
|
200
|
+
* Controlled field wrapper for complex inputs (dropdowns, date-pickers, etc.)
|
|
201
|
+
* that cannot be registered with `form.register(name)`.
|
|
202
|
+
*
|
|
203
|
+
* `fieldState.error` is typed as `ValfuseFieldError | undefined`, so both
|
|
204
|
+
* `fieldState.error?.message` and `fieldState.error?.code` work out of the box.
|
|
205
|
+
*
|
|
206
|
+
* @example
|
|
207
|
+
* <ValfuseController
|
|
208
|
+
* control={form.control}
|
|
209
|
+
* name="roleId"
|
|
210
|
+
* render={({ field, fieldState }) => (
|
|
211
|
+
* <RoleDropdown
|
|
212
|
+
* value={field.value}
|
|
213
|
+
* onChange={field.onChange}
|
|
214
|
+
* onBlur={field.onBlur}
|
|
215
|
+
* error={fieldState.error?.code}
|
|
216
|
+
* />
|
|
217
|
+
* )}
|
|
218
|
+
* />
|
|
219
|
+
*/
|
|
220
|
+
declare function ValfuseController<TFieldValues extends Record<string, unknown>, TName extends keyof TFieldValues & string = keyof TFieldValues & string>({ control, name, render, }: ValfuseControllerProps<TFieldValues, TName>): React$1.ReactElement;
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Minimal runtime store contract used by React adapter hooks and provider.
|
|
224
|
+
*/
|
|
225
|
+
interface LocalizationStore {
|
|
226
|
+
/** Returns the currently active locale. */
|
|
227
|
+
getLocale(): string;
|
|
228
|
+
/** Updates the active locale. */
|
|
229
|
+
setLocale(locale: string): void;
|
|
230
|
+
/** Looks up a key with fallback and optional interpolation. */
|
|
231
|
+
t(key: string, params?: Record<string, string | number>): string;
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Creates a lightweight mutable localization store for React runtime usage.
|
|
235
|
+
*
|
|
236
|
+
* @param manifest Generated runtime manifest from `@valfuse-node/localization`.
|
|
237
|
+
* @param initialLocale Optional starting locale; defaults to `manifest.base_locale`.
|
|
238
|
+
*/
|
|
239
|
+
declare function createLocalizationStore(manifest: RuntimeManifest, initialLocale?: string): LocalizationStore;
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* Generic contract for persisting / reading the active locale.
|
|
243
|
+
*
|
|
244
|
+
* Implement this interface to connect any storage backend
|
|
245
|
+
* (localStorage, sessionStorage, cookies, IndexedDB, remote API, …).
|
|
246
|
+
*/
|
|
247
|
+
interface LocaleStorage {
|
|
248
|
+
/** Read the previously-saved locale. Returns `undefined` when nothing is stored. */
|
|
249
|
+
get(): string | undefined;
|
|
250
|
+
/** Persist the newly selected locale. */
|
|
251
|
+
set(locale: string): void;
|
|
252
|
+
/** Optional: remove the stored value (e.g. when locale is reset). */
|
|
253
|
+
remove?(): void;
|
|
254
|
+
}
|
|
255
|
+
interface LocalStorageStrategyOptions {
|
|
256
|
+
/** Storage key. Defaults to `"locale"`. */
|
|
257
|
+
key?: string;
|
|
258
|
+
}
|
|
259
|
+
interface SessionStorageStrategyOptions {
|
|
260
|
+
/** Storage key. Defaults to `"locale"`. */
|
|
261
|
+
key?: string;
|
|
262
|
+
}
|
|
263
|
+
interface CookieStrategyOptions {
|
|
264
|
+
/** Cookie name. Defaults to `"locale"`. */
|
|
265
|
+
key?: string;
|
|
266
|
+
/**
|
|
267
|
+
* Domain the cookie is scoped to.
|
|
268
|
+
* e.g. `".example.com"` shares across all sub-domains.
|
|
269
|
+
* Omit for the current host only.
|
|
270
|
+
*/
|
|
271
|
+
domain?: string;
|
|
272
|
+
/** Cookie path. Defaults to `"/"`. */
|
|
273
|
+
path?: string;
|
|
274
|
+
/**
|
|
275
|
+
* Max age in seconds.
|
|
276
|
+
* Defaults to 1 year (`31_536_000`).
|
|
277
|
+
* Pass `0` to create a session cookie.
|
|
278
|
+
*/
|
|
279
|
+
maxAge?: number;
|
|
280
|
+
/** Mark cookie as Secure. Defaults to `true` when on `https:`. */
|
|
281
|
+
secure?: boolean;
|
|
282
|
+
/** SameSite policy. Defaults to `"Lax"`. */
|
|
283
|
+
sameSite?: "Strict" | "Lax" | "None";
|
|
284
|
+
}
|
|
285
|
+
/**
|
|
286
|
+
* Persists the locale in `window.localStorage`.
|
|
287
|
+
*
|
|
288
|
+
* @example
|
|
289
|
+
* <LocalizationProvider storage={localStorageStrategy()} … />
|
|
290
|
+
*/
|
|
291
|
+
declare function localStorageStrategy(options?: LocalStorageStrategyOptions): LocaleStorage;
|
|
292
|
+
/**
|
|
293
|
+
* Persists the locale in `window.sessionStorage` (cleared on tab close).
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* <LocalizationProvider storage={sessionStorageStrategy()} … />
|
|
297
|
+
*/
|
|
298
|
+
declare function sessionStorageStrategy(options?: SessionStorageStrategyOptions): LocaleStorage;
|
|
299
|
+
/**
|
|
300
|
+
* Persists the locale as an HTTP cookie.
|
|
301
|
+
*
|
|
302
|
+
* Supports `domain`, `path`, `maxAge`, `secure`, and `sameSite` options so the
|
|
303
|
+
* same cookie can be read server-side (e.g. for SSR / middleware redirects).
|
|
304
|
+
*
|
|
305
|
+
* @example
|
|
306
|
+
* <LocalizationProvider storage={cookieStrategy({ domain: ".example.com" })} … />
|
|
307
|
+
*/
|
|
308
|
+
declare function cookieStrategy(options?: CookieStrategyOptions): LocaleStorage;
|
|
309
|
+
/**
|
|
310
|
+
* In-memory storage — locale is lost on page reload.
|
|
311
|
+
* Useful for testing or when no persistence is desired.
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* <LocalizationProvider storage={memoryStrategy()} … />
|
|
315
|
+
*/
|
|
316
|
+
declare function memoryStrategy(options?: {
|
|
317
|
+
initialLocale?: string;
|
|
318
|
+
}): LocaleStorage;
|
|
319
|
+
/**
|
|
320
|
+
* Combines multiple storages in priority order.
|
|
321
|
+
* Reads from the first storage that returns a value; writes to **all** of them.
|
|
322
|
+
*
|
|
323
|
+
* @example
|
|
324
|
+
* const storage = composeStorage(
|
|
325
|
+
* cookieStrategy({ domain: ".example.com" }),
|
|
326
|
+
* localStorageStrategy()
|
|
327
|
+
* );
|
|
328
|
+
*/
|
|
329
|
+
declare function composeStorage(...storages: LocaleStorage[]): LocaleStorage;
|
|
330
|
+
|
|
331
|
+
interface LocalizationContextValue {
|
|
332
|
+
/** Active locale currently used for runtime resolution. */
|
|
333
|
+
locale: string;
|
|
334
|
+
/** Updates the active locale for all consumers under the provider. */
|
|
335
|
+
setLocale: (locale: string) => void;
|
|
336
|
+
/** Runtime store — `store.t(key, params)` looks up translations. */
|
|
337
|
+
store: LocalizationStore;
|
|
338
|
+
/** Generated runtime manifest — source of truth for keys and messages. */
|
|
339
|
+
manifest: RuntimeManifest;
|
|
340
|
+
}
|
|
341
|
+
interface LocalizationProviderProps {
|
|
342
|
+
/** Generated runtime manifest from `valfuse-localization generate`. */
|
|
343
|
+
manifest: RuntimeManifest;
|
|
344
|
+
/**
|
|
345
|
+
* Optional initial locale. When `storage` is also provided the stored value
|
|
346
|
+
* takes precedence over `initialLocale`.
|
|
347
|
+
*/
|
|
348
|
+
initialLocale?: string;
|
|
349
|
+
/**
|
|
350
|
+
* Pluggable locale storage strategy.
|
|
351
|
+
*
|
|
352
|
+
* Built-in helpers (imported from `@valfuse-node/react`):
|
|
353
|
+
* - `localStorageStrategy()` — persists in `window.localStorage`
|
|
354
|
+
* - `sessionStorageStrategy()` — persists in `window.sessionStorage`
|
|
355
|
+
* - `cookieStrategy({ domain, maxAge, … })` — persists as a cookie
|
|
356
|
+
* - `memoryStrategy()` — in-memory only (no persistence)
|
|
357
|
+
* - `composeStorage(a, b)` — combines multiple strategies
|
|
358
|
+
*/
|
|
359
|
+
storage?: LocaleStorage;
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Provides localization state and runtime store to the React subtree.
|
|
363
|
+
*
|
|
364
|
+
* Pass a `storage` strategy to persist the selected locale across page reloads.
|
|
365
|
+
*
|
|
366
|
+
* @example
|
|
367
|
+
* import { LocalizationProvider, localStorageStrategy } from "@valfuse-node/react";
|
|
368
|
+
*
|
|
369
|
+
* <LocalizationProvider manifest={manifest} storage={localStorageStrategy()}>
|
|
370
|
+
* <App />
|
|
371
|
+
* </LocalizationProvider>
|
|
372
|
+
*/
|
|
373
|
+
declare function LocalizationProvider({ manifest, initialLocale, storage, children, }: PropsWithChildren<LocalizationProviderProps>): react_jsx_runtime.JSX.Element;
|
|
374
|
+
|
|
375
|
+
type InterpolationParams = Record<string, string | number>;
|
|
376
|
+
type GenderVariant = "male" | "female" | "other";
|
|
377
|
+
interface NamespacedLocalizer {
|
|
378
|
+
translate(key: string, fallbackValue?: string | null): string;
|
|
379
|
+
/** Returns `null` when key does not exist or is `null`/`undefined`. */
|
|
380
|
+
translateOrNull(key: string | null | undefined): string | null;
|
|
381
|
+
format(key: string, params: InterpolationParams): string;
|
|
382
|
+
/** Returns `null` when key does not exist or is `null`/`undefined`. */
|
|
383
|
+
formatOrNull(key: string | null | undefined, params: InterpolationParams): string | null;
|
|
384
|
+
plural(key: string, count: number): string;
|
|
385
|
+
/** Returns `null` when key does not exist or is `null`/`undefined`. */
|
|
386
|
+
pluralOrNull(key: string | null | undefined, count: number): string | null;
|
|
387
|
+
gender(key: string, gender: GenderVariant, params: InterpolationParams): string;
|
|
388
|
+
context(key: string, context: string, params?: InterpolationParams): string;
|
|
389
|
+
}
|
|
390
|
+
type TranslationFallback = string | Record<string, string> | ((key: string) => string | undefined);
|
|
391
|
+
interface UseLocalizationOptions {
|
|
392
|
+
fallback?: TranslationFallback;
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Returns the current localization context from `LocalizationProvider`.
|
|
396
|
+
*
|
|
397
|
+
* @throws Error when called outside of `LocalizationProvider`.
|
|
398
|
+
*/
|
|
399
|
+
declare function useLocalization(options?: UseLocalizationOptions): {
|
|
400
|
+
translate: (key: string, fallbackValue?: string | null) => string;
|
|
401
|
+
translateOrNull: (key: string | null | undefined) => string | null;
|
|
402
|
+
format: (key: string, params: InterpolationParams) => string;
|
|
403
|
+
formatOrNull: (key: string | null | undefined, params: InterpolationParams) => string | null;
|
|
404
|
+
plural: (key: string, count: number) => string;
|
|
405
|
+
pluralOrNull: (key: string | null | undefined, count: number) => string | null;
|
|
406
|
+
gender: (key: string, value: GenderVariant, params: InterpolationParams) => string;
|
|
407
|
+
context: (key: string, value: string, params?: InterpolationParams) => string;
|
|
408
|
+
namespace: (scope: string) => NamespacedLocalizer;
|
|
409
|
+
entriesForLocale: [string, string][];
|
|
410
|
+
locale: string;
|
|
411
|
+
setLocale: (locale: string) => void;
|
|
412
|
+
store: LocalizationStore;
|
|
413
|
+
manifest: _valfuse_node_localization.RuntimeManifest;
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* Builds a nested object API from manifest entries for ergonomic app consumption.
|
|
418
|
+
*
|
|
419
|
+
* - Non-placeholder entries → string values.
|
|
420
|
+
* - Placeholder entries → functions accepting interpolation params.
|
|
421
|
+
*/
|
|
422
|
+
declare function useLocalizationTree(): {
|
|
423
|
+
strings: Record<string, unknown>;
|
|
424
|
+
placeholders: Record<string, unknown>;
|
|
425
|
+
};
|
|
426
|
+
|
|
427
|
+
/**
|
|
428
|
+
* Creates a lazy locale loader that fetches messages from a pre-built manifest.
|
|
429
|
+
*
|
|
430
|
+
* Useful for code-splitting scenarios or SSR hydration flows where you want to
|
|
431
|
+
* load only the active locale's messages on demand.
|
|
432
|
+
*/
|
|
433
|
+
declare function createLazyLocaleLoader(manifest: RuntimeManifest): (locale: string) => Promise<Record<string, string>>;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Creates an SSR-safe localization state snapshot.
|
|
437
|
+
*
|
|
438
|
+
* Use this on the server to pre-render localized content and hydrate
|
|
439
|
+
* the client with the correct locale without a flash of incorrect content.
|
|
440
|
+
*/
|
|
441
|
+
declare function createSsrLocalizationState(manifest: RuntimeManifest, locale?: string): {
|
|
442
|
+
locale: string;
|
|
443
|
+
messages: Record<string, string>;
|
|
444
|
+
};
|
|
445
|
+
|
|
446
|
+
export { type GenderVariant, type InterpolationParams, type LocaleStorage, type LocalizationContextValue, LocalizationProvider, type LocalizationProviderProps, type LocalizationStore, type NamespacedLocalizer, type TranslationFallback, type UseLocalizationOptions, type UseValfuseFormProps, type UseValfuseFormReturn, ValfuseController, type ValfuseControllerField, type ValfuseControllerFieldState, type ValfuseControllerProps, type ValfuseControllerRenderProps, type ValfuseDirtyFields, type ValfuseFieldError, type ValfuseFormControl, type ValfuseFormErrors, type ValfuseFormMode, type ValfuseFormState, type ValfuseRegisterReturn, type ValfuseTouchedFields, type ValfuseWatchCallback, type ValfuseWatchFunction, composeStorage, cookieStrategy, createLazyLocaleLoader, createLocalizationStore, createSsrLocalizationState, localStorageStrategy, memoryStrategy, sessionStorageStrategy, useLocalization, useLocalizationTree, useValfuseForm };
|