tempest-react-sdk 0.1.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.
@@ -0,0 +1,2327 @@
1
+ import { ButtonHTMLAttributes } from 'react';
2
+ import { Component } from 'react';
3
+ import { ComponentType } from 'react';
4
+ import { CSSProperties } from 'react';
5
+ import { default as default_2 } from 'dexie';
6
+ import { DefaultOptions } from '@tanstack/react-query';
7
+ import { ErrorInfo } from 'react';
8
+ import { FieldValues } from 'react-hook-form';
9
+ import { ForwardRefExoticComponent } from 'react';
10
+ import { HTMLAttributes } from 'react';
11
+ import { InputHTMLAttributes } from 'react';
12
+ import { JSX } from 'react/jsx-runtime';
13
+ import { lazy } from 'react';
14
+ import { PersistOptions } from 'zustand/middleware';
15
+ import { QueryClient } from '@tanstack/react-query';
16
+ import { ReactElement } from 'react';
17
+ import { ReactNode } from 'react';
18
+ import { ReactPortal } from 'react';
19
+ import { RefAttributes } from 'react';
20
+ import { RefObject } from 'react';
21
+ import { SelectHTMLAttributes } from 'react';
22
+ import { StoreApi } from 'zustand';
23
+ import { Table as Table_2 } from 'dexie';
24
+ import { TextareaHTMLAttributes } from 'react';
25
+ import { UseBoundStore } from 'zustand';
26
+ import { UseFormProps } from 'react-hook-form';
27
+ import { UseFormReturn } from 'react-hook-form';
28
+ import { z } from 'zod';
29
+
30
+ export declare interface ApiClient {
31
+ request<T>(path: string, options?: RequestOptions): Promise<T>;
32
+ get<T>(path: string, options?: RequestOptions): Promise<T>;
33
+ post<T>(path: string, options?: RequestOptions): Promise<T>;
34
+ put<T>(path: string, options?: RequestOptions): Promise<T>;
35
+ patch<T>(path: string, options?: RequestOptions): Promise<T>;
36
+ delete<T>(path: string, options?: RequestOptions): Promise<T>;
37
+ upload<T>(path: string, formData: FormData, method?: "POST" | "PUT" | "PATCH"): Promise<T>;
38
+ }
39
+
40
+ export declare interface ApiClientConfig {
41
+ /** Base URL for every request. Required. */
42
+ baseURL: string;
43
+ /** Returns the current bearer token (or null/undefined). Called per request. */
44
+ getToken?: () => string | null | undefined;
45
+ /** Called on 401 responses. Use it to logout the user or trigger a refresh. */
46
+ onUnauthorized?: (response: Response) => void | Promise<void>;
47
+ /**
48
+ * Optional refresh hook. When provided and the original request returns 401,
49
+ * the client awaits `refresh()` then retries the request once.
50
+ */
51
+ refresh?: () => Promise<void>;
52
+ /** Whether to send cookies on cross-origin requests (default: false). */
53
+ withCredentials?: boolean;
54
+ /** Default headers merged into every request. */
55
+ headers?: Record<string, string>;
56
+ /** Optional fetch implementation (defaults to globalThis.fetch). */
57
+ fetcher?: typeof fetch;
58
+ }
59
+
60
+ export declare interface ApiError {
61
+ status: number;
62
+ detail: string;
63
+ body?: unknown;
64
+ }
65
+
66
+ export declare interface AudioPlayer {
67
+ /** Play `src`. Returns the underlying element, or `null` when the browser blocked autoplay. */
68
+ play: (src: string, options?: PlayAudioOptions) => Promise<HTMLAudioElement | null>;
69
+ /** Stop the currently-playing clip and rewind it. */
70
+ stop: () => void;
71
+ /** Currently playing audio element, or `null`. */
72
+ current: () => HTMLAudioElement | null;
73
+ }
74
+
75
+ /**
76
+ * Router-agnostic auth gate. The caller decides what to render in either
77
+ * branch — typically `<Outlet />` for protected layouts and `<Navigate />` for
78
+ * the redirect. Pair with {@link createAuthStore} or any custom auth source.
79
+ *
80
+ * @example
81
+ * <AuthGuard
82
+ * isAuthenticated={useAuthStore((s) => s.isAuthenticated)}
83
+ * fallback={<Navigate to="/login" replace />}
84
+ * >
85
+ * <Outlet />
86
+ * </AuthGuard>
87
+ */
88
+ export declare function AuthGuard({ isAuthenticated, children, fallback }: AuthGuardProps): JSX.Element;
89
+
90
+ export declare interface AuthGuardProps {
91
+ /** Whether the current user is authenticated. */
92
+ isAuthenticated: boolean;
93
+ /** Element to render when authenticated. */
94
+ children: ReactNode;
95
+ /** Element to render when not authenticated. Use this to redirect (e.g. `<Navigate to="/login" />`). */
96
+ fallback: ReactNode;
97
+ }
98
+
99
+ export declare interface AuthState<TUser> {
100
+ user: TUser | null;
101
+ token: string | null;
102
+ isAuthenticated: boolean;
103
+ setSession: (session: {
104
+ user: TUser;
105
+ token: string;
106
+ }) => void;
107
+ setUser: (user: TUser | null) => void;
108
+ setToken: (token: string | null) => void;
109
+ logout: () => void;
110
+ }
111
+
112
+ /**
113
+ * Round avatar. Falls back to colored initials when the image fails to load
114
+ * or no `src` is provided. Optional status dot in the bottom-right corner.
115
+ */
116
+ export declare function Avatar({ src, alt, name, size, status, className, onClick, }: AvatarProps): JSX.Element;
117
+
118
+ export declare interface AvatarProps {
119
+ src?: string;
120
+ alt?: string;
121
+ name?: string;
122
+ size?: AvatarSize;
123
+ status?: AvatarStatus;
124
+ className?: string;
125
+ onClick?: () => void;
126
+ }
127
+
128
+ export declare type AvatarSize = "xs" | "sm" | "md" | "lg" | "xl";
129
+
130
+ export declare type AvatarStatus = "online" | "offline" | "busy";
131
+
132
+ /** Pill-shaped status badge with semantic color variants. */
133
+ export declare function Badge({ variant, className, children, ...props }: BadgeProps): JSX.Element;
134
+
135
+ export declare interface BadgeProps extends HTMLAttributes<HTMLSpanElement> {
136
+ variant?: BadgeVariant;
137
+ }
138
+
139
+ export declare type BadgeVariant = "neutral" | "success" | "warning" | "danger" | "info";
140
+
141
+ export declare interface BreadcrumbItem {
142
+ label: ReactNode;
143
+ href?: string;
144
+ onClick?: () => void;
145
+ }
146
+
147
+ /**
148
+ * Hierarchical navigation breadcrumbs. The last item is rendered as plain
149
+ * text with `aria-current="page"`. Items with neither `href` nor `onClick`
150
+ * also render as text (intermediate but non-clickable).
151
+ */
152
+ export declare function Breadcrumbs({ items, separator, className }: BreadcrumbsProps): JSX.Element;
153
+
154
+ export declare interface BreadcrumbsProps {
155
+ items: BreadcrumbItem[];
156
+ separator?: ReactNode;
157
+ className?: string;
158
+ }
159
+
160
+ /**
161
+ * Primary action button with variants, sizes and a loading state that
162
+ * preserves layout via an absolutely-positioned spinner.
163
+ */
164
+ export declare function Button({ variant, size, loading, fullWidth, leftIcon, rightIcon, disabled, className, children, ...props }: ButtonProps): JSX.Element;
165
+
166
+ export declare interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
167
+ variant?: ButtonVariant;
168
+ size?: ButtonSize;
169
+ loading?: boolean;
170
+ fullWidth?: boolean;
171
+ leftIcon?: ReactNode;
172
+ rightIcon?: ReactNode;
173
+ }
174
+
175
+ export declare type ButtonSize = "sm" | "md" | "lg";
176
+
177
+ export declare type ButtonVariant = "primary" | "secondary" | "danger" | "ghost";
178
+
179
+ /** Recommended `gcTime` presets (milliseconds). */
180
+ export declare const CACHE_TIME: {
181
+ readonly SHORT: number;
182
+ readonly DEFAULT: number;
183
+ readonly LONG: number;
184
+ };
185
+
186
+ /**
187
+ * Card container with optional header (title + actions). Use `flush` when you
188
+ * need to host content (tables, lists) that should not have inner padding.
189
+ */
190
+ export declare function Card({ title, actions, flush, className, children, ...props }: CardProps): JSX.Element;
191
+
192
+ export declare interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
193
+ title?: ReactNode;
194
+ actions?: ReactNode;
195
+ flush?: boolean;
196
+ }
197
+
198
+ export declare type Catalog = Record<string, Messages>;
199
+
200
+ export declare const CEPInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
201
+ value: string;
202
+ onChange: (value: string) => void;
203
+ } & RefAttributes<HTMLInputElement>>;
204
+
205
+ /**
206
+ * Accessible checkbox. Supports a tri-state via `indeterminate` and pairs the
207
+ * input with a label/description column for forms.
208
+ */
209
+ export declare const Checkbox: ForwardRefExoticComponent<CheckboxProps & RefAttributes<HTMLInputElement>>;
210
+
211
+ export declare interface CheckboxProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
212
+ label?: ReactNode;
213
+ description?: ReactNode;
214
+ /** Render the box in the indeterminate state regardless of `checked`. */
215
+ indeterminate?: boolean;
216
+ wrapperClassName?: string;
217
+ }
218
+
219
+ /**
220
+ * Multi-value input. Type a value and press Enter (or comma / Tab) to push a
221
+ * chip. Backspace on empty input removes the last chip.
222
+ */
223
+ export declare function ChipInput({ value, onChange, label, placeholder, helperText, error, commitKeys, normalize, className, }: ChipInputProps): JSX.Element;
224
+
225
+ export declare interface ChipInputProps {
226
+ value: string[];
227
+ onChange: (next: string[]) => void;
228
+ label?: string;
229
+ placeholder?: string;
230
+ helperText?: string;
231
+ error?: string;
232
+ /** Keys that commit the current draft as a chip. Default: Enter, comma, Tab. */
233
+ commitKeys?: string[];
234
+ /** Lowercase + trim each chip + dedupe. Default: true. */
235
+ normalize?: boolean;
236
+ className?: string;
237
+ }
238
+
239
+ declare type ClassValue = string | number | bigint | boolean | null | undefined | ClassValue[];
240
+
241
+ /**
242
+ * Tiny classnames helper. Accepts strings, falsy values and nested arrays.
243
+ *
244
+ * @param values - Class entries, conditionally truthy.
245
+ * @returns A single space-joined class string.
246
+ */
247
+ export declare function cn(...values: ClassValue[]): string;
248
+
249
+ export declare const CNPJInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
250
+ value: string;
251
+ onChange: (value: string) => void;
252
+ } & RefAttributes<HTMLInputElement>>;
253
+
254
+ /**
255
+ * Quick confirmation prompt built on top of {@link Modal}. Use for destructive
256
+ * actions with `variant="danger"`.
257
+ */
258
+ export declare function ConfirmDialog({ open, title, description, confirmLabel, cancelLabel, variant, loading, onConfirm, onCancel, }: ConfirmDialogProps): JSX.Element;
259
+
260
+ export declare interface ConfirmDialogProps {
261
+ open: boolean;
262
+ title: ReactNode;
263
+ description?: ReactNode;
264
+ confirmLabel?: string;
265
+ cancelLabel?: string;
266
+ variant?: "primary" | "danger";
267
+ loading?: boolean;
268
+ onConfirm: () => void | Promise<void>;
269
+ onCancel: () => void;
270
+ }
271
+
272
+ /** Default sink that writes to the browser console. */
273
+ export declare const consoleSink: LoggerSink;
274
+
275
+ /**
276
+ * Dev-friendly adapter that logs every call to `console`. Use as a default
277
+ * before plugging the real provider (Sentry / Datadog / PostHog).
278
+ */
279
+ export declare const consoleTelemetryAdapter: TelemetryAdapter;
280
+
281
+ /** Page-level horizontal container with a max-width preset and side padding. */
282
+ export declare function Container({ size, className, children, ...props }: ContainerProps): JSX.Element;
283
+
284
+ export declare interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
285
+ size?: ContainerSize;
286
+ }
287
+
288
+ export declare type ContainerSize = "sm" | "md" | "lg" | "xl" | "full";
289
+
290
+ export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
291
+ value: string;
292
+ onChange: (value: string) => void;
293
+ } & RefAttributes<HTMLInputElement>>;
294
+
295
+ /**
296
+ * Create a typed HTTP client backed by `fetch`.
297
+ *
298
+ * Handles JSON serialization, query params, bearer auth via `getToken`,
299
+ * automatic refresh + retry on 401 when `refresh` is supplied, and uploads
300
+ * via `FormData`. Throws an `ApiError` on non-2xx responses.
301
+ */
302
+ export declare function createApiClient(config: ApiClientConfig): ApiClient;
303
+
304
+ /**
305
+ * Create an isolated audio player that tracks a single "current" clip.
306
+ * Multiple players coexist independently; use this when several layers of UI
307
+ * need their own playback state.
308
+ */
309
+ export declare function createAudioPlayer(): AudioPlayer;
310
+
311
+ /**
312
+ * Build a typed Zustand auth store with `persist` middleware. Each app passes
313
+ * its own `TUser` shape so the SDK does not own the user model.
314
+ *
315
+ * @example
316
+ * const useAuthStore = createAuthStore<UserResponse>();
317
+ * const { user, token, logout } = useAuthStore();
318
+ */
319
+ export declare function createAuthStore<TUser>(options?: CreateAuthStoreOptions<TUser>): UseBoundStore<Omit<StoreApi<AuthState<TUser>>, "setState" | "persist"> & {
320
+ setState(partial: AuthState<TUser> | Partial<AuthState<TUser>> | ((state: AuthState<TUser>) => AuthState<TUser> | Partial<AuthState<TUser>>), replace?: false | undefined): unknown;
321
+ setState(state: AuthState<TUser> | ((state: AuthState<TUser>) => AuthState<TUser>), replace: true): unknown;
322
+ persist: {
323
+ setOptions: (options: Partial<PersistOptions<AuthState<TUser>, unknown, unknown>>) => void;
324
+ clearStorage: () => void;
325
+ rehydrate: () => Promise<void> | void;
326
+ hasHydrated: () => boolean;
327
+ onHydrate: (fn: (state: AuthState<TUser>) => void) => () => void;
328
+ onFinishHydration: (fn: (state: AuthState<TUser>) => void) => () => void;
329
+ getOptions: () => Partial<PersistOptions<AuthState<TUser>, unknown, unknown>>;
330
+ };
331
+ }>;
332
+
333
+ export declare interface CreateAuthStoreOptions<TUser> {
334
+ /** Persist key used in storage (default: "tempest-auth"). */
335
+ name?: string;
336
+ /** Which storage to persist into (default: localStorage). */
337
+ storage?: "local" | "session";
338
+ /** Initial user (useful for SSR hydration). */
339
+ initialUser?: TUser | null;
340
+ /** Initial token. */
341
+ initialToken?: string | null;
342
+ }
343
+
344
+ /**
345
+ * Open a Server-Sent Events stream with automatic exponential-backoff reconnect.
346
+ *
347
+ * Heartbeat events (default `"ping"`) keep the socket alive without firing
348
+ * `onMessage`. Pass `withCredentials: true` when the backend authenticates via
349
+ * cookies. Call `close()` from the returned controller to tear down.
350
+ *
351
+ * @param url - Full SSE endpoint URL.
352
+ * @param options - Stream configuration and callbacks.
353
+ * @returns A controller exposing `close`, `reconnect` and the current `status`.
354
+ */
355
+ export declare function createEventStream<T = unknown>(url: string, options?: CreateEventStreamOptions<T>): EventStreamController;
356
+
357
+ export declare interface CreateEventStreamOptions<T> {
358
+ /** Send cookies with the EventSource handshake. Default: false. */
359
+ withCredentials?: boolean;
360
+ /** Subscribe to named events in addition to `message`. */
361
+ namedEvents?: readonly string[];
362
+ /** Treat these named events as heartbeat-only (no callback). Default: `["ping"]`. */
363
+ heartbeatEvents?: readonly string[];
364
+ /** Max reconnect attempts. Default: 10. Pass 0 to disable reconnect. */
365
+ maxRetries?: number;
366
+ /** Initial backoff in ms; doubles per attempt, capped at `maxBackoff`. Default: 1000. */
367
+ initialBackoff?: number;
368
+ /** Maximum backoff in ms. Default: 30000. */
369
+ maxBackoff?: number;
370
+ /** Parse `event.data`. Defaults to JSON with raw-string fallback. */
371
+ parser?: (raw: string) => T;
372
+ onOpen?: () => void;
373
+ onMessage?: (message: EventStreamMessage<T>) => void;
374
+ onError?: (error: Event) => void;
375
+ onStatusChange?: (status: EventStreamStatus) => void;
376
+ }
377
+
378
+ /**
379
+ * Create an i18n object with translation, pluralization and Intl helpers.
380
+ *
381
+ * The catalog is a plain `{ [locale]: { [key]: "..." } }` map — bring your
382
+ * own keys, namespaces, or nested-key conventions. The SDK does not enforce
383
+ * a schema so you can plug it into any string-loading pipeline.
384
+ *
385
+ * @example
386
+ * const i18n = createI18n({
387
+ * locale: "pt-BR",
388
+ * fallbackLocale: "en",
389
+ * messages: {
390
+ * "pt-BR": {
391
+ * "greet": "Olá, {name}",
392
+ * "alos_one": "{count} Alô",
393
+ * "alos_other": "{count} Alôs",
394
+ * },
395
+ * "en": { greet: "Hi, {name}", alos_one: "{count} Alo", alos_other: "{count} Alos" },
396
+ * },
397
+ * });
398
+ * i18n.t("greet", { name: "Mau" }); // "Olá, Mau"
399
+ * i18n.plural("alos", 3); // "3 Alôs"
400
+ */
401
+ export declare function createI18n(options: CreateI18nOptions): I18n;
402
+
403
+ export declare interface CreateI18nOptions {
404
+ /** Initial locale. */
405
+ locale: string;
406
+ /** Fallback locale used when a key is missing in the active locale. */
407
+ fallbackLocale?: string;
408
+ /** Catalog `{ [locale]: { [key]: "..." } }`. */
409
+ messages: Catalog;
410
+ }
411
+
412
+ /**
413
+ * Trivial in-memory adapter. Suitable for tests, local development, or as a
414
+ * fallback wrapping the real provider while it loads.
415
+ */
416
+ export declare function createInMemoryFlags(options?: InMemoryFlagsOptions): FeatureFlagsAdapter & {
417
+ set: (key: string, value: FlagValue) => void;
418
+ };
419
+
420
+ /**
421
+ * Create a structured leveled logger. Plug arbitrary sinks (Sentry, Datadog,
422
+ * remote ingestion) by implementing the `LoggerSink` interface.
423
+ */
424
+ export declare function createLogger(options?: CreateLoggerOptions): Logger;
425
+
426
+ export declare interface CreateLoggerOptions {
427
+ /** Lowest level recorded. Default: `"info"`. */
428
+ level?: LogLevel;
429
+ /** Output adapters. Default: a `console.*` sink. */
430
+ sinks?: LoggerSink[];
431
+ /** Initial namespace (prepended to every message). */
432
+ namespace?: string;
433
+ }
434
+
435
+ /**
436
+ * Build a typed IndexedDB-backed store using Dexie. Optionally scope every
437
+ * operation by an `ownerField` (useful for multi-user SSE history, drafts,
438
+ * cache per workspace, etc.).
439
+ *
440
+ * Dexie is an **optional peer dependency** — install it (`npm i dexie`) only
441
+ * when your app needs offline storage.
442
+ *
443
+ * @example
444
+ * type Note = { id: string; owner_id: string; text: string; created_at: string };
445
+ * const notes = createOfflineStore<Note, string>({
446
+ * databaseName: "TempestNotes",
447
+ * version: 1,
448
+ * tableName: "notes",
449
+ * indexes: "&id, owner_id, created_at",
450
+ * ownerField: "owner_id",
451
+ * });
452
+ * await notes.put({ id: "n1", owner_id: "u1", text: "hi", created_at: ... }, "u1");
453
+ * const mine = await notes.list("u1", { orderBy: "created_at", reverse: true });
454
+ */
455
+ export declare function createOfflineStore<TItem, TKey extends string | number = string>(config: OfflineStoreConfig<TItem>): OfflineStore<TItem, TKey>;
456
+
457
+ /**
458
+ * Build a typed query-key factory for a domain. Each entry can be a static
459
+ * tuple or a function returning a tuple. The returned object is `as const`
460
+ * so TanStack Query infers literal keys.
461
+ *
462
+ * @example
463
+ * const userKeys = createQueryKeys("user", {
464
+ * me: () => ["me"] as const,
465
+ * byId: (id: string) => [id] as const,
466
+ * list: (filters: { page: number }) => ["list", filters] as const,
467
+ * });
468
+ * // userKeys.byId("42") === ["user", "42"]
469
+ */
470
+ export declare function createQueryKeys<TKey extends string, TEntries extends Record<string, KeyBuilder | readonly unknown[]>>(scope: TKey, entries: TEntries): {
471
+ all: readonly [TKey];
472
+ } & { [K in keyof TEntries]: TEntries[K] extends KeyBuilder ? (...args: Parameters<TEntries[K]>) => readonly [TKey, ...ReturnType<TEntries[K]>] : TEntries[K] extends readonly unknown[] ? readonly [TKey, ...TEntries[K]] : never; };
473
+
474
+ /**
475
+ * Deduplicate concurrent refresh calls. When multiple 401 responses arrive
476
+ * at once, all of them share the same in-flight `refresh()` promise instead
477
+ * of triggering N parallel refreshes.
478
+ *
479
+ * @example
480
+ * const refresh = createRefreshQueue(() => AuthService.refresh());
481
+ *
482
+ * // In every request that hits 401:
483
+ * await refresh();
484
+ * // ...retry the original request
485
+ */
486
+ export declare function createRefreshQueue(refresh: () => Promise<void>): () => Promise<void>;
487
+
488
+ /**
489
+ * Open a WebSocket with automatic exponential-backoff reconnect, optional
490
+ * heartbeat pings, and typed JSON parsing.
491
+ *
492
+ * @param url - Full ws:// or wss:// URL.
493
+ * @param options - Connection configuration and callbacks.
494
+ * @returns Controller exposing `send`, `close`, `reconnect`, and `status`.
495
+ */
496
+ export declare function createWebSocket<T = unknown>(url: string, options?: CreateWebSocketOptions<T>): WebSocketController;
497
+
498
+ export declare interface CreateWebSocketOptions<T> {
499
+ /** Subprotocol(s) forwarded to the `WebSocket` constructor. */
500
+ protocols?: string | string[];
501
+ /** Max reconnect attempts. Default: 10. Pass 0 to disable. */
502
+ maxRetries?: number;
503
+ /** Initial backoff (ms). Doubles each attempt, capped at `maxBackoff`. Default: 1000. */
504
+ initialBackoff?: number;
505
+ /** Maximum backoff (ms). Default: 30000. */
506
+ maxBackoff?: number;
507
+ /**
508
+ * Ping interval (ms). When set, the client sends `pingPayload` periodically
509
+ * to keep the socket alive. Default: 0 (disabled).
510
+ */
511
+ pingInterval?: number;
512
+ /** Payload sent on each ping. Default: `JSON.stringify({ type: "ping" })`. */
513
+ pingPayload?: string | ArrayBufferLike | Blob | ArrayBufferView;
514
+ /** Parse incoming frames. Default: JSON with raw-string fallback. */
515
+ parser?: (raw: string) => T;
516
+ onOpen?: (event: Event) => void;
517
+ onMessage?: (message: WebSocketMessage<T>) => void;
518
+ onClose?: (event: CloseEvent) => void;
519
+ onError?: (event: Event) => void;
520
+ onStatusChange?: (status: WebSocketStatus) => void;
521
+ }
522
+
523
+ /**
524
+ * Thin wrapper around the native `<input type="date">` (or `datetime-local`,
525
+ * `time`, `month`). For richer pickers, pair with `react-datepicker` directly
526
+ * — this primitive keeps the SDK dep-free.
527
+ */
528
+ export declare const DatePicker: ForwardRefExoticComponent<DatePickerProps & RefAttributes<HTMLInputElement>>;
529
+
530
+ export declare interface DatePickerProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "value" | "onChange"> {
531
+ /** ISO date string (`YYYY-MM-DD`) or empty. */
532
+ value: string;
533
+ onChange: (value: string) => void;
534
+ label?: string;
535
+ helperText?: string;
536
+ error?: string;
537
+ /** Lower bound (`YYYY-MM-DD`). */
538
+ min?: string;
539
+ /** Upper bound (`YYYY-MM-DD`). */
540
+ max?: string;
541
+ /** Mode. `date` (default), `datetime-local`, `time`, or `month`. */
542
+ mode?: "date" | "datetime-local" | "time" | "month";
543
+ wrapperClassName?: string;
544
+ }
545
+
546
+ export declare interface DecodedJWT {
547
+ header: Record<string, unknown>;
548
+ payload: Record<string, unknown> & {
549
+ exp?: number;
550
+ iat?: number;
551
+ sub?: string;
552
+ };
553
+ signature: string;
554
+ }
555
+
556
+ /**
557
+ * Decode a JWT into header/payload/signature. Does **not** verify the
558
+ * signature — for that, do it server-side or use a JOSE library on the
559
+ * client.
560
+ *
561
+ * @throws If the token shape is invalid (missing parts, bad JSON).
562
+ */
563
+ export declare function decodeJWT(token: string): DecodedJWT;
564
+
565
+ export declare type DocumentVisibility = "visible" | "hidden";
566
+
567
+ /**
568
+ * Sliding side panel. Same building blocks as {@link Modal} but anchored to
569
+ * an edge. Locks body scroll while open.
570
+ */
571
+ export declare function Drawer({ open, onClose, placement, title, children, footer, closeOnBackdrop, closeOnEsc, hideCloseButton, className, }: DrawerProps): ReactPortal | null;
572
+
573
+ export declare type DrawerPlacement = "right" | "left" | "top" | "bottom";
574
+
575
+ export declare interface DrawerProps {
576
+ open: boolean;
577
+ onClose: () => void;
578
+ placement?: DrawerPlacement;
579
+ title?: ReactNode;
580
+ children?: ReactNode;
581
+ footer?: ReactNode;
582
+ closeOnBackdrop?: boolean;
583
+ closeOnEsc?: boolean;
584
+ hideCloseButton?: boolean;
585
+ className?: string;
586
+ }
587
+
588
+ export declare interface ElementSize {
589
+ width: number;
590
+ height: number;
591
+ }
592
+
593
+ /** Centered "nothing here yet" placeholder with optional icon and CTA. */
594
+ export declare function EmptyState({ icon, title, description, action, className }: EmptyStateProps): JSX.Element;
595
+
596
+ export declare interface EmptyStateProps {
597
+ icon?: ReactNode;
598
+ title: ReactNode;
599
+ description?: ReactNode;
600
+ action?: ReactNode;
601
+ className?: string;
602
+ }
603
+
604
+ /**
605
+ * Class-based React error boundary with a render-prop or static fallback.
606
+ * Auto-resets when any value in `resetKeys` changes.
607
+ *
608
+ * @example
609
+ * <ErrorBoundary
610
+ * resetKeys={[location.pathname]}
611
+ * onError={(err) => reportError(err)}
612
+ * fallback={({ error, reset }) => (
613
+ * <ErrorState description={error.message} onRetry={reset} />
614
+ * )}
615
+ * >
616
+ * <App />
617
+ * </ErrorBoundary>
618
+ */
619
+ export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
620
+ state: ErrorBoundaryState;
621
+ static getDerivedStateFromError(error: Error): ErrorBoundaryState;
622
+ componentDidCatch(error: Error, info: ErrorInfo): void;
623
+ componentDidUpdate(previousProps: ErrorBoundaryProps): void;
624
+ reset: () => void;
625
+ render(): ReactNode;
626
+ }
627
+
628
+ export declare interface ErrorBoundaryProps {
629
+ children: ReactNode;
630
+ /**
631
+ * Element shown when a descendant throws. Receives the captured error and
632
+ * a `reset` callback that clears the boundary state.
633
+ */
634
+ fallback: ReactNode | ((props: ErrorBoundaryRenderProps) => ReactNode);
635
+ /** Forwarded to your error tracker (Sentry, Datadog, console, etc.). */
636
+ onError?: (error: Error, info: ErrorInfo) => void;
637
+ /**
638
+ * When any value in this array changes, the boundary automatically resets.
639
+ * Useful for clearing the error after a navigation.
640
+ */
641
+ resetKeys?: readonly unknown[];
642
+ }
643
+
644
+ export declare interface ErrorBoundaryRenderProps {
645
+ error: Error;
646
+ reset: () => void;
647
+ }
648
+
649
+ declare interface ErrorBoundaryState {
650
+ error: Error | null;
651
+ }
652
+
653
+ /** Error placeholder with optional retry CTA. Use when a request fails. */
654
+ export declare function ErrorState({ title, description, onRetry, retryLabel, icon, className, }: ErrorStateProps): JSX.Element;
655
+
656
+ export declare interface ErrorStateProps {
657
+ title?: ReactNode;
658
+ description?: ReactNode;
659
+ onRetry?: () => void;
660
+ retryLabel?: string;
661
+ icon?: ReactNode;
662
+ className?: string;
663
+ }
664
+
665
+ export declare interface EventStreamController {
666
+ close: () => void;
667
+ /** Force an immediate reconnect, resetting the retry counter. */
668
+ reconnect: () => void;
669
+ /** Current connection status. */
670
+ readonly status: EventStreamStatus;
671
+ }
672
+
673
+ export declare interface EventStreamMessage<T> {
674
+ /** Server-named event (default `"message"`). */
675
+ event: string;
676
+ /** Parsed payload — JSON-decoded when possible, raw string otherwise. */
677
+ data: T;
678
+ /** Server-supplied id, if any. */
679
+ id?: string;
680
+ /** Raw `MessageEvent` for advanced cases. */
681
+ raw: MessageEvent;
682
+ }
683
+
684
+ export declare type EventStreamStatus = "idle" | "connecting" | "open" | "closed" | "error";
685
+
686
+ export declare interface FeatureFlagsAdapter {
687
+ /** Synchronous lookup of a flag with a default. */
688
+ isEnabled: (key: string, defaultValue?: boolean) => boolean;
689
+ /** Read a string/number/json flag value. */
690
+ get: <T extends FlagValue = FlagValue>(key: string, defaultValue?: T) => T;
691
+ /** Subscribe to flag changes. Optional. */
692
+ onChange?: (listener: () => void) => () => void;
693
+ }
694
+
695
+ /** Inject a feature flags adapter into the tree. */
696
+ export declare function FeatureFlagsProvider({ adapter, children }: FeatureFlagsProviderProps): JSX.Element;
697
+
698
+ export declare interface FeatureFlagsProviderProps {
699
+ adapter: FeatureFlagsAdapter;
700
+ children: ReactNode;
701
+ }
702
+
703
+ /**
704
+ * Drag-and-drop file dropzone. Pair with `uploadWithProgress` from the SDK
705
+ * to wire actual uploads with byte-level progress.
706
+ */
707
+ export declare function FileUpload({ value, onChange, label, accept, multiple, maxSize, onReject, disabled, title, subtitle, className, }: FileUploadProps): JSX.Element;
708
+
709
+ export declare interface FileUploadProps {
710
+ /** Files currently in the dropzone (controlled). */
711
+ value: File[];
712
+ /** Called with the new list when the user adds or removes a file. */
713
+ onChange: (files: File[]) => void;
714
+ label?: string;
715
+ /** Accept attribute forwarded to `<input>`. */
716
+ accept?: string;
717
+ /** Allow multiple files. Default: false. */
718
+ multiple?: boolean;
719
+ /** Max file size in bytes. Files above are rejected via `onReject`. */
720
+ maxSize?: number;
721
+ /** Called with rejected files when they exceed `maxSize` or fail the `accept` filter. */
722
+ onReject?: (rejected: {
723
+ file: File;
724
+ reason: "size" | "type";
725
+ }[]) => void;
726
+ disabled?: boolean;
727
+ /** Title shown on the empty dropzone. */
728
+ title?: string;
729
+ /** Helper line below the title. */
730
+ subtitle?: string;
731
+ className?: string;
732
+ }
733
+
734
+ export declare type FilterPredicate<T> = (item: T, search: string) => boolean;
735
+
736
+ export declare type FlagValue = boolean | string | number | null;
737
+
738
+ /** Format an 11-digit Brazilian CEP-like value as `00000-000`. */
739
+ export declare function formatCEP(value: string): string;
740
+
741
+ /** Format an unmasked CNPJ-shaped value as `00.000.000/0000-00`. */
742
+ export declare function formatCNPJ(value: string): string;
743
+
744
+ /**
745
+ * Apply the Brazilian CPF mask `XXX.XXX.XXX-XX`.
746
+ *
747
+ * @param value - Raw digits or partially masked string.
748
+ * @returns Masked CPF string.
749
+ */
750
+ export declare function formatCPF(value: string): string;
751
+
752
+ /**
753
+ * Format a number as Brazilian Real currency.
754
+ *
755
+ * @param value - The amount in BRL.
756
+ * @returns A locale-formatted string, e.g. "R$ 1.234,56".
757
+ */
758
+ export declare function formatCurrency(value: number): string;
759
+
760
+ /**
761
+ * Format an ISO date or Date instance as `dd/MM/yyyy`.
762
+ *
763
+ * @param value - ISO string or Date.
764
+ * @returns Formatted date string, or empty string when input is invalid.
765
+ */
766
+ export declare function formatDate(value: string | Date): string;
767
+
768
+ /**
769
+ * Format an ISO date or Date instance as `dd/MM/yyyy HH:mm`.
770
+ *
771
+ * @param value - ISO string or Date.
772
+ * @returns Formatted datetime string, or empty string when input is invalid.
773
+ */
774
+ export declare function formatDateTime(value: string | Date): string;
775
+
776
+ /**
777
+ * Format a fraction (0-1) as a percentage with one decimal.
778
+ *
779
+ * @param value - Fraction between 0 and 1.
780
+ * @returns Formatted percent string, e.g. "12,5%".
781
+ */
782
+ export declare function formatPercent(value: number): string;
783
+
784
+ /**
785
+ * Apply the Brazilian phone mask `(XX) XXXXX-XXXX` or `(XX) XXXX-XXXX`.
786
+ *
787
+ * @param value - Raw digits or partially masked string.
788
+ * @returns Masked phone string.
789
+ */
790
+ export declare function formatPhone(value: string): string;
791
+
792
+ /**
793
+ * Generate an RFC4122 v4 idempotency key (UUID). Use as the value for an
794
+ * `Idempotency-Key` header on POST/PATCH requests that must not run twice.
795
+ */
796
+ export declare function generateIdempotencyKey(): string;
797
+
798
+ export declare interface GeolocationState {
799
+ loading: boolean;
800
+ error: GeolocationPositionError | null;
801
+ coords: GeolocationCoordinates | null;
802
+ timestamp: number | null;
803
+ }
804
+
805
+ /**
806
+ * Inline-safe theme resolution intended for early bootstrap (e.g. inside the
807
+ * `<head>` script that prevents the flash of incorrect theme). Reads from
808
+ * localStorage and falls back to `prefers-color-scheme`.
809
+ */
810
+ export declare function getInitialTheme(options?: GetInitialThemeOptions): ResolvedTheme;
811
+
812
+ export declare interface GetInitialThemeOptions {
813
+ /** localStorage key. Default: `"tempest-theme"`. */
814
+ storageKey?: string;
815
+ /** Theme used when nothing is stored and the user has no system preference. */
816
+ defaultTheme?: ThemeMode;
817
+ }
818
+
819
+ /** Simple CSS-Grid wrapper for equal-width or custom column layouts. */
820
+ export declare function Grid({ columns, gap, className, style, children, ...props }: GridProps): JSX.Element;
821
+
822
+ export declare interface GridProps extends HTMLAttributes<HTMLDivElement> {
823
+ /** Number of columns or a custom `grid-template-columns` value. */
824
+ columns?: number | string;
825
+ /** Gap as a CSS length. Numbers map to a multiple of the 4px scale. */
826
+ gap?: number | string;
827
+ children?: ReactNode;
828
+ }
829
+
830
+ export declare interface I18n {
831
+ /** Currently active locale. */
832
+ locale: string;
833
+ /** Fallback locale (or `null` when not configured). */
834
+ fallbackLocale: string | null;
835
+ /**
836
+ * Translate `key`, interpolating `{name}` placeholders from `params`.
837
+ * Falls back to the configured fallback locale, then to the key itself.
838
+ */
839
+ t: (key: string, params?: InterpolationValues) => string;
840
+ /**
841
+ * Plural-aware translation. Tries `${key}_one` for `count === 1` and
842
+ * `${key}_other` otherwise, with `{count}` available for interpolation.
843
+ */
844
+ plural: (key: string, count: number, params?: InterpolationValues) => string;
845
+ /** Format a number using `Intl.NumberFormat` on the active locale. */
846
+ formatNumber: (value: number, options?: Intl.NumberFormatOptions) => string;
847
+ /** Format a Date using `Intl.DateTimeFormat` on the active locale. */
848
+ formatDate: (value: Date | string, options?: Intl.DateTimeFormatOptions) => string;
849
+ /** Build a new `I18n` instance pointing at a different locale. */
850
+ withLocale: (locale: string) => I18n;
851
+ }
852
+
853
+ export declare interface I18nContextValue extends I18n {
854
+ /** Switch the active locale. Persisted when `storageKey` is set. */
855
+ setLocale: (locale: string) => void;
856
+ /** Locales available in the catalog. */
857
+ availableLocales: string[];
858
+ }
859
+
860
+ /**
861
+ * React provider for the SDK's lightweight i18n. Exposes the translation
862
+ * helpers and a `setLocale` setter to children.
863
+ */
864
+ export declare function I18nProvider({ children, locale: initialLocale, fallbackLocale, messages, storageKey, }: I18nProviderProps): JSX.Element;
865
+
866
+ export declare interface I18nProviderProps {
867
+ children: ReactNode;
868
+ /** Initial locale. */
869
+ locale: string;
870
+ /** Fallback locale used when a key is missing. */
871
+ fallbackLocale?: string;
872
+ /** Translation catalog. */
873
+ messages: Catalog;
874
+ /** localStorage key for persisting the user choice. Pass `null` to disable. Default: `"tempest-locale"`. */
875
+ storageKey?: string | null;
876
+ }
877
+
878
+ export declare interface InMemoryFlagsOptions {
879
+ initial?: Record<string, FlagValue>;
880
+ }
881
+
882
+ /**
883
+ * Labelled text input with helper/error slots and optional adornment icons.
884
+ * Forwards refs to the underlying `<input>` for integration with form libraries.
885
+ */
886
+ export declare const Input: ForwardRefExoticComponent<InputProps & RefAttributes<HTMLInputElement>>;
887
+
888
+ export declare interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
889
+ label?: string;
890
+ helperText?: string;
891
+ error?: string;
892
+ leftIcon?: ReactNode;
893
+ rightIcon?: ReactNode;
894
+ wrapperClassName?: string;
895
+ }
896
+
897
+ /**
898
+ * Install a `notificationclick` handler that focuses an existing client when
899
+ * possible and falls back to opening a new window.
900
+ */
901
+ export declare function installNotificationClickHandler(options?: InstallNotificationClickHandlerOptions): void;
902
+
903
+ export declare interface InstallNotificationClickHandlerOptions {
904
+ /** Resolve the destination URL from the notification data. Default: `data.url`. */
905
+ resolveUrl?: (data: unknown) => string;
906
+ }
907
+
908
+ /**
909
+ * Install a `push` event listener that parses the payload as JSON (with a
910
+ * plain-text fallback) and shows a notification.
911
+ */
912
+ export declare function installPushHandler(options?: InstallPushHandlerOptions): void;
913
+
914
+ export declare interface InstallPushHandlerOptions {
915
+ /** Title used when the payload omits one. */
916
+ defaultTitle?: string;
917
+ /** Icon used when the payload omits one. */
918
+ defaultIcon?: string;
919
+ /** Badge image (mobile). */
920
+ defaultBadge?: string;
921
+ /**
922
+ * Transform the raw payload before showing the notification. Return `null`
923
+ * to suppress the notification entirely (e.g. silent pings).
924
+ */
925
+ transform?: (payload: PushPayload) => PushPayload | null;
926
+ }
927
+
928
+ /**
929
+ * Install a `message` listener that activates a waiting worker when the host
930
+ * app sends `{ type: "SKIP_WAITING" }`.
931
+ */
932
+ export declare function installSkipWaitingListener(): void;
933
+
934
+ export declare type InterpolationValues = Record<string, string | number>;
935
+
936
+ /**
937
+ * Return true when the JWT's `exp` claim is in the past (or missing).
938
+ *
939
+ * @param token - JWT to inspect.
940
+ * @param leewaySeconds - Treat tokens expiring within this window as expired.
941
+ */
942
+ export declare function isJWTExpired(token: string, leewaySeconds?: number): boolean;
943
+
944
+ /**
945
+ * Convenience check for environments where the Push API is unavailable
946
+ * (Safari iOS without PWA install, older browsers, SSR, etc.).
947
+ */
948
+ export declare function isPushSupported(): boolean;
949
+
950
+ /** True when the Web Share API is available in this environment. */
951
+ export declare function isShareSupported(): boolean;
952
+
953
+ export declare interface KeyboardShortcut {
954
+ /** Key name (`"k"`, `"Enter"`, `"Escape"`, `"ArrowDown"`, etc.). Case-insensitive. */
955
+ key: string;
956
+ ctrl?: boolean;
957
+ meta?: boolean;
958
+ shift?: boolean;
959
+ alt?: boolean;
960
+ /** Match either Ctrl or Cmd. Useful for cross-OS shortcuts. */
961
+ mod?: boolean;
962
+ }
963
+
964
+ declare type KeyBuilder = (...args: any[]) => readonly unknown[];
965
+
966
+ /**
967
+ * Wrap `React.lazy` with automatic retry. Common cause of failure:
968
+ * deployed-then-cached `index.html` references chunk filenames that no
969
+ * longer exist. Retrying after a short delay typically picks up the new
970
+ * bundle; a final `location.reload()` recovers from stale `index.html`.
971
+ *
972
+ * @example
973
+ * const Settings = lazyWithRetry(() => import("./Settings"));
974
+ */
975
+ export declare function lazyWithRetry<T extends ComponentType<unknown>>(factory: () => Promise<{
976
+ default: T;
977
+ }>, options?: LazyWithRetryOptions): ReturnType<typeof lazy<T>>;
978
+
979
+ export declare interface LazyWithRetryOptions {
980
+ /** Max attempts. Default: 3. */
981
+ retries?: number;
982
+ /** Initial delay (ms) before retrying. Default: 400. */
983
+ initialDelay?: number;
984
+ /**
985
+ * Reload the page after every retry fails. Helps when the stale chunk
986
+ * error is caused by an old `index.html` referencing deleted bundles.
987
+ * Default: true.
988
+ */
989
+ reloadOnFinalFailure?: boolean;
990
+ }
991
+
992
+ export declare interface ListOptions<TItem> {
993
+ /** Property to order by. Default: `keyPath`. */
994
+ orderBy?: keyof TItem & string;
995
+ /** Reverse the ordering. Default: false. */
996
+ reverse?: boolean;
997
+ /** Maximum number of items to return. */
998
+ limit?: number;
999
+ /** Skip this many items from the start of the result set. */
1000
+ offset?: number;
1001
+ /** Custom predicate applied after the index query. */
1002
+ filter?: (item: TItem) => boolean;
1003
+ }
1004
+
1005
+ export declare interface LogEntry {
1006
+ level: LogLevel;
1007
+ message: string;
1008
+ context?: Record<string, unknown>;
1009
+ timestamp: number;
1010
+ }
1011
+
1012
+ export declare interface Logger {
1013
+ debug: (message: string, context?: Record<string, unknown>) => void;
1014
+ info: (message: string, context?: Record<string, unknown>) => void;
1015
+ warn: (message: string, context?: Record<string, unknown>) => void;
1016
+ error: (message: string, context?: Record<string, unknown>) => void;
1017
+ /** Build a child logger that prefixes the namespace to each message. */
1018
+ child: (namespace: string) => Logger;
1019
+ }
1020
+
1021
+ export declare interface LoggerSink {
1022
+ (entry: LogEntry): void;
1023
+ }
1024
+
1025
+ export declare type LogLevel = "debug" | "info" | "warn" | "error";
1026
+
1027
+ export declare type Messages = Record<string, string>;
1028
+
1029
+ /**
1030
+ * Portal-rendered modal dialog with backdrop, Esc handler, and slots for
1031
+ * header/body/footer. Locks body scroll while open.
1032
+ */
1033
+ export declare function Modal({ open, onClose, title, children, footer, size, closeOnBackdrop, closeOnEsc, className, hideCloseButton, }: ModalProps): ReactPortal | null;
1034
+
1035
+ export declare interface ModalProps {
1036
+ open: boolean;
1037
+ onClose: () => void;
1038
+ title?: ReactNode;
1039
+ children?: ReactNode;
1040
+ footer?: ReactNode;
1041
+ size?: ModalSize;
1042
+ closeOnBackdrop?: boolean;
1043
+ closeOnEsc?: boolean;
1044
+ className?: string;
1045
+ hideCloseButton?: boolean;
1046
+ }
1047
+
1048
+ export declare type ModalSize = "sm" | "md" | "lg" | "xl";
1049
+
1050
+ /**
1051
+ * Currency-masked input. Stores the value as an integer number of cents to
1052
+ * avoid floating-point error. Suitable for `react-hook-form` once you adapt
1053
+ * the field to expose cents.
1054
+ */
1055
+ export declare const MoneyInput: ForwardRefExoticComponent<MoneyInputProps & RefAttributes<HTMLInputElement>>;
1056
+
1057
+ export declare interface MoneyInputProps extends Omit<InputProps, "value" | "onChange" | "type"> {
1058
+ /** Cents (integer). Internally treated as 1/100 of the currency unit. */
1059
+ value: number;
1060
+ onChange: (cents: number) => void;
1061
+ /** Currency code for `Intl.NumberFormat`. Default: `"BRL"`. */
1062
+ currency?: string;
1063
+ /** Locale for `Intl.NumberFormat`. Default: `"pt-BR"`. */
1064
+ locale?: string;
1065
+ }
1066
+
1067
+ export declare interface OfflineStore<TItem, TKey extends string | number> {
1068
+ /** Insert or replace a record. */
1069
+ put: (item: TItem, owner?: string) => Promise<TKey>;
1070
+ /** Insert or replace multiple records in a single transaction. */
1071
+ bulkPut: (items: TItem[], owner?: string) => Promise<TKey>;
1072
+ /** Fetch one record by its primary key. */
1073
+ get: (key: TKey) => Promise<TItem | undefined>;
1074
+ /** List records, optionally scoped to `owner` when `ownerField` is configured. */
1075
+ list: (owner?: string, options?: ListOptions<TItem>) => Promise<TItem[]>;
1076
+ /** Partial update by primary key. Returns the number of records changed. */
1077
+ update: (key: TKey, changes: Partial<TItem>) => Promise<number>;
1078
+ /** Apply a modification to every record matching `owner`. */
1079
+ updateMany: (owner: string | undefined, changes: Partial<TItem>) => Promise<number>;
1080
+ /** Delete one record by primary key. */
1081
+ delete: (key: TKey) => Promise<void>;
1082
+ /** Delete every record matching `owner` (or the entire table when no scope is set). */
1083
+ clear: (owner?: string) => Promise<void>;
1084
+ /** Count records, optionally scoped to `owner`. */
1085
+ count: (owner?: string) => Promise<number>;
1086
+ /** Raw Dexie table for advanced queries. */
1087
+ raw: Table_2<TItem, TKey>;
1088
+ /** Underlying Dexie instance. */
1089
+ db: default_2;
1090
+ }
1091
+
1092
+ export declare interface OfflineStoreConfig<TItem> {
1093
+ /** IndexedDB database name. */
1094
+ databaseName: string;
1095
+ /** Schema version. Bump when changing indexes; pair with a migration if needed. */
1096
+ version: number;
1097
+ /** Object-store name. */
1098
+ tableName: string;
1099
+ /**
1100
+ * Dexie index definition for the table. Use `&` for the primary key
1101
+ * (unique), e.g. `"&id, owner_id, created_at"`. See Dexie docs for the
1102
+ * full syntax.
1103
+ */
1104
+ indexes: string;
1105
+ /** Property used as the primary key (default: `"id"`). */
1106
+ keyPath?: keyof TItem & string;
1107
+ /**
1108
+ * Optional owner scoping. When set, every read/write method honors the
1109
+ * `owner` argument and persists it on each record (e.g. multi-tenant
1110
+ * notifications keyed by `user_id`).
1111
+ */
1112
+ ownerField?: keyof TItem & string;
1113
+ }
1114
+
1115
+ /**
1116
+ * Numeric pagination controls. Pair with {@link usePagination} for state.
1117
+ */
1118
+ export declare function Pagination({ page, totalPages, onPageChange, pageSize, onPageSizeChange, pageSizeOptions, totalItems, siblingCount, className, }: PaginationProps): JSX.Element | null;
1119
+
1120
+ export declare interface PaginationProps {
1121
+ page: number;
1122
+ totalPages: number;
1123
+ onPageChange: (page: number) => void;
1124
+ pageSize?: number;
1125
+ onPageSizeChange?: (size: number) => void;
1126
+ pageSizeOptions?: number[];
1127
+ /** Total items count; if provided, renders the summary text. */
1128
+ totalItems?: number;
1129
+ /** Max number of numbered page buttons to show. Default 7. */
1130
+ siblingCount?: number;
1131
+ className?: string;
1132
+ }
1133
+
1134
+ /**
1135
+ * Validate an unknown response payload against a zod schema.
1136
+ *
1137
+ * In development, throws a detailed error pointing at the divergent field.
1138
+ * In production, throws a generic error so internals do not leak to users.
1139
+ *
1140
+ * @param schema - The zod schema to parse against.
1141
+ * @param raw - The raw response payload.
1142
+ * @param context - A label used in error messages, e.g. "POST /auth/login".
1143
+ * @returns The parsed, typed payload.
1144
+ */
1145
+ export declare function parseResponse<TSchema extends z.ZodTypeAny>(schema: TSchema, raw: unknown, context: string): z.infer<TSchema>;
1146
+
1147
+ export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
1148
+ value: string;
1149
+ onChange: (value: string) => void;
1150
+ } & RefAttributes<HTMLInputElement>>;
1151
+
1152
+ /**
1153
+ * Convenience wrapper around a shared {@link AudioPlayer}. Use this for
1154
+ * one-off notification sounds. For more complex flows (e.g. several
1155
+ * simultaneous channels), build a dedicated player with {@link createAudioPlayer}.
1156
+ */
1157
+ export declare function playAudio(src: string, options?: PlayAudioOptions): Promise<HTMLAudioElement | null>;
1158
+
1159
+ export declare interface PlayAudioOptions {
1160
+ /** Volume between 0 and 1. Default: 1. */
1161
+ volume?: number;
1162
+ /** Loop the clip. Default: false. */
1163
+ loop?: boolean;
1164
+ /** Begin playback immediately. Default: true. */
1165
+ autoplay?: boolean;
1166
+ /** Stop the previous clip managed by this player. Default: false. */
1167
+ stopPrevious?: boolean;
1168
+ /** Fired when playback ends naturally. */
1169
+ onEnded?: () => void;
1170
+ /** Fired on playback error. */
1171
+ onError?: (error: unknown) => void;
1172
+ }
1173
+
1174
+ /** Linear progress bar with determinate / indeterminate modes. */
1175
+ export declare function Progress({ value, max, variant, indeterminate, showLabel, label, className, }: ProgressProps): JSX.Element;
1176
+
1177
+ export declare interface ProgressProps {
1178
+ /** Value between 0 and `max` (or 0-100 by default). Ignored when `indeterminate`. */
1179
+ value?: number;
1180
+ max?: number;
1181
+ variant?: ProgressVariant;
1182
+ /** Show an animated indeterminate bar. Default: false. */
1183
+ indeterminate?: boolean;
1184
+ /** Render a numeric label "x% / max" above the bar. Default: false. */
1185
+ showLabel?: boolean;
1186
+ /** Optional left-aligned descriptor (e.g. "Enviando arquivo…"). */
1187
+ label?: string;
1188
+ className?: string;
1189
+ }
1190
+
1191
+ export declare type ProgressVariant = "primary" | "success" | "warning" | "danger";
1192
+
1193
+ /**
1194
+ * Service-worker context helpers for handling `push` and `notificationclick`
1195
+ * events. Import these inside your own `sw.ts` — they expect to run in the
1196
+ * service-worker global scope, not in the main thread.
1197
+ *
1198
+ * @example
1199
+ * /// <reference lib="webworker" />
1200
+ * import { installPushHandler, installNotificationClickHandler } from "tempest-react-sdk";
1201
+ *
1202
+ * installPushHandler({ defaultIcon: "/icons/Logo.png" });
1203
+ * installNotificationClickHandler();
1204
+ */
1205
+ export declare interface PushPayload {
1206
+ title?: string;
1207
+ body?: string;
1208
+ icon?: string;
1209
+ badge?: string;
1210
+ image?: string;
1211
+ tag?: string;
1212
+ url?: string;
1213
+ /** Arbitrary extra data forwarded to `event.notification.data`. */
1214
+ data?: Record<string, unknown>;
1215
+ }
1216
+
1217
+ /**
1218
+ * Wrapper around `QueryClientProvider` that bootstraps a `QueryClient` with
1219
+ * sane SDK defaults (5-minute stale time, 30-minute gc time, 1 retry).
1220
+ */
1221
+ export declare function QueryProvider({ children, client, defaultOptions }: QueryProviderProps): JSX.Element;
1222
+
1223
+ export declare interface QueryProviderProps {
1224
+ children: ReactNode;
1225
+ /** Pass an existing client to share it across roots. */
1226
+ client?: QueryClient;
1227
+ /** Overrides for the default options applied when no `client` is provided. */
1228
+ defaultOptions?: DefaultOptions;
1229
+ }
1230
+
1231
+ /**
1232
+ * Single radio button. Inside a {@link RadioGroup}, name/checked/onChange are
1233
+ * managed by the group; outside, behaves as a regular radio input.
1234
+ */
1235
+ export declare const Radio: ForwardRefExoticComponent<RadioProps & RefAttributes<HTMLInputElement>>;
1236
+
1237
+ /**
1238
+ * Wraps multiple {@link Radio} children and coordinates selection via context.
1239
+ * Pass `value` for controlled mode or `defaultValue` for uncontrolled.
1240
+ */
1241
+ export declare function RadioGroup({ value, defaultValue, onChange, name, disabled, horizontal, className, children, }: RadioGroupProps): JSX.Element;
1242
+
1243
+ export declare interface RadioGroupProps {
1244
+ /** Selected value (controlled). */
1245
+ value?: string;
1246
+ /** Default selected value (uncontrolled). */
1247
+ defaultValue?: string;
1248
+ /** Called when the selection changes. */
1249
+ onChange?: (value: string) => void;
1250
+ /** `name` attribute applied to every Radio inside. Auto-generated if omitted. */
1251
+ name?: string;
1252
+ /** Disable every Radio inside. */
1253
+ disabled?: boolean;
1254
+ /** Lay out radios horizontally. Default: false (column). */
1255
+ horizontal?: boolean;
1256
+ className?: string;
1257
+ children: ReactNode;
1258
+ }
1259
+
1260
+ export declare interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
1261
+ label?: ReactNode;
1262
+ description?: ReactNode;
1263
+ value: string;
1264
+ wrapperClassName?: string;
1265
+ }
1266
+
1267
+ /** Recommended refetch intervals (milliseconds). */
1268
+ export declare const REFETCH_TIME: {
1269
+ readonly REALTIME: number;
1270
+ readonly FAST: number;
1271
+ readonly DEFAULT: number;
1272
+ readonly SLOW: number;
1273
+ };
1274
+
1275
+ /**
1276
+ * Register a service worker with consistent update-detection wiring.
1277
+ *
1278
+ * Skips silently when the runtime has no `serviceWorker` support. The host
1279
+ * app keeps full control over the SW file — this helper only handles the
1280
+ * boilerplate around `register()` and `updatefound`.
1281
+ *
1282
+ * @returns The registration when it succeeds, or `null` when unsupported.
1283
+ */
1284
+ export declare function registerServiceWorker(options: RegisterServiceWorkerOptions): Promise<ServiceWorkerRegistration | null>;
1285
+
1286
+ export declare interface RegisterServiceWorkerOptions {
1287
+ /** Public URL of the compiled service worker file (e.g. `/sw.js`). */
1288
+ url: string;
1289
+ /** SW scope (default: SW directory). */
1290
+ scope?: string;
1291
+ /** Called once the registration is active. */
1292
+ onReady?: (registration: ServiceWorkerRegistration) => void;
1293
+ /**
1294
+ * Called when a new worker has finished installing while another worker
1295
+ * still controls the page. The host app typically prompts the user to
1296
+ * reload and then calls {@link skipWaiting} on the returned worker.
1297
+ */
1298
+ onUpdate?: (waiting: ServiceWorker, registration: ServiceWorkerRegistration) => void;
1299
+ /** Called on registration failure. */
1300
+ onError?: (error: unknown) => void;
1301
+ }
1302
+
1303
+ export declare interface RequestOptions extends Omit<RequestInit, "body"> {
1304
+ body?: unknown;
1305
+ params?: Record<string, string | number | boolean | undefined | null>;
1306
+ }
1307
+
1308
+ export declare type ResolvedTheme = "light" | "dark";
1309
+
1310
+ declare type Resolver<T> = (values: unknown, context: unknown, options: {
1311
+ criteriaMode?: "firstError" | "all";
1312
+ }) => Promise<ResolverOutput<T>>;
1313
+
1314
+ declare interface ResolverError {
1315
+ type: string;
1316
+ message: string;
1317
+ }
1318
+
1319
+ declare interface ResolverOutput<T> {
1320
+ values: T | object;
1321
+ errors: Record<string, ResolverError | object>;
1322
+ }
1323
+
1324
+ /**
1325
+ * Run `factory()` with exponential backoff. Each attempt awaits an
1326
+ * increasing delay capped at `maxDelay`. Throws the last error if every
1327
+ * attempt fails.
1328
+ *
1329
+ * @example
1330
+ * const data = await retry(() => api.get("/flaky"), { retries: 5 });
1331
+ */
1332
+ export declare function retry<T>(factory: () => Promise<T>, options?: RetryOptions): Promise<T>;
1333
+
1334
+ export declare interface RetryOptions {
1335
+ /** Max attempts (including the first). Default: 3. */
1336
+ retries?: number;
1337
+ /** Initial backoff in ms. Doubles each attempt, capped at `maxDelay`. Default: 300. */
1338
+ initialDelay?: number;
1339
+ /** Maximum delay between attempts. Default: 10_000. */
1340
+ maxDelay?: number;
1341
+ /**
1342
+ * Return false to stop retrying for a specific error.
1343
+ * Default: retry on any thrown error.
1344
+ */
1345
+ shouldRetry?: (error: unknown, attempt: number) => boolean;
1346
+ /** Called before each retry with the upcoming delay. */
1347
+ onRetry?: (info: {
1348
+ attempt: number;
1349
+ delay: number;
1350
+ error: unknown;
1351
+ }) => void;
1352
+ /** Cancel pending retries. */
1353
+ signal?: AbortSignal;
1354
+ }
1355
+
1356
+ /**
1357
+ * Search input with magnifier icon and a clear button. Controlled component:
1358
+ * pass `value` and `onChange`.
1359
+ */
1360
+ export declare const SearchBar: ForwardRefExoticComponent<SearchBarProps & RefAttributes<HTMLInputElement>>;
1361
+
1362
+ export declare interface SearchBarProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "onChange"> {
1363
+ value: string;
1364
+ onChange: (value: string) => void;
1365
+ onClear?: () => void;
1366
+ wrapperClassName?: string;
1367
+ }
1368
+
1369
+ /**
1370
+ * Native `<select>` wrapper with label/helper/error slots. Either provide
1371
+ * `options` for a quick render, or pass `<option>` children directly.
1372
+ */
1373
+ export declare const Select: ForwardRefExoticComponent<SelectProps & RefAttributes<HTMLSelectElement>>;
1374
+
1375
+ export declare interface SelectOption {
1376
+ value: string | number;
1377
+ label: string;
1378
+ disabled?: boolean;
1379
+ }
1380
+
1381
+ export declare interface SelectProps extends SelectHTMLAttributes<HTMLSelectElement> {
1382
+ label?: string;
1383
+ helperText?: string;
1384
+ error?: string;
1385
+ options?: SelectOption[];
1386
+ placeholder?: string;
1387
+ wrapperClassName?: string;
1388
+ }
1389
+
1390
+ /**
1391
+ * Wrap the Web Share API with a uniform result object. Falls through to
1392
+ * `unsupported: true` when the browser lacks `navigator.share`, leaving the
1393
+ * caller free to render a custom fallback (copy-link, social buttons).
1394
+ */
1395
+ export declare function share(payload: SharePayload): Promise<ShareResult>;
1396
+
1397
+ export declare interface SharePayload {
1398
+ title?: string;
1399
+ text?: string;
1400
+ url?: string;
1401
+ /** Files to share (supported only on a subset of browsers). */
1402
+ files?: File[];
1403
+ }
1404
+
1405
+ export declare interface ShareResult {
1406
+ /** True when `navigator.share` resolved successfully. */
1407
+ shared: boolean;
1408
+ /** True when the platform did not support the requested payload. */
1409
+ unsupported: boolean;
1410
+ /** True when the user cancelled the share dialog. */
1411
+ cancelled: boolean;
1412
+ error?: unknown;
1413
+ }
1414
+
1415
+ /** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
1416
+ export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
1417
+
1418
+ export declare interface SkeletonProps {
1419
+ variant?: "rect" | "text" | "circle";
1420
+ width?: number | string;
1421
+ height?: number | string;
1422
+ className?: string;
1423
+ style?: CSSProperties;
1424
+ }
1425
+
1426
+ /**
1427
+ * Tell a waiting worker to activate immediately. Pair with `onUpdate` to roll
1428
+ * out updates after the user confirms a reload prompt.
1429
+ */
1430
+ export declare function skipWaiting(worker: ServiceWorker): void;
1431
+
1432
+ /** Loading spinner with three preset sizes. Provide `label` for screen readers. */
1433
+ export declare function Spinner({ size, className, label }: SpinnerProps): JSX.Element;
1434
+
1435
+ export declare interface SpinnerProps {
1436
+ size?: SpinnerSize;
1437
+ className?: string;
1438
+ label?: string;
1439
+ }
1440
+
1441
+ export declare type SpinnerSize = "sm" | "md" | "lg";
1442
+
1443
+ /** Flex-based vertical or horizontal stack with a numeric `gap`. */
1444
+ export declare function Stack({ direction, gap, align, justify, wrap, className, style, children, ...props }: StackProps): JSX.Element;
1445
+
1446
+ export declare type StackAlign = "start" | "center" | "end" | "stretch";
1447
+
1448
+ export declare type StackJustify = "start" | "center" | "end" | "between";
1449
+
1450
+ export declare interface StackProps extends HTMLAttributes<HTMLDivElement> {
1451
+ /** Direction. Default `vertical`. */
1452
+ direction?: "vertical" | "horizontal";
1453
+ /** Gap as a CSS length. Numbers map to a multiple of the 4px scale. */
1454
+ gap?: number | string;
1455
+ align?: StackAlign;
1456
+ justify?: StackJustify;
1457
+ wrap?: boolean;
1458
+ children?: ReactNode;
1459
+ }
1460
+
1461
+ /** Recommended `staleTime` presets (milliseconds). */
1462
+ export declare const STALE_TIME: {
1463
+ readonly SHORT: number;
1464
+ readonly DEFAULT: number;
1465
+ readonly LONG: number;
1466
+ readonly INFINITE: number;
1467
+ };
1468
+
1469
+ export declare interface StepItem {
1470
+ label: ReactNode;
1471
+ }
1472
+
1473
+ /**
1474
+ * Linear progress indicator for multi-step flows. Steps before `current`
1475
+ * render as completed; the step at `current` is active; later steps are
1476
+ * upcoming.
1477
+ */
1478
+ export declare function Stepper({ steps, current, orientation, className }: StepperProps): JSX.Element;
1479
+
1480
+ export declare interface StepperProps {
1481
+ steps: StepItem[];
1482
+ /** Index of the currently active step (0-based). */
1483
+ current: number;
1484
+ orientation?: "horizontal" | "vertical";
1485
+ className?: string;
1486
+ }
1487
+
1488
+ /** Stop the clip currently playing on the shared default player. */
1489
+ export declare function stopAudio(): void;
1490
+
1491
+ /**
1492
+ * Typed wrapper around `localStorage` that JSON-encodes values and
1493
+ * silently handles environments where storage is unavailable (SSR, private mode).
1494
+ */
1495
+ export declare const storage: {
1496
+ get<T>(key: string, fallback: T): T;
1497
+ set<T>(key: string, value: T): void;
1498
+ remove(key: string): void;
1499
+ };
1500
+
1501
+ /** Toggle switch backed by a checkbox input. Accessible via keyboard. */
1502
+ export declare const Switch: ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLInputElement>>;
1503
+
1504
+ export declare interface SwitchProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type"> {
1505
+ label?: ReactNode;
1506
+ wrapperClassName?: string;
1507
+ }
1508
+
1509
+ export declare interface TabItem {
1510
+ id: string;
1511
+ label: ReactNode;
1512
+ content: ReactNode;
1513
+ disabled?: boolean;
1514
+ }
1515
+
1516
+ /**
1517
+ * Lightweight table that maps a list of rows through declarative `columns`.
1518
+ * Provide `rowKey` so React reconciliation works. Rows become clickable when
1519
+ * `onRowClick` is supplied.
1520
+ */
1521
+ export declare function Table<T>({ columns, data, rowKey, onRowClick, emptyMessage, className, }: TableProps<T>): JSX.Element;
1522
+
1523
+ export declare type TableAlign = "left" | "right" | "center";
1524
+
1525
+ export declare interface TableColumn<T> {
1526
+ key: string;
1527
+ header: ReactNode;
1528
+ /** Render the cell content. Defaults to `row[key]` if not provided. */
1529
+ render?: (row: T, index: number) => ReactNode;
1530
+ align?: TableAlign;
1531
+ width?: string | number;
1532
+ className?: string;
1533
+ }
1534
+
1535
+ export declare interface TableProps<T> {
1536
+ columns: TableColumn<T>[];
1537
+ data: T[];
1538
+ rowKey: (row: T, index: number) => string | number;
1539
+ onRowClick?: (row: T) => void;
1540
+ emptyMessage?: ReactNode;
1541
+ className?: string;
1542
+ }
1543
+
1544
+ /**
1545
+ * Accessible tabs with an underline (default) or pill variant. Controlled via
1546
+ * `activeId` + `onChange` or uncontrolled via `defaultId`.
1547
+ */
1548
+ export declare function Tabs({ items, defaultId, activeId, onChange, variant, className, }: TabsProps): JSX.Element;
1549
+
1550
+ export declare interface TabsProps {
1551
+ items: TabItem[];
1552
+ /** Initial active tab id. Defaults to the first non-disabled item. */
1553
+ defaultId?: string;
1554
+ /** Controlled active id. When provided, ignore internal state. */
1555
+ activeId?: string;
1556
+ onChange?: (id: string) => void;
1557
+ variant?: "underline" | "pill";
1558
+ className?: string;
1559
+ }
1560
+
1561
+ export declare interface TelemetryAdapter {
1562
+ /** Optional. Called when the provider mounts. */
1563
+ init?: () => void | Promise<void>;
1564
+ /** Associate the current session with a user. */
1565
+ identify: (user: TelemetryUser | null) => void;
1566
+ /** Track a discrete event. */
1567
+ track: (event: TelemetryEvent) => void;
1568
+ /** Report an error / exception with optional context. */
1569
+ captureException: (error: unknown, context?: Record<string, unknown>) => void;
1570
+ /** Flush queued events (e.g. before page unload). */
1571
+ flush?: () => Promise<void> | void;
1572
+ }
1573
+
1574
+ export declare interface TelemetryEvent {
1575
+ name: string;
1576
+ properties?: Record<string, unknown>;
1577
+ }
1578
+
1579
+ /**
1580
+ * Inject a telemetry adapter into the tree. Apps can swap implementations
1581
+ * (Sentry, Datadog, PostHog, console) without touching call sites.
1582
+ */
1583
+ export declare function TelemetryProvider({ adapter, children }: TelemetryProviderProps): JSX.Element;
1584
+
1585
+ export declare interface TelemetryProviderProps {
1586
+ adapter: TelemetryAdapter;
1587
+ children: ReactNode;
1588
+ }
1589
+
1590
+ export declare interface TelemetryUser {
1591
+ id?: string;
1592
+ email?: string;
1593
+ name?: string;
1594
+ /** Free-form trait bag (plan, role, region, etc.). */
1595
+ traits?: Record<string, unknown>;
1596
+ }
1597
+
1598
+ /**
1599
+ * Multi-line text input. Mirrors the {@link Input} API for label/helper/error.
1600
+ */
1601
+ export declare const Textarea: ForwardRefExoticComponent<TextareaProps & RefAttributes<HTMLTextAreaElement>>;
1602
+
1603
+ export declare interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
1604
+ label?: string;
1605
+ helperText?: string;
1606
+ error?: string;
1607
+ wrapperClassName?: string;
1608
+ }
1609
+
1610
+ export declare interface ThemeContextValue {
1611
+ /** Raw user preference (light / dark / system). */
1612
+ theme: ThemeMode;
1613
+ /** Effective theme actually applied to the DOM (light or dark). */
1614
+ resolvedTheme: ResolvedTheme;
1615
+ /** Update the preference. Persisted to localStorage when `storageKey` is set. */
1616
+ setTheme: (next: ThemeMode) => void;
1617
+ /** Convenience: flip light ↔ dark. When in `system` mode, switches to the opposite of the current resolved theme. */
1618
+ toggle: () => void;
1619
+ }
1620
+
1621
+ /**
1622
+ * Plain HTML snippet that sets `data-tempest-theme` on `<html>` before React
1623
+ * hydrates. Inline this in `<head>` to avoid a flash of the wrong theme on
1624
+ * first paint.
1625
+ *
1626
+ * @example
1627
+ * <script dangerouslySetInnerHTML={{ __html: themeInitScript() }} />
1628
+ */
1629
+ export declare function themeInitScript(options?: GetInitialThemeOptions): string;
1630
+
1631
+ export declare type ThemeMode = "light" | "dark" | "system";
1632
+
1633
+ /**
1634
+ * Wire dark/light theming. Writes a data attribute on a target element (the
1635
+ * `<html>` element by default) and exposes the current preference via
1636
+ * {@link useTheme}.
1637
+ *
1638
+ * Pair with `themeInitScript()` in the HTML head to prevent the flash of
1639
+ * incorrect theme on first paint.
1640
+ */
1641
+ export declare function ThemeProvider({ children, defaultTheme, storageKey, target, attribute, }: ThemeProviderProps): JSX.Element;
1642
+
1643
+ export declare interface ThemeProviderProps {
1644
+ children: ReactNode;
1645
+ /** Initial preference when nothing is stored. Default: `"system"`. */
1646
+ defaultTheme?: ThemeMode;
1647
+ /** localStorage key used to persist the preference. Pass `null` to disable persistence. Default: `"tempest-theme"`. */
1648
+ storageKey?: string | null;
1649
+ /**
1650
+ * Element that receives the `data-tempest-theme` attribute. Defaults to
1651
+ * `document.documentElement`. Override when scoping the theme to a subtree.
1652
+ */
1653
+ target?: () => HTMLElement | null;
1654
+ /** Attribute name written on the target. Default: `"data-tempest-theme"`. */
1655
+ attribute?: string;
1656
+ }
1657
+
1658
+ export declare interface ToastApi {
1659
+ show: (options: ToastOptions) => string;
1660
+ dismiss: (id: string) => void;
1661
+ success: (description: string, options?: Omit<ToastOptions, "variant" | "description">) => string;
1662
+ error: (description: string, options?: Omit<ToastOptions, "variant" | "description">) => string;
1663
+ warning: (description: string, options?: Omit<ToastOptions, "variant" | "description">) => string;
1664
+ info: (description: string, options?: Omit<ToastOptions, "variant" | "description">) => string;
1665
+ }
1666
+
1667
+ export declare interface ToastOptions {
1668
+ id?: string;
1669
+ title?: string;
1670
+ description?: string;
1671
+ variant?: ToastVariant;
1672
+ /** Auto-dismiss timeout in ms. Pass `0` to keep the toast until dismissed manually. */
1673
+ duration?: number;
1674
+ }
1675
+
1676
+ /**
1677
+ * Renders a portalled toast container and exposes the imperative {@link useToast} API.
1678
+ */
1679
+ export declare function ToastProvider({ children, defaultDuration }: ToastProviderProps): JSX.Element;
1680
+
1681
+ export declare interface ToastProviderProps {
1682
+ children: ReactNode;
1683
+ /** Default auto-dismiss duration (ms). Default 4000. */
1684
+ defaultDuration?: number;
1685
+ }
1686
+
1687
+ export declare type ToastVariant = "success" | "warning" | "error" | "info";
1688
+
1689
+ /**
1690
+ * Lightweight tooltip. Shows on hover and on focus (keyboard-friendly). Wraps
1691
+ * a single child element via `cloneElement`, so the trigger keeps its own ref
1692
+ * and props.
1693
+ */
1694
+ export declare function Tooltip({ content, placement, children, disabled, openDelay, }: TooltipProps): JSX.Element;
1695
+
1696
+ export declare type TooltipPlacement = "top" | "bottom" | "left" | "right";
1697
+
1698
+ export declare interface TooltipProps {
1699
+ /** Tooltip content. Plain text recommended; rich content also works. */
1700
+ content: ReactNode;
1701
+ /** Placement relative to the trigger. Default: `"top"`. */
1702
+ placement?: TooltipPlacement;
1703
+ /** Single React element to attach hover/focus listeners to. */
1704
+ children: ReactElement;
1705
+ /** Disable the tooltip without changing the trigger. */
1706
+ disabled?: boolean;
1707
+ /** Delay (ms) before showing the tooltip. Default: 150. */
1708
+ openDelay?: number;
1709
+ }
1710
+
1711
+ /** Strip any masking and return only digits. */
1712
+ export declare function unmask(value: string): string;
1713
+
1714
+ /**
1715
+ * Unregister all registered service workers for this origin.
1716
+ *
1717
+ * @returns Number of workers that were unregistered.
1718
+ */
1719
+ export declare function unregisterAllServiceWorkers(): Promise<number>;
1720
+
1721
+ export declare interface UploadProgressEvent {
1722
+ /** Bytes already uploaded. */
1723
+ loaded: number;
1724
+ /** Total payload size in bytes — only meaningful when `lengthComputable` is true. */
1725
+ total: number;
1726
+ /** Fraction between 0 and 1, or null when total is unknown. */
1727
+ fraction: number | null;
1728
+ lengthComputable: boolean;
1729
+ }
1730
+
1731
+ /**
1732
+ * Upload a file (or any payload) with byte-level progress reporting.
1733
+ *
1734
+ * `fetch` cannot report upload progress in browsers, so this helper falls
1735
+ * back to `XMLHttpRequest`. It mirrors the error contract used by
1736
+ * {@link createApiClient}: non-2xx responses throw an {@link ApiError}.
1737
+ *
1738
+ * @returns The parsed JSON response, or the raw text when the response is not JSON.
1739
+ */
1740
+ export declare function uploadWithProgress<T = unknown>(options: UploadWithProgressOptions): Promise<T>;
1741
+
1742
+ export declare interface UploadWithProgressOptions {
1743
+ url: string;
1744
+ body: FormData | Blob | File;
1745
+ method?: "POST" | "PUT" | "PATCH";
1746
+ headers?: Record<string, string>;
1747
+ /** Returns the current bearer token. */
1748
+ getToken?: () => string | null | undefined;
1749
+ /** Send cookies. Defaults to false. */
1750
+ withCredentials?: boolean;
1751
+ /** Called on every `progress` event from the XHR upload channel. */
1752
+ onProgress?: (event: UploadProgressEvent) => void;
1753
+ /** Abort the request. */
1754
+ signal?: AbortSignal;
1755
+ /** Override the JSON parser. Defaults to `JSON.parse`. */
1756
+ parser?: (raw: string) => unknown;
1757
+ }
1758
+
1759
+ /**
1760
+ * Convert a base64url-encoded VAPID public key into the `Uint8Array` format
1761
+ * required by `PushManager.subscribe({ applicationServerKey })`.
1762
+ *
1763
+ * @param base64String - VAPID public key (URL-safe base64).
1764
+ * @returns The decoded key as bytes.
1765
+ */
1766
+ export declare function urlBase64ToUint8Array(base64String: string): Uint8Array<ArrayBuffer>;
1767
+
1768
+ /**
1769
+ * Hook-managed audio player. Each component instance gets its own
1770
+ * {@link AudioPlayer}, so unmounting cleanly stops playback. Useful for
1771
+ * notification chimes, UI feedback sounds, and per-component soundtracks.
1772
+ */
1773
+ export declare function useAudio(): UseAudioResult;
1774
+
1775
+ export declare interface UseAudioResult {
1776
+ /** Play `src` on the hook's private player. */
1777
+ play: (src: string, options?: PlayAudioOptions) => Promise<void>;
1778
+ /** Stop the current clip. */
1779
+ stop: () => void;
1780
+ /**
1781
+ * Whether the browser's autoplay policy has been satisfied. Becomes
1782
+ * `true` after the first successful `play()`.
1783
+ */
1784
+ unlocked: boolean;
1785
+ }
1786
+
1787
+ /**
1788
+ * React hook for the PWA install prompt. Captures the `beforeinstallprompt`
1789
+ * event so you can defer the install UI to a moment that fits your UX.
1790
+ */
1791
+ export declare function useBeforeInstallPrompt(): UseBeforeInstallPromptResult;
1792
+
1793
+ export declare interface UseBeforeInstallPromptResult {
1794
+ /** True when the browser fired `beforeinstallprompt` and the user has not yet decided. */
1795
+ installable: boolean;
1796
+ /** True after the user accepts the install prompt. */
1797
+ installed: boolean;
1798
+ /** Show the install prompt. Resolves with the user's choice. */
1799
+ prompt: () => Promise<"accepted" | "dismissed" | "unsupported">;
1800
+ }
1801
+
1802
+ /**
1803
+ * Client-side filter helper. Performs a case-insensitive match on the listed
1804
+ * keys when no custom predicate is provided.
1805
+ *
1806
+ * @param items - Source list.
1807
+ * @param search - Search string.
1808
+ * @param keysOrPredicate - Either a list of keys to match against or a custom predicate.
1809
+ * @returns Filtered list (referential identity preserved when search is empty).
1810
+ */
1811
+ export declare function useClientFilter<T extends Record<string, unknown>>(items: T[], search: string, keysOrPredicate: (keyof T)[] | FilterPredicate<T>): T[];
1812
+
1813
+ /**
1814
+ * Wrapper around `navigator.clipboard.writeText` with a transient `copied`
1815
+ * flag for UI feedback ("Copied!" toast). Falls back gracefully when the
1816
+ * Clipboard API is unavailable.
1817
+ */
1818
+ export declare function useClipboard(options?: UseClipboardOptions): UseClipboardResult;
1819
+
1820
+ export declare interface UseClipboardOptions {
1821
+ /** Time (ms) before the `copied` flag resets back to false. Default: 1500. */
1822
+ resetAfter?: number;
1823
+ }
1824
+
1825
+ export declare interface UseClipboardResult {
1826
+ /** True briefly after a successful copy. */
1827
+ copied: boolean;
1828
+ /** Copy a string to the clipboard. Returns `true` on success. */
1829
+ copy: (text: string) => Promise<boolean>;
1830
+ /** Manually reset the `copied` flag. */
1831
+ reset: () => void;
1832
+ }
1833
+
1834
+ /**
1835
+ * Debounce a fast-changing value. Returns the latest value once `delay` ms
1836
+ * have elapsed without further changes.
1837
+ *
1838
+ * @param value - The value to debounce.
1839
+ * @param delay - Delay in milliseconds (default 300).
1840
+ * @returns The debounced value.
1841
+ */
1842
+ export declare function useDebounce<T>(value: T, delay?: number): T;
1843
+
1844
+ /**
1845
+ * Memoize a value with a structural equality check. Use when an object/array
1846
+ * created during render is fed to `useEffect` dependencies and you want to
1847
+ * avoid spurious effect runs when only the reference changes.
1848
+ */
1849
+ export declare function useDeepMemo<T>(value: T): T;
1850
+
1851
+ /** Subscribe to `document.visibilityState`. Returns `"visible"` during SSR. */
1852
+ export declare function useDocumentVisibility(): DocumentVisibility;
1853
+
1854
+ /**
1855
+ * Hook that propagates errors to the nearest {@link ErrorBoundary}.
1856
+ *
1857
+ * React error boundaries only catch errors thrown during render. Async errors
1858
+ * (failed mutations, websocket failures, etc.) need to be re-thrown in a
1859
+ * render pass — that is what `throwError` does.
1860
+ *
1861
+ * @example
1862
+ * const throwError = useErrorHandler();
1863
+ * useEffect(() => {
1864
+ * stream.on("error", throwError);
1865
+ * }, []);
1866
+ */
1867
+ export declare function useErrorHandler(): (error: unknown) => void;
1868
+
1869
+ /**
1870
+ * React hook wrapper around {@link createEventStream}. Connection lifecycle is
1871
+ * tied to the component (and the `url`/`enabled` dependencies); the stream
1872
+ * closes on unmount.
1873
+ *
1874
+ * @example
1875
+ * useEventStream<Notification>(`${API}/notifications/stream`, {
1876
+ * enabled: !!user,
1877
+ * withCredentials: true,
1878
+ * onMessage: ({ data }) => addNotification(data),
1879
+ * });
1880
+ */
1881
+ export declare function useEventStream<T = unknown>(url: string, options?: UseEventStreamOptions<T>): UseEventStreamResult<T>;
1882
+
1883
+ export declare interface UseEventStreamOptions<T> extends Omit<CreateEventStreamOptions<T>, "onStatusChange"> {
1884
+ /** When false, the stream is not opened. Useful for "wait for auth". Default: true. */
1885
+ enabled?: boolean;
1886
+ }
1887
+
1888
+ export declare interface UseEventStreamResult<T> {
1889
+ status: EventStreamStatus;
1890
+ /** Last message received (excluding heartbeats). */
1891
+ lastMessage: EventStreamMessage<T> | null;
1892
+ /** Force a reconnect. */
1893
+ reconnect: () => void;
1894
+ }
1895
+
1896
+ /**
1897
+ * Read a boolean flag and re-render when the adapter fires `onChange`.
1898
+ *
1899
+ * @example
1900
+ * const showNewFeed = useFeatureFlag("new-feed", false);
1901
+ */
1902
+ export declare function useFeatureFlag(key: string, defaultValue?: boolean): boolean;
1903
+
1904
+ /**
1905
+ * Read a typed flag value (string / number / boolean / null) and re-render
1906
+ * on change.
1907
+ */
1908
+ export declare function useFlagValue<T extends FlagValue = FlagValue>(key: string, defaultValue?: T): T;
1909
+
1910
+ /**
1911
+ * Trap keyboard focus inside `containerRef` while `active` is true. Cycles
1912
+ * Tab and Shift+Tab between the first and last focusable descendants. Pair
1913
+ * with Modal/Drawer for fully-accessible overlays.
1914
+ */
1915
+ export declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, active: boolean): void;
1916
+
1917
+ /** React hook around the Geolocation API. */
1918
+ export declare function useGeolocation(options?: UseGeolocationOptions): GeolocationState;
1919
+
1920
+ export declare interface UseGeolocationOptions extends PositionOptions {
1921
+ /** Use `watchPosition` instead of one-shot `getCurrentPosition`. Default: false. */
1922
+ watch?: boolean;
1923
+ /** Disable the hook without unmounting. Default: false. */
1924
+ disabled?: boolean;
1925
+ }
1926
+
1927
+ /**
1928
+ * Access translation helpers. Must be used inside an {@link I18nProvider}.
1929
+ */
1930
+ export declare function useI18n(): I18nContextValue;
1931
+
1932
+ /**
1933
+ * Detect when the user has been idle for `timeout` ms (no interaction).
1934
+ * Returns `true` once the threshold elapses and back to `false` on activity.
1935
+ */
1936
+ export declare function useIdle(timeout?: number): boolean;
1937
+
1938
+ /**
1939
+ * Track whether the referenced element intersects the viewport. Useful for
1940
+ * lazy-loading images, "load more" sentinels, and animation triggers.
1941
+ *
1942
+ * @returns `IntersectionObserverEntry | null`. `null` until the first observation.
1943
+ */
1944
+ export declare function useIntersectionObserver(ref: RefObject<Element | null>, options?: UseIntersectionObserverOptions): IntersectionObserverEntry | null;
1945
+
1946
+ export declare interface UseIntersectionObserverOptions extends IntersectionObserverInit {
1947
+ /** Stop observing after the first intersection (one-shot). Default: false. */
1948
+ once?: boolean;
1949
+ }
1950
+
1951
+ /**
1952
+ * Bind a global keyboard shortcut. Supports modifier combinations and a
1953
+ * cross-OS `mod` key (Ctrl on Windows/Linux, Cmd on macOS).
1954
+ *
1955
+ * @example
1956
+ * useKeyboardShortcut({ key: "k", mod: true }, () => openSearch());
1957
+ */
1958
+ export declare function useKeyboardShortcut(shortcut: KeyboardShortcut, handler: (event: KeyboardEvent) => void, options?: UseKeyboardShortcutOptions): void;
1959
+
1960
+ export declare interface UseKeyboardShortcutOptions {
1961
+ /** Disable the shortcut without unmounting. Default: false. */
1962
+ disabled?: boolean;
1963
+ /** Listen to the entire window. Pass `false` to scope to a specific element via the handler. Default: true. */
1964
+ global?: boolean;
1965
+ /** Suppress the event from firing inside `<input>`/`<textarea>`/`[contenteditable]`. Default: true. */
1966
+ ignoreInput?: boolean;
1967
+ }
1968
+
1969
+ /**
1970
+ * Subscribe to a CSS media query and re-render on match changes.
1971
+ *
1972
+ * @param query - A standard CSS media query string, e.g. "(max-width: 768px)".
1973
+ * @returns True when the query matches.
1974
+ */
1975
+ export declare function useMediaQuery(query: string): boolean;
1976
+
1977
+ /**
1978
+ * Track the browser's `navigator.onLine` value and re-render on changes.
1979
+ * Returns `true` during SSR (assumption: server is online).
1980
+ */
1981
+ export declare function useOnline(): boolean;
1982
+
1983
+ /**
1984
+ * Manage page/size state for paginated lists. Reset goes back to page 1
1985
+ * without touching the page size.
1986
+ *
1987
+ * @param initialPage - Starting page (default 1).
1988
+ * @param initialSize - Starting page size (default 50).
1989
+ * @returns Pagination state and setters.
1990
+ */
1991
+ export declare function usePagination(initialPage?: number, initialSize?: number): UsePaginationResult;
1992
+
1993
+ export declare interface UsePaginationResult {
1994
+ page: number;
1995
+ size: number;
1996
+ setPage: (page: number) => void;
1997
+ setSize: (size: number) => void;
1998
+ reset: () => void;
1999
+ }
2000
+
2001
+ /**
2002
+ * Poll an async factory on a fixed interval. Skips overlapping requests if a
2003
+ * prior call has not finished. Pause via `disabled` or `stopWhen`.
2004
+ */
2005
+ export declare function usePoll<T>(factory: () => Promise<T>, options: UsePollOptions<T>): UsePollResult<T>;
2006
+
2007
+ export declare interface UsePollOptions<T> {
2008
+ /** Polling interval in ms. */
2009
+ interval: number;
2010
+ /** Disable polling without unmounting. Default: false. */
2011
+ disabled?: boolean;
2012
+ /** Stop polling once the predicate returns true. */
2013
+ stopWhen?: (data: T) => boolean;
2014
+ /** Called on each error. */
2015
+ onError?: (error: unknown) => void;
2016
+ }
2017
+
2018
+ export declare interface UsePollResult<T> {
2019
+ data: T | null;
2020
+ error: unknown;
2021
+ loading: boolean;
2022
+ stop: () => void;
2023
+ start: () => void;
2024
+ }
2025
+
2026
+ /**
2027
+ * React hook around {@link WebPushClient}. Tracks subscription, permission and
2028
+ * loading state; exposes imperative `subscribe`/`unsubscribe` actions.
2029
+ *
2030
+ * The hook does NOT register the service worker — the host app must do that
2031
+ * (e.g. via `vite-plugin-pwa` or a manual `navigator.serviceWorker.register`).
2032
+ *
2033
+ * @example
2034
+ * const push = usePushSubscription({
2035
+ * vapidPublicKey: import.meta.env.VITE_VAPID_PUBLIC_KEY,
2036
+ * onSubscribe: (sub) => api.post("/webpush/subscribe", { body: sub }),
2037
+ * onUnsubscribe: () => api.delete("/webpush/my"),
2038
+ * });
2039
+ */
2040
+ export declare function usePushSubscription(config: WebPushClientConfig): UsePushSubscriptionResult;
2041
+
2042
+ export declare interface UsePushSubscriptionResult {
2043
+ /** True when the browser exposes the Push + Notification APIs. */
2044
+ supported: boolean;
2045
+ /** Current `Notification.permission` value, or `"unsupported"`. */
2046
+ permission: NotificationPermission | "unsupported";
2047
+ /** True when a subscription is active on this device. */
2048
+ subscribed: boolean;
2049
+ /** True while a subscribe/unsubscribe call is in-flight. */
2050
+ loading: boolean;
2051
+ /** Last error thrown by subscribe/unsubscribe, if any. */
2052
+ error: Error | null;
2053
+ subscribe: () => Promise<void>;
2054
+ unsubscribe: () => Promise<void>;
2055
+ /** Re-read the current subscription/permission state from the browser. */
2056
+ refresh: () => Promise<void>;
2057
+ }
2058
+
2059
+ /**
2060
+ * Track size changes of a DOM element via `ResizeObserver`.
2061
+ * Returns `null` until the first measurement.
2062
+ */
2063
+ export declare function useResizeObserver(ref: RefObject<Element | null>): ElementSize | null;
2064
+
2065
+ /**
2066
+ * Lock `<body>` scroll while `active` is true. Restores the previous overflow
2067
+ * value on unmount. Safe to nest: stacks the restoration via a counter.
2068
+ */
2069
+ export declare function useScrollLock(active: boolean): void;
2070
+
2071
+ /**
2072
+ * Returns a stable function reference that always invokes the latest
2073
+ * `callback` argument. Use to break dependency cycles in effects without
2074
+ * triggering re-runs when the callback identity changes.
2075
+ */
2076
+ export declare function useStableCallback<TArgs extends unknown[], TReturn>(callback: (...args: TArgs) => TReturn): (...args: TArgs) => TReturn;
2077
+
2078
+ /**
2079
+ * Access the active telemetry adapter. Returns `null` when no provider is
2080
+ * mounted (calls are silently dropped — useful for unit tests).
2081
+ */
2082
+ export declare function useTelemetry(): TelemetryAdapter | null;
2083
+
2084
+ /**
2085
+ * Read and mutate the current theme. Must be used inside a {@link ThemeProvider}.
2086
+ */
2087
+ export declare function useTheme(): ThemeContextValue;
2088
+
2089
+ /**
2090
+ * Access the toast API. Must be used inside a {@link ToastProvider}.
2091
+ *
2092
+ * @returns Methods to show and dismiss toasts.
2093
+ */
2094
+ export declare function useToast(): ToastApi;
2095
+
2096
+ /**
2097
+ * Shortcut for components that only need the `t` function — avoids destructuring.
2098
+ */
2099
+ export declare function useTranslate(): I18nContextValue["t"];
2100
+
2101
+ /**
2102
+ * React hook for the public ViaCEP service (`viacep.com.br`). No backend
2103
+ * required. Returns address fields when the CEP exists, or sets `error` for
2104
+ * invalid CEPs.
2105
+ */
2106
+ export declare function useViaCEP(): UseViaCEPResult;
2107
+
2108
+ export declare interface UseViaCEPResult {
2109
+ loading: boolean;
2110
+ error: string | null;
2111
+ data: ViaCEPResult | null;
2112
+ /** Fetch the given CEP (8 digits or masked). Sets `data`/`error`. Returns the result. */
2113
+ lookup: (cep: string) => Promise<ViaCEPResult | null>;
2114
+ reset: () => void;
2115
+ }
2116
+
2117
+ /**
2118
+ * React hook around {@link createWebSocket}. Manages the connection lifecycle
2119
+ * for the host component and tears it down on unmount.
2120
+ */
2121
+ export declare function useWebSocket<T = unknown>(url: string, options?: UseWebSocketOptions<T>): UseWebSocketResult<T>;
2122
+
2123
+ export declare interface UseWebSocketOptions<T> extends Omit<CreateWebSocketOptions<T>, "onStatusChange"> {
2124
+ /** When false, the socket is not opened. Default: true. */
2125
+ enabled?: boolean;
2126
+ }
2127
+
2128
+ export declare interface UseWebSocketResult<T> {
2129
+ status: WebSocketStatus;
2130
+ /** Last decoded frame received. */
2131
+ lastMessage: WebSocketMessage<T> | null;
2132
+ /** Send a payload through the active connection. Returns false when not open. */
2133
+ send: (payload: string | ArrayBufferLike | Blob | ArrayBufferView) => boolean;
2134
+ /** Force a reconnect, resetting the retry counter. */
2135
+ reconnect: () => void;
2136
+ }
2137
+
2138
+ /**
2139
+ * Convenience wrapper around `react-hook-form`'s `useForm` that wires a zod
2140
+ * resolver and infers the form's value type from the schema.
2141
+ *
2142
+ * Both `react-hook-form` and `zod` are optional peer dependencies — install
2143
+ * them when your app uses forms.
2144
+ *
2145
+ * @example
2146
+ * const form = useZodForm(loginSchema, { defaultValues: { email: "" } });
2147
+ * form.register("email");
2148
+ */
2149
+ export declare function useZodForm<TSchema extends z.ZodTypeAny, TValues extends FieldValues = z.infer<TSchema> & FieldValues>(schema: TSchema, options?: Omit<UseFormProps<TValues>, "resolver">): UseFormReturn<TValues>;
2150
+
2151
+ /**
2152
+ * Validate a Brazilian CNPJ using the standard check-digit algorithm.
2153
+ * Accepts masked or raw input; rejects all-equal digits.
2154
+ */
2155
+ export declare function validateCNPJ(value: string): boolean;
2156
+
2157
+ /**
2158
+ * Validate a Brazilian CPF using the standard check-digit algorithm.
2159
+ * Accepts masked or raw input; rejects all-equal digits ("111.111.111-11").
2160
+ */
2161
+ export declare function validateCPF(value: string): boolean;
2162
+
2163
+ /**
2164
+ * Validate `values` against a zod schema and return a per-field error map
2165
+ * compatible with most form libraries.
2166
+ *
2167
+ * Field paths follow zod's `issue.path.join(".")` convention — nested fields
2168
+ * become `"address.city"`, array entries `"items.0.name"`. The first issue
2169
+ * per path wins (subsequent ones are dropped to keep error UIs tidy).
2170
+ *
2171
+ * @param schema - zod schema describing the form shape.
2172
+ * @param values - Raw form values (typed as `unknown`).
2173
+ * @returns Either `{ success: true, data, errors: {} }` or `{ success: false, errors }`.
2174
+ */
2175
+ export declare function validateForm<TSchema extends z.ZodTypeAny>(schema: TSchema, values: unknown): ValidateFormResult<z.infer<TSchema>>;
2176
+
2177
+ export declare interface ValidateFormFailure {
2178
+ success: false;
2179
+ errors: Record<string, string>;
2180
+ }
2181
+
2182
+ export declare type ValidateFormResult<T> = ValidateFormSuccess<T> | ValidateFormFailure;
2183
+
2184
+ export declare interface ValidateFormSuccess<T> {
2185
+ success: true;
2186
+ data: T;
2187
+ errors: Record<string, string>;
2188
+ }
2189
+
2190
+ export declare interface ViaCEPResult {
2191
+ cep: string;
2192
+ logradouro: string;
2193
+ complemento: string;
2194
+ bairro: string;
2195
+ localidade: string;
2196
+ uf: string;
2197
+ ibge?: string;
2198
+ gia?: string;
2199
+ ddd?: string;
2200
+ siafi?: string;
2201
+ }
2202
+
2203
+ /**
2204
+ * Fixed-height virtual list. Renders only the visible window plus a small
2205
+ * overscan buffer. Suitable for lists of thousands of identical rows.
2206
+ *
2207
+ * For variable heights, use `react-window`/`@tanstack/react-virtual` — those
2208
+ * solve a more general problem at the cost of extra setup.
2209
+ */
2210
+ export declare function VirtualList<T>({ items, itemHeight, renderItem, height, overscan, getKey, className, style, }: VirtualListProps<T>): JSX.Element;
2211
+
2212
+ export declare interface VirtualListProps<T> {
2213
+ items: T[];
2214
+ /** Fixed pixel height for each row. */
2215
+ itemHeight: number;
2216
+ /** Render a single row. */
2217
+ renderItem: (item: T, index: number) => ReactNode;
2218
+ /** Container height (px) or any CSS length. */
2219
+ height: number | string;
2220
+ /** Number of items rendered above/below the viewport. Default: 4. */
2221
+ overscan?: number;
2222
+ /** Stable key derivation; defaults to the index. */
2223
+ getKey?: (item: T, index: number) => string | number;
2224
+ className?: string;
2225
+ style?: CSSProperties;
2226
+ }
2227
+
2228
+ /**
2229
+ * Browser-side Web Push helper. Wraps `Notification.requestPermission`,
2230
+ * `pushManager.subscribe`, and the corresponding teardown. Transport is up to
2231
+ * the caller via `onSubscribe` / `onUnsubscribe` callbacks.
2232
+ */
2233
+ export declare class WebPushClient {
2234
+ private readonly config;
2235
+ constructor(config: WebPushClientConfig);
2236
+ /** Whether the runtime supports the Push API. */
2237
+ static isSupported(): boolean;
2238
+ private registration;
2239
+ /** Current `Notification.permission` value, or `"unsupported"`. */
2240
+ permission(): NotificationPermission | "unsupported";
2241
+ /**
2242
+ * Ask the user for notification permission.
2243
+ *
2244
+ * @throws {WebPushUnsupportedError} If the runtime lacks the Notification API.
2245
+ * @returns The resulting `NotificationPermission` value.
2246
+ */
2247
+ requestPermission(): Promise<NotificationPermission>;
2248
+ /** Return the active push subscription, if any. */
2249
+ getSubscription(): Promise<PushSubscription | null>;
2250
+ /** True when a subscription already exists for this browser. */
2251
+ isSubscribed(): Promise<boolean>;
2252
+ /**
2253
+ * Subscribe the current device. Requests permission, creates a push
2254
+ * subscription if none exists, and forwards the JSON payload to
2255
+ * `onSubscribe` for backend persistence.
2256
+ *
2257
+ * @returns The active `PushSubscription`.
2258
+ * @throws {WebPushUnsupportedError} If Web Push is unavailable.
2259
+ * @throws {WebPushPermissionDeniedError} If the user denies the prompt.
2260
+ */
2261
+ subscribe(): Promise<PushSubscription>;
2262
+ /**
2263
+ * Cancel the current subscription. Calls `onUnsubscribe` first (so the
2264
+ * backend can purge the record) and then `subscription.unsubscribe()`.
2265
+ *
2266
+ * @returns True when an active subscription was removed, false otherwise.
2267
+ */
2268
+ unsubscribe(): Promise<boolean>;
2269
+ }
2270
+
2271
+ export declare interface WebPushClientConfig {
2272
+ /** VAPID public key (URL-safe base64). */
2273
+ vapidPublicKey: string;
2274
+ /**
2275
+ * Persist the subscription on the backend. The SDK does not own this call —
2276
+ * the host app decides the endpoint and how the payload is serialized.
2277
+ */
2278
+ onSubscribe: (subscription: PushSubscriptionJSON) => Promise<void> | void;
2279
+ /** Remove the subscription from the backend. Called before `subscription.unsubscribe()`. */
2280
+ onUnsubscribe?: (subscription: PushSubscriptionJSON) => Promise<void> | void;
2281
+ /**
2282
+ * Override how the service worker registration is obtained.
2283
+ * Defaults to `navigator.serviceWorker.ready` — provide this only when you
2284
+ * register the SW yourself and want to reuse the registration.
2285
+ */
2286
+ getRegistration?: () => Promise<ServiceWorkerRegistration>;
2287
+ }
2288
+
2289
+ export declare class WebPushPermissionDeniedError extends Error {
2290
+ constructor();
2291
+ }
2292
+
2293
+ export declare class WebPushUnsupportedError extends Error {
2294
+ constructor();
2295
+ }
2296
+
2297
+ export declare interface WebSocketController {
2298
+ /** Send a payload over the current connection. No-op when not open. */
2299
+ send: (payload: string | ArrayBufferLike | Blob | ArrayBufferView) => boolean;
2300
+ /** Close the connection and stop reconnecting. */
2301
+ close: (code?: number, reason?: string) => void;
2302
+ /** Force an immediate reconnect, resetting the retry counter. */
2303
+ reconnect: () => void;
2304
+ /** Current connection status. */
2305
+ readonly status: WebSocketStatus;
2306
+ }
2307
+
2308
+ export declare interface WebSocketMessage<T> {
2309
+ /** Parsed payload — JSON-decoded when possible, raw string otherwise. */
2310
+ data: T;
2311
+ /** The original `MessageEvent`. */
2312
+ raw: MessageEvent;
2313
+ }
2314
+
2315
+ export declare type WebSocketStatus = "idle" | "connecting" | "open" | "closing" | "closed" | "error";
2316
+
2317
+ /**
2318
+ * Minimal `react-hook-form` resolver built on top of zod. Mirrors the shape
2319
+ * produced by `@hookform/resolvers/zod` so it can be passed straight to
2320
+ * `useForm({ resolver })`.
2321
+ *
2322
+ * @example
2323
+ * const form = useForm<LoginForm>({ resolver: zodResolver(loginSchema) });
2324
+ */
2325
+ export declare function zodResolver<TSchema extends z.ZodTypeAny>(schema: TSchema): Resolver<z.infer<TSchema>>;
2326
+
2327
+ export { }