tempest-react-sdk 0.2.0 → 0.4.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.
@@ -1,17 +1,26 @@
1
1
  import { ButtonHTMLAttributes } from 'react';
2
2
  import { Component } from 'react';
3
3
  import { ComponentType } from 'react';
4
+ import { Control } from 'react-hook-form';
5
+ import { Controller } from 'react-hook-form';
6
+ import { ControllerRenderProps } from 'react-hook-form';
4
7
  import { CSSProperties } from 'react';
5
8
  import { default as default_2 } from 'dexie';
6
9
  import { DefaultOptions } from '@tanstack/react-query';
7
10
  import { ErrorInfo } from 'react';
11
+ import { FieldArrayWithId } from 'react-hook-form';
12
+ import { FieldError } from 'react-hook-form';
13
+ import { FieldErrors } from 'react-hook-form';
14
+ import { FieldPath } from 'react-hook-form';
8
15
  import { FieldValues } from 'react-hook-form';
9
16
  import { FormHTMLAttributes } from 'react';
17
+ import { FormProvider } from 'react-hook-form';
10
18
  import { ForwardRefExoticComponent } from 'react';
11
19
  import { HTMLAttributes } from 'react';
12
20
  import { InputHTMLAttributes } from 'react';
13
21
  import { JSX } from 'react/jsx-runtime';
14
22
  import { lazy } from 'react';
23
+ import { Path } from 'react-hook-form';
15
24
  import { PersistOptions } from 'zustand/middleware';
16
25
  import { QueryClient } from '@tanstack/react-query';
17
26
  import { ReactElement } from 'react';
@@ -21,13 +30,48 @@ import { RefAttributes } from 'react';
21
30
  import { RefObject } from 'react';
22
31
  import { SelectHTMLAttributes } from 'react';
23
32
  import { StoreApi } from 'zustand';
33
+ import { SubmitHandler } from 'react-hook-form';
24
34
  import { Table as Table_2 } from 'dexie';
25
35
  import { TextareaHTMLAttributes } from 'react';
26
36
  import { UseBoundStore } from 'zustand';
37
+ import { useFieldArray } from 'react-hook-form';
38
+ import { UseFieldArrayReturn } from 'react-hook-form';
39
+ import { useForm } from 'react-hook-form';
40
+ import { useFormContext } from 'react-hook-form';
27
41
  import { UseFormProps } from 'react-hook-form';
42
+ import { UseFormRegister } from 'react-hook-form';
28
43
  import { UseFormReturn } from 'react-hook-form';
44
+ import { useFormState } from 'react-hook-form';
45
+ import { useWatch } from 'react-hook-form';
29
46
  import { z } from 'zod';
30
47
 
48
+ /**
49
+ * Accessible accordion. Each item collapses/expands its content. Single-mode by
50
+ * default — pass `multiple` to allow more than one item open at a time. Can be
51
+ * controlled via `value` + `onChange`, or uncontrolled via `defaultValue`.
52
+ */
53
+ export declare function Accordion({ items, multiple, value, defaultValue, onChange, className, }: AccordionProps): JSX.Element;
54
+
55
+ export declare interface AccordionItem {
56
+ /** Stable identifier. */
57
+ id: string;
58
+ title: ReactNode;
59
+ children: ReactNode;
60
+ disabled?: boolean;
61
+ }
62
+
63
+ export declare interface AccordionProps {
64
+ items: AccordionItem[];
65
+ /** When `true` multiple items can be open simultaneously. Default `false`. */
66
+ multiple?: boolean;
67
+ /** Controlled open ids. */
68
+ value?: string[];
69
+ /** Uncontrolled default open ids. */
70
+ defaultValue?: string[];
71
+ onChange?: (openIds: string[]) => void;
72
+ className?: string;
73
+ }
74
+
31
75
  /**
32
76
  * Inline alert / notice with tone (info/success/warning/danger) and appearance
33
77
  * (soft/solid/outline). Accepts optional `icon`, `title`, `description` and
@@ -52,6 +96,10 @@ export declare interface AlertProps extends Omit<HTMLAttributes<HTMLDivElement>,
52
96
 
53
97
  export declare type AlertVariant = "neutral" | "info" | "success" | "warning" | "danger";
54
98
 
99
+ declare type AnyEventTarget = EventTarget | {
100
+ current: EventTarget | null;
101
+ } | null | undefined;
102
+
55
103
  export declare interface ApiClient {
56
104
  request<T>(path: string, options?: RequestOptions): Promise<T>;
57
105
  get<T>(path: string, options?: RequestOptions): Promise<T>;
@@ -88,6 +136,63 @@ export declare interface ApiError {
88
136
  body?: unknown;
89
137
  }
90
138
 
139
+ /**
140
+ * Full app layout — composes [[Navbar]] + [[Sidebar]] + content +
141
+ * [[BottomNavigation]] + footer with responsive behaviour:
142
+ *
143
+ * - **Desktop (`>= sidebarBreakpoint`)**: navbar + sidebar + main + footer.
144
+ * - **Mobile (`< sidebarBreakpoint`)**: navbar + main + bottom nav + footer
145
+ * (sidebar hidden — app should expose it via `<Drawer>` from a hamburger).
146
+ *
147
+ * @example
148
+ * <AppShell
149
+ * navbar={<Navbar logo={<Brand />} actions={<UserMenu />} />}
150
+ * sidebar={<Sidebar items={...} value={tab} onChange={setTab} />}
151
+ * bottomNav={<BottomNavigation items={...} value={tab} onChange={setTab} />}
152
+ * footer={<Footer />}
153
+ * >
154
+ * <Page title="Dashboard">{content}</Page>
155
+ * </AppShell>
156
+ */
157
+ export declare function AppShell({ navbar, sidebar, bottomNav, footer, sidebarBreakpoint, className, children, ...props }: AppShellProps): JSX.Element;
158
+
159
+ export declare interface AppShellProps extends HTMLAttributes<HTMLDivElement> {
160
+ /** Top navigation bar (Navbar / custom). Renders on every breakpoint. */
161
+ navbar?: ReactNode;
162
+ /** Side navigation (Sidebar). Hidden below `md` — pair with `<Drawer>` for mobile. */
163
+ sidebar?: ReactNode;
164
+ /** Mobile-only bottom navigation (BottomNavigation). Hidden at `md+`. */
165
+ bottomNav?: ReactNode;
166
+ /** Footer rendered after the main content. */
167
+ footer?: ReactNode;
168
+ /** Breakpoint at which the sidebar appears. Default `"md"`. */
169
+ sidebarBreakpoint?: "sm" | "md" | "lg" | "xl";
170
+ children?: ReactNode;
171
+ }
172
+
173
+ /**
174
+ * Preserve a constant aspect ratio for media (images, video, embeds). The
175
+ * inner child stretches to fill the box. Uses the native `aspect-ratio`
176
+ * CSS property — works on all modern browsers (Safari 15+, Chrome 88+).
177
+ *
178
+ * @example
179
+ * <AspectRatio ratio={16 / 9}>
180
+ * <img src="/cover.jpg" alt="" style={{ width: "100%", height: "100%", objectFit: "cover" }} />
181
+ * </AspectRatio>
182
+ */
183
+ export declare function AspectRatio({ ratio, className, style, children, ...props }: AspectRatioProps): JSX.Element;
184
+
185
+ export declare interface AspectRatioProps extends HTMLAttributes<HTMLDivElement> {
186
+ /**
187
+ * Width-to-height ratio. Pass `16/9` for widescreen, `1` for square,
188
+ * `4/3` for SD video, `3/4` for portrait, etc. Default `16/9`.
189
+ */
190
+ ratio?: number;
191
+ children?: ReactNode;
192
+ }
193
+
194
+ export declare type AsyncStatus = "idle" | "pending" | "success" | "error";
195
+
91
196
  export declare interface AudioPlayer {
92
197
  /** Play `src`. Returns the underlying element, or `null` when the browser blocked autoplay. */
93
198
  play: (src: string, options?: PlayAudioOptions) => Promise<HTMLAudioElement | null>;
@@ -182,6 +287,105 @@ export declare type BadgeSize = "sm" | "md" | "lg";
182
287
 
183
288
  export declare type BadgeVariant = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
184
289
 
290
+ /**
291
+ * Top-of-page persistent notice. Use for environment indicators
292
+ * ("Você está em sandbox"), maintenance windows, account warnings.
293
+ * Different from `Alert` (inline near a field) and `Toast` (transient).
294
+ *
295
+ * @example
296
+ * <Banner variant="warning" dismissible onDismiss={() => setOpen(false)}>
297
+ * Sua assinatura expira em 3 dias.
298
+ * </Banner>
299
+ */
300
+ export declare function Banner({ variant, icon, title, action, dismissible, onDismiss, className, children, ...props }: BannerProps): JSX.Element | null;
301
+
302
+ export declare interface BannerProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
303
+ /** Visual variant. Default `"info"`. */
304
+ variant?: BannerVariant;
305
+ /** Optional leading icon. */
306
+ icon?: ReactNode;
307
+ /** Optional title displayed before description. */
308
+ title?: ReactNode;
309
+ /** Optional action button rendered on the right side. */
310
+ action?: ReactNode;
311
+ /** Show a dismiss button on the right. */
312
+ dismissible?: boolean;
313
+ /** Callback fired when the dismiss button is clicked. */
314
+ onDismiss?: () => void;
315
+ children?: ReactNode;
316
+ }
317
+
318
+ export declare type BannerVariant = "info" | "success" | "warning" | "danger";
319
+
320
+ /**
321
+ * Fixed-bottom mobile tab bar. 3–5 items recommended. Pair with
322
+ * `<Show below="md">` to render only on mobile.
323
+ *
324
+ * @example
325
+ * <Show below="md">
326
+ * <BottomNavigation
327
+ * items={[
328
+ * { key: "home", label: "Início", icon: <Home /> },
329
+ * { key: "search", label: "Buscar", icon: <Search /> },
330
+ * { key: "profile", label: "Perfil", icon: <User /> },
331
+ * ]}
332
+ * value={tab}
333
+ * onChange={setTab}
334
+ * />
335
+ * </Show>
336
+ */
337
+ export declare function BottomNavigation({ items, value, onChange, showLabels, className, ...props }: BottomNavigationProps): JSX.Element;
338
+
339
+ export declare interface BottomNavigationItem {
340
+ /** Unique identifier — used as React key and for value matching. */
341
+ key: string;
342
+ /** Visible label. */
343
+ label: ReactNode;
344
+ /** Icon rendered above the label. */
345
+ icon?: ReactNode;
346
+ /** Optional badge content rendered above the icon. */
347
+ badge?: ReactNode;
348
+ /** When true, the item is not selectable. */
349
+ disabled?: boolean;
350
+ }
351
+
352
+ export declare interface BottomNavigationProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
353
+ items: BottomNavigationItem[];
354
+ /** Selected key. */
355
+ value: string;
356
+ /** Called with the new selected key on click. */
357
+ onChange: (key: string) => void;
358
+ /** Show label below each icon. Default `true`. */
359
+ showLabels?: boolean;
360
+ }
361
+
362
+ /**
363
+ * Slide-up modal panel — mobile-style sheet anchored to the bottom edge.
364
+ * Uses portal + safe-area padding + scroll lock.
365
+ *
366
+ * @example
367
+ * <BottomSheet open={open} onClose={() => setOpen(false)} title="Filters">
368
+ * <FilterForm />
369
+ * </BottomSheet>
370
+ */
371
+ export declare function BottomSheet({ open, onClose, title, showHandle, dismissOnBackdrop, dismissOnEsc, className, children, ...props }: BottomSheetProps): ReactPortal | null;
372
+
373
+ export declare interface BottomSheetProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
374
+ /** Controlled open state. */
375
+ open: boolean;
376
+ /** Fires when user dismisses (backdrop click, Esc, swipe). */
377
+ onClose: () => void;
378
+ /** Optional title rendered at the top of the sheet. */
379
+ title?: ReactNode;
380
+ /** Show a drag handle indicator at the top. Default `true`. */
381
+ showHandle?: boolean;
382
+ /** When `true`, clicking the backdrop closes the sheet. Default `true`. */
383
+ dismissOnBackdrop?: boolean;
384
+ /** When `true`, pressing Esc closes the sheet. Default `true`. */
385
+ dismissOnEsc?: boolean;
386
+ children?: ReactNode;
387
+ }
388
+
185
389
  export declare interface BreadcrumbItem {
186
390
  label: ReactNode;
187
391
  href?: string;
@@ -283,7 +487,31 @@ export declare interface CardProps extends Omit<HTMLAttributes<HTMLDivElement>,
283
487
 
284
488
  export declare type Catalog = Record<string, Messages>;
285
489
 
286
- export declare const CEPInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
490
+ /**
491
+ * Center children horizontally, vertically, or both. Flex-based; works with
492
+ * any child size. Pair with `minHeight` (or set parent height) when
493
+ * centering vertically.
494
+ *
495
+ * @example
496
+ * <Center axis="both" minHeight="100vh">
497
+ * <Spinner />
498
+ * </Center>
499
+ */
500
+ export declare function Center({ axis, minHeight, fullWidth, className, style, children, ...props }: CenterProps): JSX.Element;
501
+
502
+ export declare type CenterAxis = "both" | "horizontal" | "vertical";
503
+
504
+ export declare interface CenterProps extends HTMLAttributes<HTMLDivElement> {
505
+ /** Which axis to center on. Default `"both"`. */
506
+ axis?: CenterAxis;
507
+ /** Fixed height for the container. Numbers map to `${n}px`; strings pass through. Useful when centering inside an unsized parent. */
508
+ minHeight?: number | string;
509
+ /** When `true` (default), takes up `100%` width of the parent. */
510
+ fullWidth?: boolean;
511
+ children?: ReactNode;
512
+ }
513
+
514
+ export declare const CEPInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
287
515
  value: string;
288
516
  onChange: (value: string) => void;
289
517
  } & RefAttributes<HTMLInputElement>>;
@@ -332,11 +560,41 @@ declare type ClassValue = string | number | bigint | boolean | null | undefined
332
560
  */
333
561
  export declare function cn(...values: ClassValue[]): string;
334
562
 
335
- export declare const CNPJInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
563
+ export declare const CNPJInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
336
564
  value: string;
337
565
  onChange: (value: string) => void;
338
566
  } & RefAttributes<HTMLInputElement>>;
339
567
 
568
+ /**
569
+ * Combobox — text input with a filterable dropdown of options.
570
+ *
571
+ * Selecting an option fires `onChange(value)`. Typing filters the list.
572
+ * Keyboard: ArrowUp/ArrowDown to navigate, Enter to select, Esc to close.
573
+ */
574
+ export declare function Combobox({ options, value, onChange, label, placeholder, helperText, error, disabled, filter, emptyMessage, className, }: ComboboxProps): JSX.Element;
575
+
576
+ export declare interface ComboboxOption {
577
+ value: string;
578
+ label: string;
579
+ disabled?: boolean;
580
+ }
581
+
582
+ export declare interface ComboboxProps {
583
+ options: ComboboxOption[];
584
+ value: string;
585
+ onChange: (value: string) => void;
586
+ label?: string;
587
+ placeholder?: string;
588
+ helperText?: string;
589
+ error?: string;
590
+ disabled?: boolean;
591
+ /** Custom filter — return true to keep the option. Default is case-insensitive substring match on label. */
592
+ filter?: (option: ComboboxOption, query: string) => boolean;
593
+ /** Message shown when no option matches. */
594
+ emptyMessage?: string;
595
+ className?: string;
596
+ }
597
+
340
598
  /**
341
599
  * Quick confirmation prompt built on top of {@link Modal}. Use for destructive
342
600
  * actions with `variant="danger"`.
@@ -376,7 +634,11 @@ export declare interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
376
634
 
377
635
  export declare type ContainerSize = "sm" | "md" | "lg" | "xl" | "full";
378
636
 
379
- export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
637
+ export { Control }
638
+
639
+ export { Controller }
640
+
641
+ export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
380
642
  value: string;
381
643
  onChange: (value: string) => void;
382
644
  } & RefAttributes<HTMLInputElement>>;
@@ -826,6 +1088,46 @@ export declare interface DrawerProps {
826
1088
  showHandle?: boolean;
827
1089
  }
828
1090
 
1091
+ /**
1092
+ * Dropdown menu — list of selectable actions anchored to a trigger.
1093
+ *
1094
+ * - Toggle on trigger click.
1095
+ * - Close on outside click / Escape / item selection.
1096
+ * - Arrow keys navigate, Enter activates focused item.
1097
+ */
1098
+ export declare function DropdownMenu({ trigger, items, placement, className, }: DropdownMenuProps): JSX.Element;
1099
+
1100
+ export declare type DropdownMenuEntry = {
1101
+ type: "item";
1102
+ id: string;
1103
+ label: ReactNode;
1104
+ icon?: ReactNode;
1105
+ danger?: boolean;
1106
+ disabled?: boolean;
1107
+ onSelect: () => void;
1108
+ } | {
1109
+ type: "separator";
1110
+ id: string;
1111
+ } | {
1112
+ type: "label";
1113
+ id: string;
1114
+ label: ReactNode;
1115
+ };
1116
+
1117
+ export declare type DropdownMenuPlacement = "bottom-start" | "bottom-end" | "top-start" | "top-end";
1118
+
1119
+ export declare interface DropdownMenuProps {
1120
+ trigger: ReactElement<{
1121
+ onClick?: (e: React.MouseEvent) => void;
1122
+ "aria-expanded"?: boolean;
1123
+ "aria-controls"?: string;
1124
+ "aria-haspopup"?: boolean | "menu";
1125
+ }>;
1126
+ items: DropdownMenuEntry[];
1127
+ placement?: DropdownMenuPlacement;
1128
+ className?: string;
1129
+ }
1130
+
829
1131
  export declare interface ElementSize {
830
1132
  width: number;
831
1133
  height: number;
@@ -941,6 +1243,16 @@ export declare interface FeatureFlagsProviderProps {
941
1243
  children: ReactNode;
942
1244
  }
943
1245
 
1246
+ export { FieldArrayWithId }
1247
+
1248
+ export { FieldError }
1249
+
1250
+ export { FieldErrors }
1251
+
1252
+ export { FieldPath }
1253
+
1254
+ export { FieldValues }
1255
+
944
1256
  /**
945
1257
  * Drag-and-drop file dropzone. Pair with `uploadWithProgress` from the SDK
946
1258
  * to wire actual uploads with byte-level progress.
@@ -1066,11 +1378,70 @@ export declare function formatPercent(value: number): string;
1066
1378
  */
1067
1379
  export declare function formatPhone(value: string): string;
1068
1380
 
1381
+ /**
1382
+ * Glue between `react-hook-form` `Controller` and the SDK's controlled
1383
+ * components. Wraps any control that accepts `{ value, onChange, label,
1384
+ * error }` and routes RHF state into it — eliminating the per-field
1385
+ * `<Controller render={...} />` boilerplate.
1386
+ *
1387
+ * @example
1388
+ * const form = useZodForm(schema);
1389
+ * <FormProvider {...form}>
1390
+ * <Form>
1391
+ * <FormField name="email" label="Email" required>
1392
+ * <Input type="email" />
1393
+ * </FormField>
1394
+ * <FormField name="cep" label="CEP">
1395
+ * <CEPInput />
1396
+ * </FormField>
1397
+ * </Form>
1398
+ * </FormProvider>;
1399
+ */
1400
+ export declare function FormField<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>>({ name, label, helperText, required, control, children }: FormFieldProps<TValues, TName>): JSX.Element;
1401
+
1402
+ export declare interface FormFieldChildProps {
1403
+ name: string;
1404
+ value: unknown;
1405
+ onChange: (...args: unknown[]) => void;
1406
+ onBlur: () => void;
1407
+ ref: ControllerRenderProps["ref"];
1408
+ error?: string;
1409
+ "aria-invalid"?: boolean;
1410
+ "aria-describedby"?: string;
1411
+ label?: ReactNode;
1412
+ helperText?: ReactNode;
1413
+ required?: boolean;
1414
+ id?: string;
1415
+ }
1416
+
1417
+ export declare interface FormFieldProps<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>> {
1418
+ /** Field name (dot path supported, e.g. `"address.city"`). */
1419
+ name: TName;
1420
+ /** Field label rendered by the wrapped control. */
1421
+ label?: ReactNode;
1422
+ /** Helper text rendered by the wrapped control when there is no error. */
1423
+ helperText?: ReactNode;
1424
+ /** When `true`, marks the control as required (visual hint + native attribute). */
1425
+ required?: boolean;
1426
+ /**
1427
+ * Explicit `control` from `useForm()` / `useZodForm()`. Optional when a
1428
+ * `FormProvider` is in the tree.
1429
+ */
1430
+ control?: Control<TValues>;
1431
+ /**
1432
+ * The control to render. Receives `{ value, onChange, onBlur, ref, error, ... }`
1433
+ * via `cloneElement`. Pass `<Input />`, `<Select />`, masked inputs, etc.
1434
+ */
1435
+ children: ReactElement;
1436
+ }
1437
+
1069
1438
  export declare type FormLayout = "stack" | "inline" | "grid";
1070
1439
 
1071
1440
  export declare interface FormProps extends FormHTMLAttributes<HTMLFormElement>, LayoutProps {
1072
1441
  }
1073
1442
 
1443
+ export { FormProvider }
1444
+
1074
1445
  /**
1075
1446
  * Forces a horizontal row regardless of parent layout — useful for grouping
1076
1447
  * two short fields side-by-side inside an otherwise stacked form (e.g. CEP +
@@ -1138,6 +1509,71 @@ export declare interface GetInitialThemeOptions {
1138
1509
  defaultTheme?: ThemeMode;
1139
1510
  }
1140
1511
 
1512
+ /**
1513
+ * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:
1514
+ *
1515
+ * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,
1516
+ * `provider: "google"`, `raw`).
1517
+ * 2. Normalises errors into [[OAuthError]].
1518
+ * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does
1519
+ * not declare `@react-oauth/google` as a peer dep — apps that don't use
1520
+ * Google never pay for it.
1521
+ *
1522
+ * @example
1523
+ * import { GoogleLogin, GoogleOAuthProvider } from "@react-oauth/google";
1524
+ * import { GoogleSignIn } from "tempest-react-sdk";
1525
+ *
1526
+ * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>
1527
+ * <GoogleSignIn
1528
+ * component={GoogleLogin}
1529
+ * onSuccess={async ({ idToken }) => {
1530
+ * await api.post("/auth/google", { body: { id_token: idToken } });
1531
+ * }}
1532
+ * onError={(err) => toast.error(err.message)}
1533
+ * />
1534
+ * </GoogleOAuthProvider>
1535
+ */
1536
+ export declare function GoogleSignIn({ component: Component, onSuccess, onError, locale, theme, text, shape, size, disableOneTap, width, className, style, }: GoogleSignInProps): JSX.Element;
1537
+
1538
+ export declare interface GoogleSignInProps {
1539
+ /**
1540
+ * `GoogleLogin` component from `@react-oauth/google`. The caller imports
1541
+ * it and passes it through so the SDK doesn't take `@react-oauth/google`
1542
+ * as a peer dep.
1543
+ */
1544
+ component: (props: Record<string, unknown>) => ReactNode;
1545
+ /** Fired with the validated credential on success. */
1546
+ onSuccess: (credential: OAuthCredential) => void | Promise<void>;
1547
+ /** Fired with a normalised error on failure. */
1548
+ onError?: (error: OAuthError) => void;
1549
+ /** Optional locale override (e.g. `"pt-BR"`). Falls back to browser locale. */
1550
+ locale?: string;
1551
+ /** Visual theme — passed through to `<GoogleLogin>`. */
1552
+ theme?: GoogleSignInTheme;
1553
+ /** Button text variant. */
1554
+ text?: GoogleSignInText;
1555
+ /** Button shape. */
1556
+ shape?: GoogleSignInShape;
1557
+ /** Button size. */
1558
+ size?: GoogleSignInSize;
1559
+ /** Disable Google's "One Tap" auto-prompt. Default `false`. */
1560
+ disableOneTap?: boolean;
1561
+ /** Optional `width` override (px) — Google's button is fixed-width. */
1562
+ width?: number;
1563
+ /** Optional className applied to the wrapper. */
1564
+ className?: string;
1565
+ /** Optional inline style applied to the wrapper. */
1566
+ style?: CSSProperties;
1567
+ }
1568
+
1569
+ export declare type GoogleSignInShape = "rectangular" | "pill" | "circle" | "square";
1570
+
1571
+ export declare type GoogleSignInSize = "large" | "medium" | "small";
1572
+
1573
+ export declare type GoogleSignInText = "signin_with" | "signup_with" | "continue_with" | "signin";
1574
+
1575
+ export declare type GoogleSignInTheme = "filled_blue" | "filled_black" | "outline";
1576
+
1141
1577
  /** Simple CSS-Grid wrapper for equal-width or custom column layouts. */
1142
1578
  export declare function Grid({ columns, gap, className, style, children, ...props }: GridProps): JSX.Element;
1143
1579
 
@@ -1383,6 +1819,11 @@ export declare interface ListOptions<TItem> {
1383
1819
  filter?: (item: TItem) => boolean;
1384
1820
  }
1385
1821
 
1822
+ export declare type LocalStorageOptions<T> = {
1823
+ serialize?: (value: T) => string;
1824
+ deserialize?: (raw: string) => T;
1825
+ };
1826
+
1386
1827
  export declare interface LogEntry {
1387
1828
  level: LogLevel;
1388
1829
  message: string;
@@ -1449,6 +1890,56 @@ export declare interface MoneyInputProps extends Omit<InputProps, "value" | "onC
1449
1890
  locale?: string;
1450
1891
  }
1451
1892
 
1893
+ /**
1894
+ * Top app bar. Three-slot layout (logo / nav / actions) that collapses
1895
+ * gracefully on mobile (nav slot wraps below).
1896
+ *
1897
+ * @example
1898
+ * <Navbar
1899
+ * logo={<img src="/logo.svg" alt="App" />}
1900
+ * nav={<NavLinks />}
1901
+ * actions={<UserMenu />}
1902
+ * />
1903
+ */
1904
+ export declare function Navbar({ logo, nav, actions, sticky, tone, bordered, className, ...props }: NavbarProps): JSX.Element;
1905
+
1906
+ export declare interface NavbarProps extends HTMLAttributes<HTMLElement> {
1907
+ /** Left slot — typically logo + brand name. */
1908
+ logo?: ReactNode;
1909
+ /** Center slot — typically nav links. */
1910
+ nav?: ReactNode;
1911
+ /** Right slot — typically user menu / actions. */
1912
+ actions?: ReactNode;
1913
+ /** Make the bar sticky at the top of the scroll container. Default `true`. */
1914
+ sticky?: boolean;
1915
+ /** Visual tone. Default `"surface"`. */
1916
+ tone?: NavbarTone;
1917
+ /** When set, renders a thin bottom border. Default `true`. */
1918
+ bordered?: boolean;
1919
+ }
1920
+
1921
+ export declare type NavbarTone = "surface" | "primary" | "transparent";
1922
+
1923
+ export declare interface OAuthCredential {
1924
+ /** Provider-issued ID token (JWT). */
1925
+ idToken: string;
1926
+ /** Provider name (e.g. `"google"`, `"facebook"`). */
1927
+ provider: string;
1928
+ /** Raw response from the provider's SDK — opaque, for app-level inspection. */
1929
+ raw?: unknown;
1930
+ }
1931
+
1932
+ export declare interface OAuthError {
1933
+ /** Provider name. */
1934
+ provider: string;
1935
+ /** Provider-specific error code, when available. */
1936
+ code?: string;
1937
+ /** Human-readable message. */
1938
+ message: string;
1939
+ /** Raw underlying error object. */
1940
+ raw?: unknown;
1941
+ }
1942
+
1452
1943
  export declare interface OfflineStore<TItem, TKey extends string | number> {
1453
1944
  /** Insert or replace a record. */
1454
1945
  put: (item: TItem, owner?: string) => Promise<TKey>;
@@ -1497,6 +1988,35 @@ export declare interface OfflineStoreConfig<TItem> {
1497
1988
  ownerField?: keyof TItem & string;
1498
1989
  }
1499
1990
 
1991
+ /**
1992
+ * Page wrapper with header + (optional) toolbar + content + footer. Pairs
1993
+ * with `Container` when you want a max-width content well.
1994
+ *
1995
+ * @example
1996
+ * <Page title="Pedidos" description="Acompanhe seus pedidos" actions={<Button>Novo</Button>}>
1997
+ * <Table {...} />
1998
+ * </Page>
1999
+ */
2000
+ export declare function Page({ title, eyebrow, description, actions, toolbar, footer, padded, className, children, ...props }: PageProps): JSX.Element;
2001
+
2002
+ export declare interface PageProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
2003
+ /** Page title rendered as `<h1>`. */
2004
+ title?: ReactNode;
2005
+ /** Optional subtitle / breadcrumbs slot rendered above the title. */
2006
+ eyebrow?: ReactNode;
2007
+ /** Optional description rendered below the title. */
2008
+ description?: ReactNode;
2009
+ /** Right-side actions slot in the header (buttons, menus). */
2010
+ actions?: ReactNode;
2011
+ /** Sticky tab bar / filter row rendered just below the header. */
2012
+ toolbar?: ReactNode;
2013
+ /** Footer slot rendered at the bottom of the content area. */
2014
+ footer?: ReactNode;
2015
+ /** Page-level padding. Default `true`. */
2016
+ padded?: boolean;
2017
+ children?: ReactNode;
2018
+ }
2019
+
1500
2020
  /**
1501
2021
  * Numeric pagination controls. Pair with {@link usePagination} for state.
1502
2022
  */
@@ -1529,7 +2049,9 @@ export declare interface PaginationProps {
1529
2049
  */
1530
2050
  export declare function parseResponse<TSchema extends z.ZodTypeAny>(schema: TSchema, raw: unknown, context: string): z.infer<TSchema>;
1531
2051
 
1532
- export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "onChange" | "value"> & {
2052
+ export { Path }
2053
+
2054
+ export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
1533
2055
  value: string;
1534
2056
  onChange: (value: string) => void;
1535
2057
  } & RefAttributes<HTMLInputElement>>;
@@ -1556,6 +2078,37 @@ export declare interface PlayAudioOptions {
1556
2078
  onError?: (error: unknown) => void;
1557
2079
  }
1558
2080
 
2081
+ /**
2082
+ * Lightweight popover. Renders a positioned panel anchored to a trigger,
2083
+ * dismissed on outside click / Escape. Does NOT include collision detection
2084
+ * or smart positioning — pair with Floating UI if you need that.
2085
+ */
2086
+ export declare function Popover({ trigger, children, placement, open, onOpenChange, defaultOpen, closeOnEsc, closeOnOutsideClick, className, }: PopoverProps): JSX.Element;
2087
+
2088
+ export declare type PopoverPlacement = "top" | "bottom" | "left" | "right";
2089
+
2090
+ export declare interface PopoverProps {
2091
+ /** Trigger element. Receives `onClick`/`aria-expanded`/`aria-controls`. */
2092
+ trigger: ReactElement<{
2093
+ onClick?: (e: React.MouseEvent) => void;
2094
+ "aria-expanded"?: boolean;
2095
+ "aria-controls"?: string;
2096
+ }>;
2097
+ children: ReactNode;
2098
+ placement?: PopoverPlacement;
2099
+ /** Controlled open state. */
2100
+ open?: boolean;
2101
+ /** Called when the user toggles or dismisses. */
2102
+ onOpenChange?: (open: boolean) => void;
2103
+ /** Default open state for uncontrolled usage. */
2104
+ defaultOpen?: boolean;
2105
+ /** Close on Escape. Default true. */
2106
+ closeOnEsc?: boolean;
2107
+ /** Close on outside click. Default true. */
2108
+ closeOnOutsideClick?: boolean;
2109
+ className?: string;
2110
+ }
2111
+
1559
2112
  /**
1560
2113
  * Minimal subset of `posthog-js` used by the adapter. Pass either the real
1561
2114
  * default export (`import posthog from "posthog-js"`) or a stubbed object
@@ -1662,6 +2215,51 @@ export declare interface RadioProps extends Omit<InputHTMLAttributes<HTMLInputEl
1662
2215
  wrapperClassName?: string;
1663
2216
  }
1664
2217
 
2218
+ /**
2219
+ * Dual-thumb range slider. Built on two native `<input type="range">` so it
2220
+ * stays accessible and works with keyboards/screen readers without
2221
+ * heavyweight positioning libs. The active fill is positioned via percentages.
2222
+ */
2223
+ export declare function RangeSlider({ value, onChange, min, max, step, label, helperText, disabled, formatValue, className, }: RangeSliderProps): JSX.Element;
2224
+
2225
+ export declare interface RangeSliderProps {
2226
+ value: RangeValue;
2227
+ onChange: (value: RangeValue) => void;
2228
+ min?: number;
2229
+ max?: number;
2230
+ step?: number;
2231
+ label?: string;
2232
+ helperText?: string;
2233
+ disabled?: boolean;
2234
+ /** Formatter for the value badge next to the label. Defaults to `min – max`. */
2235
+ formatValue?: (value: RangeValue) => string;
2236
+ className?: string;
2237
+ }
2238
+
2239
+ export declare type RangeValue = [number, number];
2240
+
2241
+ export declare type RatingSize = "sm" | "md" | "lg";
2242
+
2243
+ /**
2244
+ * Star rating control. Renders `max` stars, fills the first `value`. Click a
2245
+ * star to set rating (when not readonly). Hovering previews the value.
2246
+ */
2247
+ export declare function RatingStars({ value, max, onChange, size, readonly, disabled, label, className, }: RatingStarsProps): JSX.Element;
2248
+
2249
+ export declare interface RatingStarsProps {
2250
+ /** Current selected value (1..max). 0 means none. */
2251
+ value: number;
2252
+ /** Total number of stars. Default 5. */
2253
+ max?: number;
2254
+ onChange?: (value: number) => void;
2255
+ size?: RatingSize;
2256
+ readonly?: boolean;
2257
+ disabled?: boolean;
2258
+ /** Accessible label for the rating group. */
2259
+ label?: string;
2260
+ className?: string;
2261
+ }
2262
+
1665
2263
  /** Recommended refetch intervals (milliseconds). */
1666
2264
  export declare const REFETCH_TIME: {
1667
2265
  readonly REALTIME: number;
@@ -1762,6 +2360,28 @@ export declare interface RetryOptions {
1762
2360
  signal?: AbortSignal;
1763
2361
  }
1764
2362
 
2363
+ /**
2364
+ * Apply `env(safe-area-inset-*)` padding so content avoids iOS notch /
2365
+ * Android navbar / device chrome. Wrap the outermost container of pages
2366
+ * with sticky headers/footers.
2367
+ *
2368
+ * @example
2369
+ * <SafeArea edges={["top"]}>
2370
+ * <Navbar />
2371
+ * </SafeArea>
2372
+ */
2373
+ export declare function SafeArea({ edges, inline, className, children, ...props }: SafeAreaProps): JSX.Element;
2374
+
2375
+ export declare type SafeAreaEdge = "top" | "right" | "bottom" | "left";
2376
+
2377
+ export declare interface SafeAreaProps extends HTMLAttributes<HTMLDivElement> {
2378
+ /** Edges to pad. Default `["top","right","bottom","left"]` (all). */
2379
+ edges?: SafeAreaEdge[];
2380
+ /** Render as inline (use `display: contents`). */
2381
+ inline?: boolean;
2382
+ children?: ReactNode;
2383
+ }
2384
+
1765
2385
  /**
1766
2386
  * Search input with magnifier icon and a clear button. Controlled component:
1767
2387
  * pass `value` and `onChange`.
@@ -1864,6 +2484,51 @@ export declare interface ShowProps {
1864
2484
  children: ReactNode;
1865
2485
  }
1866
2486
 
2487
+ /**
2488
+ * Desktop sidebar navigation. Pair with `<Show above="md">` and a `Drawer`
2489
+ * for mobile.
2490
+ *
2491
+ * @example
2492
+ * const [tab, setTab] = useState("home");
2493
+ * <Show above="md">
2494
+ * <Sidebar
2495
+ * header={<Brand />}
2496
+ * items={[{ key: "home", label: "Home", icon: <Home /> }]}
2497
+ * value={tab}
2498
+ * onChange={setTab}
2499
+ * />
2500
+ * </Show>
2501
+ */
2502
+ export declare function Sidebar({ header, items, value, onChange, footer, collapsed, width, collapsedWidth, className, style, ...props }: SidebarProps): JSX.Element;
2503
+
2504
+ export declare interface SidebarItem {
2505
+ key: string;
2506
+ label: ReactNode;
2507
+ icon?: ReactNode;
2508
+ badge?: ReactNode;
2509
+ disabled?: boolean;
2510
+ href?: string;
2511
+ }
2512
+
2513
+ export declare interface SidebarProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
2514
+ /** Top slot — typically the logo + brand. */
2515
+ header?: ReactNode;
2516
+ /** Navigation items. */
2517
+ items: SidebarItem[];
2518
+ /** Active item key. */
2519
+ value?: string;
2520
+ /** Fires when an item is clicked. Receives the item's `key`. */
2521
+ onChange?: (key: string) => void;
2522
+ /** Bottom slot — typically settings/profile/logout. */
2523
+ footer?: ReactNode;
2524
+ /** Collapsed mode — only icons visible. Default `false`. */
2525
+ collapsed?: boolean;
2526
+ /** Width when expanded, in pixels or any CSS length. Default `240px`. */
2527
+ width?: number | string;
2528
+ /** Width when collapsed, in pixels or any CSS length. Default `64px`. */
2529
+ collapsedWidth?: number | string;
2530
+ }
2531
+
1867
2532
  /** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
1868
2533
  export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
1869
2534
 
@@ -1881,6 +2546,26 @@ export declare interface SkeletonProps {
1881
2546
  */
1882
2547
  export declare function skipWaiting(worker: ServiceWorker): void;
1883
2548
 
2549
+ /**
2550
+ * Flex spacer — pushes siblings apart inside a flex container. Equivalent
2551
+ * to `<div style={{ flex: 1 }}>` but typed and intent-revealing.
2552
+ *
2553
+ * @example
2554
+ * <Stack direction="horizontal">
2555
+ * <Button>Cancelar</Button>
2556
+ * <Spacer />
2557
+ * <Button variant="primary">Salvar</Button>
2558
+ * </Stack>
2559
+ */
2560
+ export declare function Spacer({ axis, className, ...props }: SpacerProps): JSX.Element;
2561
+
2562
+ export declare type SpacerAxis = "both" | "x" | "y";
2563
+
2564
+ export declare interface SpacerProps extends HTMLAttributes<HTMLDivElement> {
2565
+ /** Axis to flex along. Default `"both"` (`flex: 1`). */
2566
+ axis?: SpacerAxis;
2567
+ }
2568
+
1884
2569
  /** Loading spinner with preset sizes (xs..xl). Provide `label` for screen readers. */
1885
2570
  export declare function Spinner({ size, className, label }: SpinnerProps): JSX.Element;
1886
2571
 
@@ -1920,6 +2605,32 @@ export declare const STALE_TIME: {
1920
2605
  readonly INFINITE: number;
1921
2606
  };
1922
2607
 
2608
+ /**
2609
+ * KPI card. Dashboard widget showing a label + big value + optional
2610
+ * delta/trend and hint.
2611
+ *
2612
+ * @example
2613
+ * <Stat label="Receita" value="R$ 12.345" delta="+12,4%" trend="up" hint="vs. mês anterior" />
2614
+ */
2615
+ export declare function Stat({ label, value, delta, trend, hint, icon, className, ...props }: StatProps): JSX.Element;
2616
+
2617
+ export declare interface StatProps extends HTMLAttributes<HTMLDivElement> {
2618
+ /** Metric label (e.g. "Revenue", "Active users"). */
2619
+ label: ReactNode;
2620
+ /** Metric value (e.g. "R$ 12.345", "1.2k"). */
2621
+ value: ReactNode;
2622
+ /** Optional comparison delta — when set, renders alongside the value. */
2623
+ delta?: ReactNode;
2624
+ /** Trend direction for the delta. Default inferred from delta string. */
2625
+ trend?: StatTrend;
2626
+ /** Optional supporting context line below the value. */
2627
+ hint?: ReactNode;
2628
+ /** Optional leading icon. */
2629
+ icon?: ReactNode;
2630
+ }
2631
+
2632
+ export declare type StatTrend = "up" | "down" | "flat";
2633
+
1923
2634
  export declare interface StepItem {
1924
2635
  label: ReactNode;
1925
2636
  }
@@ -1952,6 +2663,8 @@ export declare const storage: {
1952
2663
  remove(key: string): void;
1953
2664
  };
1954
2665
 
2666
+ export { SubmitHandler }
2667
+
1955
2668
  /** Toggle switch backed by a checkbox input. Accessible via keyboard. */
1956
2669
  export declare const Switch: ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLInputElement>>;
1957
2670
 
@@ -2026,6 +2739,33 @@ export declare interface TabsProps {
2026
2739
  className?: string;
2027
2740
  }
2028
2741
 
2742
+ /**
2743
+ * Removable chip — used for filter tokens, applied search filters,
2744
+ * selected entities. Different from `Badge` (status-only, not removable).
2745
+ *
2746
+ * @example
2747
+ * <Tag variant="primary" onRemove={() => removeFilter("sao-paulo")}>
2748
+ * São Paulo
2749
+ * </Tag>
2750
+ */
2751
+ export declare function Tag({ variant, size, onRemove, removeLabel, className, children, ...props }: TagProps): JSX.Element;
2752
+
2753
+ export declare interface TagProps extends Omit<HTMLAttributes<HTMLSpanElement>, "onRemove"> {
2754
+ /** Visual variant. Default `"neutral"`. */
2755
+ variant?: TagVariant;
2756
+ /** Visual size. Default `"md"`. */
2757
+ size?: TagSize;
2758
+ /** When set, renders a close button that fires this callback. */
2759
+ onRemove?: () => void;
2760
+ /** Custom remove label for screen readers. Default `"Remover"`. */
2761
+ removeLabel?: string;
2762
+ children?: ReactNode;
2763
+ }
2764
+
2765
+ export declare type TagSize = "sm" | "md" | "lg";
2766
+
2767
+ export declare type TagVariant = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
2768
+
2029
2769
  export declare interface TelemetryAdapter {
2030
2770
  /** Optional. Called when the provider mounts. */
2031
2771
  init?: () => void | Promise<void>;
@@ -2158,6 +2898,13 @@ export declare interface ToastProviderProps {
2158
2898
 
2159
2899
  export declare type ToastVariant = "success" | "warning" | "error" | "info";
2160
2900
 
2901
+ export declare interface ToggleHelpers {
2902
+ toggle: () => void;
2903
+ setTrue: () => void;
2904
+ setFalse: () => void;
2905
+ set: (next: boolean) => void;
2906
+ }
2907
+
2161
2908
  /**
2162
2909
  * Lightweight tooltip. Shows on hover and on focus (keyboard-friendly). Wraps
2163
2910
  * a single child element via `cloneElement`, so the trigger keeps its own ref
@@ -2237,6 +2984,34 @@ export declare interface UploadWithProgressOptions {
2237
2984
  */
2238
2985
  export declare function urlBase64ToUint8Array(base64String: string): Uint8Array<ArrayBuffer>;
2239
2986
 
2987
+ /**
2988
+ * Run an async function and track its `idle/pending/success/error` state.
2989
+ *
2990
+ * - Discards results from stale runs (race-condition safe).
2991
+ * - `immediate` (default `false`) triggers the function on mount and when
2992
+ * `deps` change. With `false`, call `run()` manually.
2993
+ * - Returns a stable object so callers can destructure or pass around safely.
2994
+ *
2995
+ * For server data with caching, prefer React Query — `useAsync` is the
2996
+ * minimal one-shot primitive without dependencies.
2997
+ */
2998
+ export declare function useAsync<T>(asyncFn: () => Promise<T>, deps?: ReadonlyArray<unknown>, options?: {
2999
+ immediate?: boolean;
3000
+ }): UseAsyncResult<T>;
3001
+
3002
+ export declare interface UseAsyncResult<T> {
3003
+ status: AsyncStatus;
3004
+ data: T | undefined;
3005
+ error: unknown;
3006
+ isPending: boolean;
3007
+ isSuccess: boolean;
3008
+ isError: boolean;
3009
+ /** Trigger the async function. Resolves with the new data or rejects. */
3010
+ run: () => Promise<T>;
3011
+ /** Reset state back to idle. */
3012
+ reset: () => void;
3013
+ }
3014
+
2240
3015
  /**
2241
3016
  * Hook-managed audio player. Each component instance gets its own
2242
3017
  * {@link AudioPlayer}, so unmounting cleanly stops playback. Useful for
@@ -2347,6 +3122,21 @@ export declare function useDocumentVisibility(): DocumentVisibility;
2347
3122
  */
2348
3123
  export declare function useErrorHandler(): (error: unknown) => void;
2349
3124
 
3125
+ /**
3126
+ * Subscribe to a DOM event with React-friendly semantics.
3127
+ *
3128
+ * - Handler is stored in a ref so callers can pass inline functions without
3129
+ * resubscribing on every render.
3130
+ * - `target` defaults to `window`. Accepts a raw `EventTarget` (window, document,
3131
+ * element) OR a ref pointing at one.
3132
+ * - Returns nothing — cleanup is automatic on unmount or when `eventName`/`target` change.
3133
+ */
3134
+ export declare function useEventListener<K extends keyof WindowEventMap>(eventName: K, handler: (event: WindowEventMap[K]) => void, target?: AnyEventTarget, options?: AddEventListenerOptions | boolean): void;
3135
+
3136
+ export declare function useEventListener<K extends keyof DocumentEventMap>(eventName: K, handler: (event: DocumentEventMap[K]) => void, target?: AnyEventTarget, options?: AddEventListenerOptions | boolean): void;
3137
+
3138
+ export declare function useEventListener<K extends keyof HTMLElementEventMap>(eventName: K, handler: (event: HTMLElementEventMap[K]) => void, target?: AnyEventTarget, options?: AddEventListenerOptions | boolean): void;
3139
+
2350
3140
  /**
2351
3141
  * React hook wrapper around {@link createEventStream}. Connection lifecycle is
2352
3142
  * tied to the component (and the `url`/`enabled` dependencies); the stream
@@ -2382,6 +3172,10 @@ export declare interface UseEventStreamResult<T> {
2382
3172
  */
2383
3173
  export declare function useFeatureFlag(key: string, defaultValue?: boolean): boolean;
2384
3174
 
3175
+ export { useFieldArray }
3176
+
3177
+ export { UseFieldArrayReturn }
3178
+
2385
3179
  /**
2386
3180
  * Read a typed flag value (string / number / boolean / null) and re-render
2387
3181
  * on change.
@@ -2395,6 +3189,18 @@ export declare function useFlagValue<T extends FlagValue = FlagValue>(key: strin
2395
3189
  */
2396
3190
  export declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, active: boolean): void;
2397
3191
 
3192
+ export { useForm }
3193
+
3194
+ export { useFormContext }
3195
+
3196
+ export { UseFormProps }
3197
+
3198
+ export { UseFormRegister }
3199
+
3200
+ export { UseFormReturn }
3201
+
3202
+ export { useFormState }
3203
+
2398
3204
  /** React hook around the Geolocation API. */
2399
3205
  export declare function useGeolocation(options?: UseGeolocationOptions): GeolocationState;
2400
3206
 
@@ -2447,6 +3253,18 @@ export declare interface UseKeyboardShortcutOptions {
2447
3253
  ignoreInput?: boolean;
2448
3254
  }
2449
3255
 
3256
+ /**
3257
+ * State synced with `localStorage`. SSR-safe — initial render returns the
3258
+ * provided default; the stored value is hydrated after mount. Updates to the
3259
+ * same key in other tabs are picked up via the `storage` event.
3260
+ *
3261
+ * @param key - localStorage key.
3262
+ * @param defaultValue - value used when nothing is stored or in SSR.
3263
+ * @param options - custom `serialize` / `deserialize` (default JSON).
3264
+ * @returns Tuple `[value, setValue, remove]`.
3265
+ */
3266
+ export declare function useLocalStorage<T>(key: string, defaultValue: T, options?: LocalStorageOptions<T>): [T, (value: T | ((prev: T) => T)) => void, () => void];
3267
+
2450
3268
  /**
2451
3269
  * Subscribe to a CSS media query and re-render on match changes.
2452
3270
  *
@@ -2455,6 +3273,55 @@ export declare interface UseKeyboardShortcutOptions {
2455
3273
  */
2456
3274
  export declare function useMediaQuery(query: string): boolean;
2457
3275
 
3276
+ /**
3277
+ * Run an OAuth-callback "exchange" exactly once on mount. Designed for
3278
+ * `/callback` routes that receive provider redirects and need to swap a
3279
+ * code/token for an app session via the backend.
3280
+ *
3281
+ * Survives React StrictMode double-mounting in dev — uses a ref guard to
3282
+ * ensure `exchange` runs once.
3283
+ *
3284
+ * @example
3285
+ * function OAuthCallback() {
3286
+ * const { loading, error } = useOAuthCallback({
3287
+ * exchange: async () => {
3288
+ * const code = new URLSearchParams(location.search).get("code")!;
3289
+ * return api.post("/auth/google/exchange", { body: { code } });
3290
+ * },
3291
+ * onSuccess: ({ token, user }) => {
3292
+ * useAuthStore.getState().setSession({ user, token });
3293
+ * navigate("/dashboard", { replace: true });
3294
+ * },
3295
+ * onError: () => navigate("/login?error=oauth", { replace: true }),
3296
+ * });
3297
+ *
3298
+ * if (loading) return <Spinner />;
3299
+ * if (error) return <ErrorState description="OAuth falhou" />;
3300
+ * return null;
3301
+ * }
3302
+ */
3303
+ export declare function useOAuthCallback<T>(options: UseOAuthCallbackOptions<T>): UseOAuthCallbackResult<T>;
3304
+
3305
+ export declare interface UseOAuthCallbackOptions<T> {
3306
+ /** Function that exchanges the provider response for an app session. Called once on mount. */
3307
+ exchange: () => Promise<T>;
3308
+ /** Fired with the result on success. Receives the value resolved by `exchange`. */
3309
+ onSuccess?: (result: T) => void | Promise<void>;
3310
+ /** Fired when `exchange` throws or rejects. */
3311
+ onError?: (error: unknown) => void;
3312
+ }
3313
+
3314
+ export declare interface UseOAuthCallbackResult<T> {
3315
+ /** `true` while the exchange promise is pending. */
3316
+ loading: boolean;
3317
+ /** Last resolved value, when `status === "success"`. */
3318
+ data: T | null;
3319
+ /** Last rejection reason, when `status === "error"`. */
3320
+ error: unknown;
3321
+ /** Aggregated state — `"pending"`, `"success"`, or `"error"`. */
3322
+ status: "pending" | "success" | "error";
3323
+ }
3324
+
2458
3325
  /**
2459
3326
  * Track the browser's `navigator.onLine` value and re-render on changes.
2460
3327
  * Returns `true` during SSR (assumption: server is online).
@@ -2574,6 +3441,14 @@ export declare function useTheme(): ThemeContextValue;
2574
3441
  */
2575
3442
  export declare function useToast(): ToastApi;
2576
3443
 
3444
+ /**
3445
+ * Boolean state with `toggle`/`setTrue`/`setFalse` helpers.
3446
+ *
3447
+ * @param initial - initial value (default `false`).
3448
+ * @returns Tuple `[value, helpers]`.
3449
+ */
3450
+ export declare function useToggle(initial?: boolean): [boolean, ToggleHelpers];
3451
+
2577
3452
  /**
2578
3453
  * Shortcut for components that only need the `t` function — avoids destructuring.
2579
3454
  */
@@ -2595,6 +3470,8 @@ export declare interface UseViaCEPResult {
2595
3470
  reset: () => void;
2596
3471
  }
2597
3472
 
3473
+ export { useWatch }
3474
+
2598
3475
  /**
2599
3476
  * React hook around {@link createWebSocket}. Manages the connection lifecycle
2600
3477
  * for the host component and tears it down on unmount.