tempest-react-sdk 0.3.0 → 0.5.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,11 +30,19 @@ 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
 
31
48
  /**
@@ -119,6 +136,40 @@ export declare interface ApiError {
119
136
  body?: unknown;
120
137
  }
121
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
+
122
173
  /**
123
174
  * Preserve a constant aspect ratio for media (images, video, embeds). The
124
175
  * inner child stretches to fill the box. Uses the native `aspect-ratio`
@@ -236,6 +287,105 @@ export declare type BadgeSize = "sm" | "md" | "lg";
236
287
 
237
288
  export declare type BadgeVariant = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
238
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
+
239
389
  export declare interface BreadcrumbItem {
240
390
  label: ReactNode;
241
391
  href?: string;
@@ -400,6 +550,16 @@ export declare interface ChipInputProps {
400
550
  className?: string;
401
551
  }
402
552
 
553
+ /**
554
+ * Clamp `value` between `min` and `max` (inclusive).
555
+ *
556
+ * @example
557
+ * clamp(120, 0, 100); // 100
558
+ * clamp(-5, 0, 100); // 0
559
+ * clamp(42, 0, 100); // 42
560
+ */
561
+ export declare function clamp(value: number, min: number, max: number): number;
562
+
403
563
  declare type ClassValue = string | number | bigint | boolean | null | undefined | ClassValue[];
404
564
 
405
565
  /**
@@ -484,6 +644,10 @@ export declare interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
484
644
 
485
645
  export declare type ContainerSize = "sm" | "md" | "lg" | "xl" | "full";
486
646
 
647
+ export { Control }
648
+
649
+ export { Controller }
650
+
487
651
  export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
488
652
  value: string;
489
653
  onChange: (value: string) => void;
@@ -1051,6 +1215,8 @@ export declare interface ErrorStateProps {
1051
1215
  className?: string;
1052
1216
  }
1053
1217
 
1218
+ export declare function estimatePasswordStrength(value: string): PasswordStrength;
1219
+
1054
1220
  export declare interface EventStreamController {
1055
1221
  close: () => void;
1056
1222
  /** Force an immediate reconnect, resetting the retry counter. */
@@ -1089,6 +1255,16 @@ export declare interface FeatureFlagsProviderProps {
1089
1255
  children: ReactNode;
1090
1256
  }
1091
1257
 
1258
+ export { FieldArrayWithId }
1259
+
1260
+ export { FieldError }
1261
+
1262
+ export { FieldErrors }
1263
+
1264
+ export { FieldPath }
1265
+
1266
+ export { FieldValues }
1267
+
1092
1268
  /**
1093
1269
  * Drag-and-drop file dropzone. Pair with `uploadWithProgress` from the SDK
1094
1270
  * to wire actual uploads with byte-level progress.
@@ -1214,11 +1390,70 @@ export declare function formatPercent(value: number): string;
1214
1390
  */
1215
1391
  export declare function formatPhone(value: string): string;
1216
1392
 
1393
+ /**
1394
+ * Glue between `react-hook-form` `Controller` and the SDK's controlled
1395
+ * components. Wraps any control that accepts `{ value, onChange, label,
1396
+ * error }` and routes RHF state into it — eliminating the per-field
1397
+ * `<Controller render={...} />` boilerplate.
1398
+ *
1399
+ * @example
1400
+ * const form = useZodForm(schema);
1401
+ * <FormProvider {...form}>
1402
+ * <Form>
1403
+ * <FormField name="email" label="Email" required>
1404
+ * <Input type="email" />
1405
+ * </FormField>
1406
+ * <FormField name="cep" label="CEP">
1407
+ * <CEPInput />
1408
+ * </FormField>
1409
+ * </Form>
1410
+ * </FormProvider>;
1411
+ */
1412
+ 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;
1413
+
1414
+ export declare interface FormFieldChildProps {
1415
+ name: string;
1416
+ value: unknown;
1417
+ onChange: (...args: unknown[]) => void;
1418
+ onBlur: () => void;
1419
+ ref: ControllerRenderProps["ref"];
1420
+ error?: string;
1421
+ "aria-invalid"?: boolean;
1422
+ "aria-describedby"?: string;
1423
+ label?: ReactNode;
1424
+ helperText?: ReactNode;
1425
+ required?: boolean;
1426
+ id?: string;
1427
+ }
1428
+
1429
+ export declare interface FormFieldProps<TValues extends FieldValues = FieldValues, TName extends FieldPath<TValues> = FieldPath<TValues>> {
1430
+ /** Field name (dot path supported, e.g. `"address.city"`). */
1431
+ name: TName;
1432
+ /** Field label rendered by the wrapped control. */
1433
+ label?: ReactNode;
1434
+ /** Helper text rendered by the wrapped control when there is no error. */
1435
+ helperText?: ReactNode;
1436
+ /** When `true`, marks the control as required (visual hint + native attribute). */
1437
+ required?: boolean;
1438
+ /**
1439
+ * Explicit `control` from `useForm()` / `useZodForm()`. Optional when a
1440
+ * `FormProvider` is in the tree.
1441
+ */
1442
+ control?: Control<TValues>;
1443
+ /**
1444
+ * The control to render. Receives `{ value, onChange, onBlur, ref, error, ... }`
1445
+ * via `cloneElement`. Pass `<Input />`, `<Select />`, masked inputs, etc.
1446
+ */
1447
+ children: ReactElement;
1448
+ }
1449
+
1217
1450
  export declare type FormLayout = "stack" | "inline" | "grid";
1218
1451
 
1219
1452
  export declare interface FormProps extends FormHTMLAttributes<HTMLFormElement>, LayoutProps {
1220
1453
  }
1221
1454
 
1455
+ export { FormProvider }
1456
+
1222
1457
  /**
1223
1458
  * Forces a horizontal row regardless of parent layout — useful for grouping
1224
1459
  * two short fields side-by-side inside an otherwise stacked form (e.g. CEP +
@@ -1286,6 +1521,71 @@ export declare interface GetInitialThemeOptions {
1286
1521
  defaultTheme?: ThemeMode;
1287
1522
  }
1288
1523
 
1524
+ /**
1525
+ * Thin wrapper over `@react-oauth/google`'s `<GoogleLogin>` that:
1526
+ *
1527
+ * 1. Normalises the success payload into [[OAuthCredential]] (`idToken`,
1528
+ * `provider: "google"`, `raw`).
1529
+ * 2. Normalises errors into [[OAuthError]].
1530
+ * 3. Lets you pass `GoogleLogin` via the `component` prop, so the SDK does
1531
+ * not declare `@react-oauth/google` as a peer dep — apps that don't use
1532
+ * Google never pay for it.
1533
+ *
1534
+ * @example
1535
+ * import { GoogleLogin, GoogleOAuthProvider } from "@react-oauth/google";
1536
+ * import { GoogleSignIn } from "tempest-react-sdk";
1537
+ *
1538
+ * <GoogleOAuthProvider clientId={import.meta.env.VITE_GOOGLE_CLIENT_ID}>
1539
+ * <GoogleSignIn
1540
+ * component={GoogleLogin}
1541
+ * onSuccess={async ({ idToken }) => {
1542
+ * await api.post("/auth/google", { body: { id_token: idToken } });
1543
+ * }}
1544
+ * onError={(err) => toast.error(err.message)}
1545
+ * />
1546
+ * </GoogleOAuthProvider>
1547
+ */
1548
+ export declare function GoogleSignIn({ component: Component, onSuccess, onError, locale, theme, text, shape, size, disableOneTap, width, className, style, }: GoogleSignInProps): JSX.Element;
1549
+
1550
+ export declare interface GoogleSignInProps {
1551
+ /**
1552
+ * `GoogleLogin` component from `@react-oauth/google`. The caller imports
1553
+ * it and passes it through so the SDK doesn't take `@react-oauth/google`
1554
+ * as a peer dep.
1555
+ */
1556
+ component: (props: Record<string, unknown>) => ReactNode;
1557
+ /** Fired with the validated credential on success. */
1558
+ onSuccess: (credential: OAuthCredential) => void | Promise<void>;
1559
+ /** Fired with a normalised error on failure. */
1560
+ onError?: (error: OAuthError) => void;
1561
+ /** Optional locale override (e.g. `"pt-BR"`). Falls back to browser locale. */
1562
+ locale?: string;
1563
+ /** Visual theme — passed through to `<GoogleLogin>`. */
1564
+ theme?: GoogleSignInTheme;
1565
+ /** Button text variant. */
1566
+ text?: GoogleSignInText;
1567
+ /** Button shape. */
1568
+ shape?: GoogleSignInShape;
1569
+ /** Button size. */
1570
+ size?: GoogleSignInSize;
1571
+ /** Disable Google's "One Tap" auto-prompt. Default `false`. */
1572
+ disableOneTap?: boolean;
1573
+ /** Optional `width` override (px) — Google's button is fixed-width. */
1574
+ width?: number;
1575
+ /** Optional className applied to the wrapper. */
1576
+ className?: string;
1577
+ /** Optional inline style applied to the wrapper. */
1578
+ style?: CSSProperties;
1579
+ }
1580
+
1581
+ export declare type GoogleSignInShape = "rectangular" | "pill" | "circle" | "square";
1582
+
1583
+ export declare type GoogleSignInSize = "large" | "medium" | "small";
1584
+
1585
+ export declare type GoogleSignInText = "signin_with" | "signup_with" | "continue_with" | "signin";
1586
+
1587
+ export declare type GoogleSignInTheme = "filled_blue" | "filled_black" | "outline";
1588
+
1289
1589
  /** Simple CSS-Grid wrapper for equal-width or custom column layouts. */
1290
1590
  export declare function Grid({ columns, gap, className, style, children, ...props }: GridProps): JSX.Element;
1291
1591
 
@@ -1602,6 +1902,56 @@ export declare interface MoneyInputProps extends Omit<InputProps, "value" | "onC
1602
1902
  locale?: string;
1603
1903
  }
1604
1904
 
1905
+ /**
1906
+ * Top app bar. Three-slot layout (logo / nav / actions) that collapses
1907
+ * gracefully on mobile (nav slot wraps below).
1908
+ *
1909
+ * @example
1910
+ * <Navbar
1911
+ * logo={<img src="/logo.svg" alt="App" />}
1912
+ * nav={<NavLinks />}
1913
+ * actions={<UserMenu />}
1914
+ * />
1915
+ */
1916
+ export declare function Navbar({ logo, nav, actions, sticky, tone, bordered, className, ...props }: NavbarProps): JSX.Element;
1917
+
1918
+ export declare interface NavbarProps extends HTMLAttributes<HTMLElement> {
1919
+ /** Left slot — typically logo + brand name. */
1920
+ logo?: ReactNode;
1921
+ /** Center slot — typically nav links. */
1922
+ nav?: ReactNode;
1923
+ /** Right slot — typically user menu / actions. */
1924
+ actions?: ReactNode;
1925
+ /** Make the bar sticky at the top of the scroll container. Default `true`. */
1926
+ sticky?: boolean;
1927
+ /** Visual tone. Default `"surface"`. */
1928
+ tone?: NavbarTone;
1929
+ /** When set, renders a thin bottom border. Default `true`. */
1930
+ bordered?: boolean;
1931
+ }
1932
+
1933
+ export declare type NavbarTone = "surface" | "primary" | "transparent";
1934
+
1935
+ export declare interface OAuthCredential {
1936
+ /** Provider-issued ID token (JWT). */
1937
+ idToken: string;
1938
+ /** Provider name (e.g. `"google"`, `"facebook"`). */
1939
+ provider: string;
1940
+ /** Raw response from the provider's SDK — opaque, for app-level inspection. */
1941
+ raw?: unknown;
1942
+ }
1943
+
1944
+ export declare interface OAuthError {
1945
+ /** Provider name. */
1946
+ provider: string;
1947
+ /** Provider-specific error code, when available. */
1948
+ code?: string;
1949
+ /** Human-readable message. */
1950
+ message: string;
1951
+ /** Raw underlying error object. */
1952
+ raw?: unknown;
1953
+ }
1954
+
1605
1955
  export declare interface OfflineStore<TItem, TKey extends string | number> {
1606
1956
  /** Insert or replace a record. */
1607
1957
  put: (item: TItem, owner?: string) => Promise<TKey>;
@@ -1650,6 +2000,35 @@ export declare interface OfflineStoreConfig<TItem> {
1650
2000
  ownerField?: keyof TItem & string;
1651
2001
  }
1652
2002
 
2003
+ /**
2004
+ * Page wrapper with header + (optional) toolbar + content + footer. Pairs
2005
+ * with `Container` when you want a max-width content well.
2006
+ *
2007
+ * @example
2008
+ * <Page title="Pedidos" description="Acompanhe seus pedidos" actions={<Button>Novo</Button>}>
2009
+ * <Table {...} />
2010
+ * </Page>
2011
+ */
2012
+ export declare function Page({ title, eyebrow, description, actions, toolbar, footer, padded, className, children, ...props }: PageProps): JSX.Element;
2013
+
2014
+ export declare interface PageProps extends Omit<HTMLAttributes<HTMLElement>, "title"> {
2015
+ /** Page title rendered as `<h1>`. */
2016
+ title?: ReactNode;
2017
+ /** Optional subtitle / breadcrumbs slot rendered above the title. */
2018
+ eyebrow?: ReactNode;
2019
+ /** Optional description rendered below the title. */
2020
+ description?: ReactNode;
2021
+ /** Right-side actions slot in the header (buttons, menus). */
2022
+ actions?: ReactNode;
2023
+ /** Sticky tab bar / filter row rendered just below the header. */
2024
+ toolbar?: ReactNode;
2025
+ /** Footer slot rendered at the bottom of the content area. */
2026
+ footer?: ReactNode;
2027
+ /** Page-level padding. Default `true`. */
2028
+ padded?: boolean;
2029
+ children?: ReactNode;
2030
+ }
2031
+
1653
2032
  /**
1654
2033
  * Numeric pagination controls. Pair with {@link usePagination} for state.
1655
2034
  */
@@ -1682,11 +2061,90 @@ export declare interface PaginationProps {
1682
2061
  */
1683
2062
  export declare function parseResponse<TSchema extends z.ZodTypeAny>(schema: TSchema, raw: unknown, context: string): z.infer<TSchema>;
1684
2063
 
2064
+ /**
2065
+ * Password field with toggle-visibility button and optional strength meter.
2066
+ *
2067
+ * @example
2068
+ * <PasswordInput label="Senha" showStrength autoComplete="new-password" />
2069
+ */
2070
+ export declare const PasswordInput: ForwardRefExoticComponent<PasswordInputProps & RefAttributes<HTMLInputElement>>;
2071
+
2072
+ export declare interface PasswordInputProps extends Omit<InputHTMLAttributes<HTMLInputElement>, "type" | "size"> {
2073
+ /** Label rendered above the input. */
2074
+ label?: ReactNode;
2075
+ /** Helper text below — replaced by `error` when set. */
2076
+ helperText?: ReactNode;
2077
+ /** Error message. Adds `aria-invalid` + red border. */
2078
+ error?: string;
2079
+ /** Visual size of the input. */
2080
+ size?: "sm" | "md" | "lg";
2081
+ /** Show a strength meter below the field. Default `false`. */
2082
+ showStrength?: boolean;
2083
+ /** Override the automatic strength calc (0–4). */
2084
+ strength?: PasswordStrength;
2085
+ /** Custom labels per strength level (5 entries). */
2086
+ strengthLabels?: readonly [string, string, string, string, string];
2087
+ /** Custom toggle button labels for accessibility. */
2088
+ toggleLabels?: {
2089
+ show: string;
2090
+ hide: string;
2091
+ };
2092
+ }
2093
+
2094
+ export declare type PasswordStrength = 0 | 1 | 2 | 3 | 4;
2095
+
2096
+ export { Path }
2097
+
1685
2098
  export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
1686
2099
  value: string;
1687
2100
  onChange: (value: string) => void;
1688
2101
  } & RefAttributes<HTMLInputElement>>;
1689
2102
 
2103
+ /**
2104
+ * One-time-password style input — N independent cells, paste support, auto-
2105
+ * advance on input, backspace flows back, arrow keys navigate.
2106
+ *
2107
+ * @example
2108
+ * <PinInput length={6} type="numeric" onComplete={(otp) => verify(otp)} />
2109
+ */
2110
+ export declare const PinInput: ForwardRefExoticComponent<PinInputProps & RefAttributes<HTMLDivElement>>;
2111
+
2112
+ export declare interface PinInputProps {
2113
+ /** Number of cells. Default `6`. */
2114
+ length?: number;
2115
+ /** Allowed character set. `numeric` (default) rejects letters, `alphanumeric` allows both. */
2116
+ type?: PinInputType;
2117
+ /** Visual size. Default `"md"`. */
2118
+ size?: PinInputSize;
2119
+ /** Controlled value. */
2120
+ value?: string;
2121
+ /** Initial value (uncontrolled mode). */
2122
+ defaultValue?: string;
2123
+ /** Fires on every change with the current concatenated value. */
2124
+ onChange?: (value: string) => void;
2125
+ /** Fires when the user fills the last cell. */
2126
+ onComplete?: (value: string) => void;
2127
+ /** Show characters obscured (`*`). Default `false`. */
2128
+ masked?: boolean;
2129
+ /** Label rendered above the cells. */
2130
+ label?: string;
2131
+ /** Helper text below the cells. */
2132
+ helperText?: string;
2133
+ /** Error message — turns cells red and replaces helperText. */
2134
+ error?: string;
2135
+ /** Disable all cells. */
2136
+ disabled?: boolean;
2137
+ /** Auto-focus the first cell on mount. Default `false`. */
2138
+ autoFocus?: boolean;
2139
+ /** id for the wrapping group label association. */
2140
+ id?: string;
2141
+ className?: string;
2142
+ }
2143
+
2144
+ export declare type PinInputSize = "sm" | "md" | "lg";
2145
+
2146
+ export declare type PinInputType = "numeric" | "alphanumeric";
2147
+
1690
2148
  /**
1691
2149
  * Convenience wrapper around a shared {@link AudioPlayer}. Use this for
1692
2150
  * one-off notification sounds. For more complex flows (e.g. several
@@ -1927,6 +2385,21 @@ export declare interface RegisterServiceWorkerOptions {
1927
2385
  onError?: (error: unknown) => void;
1928
2386
  }
1929
2387
 
2388
+ /**
2389
+ * Render a `Date` / ISO string as a relative-time string. Supports past and
2390
+ * future, PT-BR (default) and English.
2391
+ *
2392
+ * @example
2393
+ * relativeTime(new Date(Date.now() - 90_000)); // "1 min atrás"
2394
+ * relativeTime("2026-05-17T10:00:00Z", { locale: "en" }); // "5h ago"
2395
+ */
2396
+ export declare function relativeTime(input: Date | string | number, options?: {
2397
+ locale?: RelativeTimeLocale;
2398
+ now?: Date | number;
2399
+ }): string;
2400
+
2401
+ export declare type RelativeTimeLocale = "pt-BR" | "en";
2402
+
1930
2403
  export declare interface RequestOptions extends Omit<RequestInit, "body"> {
1931
2404
  body?: unknown;
1932
2405
  params?: Record<string, string | number | boolean | undefined | null>;
@@ -1991,6 +2464,28 @@ export declare interface RetryOptions {
1991
2464
  signal?: AbortSignal;
1992
2465
  }
1993
2466
 
2467
+ /**
2468
+ * Apply `env(safe-area-inset-*)` padding so content avoids iOS notch /
2469
+ * Android navbar / device chrome. Wrap the outermost container of pages
2470
+ * with sticky headers/footers.
2471
+ *
2472
+ * @example
2473
+ * <SafeArea edges={["top"]}>
2474
+ * <Navbar />
2475
+ * </SafeArea>
2476
+ */
2477
+ export declare function SafeArea({ edges, inline, className, children, ...props }: SafeAreaProps): JSX.Element;
2478
+
2479
+ export declare type SafeAreaEdge = "top" | "right" | "bottom" | "left";
2480
+
2481
+ export declare interface SafeAreaProps extends HTMLAttributes<HTMLDivElement> {
2482
+ /** Edges to pad. Default `["top","right","bottom","left"]` (all). */
2483
+ edges?: SafeAreaEdge[];
2484
+ /** Render as inline (use `display: contents`). */
2485
+ inline?: boolean;
2486
+ children?: ReactNode;
2487
+ }
2488
+
1994
2489
  /**
1995
2490
  * Search input with magnifier icon and a clear button. Controlled component:
1996
2491
  * pass `value` and `onChange`.
@@ -2004,6 +2499,44 @@ export declare interface SearchBarProps extends Omit<InputHTMLAttributes<HTMLInp
2004
2499
  wrapperClassName?: string;
2005
2500
  }
2006
2501
 
2502
+ /**
2503
+ * iOS-style segmented control. Two-to-five mutually-exclusive options
2504
+ * rendered as a single connected pill bar.
2505
+ *
2506
+ * @example
2507
+ * <SegmentedControl
2508
+ * value={view}
2509
+ * onChange={setView}
2510
+ * options={[
2511
+ * { value: "list", label: "Lista" },
2512
+ * { value: "grid", label: "Grade" },
2513
+ * ]}
2514
+ * />
2515
+ */
2516
+ export declare function SegmentedControl<TValue extends string = string>({ options, value, onChange, size, fullWidth, className, "aria-label": ariaLabel, ...props }: SegmentedControlProps<TValue>): JSX.Element;
2517
+
2518
+ export declare interface SegmentedControlOption<TValue extends string = string> {
2519
+ value: TValue;
2520
+ label: ReactNode;
2521
+ icon?: ReactNode;
2522
+ disabled?: boolean;
2523
+ }
2524
+
2525
+ export declare interface SegmentedControlProps<TValue extends string = string> extends Omit<HTMLAttributes<HTMLDivElement>, "onChange"> {
2526
+ /** Available segments. */
2527
+ options: SegmentedControlOption<TValue>[];
2528
+ /** Selected value. */
2529
+ value: TValue;
2530
+ /** Fires with the new value when a segment is selected. */
2531
+ onChange: (value: TValue) => void;
2532
+ /** Visual size. Default `"md"`. */
2533
+ size?: "sm" | "md" | "lg";
2534
+ /** Stretch to full width of container. Default `false`. */
2535
+ fullWidth?: boolean;
2536
+ /** Group label for screen readers. */
2537
+ "aria-label"?: string;
2538
+ }
2539
+
2007
2540
  /**
2008
2541
  * Native `<select>` wrapper with label/helper/error slots. Either provide
2009
2542
  * `options` for a quick render, or pass `<option>` children directly.
@@ -2093,6 +2626,51 @@ export declare interface ShowProps {
2093
2626
  children: ReactNode;
2094
2627
  }
2095
2628
 
2629
+ /**
2630
+ * Desktop sidebar navigation. Pair with `<Show above="md">` and a `Drawer`
2631
+ * for mobile.
2632
+ *
2633
+ * @example
2634
+ * const [tab, setTab] = useState("home");
2635
+ * <Show above="md">
2636
+ * <Sidebar
2637
+ * header={<Brand />}
2638
+ * items={[{ key: "home", label: "Home", icon: <Home /> }]}
2639
+ * value={tab}
2640
+ * onChange={setTab}
2641
+ * />
2642
+ * </Show>
2643
+ */
2644
+ export declare function Sidebar({ header, items, value, onChange, footer, collapsed, width, collapsedWidth, className, style, ...props }: SidebarProps): JSX.Element;
2645
+
2646
+ export declare interface SidebarItem {
2647
+ key: string;
2648
+ label: ReactNode;
2649
+ icon?: ReactNode;
2650
+ badge?: ReactNode;
2651
+ disabled?: boolean;
2652
+ href?: string;
2653
+ }
2654
+
2655
+ export declare interface SidebarProps extends Omit<HTMLAttributes<HTMLElement>, "onChange"> {
2656
+ /** Top slot — typically the logo + brand. */
2657
+ header?: ReactNode;
2658
+ /** Navigation items. */
2659
+ items: SidebarItem[];
2660
+ /** Active item key. */
2661
+ value?: string;
2662
+ /** Fires when an item is clicked. Receives the item's `key`. */
2663
+ onChange?: (key: string) => void;
2664
+ /** Bottom slot — typically settings/profile/logout. */
2665
+ footer?: ReactNode;
2666
+ /** Collapsed mode — only icons visible. Default `false`. */
2667
+ collapsed?: boolean;
2668
+ /** Width when expanded, in pixels or any CSS length. Default `240px`. */
2669
+ width?: number | string;
2670
+ /** Width when collapsed, in pixels or any CSS length. Default `64px`. */
2671
+ collapsedWidth?: number | string;
2672
+ }
2673
+
2096
2674
  /** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
2097
2675
  export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
2098
2676
 
@@ -2110,6 +2688,19 @@ export declare interface SkeletonProps {
2110
2688
  */
2111
2689
  export declare function skipWaiting(worker: ServiceWorker): void;
2112
2690
 
2691
+ /**
2692
+ * Convert a string into a URL-safe slug.
2693
+ *
2694
+ * - Strips accents/diacritics.
2695
+ * - Lowercases.
2696
+ * - Replaces non-alphanumeric runs with `-`.
2697
+ * - Trims leading/trailing separators.
2698
+ *
2699
+ * @example
2700
+ * slugify("São Paulo / Centro"); // "sao-paulo-centro"
2701
+ */
2702
+ export declare function slugify(input: string): string;
2703
+
2113
2704
  /**
2114
2705
  * Flex spacer — pushes siblings apart inside a flex container. Equivalent
2115
2706
  * to `<div style={{ flex: 1 }}>` but typed and intent-revealing.
@@ -2169,6 +2760,32 @@ export declare const STALE_TIME: {
2169
2760
  readonly INFINITE: number;
2170
2761
  };
2171
2762
 
2763
+ /**
2764
+ * KPI card. Dashboard widget showing a label + big value + optional
2765
+ * delta/trend and hint.
2766
+ *
2767
+ * @example
2768
+ * <Stat label="Receita" value="R$ 12.345" delta="+12,4%" trend="up" hint="vs. mês anterior" />
2769
+ */
2770
+ export declare function Stat({ label, value, delta, trend, hint, icon, className, ...props }: StatProps): JSX.Element;
2771
+
2772
+ export declare interface StatProps extends HTMLAttributes<HTMLDivElement> {
2773
+ /** Metric label (e.g. "Revenue", "Active users"). */
2774
+ label: ReactNode;
2775
+ /** Metric value (e.g. "R$ 12.345", "1.2k"). */
2776
+ value: ReactNode;
2777
+ /** Optional comparison delta — when set, renders alongside the value. */
2778
+ delta?: ReactNode;
2779
+ /** Trend direction for the delta. Default inferred from delta string. */
2780
+ trend?: StatTrend;
2781
+ /** Optional supporting context line below the value. */
2782
+ hint?: ReactNode;
2783
+ /** Optional leading icon. */
2784
+ icon?: ReactNode;
2785
+ }
2786
+
2787
+ export declare type StatTrend = "up" | "down" | "flat";
2788
+
2172
2789
  export declare interface StepItem {
2173
2790
  label: ReactNode;
2174
2791
  }
@@ -2180,6 +2797,42 @@ export declare interface StepItem {
2180
2797
  */
2181
2798
  export declare function Stepper({ steps, current, orientation, className }: StepperProps): JSX.Element;
2182
2799
 
2800
+ /**
2801
+ * Numeric +/− stepper. Common in checkout quantity selectors and admin
2802
+ * forms. Clamps to `[min, max]` and emits already-bounded values.
2803
+ *
2804
+ * @example
2805
+ * <StepperInput value={qty} onChange={setQty} min={1} max={10} />
2806
+ */
2807
+ export declare const StepperInput: ForwardRefExoticComponent<StepperInputProps & RefAttributes<HTMLDivElement>>;
2808
+
2809
+ export declare interface StepperInputProps {
2810
+ /** Current value. */
2811
+ value: number;
2812
+ /** Fires with the new value (already clamped to min/max). */
2813
+ onChange: (value: number) => void;
2814
+ /** Lower bound. Default `0`. */
2815
+ min?: number;
2816
+ /** Upper bound. Default `Number.POSITIVE_INFINITY`. */
2817
+ max?: number;
2818
+ /** Increment per click. Default `1`. */
2819
+ step?: number;
2820
+ /** Visual size. Default `"md"`. */
2821
+ size?: "sm" | "md" | "lg";
2822
+ /** Disable the whole control. */
2823
+ disabled?: boolean;
2824
+ /** Optional label rendered above. */
2825
+ label?: ReactNode;
2826
+ /** Optional formatter for the displayed value. */
2827
+ format?: (value: number) => string;
2828
+ /** Custom button labels for accessibility. */
2829
+ labels?: {
2830
+ decrement: string;
2831
+ increment: string;
2832
+ };
2833
+ className?: string;
2834
+ }
2835
+
2183
2836
  export declare interface StepperProps {
2184
2837
  steps: StepItem[];
2185
2838
  /** Index of the currently active step (0-based). */
@@ -2201,6 +2854,8 @@ export declare const storage: {
2201
2854
  remove(key: string): void;
2202
2855
  };
2203
2856
 
2857
+ export { SubmitHandler }
2858
+
2204
2859
  /** Toggle switch backed by a checkbox input. Accessible via keyboard. */
2205
2860
  export declare const Switch: ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLInputElement>>;
2206
2861
 
@@ -2275,6 +2930,33 @@ export declare interface TabsProps {
2275
2930
  className?: string;
2276
2931
  }
2277
2932
 
2933
+ /**
2934
+ * Removable chip — used for filter tokens, applied search filters,
2935
+ * selected entities. Different from `Badge` (status-only, not removable).
2936
+ *
2937
+ * @example
2938
+ * <Tag variant="primary" onRemove={() => removeFilter("sao-paulo")}>
2939
+ * São Paulo
2940
+ * </Tag>
2941
+ */
2942
+ export declare function Tag({ variant, size, onRemove, removeLabel, className, children, ...props }: TagProps): JSX.Element;
2943
+
2944
+ export declare interface TagProps extends Omit<HTMLAttributes<HTMLSpanElement>, "onRemove"> {
2945
+ /** Visual variant. Default `"neutral"`. */
2946
+ variant?: TagVariant;
2947
+ /** Visual size. Default `"md"`. */
2948
+ size?: TagSize;
2949
+ /** When set, renders a close button that fires this callback. */
2950
+ onRemove?: () => void;
2951
+ /** Custom remove label for screen readers. Default `"Remover"`. */
2952
+ removeLabel?: string;
2953
+ children?: ReactNode;
2954
+ }
2955
+
2956
+ export declare type TagSize = "sm" | "md" | "lg";
2957
+
2958
+ export declare type TagVariant = "neutral" | "primary" | "success" | "warning" | "danger" | "info";
2959
+
2278
2960
  export declare interface TelemetryAdapter {
2279
2961
  /** Optional. Called when the provider mounts. */
2280
2962
  init?: () => void | Promise<void>;
@@ -2372,6 +3054,43 @@ export declare interface ThemeProviderProps {
2372
3054
  attribute?: string;
2373
3055
  }
2374
3056
 
3057
+ /**
3058
+ * Vertical event timeline — activity feeds, order trackers, audit logs.
3059
+ * Each entry has a marker (color or custom icon), title, optional
3060
+ * description and right-aligned meta column.
3061
+ *
3062
+ * @example
3063
+ * <Timeline items={[
3064
+ * { id: "1", title: "Pedido criado", meta: "10:24", marker: "primary" },
3065
+ * { id: "2", title: "Aprovação", meta: "10:25", marker: "success" },
3066
+ * { id: "3", title: "Saiu pra entrega", meta: "11:00", marker: "warning" },
3067
+ * ]} />
3068
+ */
3069
+ export declare function Timeline({ items, connector, className, ...props }: TimelineProps): JSX.Element;
3070
+
3071
+ export declare interface TimelineItem {
3072
+ /** Stable identifier (used as React key). */
3073
+ id: string;
3074
+ /** Title rendered as the entry headline. */
3075
+ title: ReactNode;
3076
+ /** Optional subtitle / description below the title. */
3077
+ description?: ReactNode;
3078
+ /** Right-aligned meta column (timestamps, durations). */
3079
+ meta?: ReactNode;
3080
+ /** Optional custom icon rendered inside the marker. */
3081
+ icon?: ReactNode;
3082
+ /** Marker color. Default `"primary"`. */
3083
+ marker?: TimelineMarker;
3084
+ }
3085
+
3086
+ export declare type TimelineMarker = "primary" | "success" | "warning" | "danger" | "neutral";
3087
+
3088
+ export declare interface TimelineProps extends HTMLAttributes<HTMLOListElement> {
3089
+ items: TimelineItem[];
3090
+ /** Show the connecting line between markers. Default `true`. */
3091
+ connector?: boolean;
3092
+ }
3093
+
2375
3094
  export declare interface ToastApi {
2376
3095
  show: (options: ToastOptions) => string;
2377
3096
  dismiss: (id: string) => void;
@@ -2436,6 +3155,16 @@ export declare interface TooltipProps {
2436
3155
  openDelay?: number;
2437
3156
  }
2438
3157
 
3158
+ /**
3159
+ * Truncate a string to `max` characters, appending `suffix` when cut.
3160
+ * Returns the original when shorter than (or equal to) `max`.
3161
+ *
3162
+ * @example
3163
+ * truncate("The quick brown fox", 12); // "The quick…"
3164
+ * truncate("The quick brown fox", 12, " (more)"); // "The qu (more)"
3165
+ */
3166
+ export declare function truncate(input: string, max: number, suffix?: string): string;
3167
+
2439
3168
  /** Strip any masking and return only digits. */
2440
3169
  export declare function unmask(value: string): string;
2441
3170
 
@@ -2681,6 +3410,10 @@ export declare interface UseEventStreamResult<T> {
2681
3410
  */
2682
3411
  export declare function useFeatureFlag(key: string, defaultValue?: boolean): boolean;
2683
3412
 
3413
+ export { useFieldArray }
3414
+
3415
+ export { UseFieldArrayReturn }
3416
+
2684
3417
  /**
2685
3418
  * Read a typed flag value (string / number / boolean / null) and re-render
2686
3419
  * on change.
@@ -2694,6 +3427,18 @@ export declare function useFlagValue<T extends FlagValue = FlagValue>(key: strin
2694
3427
  */
2695
3428
  export declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, active: boolean): void;
2696
3429
 
3430
+ export { useForm }
3431
+
3432
+ export { useFormContext }
3433
+
3434
+ export { UseFormProps }
3435
+
3436
+ export { UseFormRegister }
3437
+
3438
+ export { UseFormReturn }
3439
+
3440
+ export { useFormState }
3441
+
2697
3442
  /** React hook around the Geolocation API. */
2698
3443
  export declare function useGeolocation(options?: UseGeolocationOptions): GeolocationState;
2699
3444
 
@@ -2704,6 +3449,17 @@ export declare interface UseGeolocationOptions extends PositionOptions {
2704
3449
  disabled?: boolean;
2705
3450
  }
2706
3451
 
3452
+ /**
3453
+ * Track whether the pointer is hovering over the referenced element.
3454
+ * Returns `false` on touch-only devices (no pointer hover).
3455
+ *
3456
+ * @example
3457
+ * const ref = useRef<HTMLDivElement>(null);
3458
+ * const hovered = useHover(ref);
3459
+ * return <div ref={ref}>{hovered ? "✨" : ""}</div>;
3460
+ */
3461
+ export declare function useHover<T extends HTMLElement>(ref: RefObject<T | null>): boolean;
3462
+
2707
3463
  /**
2708
3464
  * Access translation helpers. Must be used inside an {@link I18nProvider}.
2709
3465
  */
@@ -2728,6 +3484,15 @@ export declare interface UseIntersectionObserverOptions extends IntersectionObse
2728
3484
  once?: boolean;
2729
3485
  }
2730
3486
 
3487
+ /**
3488
+ * Reactive `setInterval`. Pass `null` as `delay` to pause. `fn` is stored in
3489
+ * a ref so inline callbacks don't reset the interval on every render.
3490
+ *
3491
+ * @example
3492
+ * useInterval(() => poll(), enabled ? 5000 : null);
3493
+ */
3494
+ export declare function useInterval(fn: () => void, delay: number | null): void;
3495
+
2731
3496
  /**
2732
3497
  * Bind a global keyboard shortcut. Supports modifier combinations and a
2733
3498
  * cross-OS `mod` key (Ctrl on Windows/Linux, Cmd on macOS).
@@ -2758,6 +3523,24 @@ export declare interface UseKeyboardShortcutOptions {
2758
3523
  */
2759
3524
  export declare function useLocalStorage<T>(key: string, defaultValue: T, options?: LocalStorageOptions<T>): [T, (value: T | ((prev: T) => T)) => void, () => void];
2760
3525
 
3526
+ /**
3527
+ * Detect long-press / long-tap gestures. Fires `fn` after `delay` ms
3528
+ * while the element is held. Cancels on move beyond `moveThreshold` or
3529
+ * pointer up before `delay`.
3530
+ *
3531
+ * @example
3532
+ * const ref = useRef<HTMLDivElement>(null);
3533
+ * useLongPress(ref, () => openContextMenu(), { delay: 600 });
3534
+ */
3535
+ export declare function useLongPress<T extends HTMLElement>(ref: RefObject<T | null>, fn: () => void, options?: UseLongPressOptions): void;
3536
+
3537
+ export declare interface UseLongPressOptions {
3538
+ /** Press duration in ms. Default `500`. */
3539
+ delay?: number;
3540
+ /** Pixel threshold — finger/mouse movement beyond this cancels the press. Default `10`. */
3541
+ moveThreshold?: number;
3542
+ }
3543
+
2761
3544
  /**
2762
3545
  * Subscribe to a CSS media query and re-render on match changes.
2763
3546
  *
@@ -2766,6 +3549,55 @@ export declare function useLocalStorage<T>(key: string, defaultValue: T, options
2766
3549
  */
2767
3550
  export declare function useMediaQuery(query: string): boolean;
2768
3551
 
3552
+ /**
3553
+ * Run an OAuth-callback "exchange" exactly once on mount. Designed for
3554
+ * `/callback` routes that receive provider redirects and need to swap a
3555
+ * code/token for an app session via the backend.
3556
+ *
3557
+ * Survives React StrictMode double-mounting in dev — uses a ref guard to
3558
+ * ensure `exchange` runs once.
3559
+ *
3560
+ * @example
3561
+ * function OAuthCallback() {
3562
+ * const { loading, error } = useOAuthCallback({
3563
+ * exchange: async () => {
3564
+ * const code = new URLSearchParams(location.search).get("code")!;
3565
+ * return api.post("/auth/google/exchange", { body: { code } });
3566
+ * },
3567
+ * onSuccess: ({ token, user }) => {
3568
+ * useAuthStore.getState().setSession({ user, token });
3569
+ * navigate("/dashboard", { replace: true });
3570
+ * },
3571
+ * onError: () => navigate("/login?error=oauth", { replace: true }),
3572
+ * });
3573
+ *
3574
+ * if (loading) return <Spinner />;
3575
+ * if (error) return <ErrorState description="OAuth falhou" />;
3576
+ * return null;
3577
+ * }
3578
+ */
3579
+ export declare function useOAuthCallback<T>(options: UseOAuthCallbackOptions<T>): UseOAuthCallbackResult<T>;
3580
+
3581
+ export declare interface UseOAuthCallbackOptions<T> {
3582
+ /** Function that exchanges the provider response for an app session. Called once on mount. */
3583
+ exchange: () => Promise<T>;
3584
+ /** Fired with the result on success. Receives the value resolved by `exchange`. */
3585
+ onSuccess?: (result: T) => void | Promise<void>;
3586
+ /** Fired when `exchange` throws or rejects. */
3587
+ onError?: (error: unknown) => void;
3588
+ }
3589
+
3590
+ export declare interface UseOAuthCallbackResult<T> {
3591
+ /** `true` while the exchange promise is pending. */
3592
+ loading: boolean;
3593
+ /** Last resolved value, when `status === "success"`. */
3594
+ data: T | null;
3595
+ /** Last rejection reason, when `status === "error"`. */
3596
+ error: unknown;
3597
+ /** Aggregated state — `"pending"`, `"success"`, or `"error"`. */
3598
+ status: "pending" | "success" | "error";
3599
+ }
3600
+
2769
3601
  /**
2770
3602
  * Track the browser's `navigator.onLine` value and re-render on changes.
2771
3603
  * Returns `true` during SSR (assumption: server is online).
@@ -2815,6 +3647,19 @@ export declare interface UsePollResult<T> {
2815
3647
  start: () => void;
2816
3648
  }
2817
3649
 
3650
+ /**
3651
+ * Return the value from the previous render. `undefined` on the first render.
3652
+ *
3653
+ * @example
3654
+ * const previousCount = usePrevious(count);
3655
+ * useEffect(() => {
3656
+ * if (previousCount !== undefined && previousCount !== count) {
3657
+ * analytics.track("count.changed", { from: previousCount, to: count });
3658
+ * }
3659
+ * }, [count, previousCount]);
3660
+ */
3661
+ export declare function usePrevious<T>(value: T): T | undefined;
3662
+
2818
3663
  /**
2819
3664
  * React hook around {@link WebPushClient}. Tracks subscription, permission and
2820
3665
  * loading state; exposes imperative `subscribe`/`unsubscribe` actions.
@@ -2878,6 +3723,25 @@ export declare function useTelemetry(): TelemetryAdapter | null;
2878
3723
  */
2879
3724
  export declare function useTheme(): ThemeContextValue;
2880
3725
 
3726
+ /**
3727
+ * Return a value that updates at most once every `delay` ms. Complements
3728
+ * `useDebounce` — throttle emits on the leading edge and again after the
3729
+ * interval; debounce only emits after a period of stillness.
3730
+ *
3731
+ * @example
3732
+ * const throttledScroll = useThrottle(scrollY, 100);
3733
+ */
3734
+ export declare function useThrottle<T>(value: T, delay: number): T;
3735
+
3736
+ /**
3737
+ * Run a callback after `delay` ms. Pass `null` to disable. Resets when
3738
+ * `delay` changes; the callback ref always points at the latest closure.
3739
+ *
3740
+ * @example
3741
+ * useTimeout(() => setShow(false), show ? 3000 : null);
3742
+ */
3743
+ export declare function useTimeout(fn: () => void, delay: number | null): void;
3744
+
2881
3745
  /**
2882
3746
  * Access the toast API. Must be used inside a {@link ToastProvider}.
2883
3747
  *
@@ -2914,6 +3778,8 @@ export declare interface UseViaCEPResult {
2914
3778
  reset: () => void;
2915
3779
  }
2916
3780
 
3781
+ export { useWatch }
3782
+
2917
3783
  /**
2918
3784
  * React hook around {@link createWebSocket}. Manages the connection lifecycle
2919
3785
  * for the host component and tears it down on unmount.
@@ -2935,6 +3801,16 @@ export declare interface UseWebSocketResult<T> {
2935
3801
  reconnect: () => void;
2936
3802
  }
2937
3803
 
3804
+ /**
3805
+ * Reactive window dimensions. SSR-safe — returns `{ width: 0, height: 0 }`
3806
+ * until the first client render.
3807
+ *
3808
+ * @example
3809
+ * const { width, height } = useWindowSize();
3810
+ * const columns = width < 640 ? 1 : width < 1024 ? 2 : 3;
3811
+ */
3812
+ export declare function useWindowSize(): WindowSize;
3813
+
2938
3814
  /**
2939
3815
  * Convenience wrapper around `react-hook-form`'s `useForm` that wires a zod
2940
3816
  * resolver and infers the form's value type from the schema.
@@ -3114,6 +3990,11 @@ export declare interface WebSocketMessage<T> {
3114
3990
 
3115
3991
  export declare type WebSocketStatus = "idle" | "connecting" | "open" | "closing" | "closed" | "error";
3116
3992
 
3993
+ export declare interface WindowSize {
3994
+ width: number;
3995
+ height: number;
3996
+ }
3997
+
3117
3998
  /**
3118
3999
  * Minimal `react-hook-form` resolver built on top of zod. Mirrors the shape
3119
4000
  * produced by `@hookform/resolvers/zod` so it can be passed straight to