tempest-react-sdk 0.3.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,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;
@@ -484,6 +634,10 @@ export declare interface ContainerProps extends HTMLAttributes<HTMLDivElement> {
484
634
 
485
635
  export declare type ContainerSize = "sm" | "md" | "lg" | "xl" | "full";
486
636
 
637
+ export { Control }
638
+
639
+ export { Controller }
640
+
487
641
  export declare const CPFInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
488
642
  value: string;
489
643
  onChange: (value: string) => void;
@@ -1089,6 +1243,16 @@ export declare interface FeatureFlagsProviderProps {
1089
1243
  children: ReactNode;
1090
1244
  }
1091
1245
 
1246
+ export { FieldArrayWithId }
1247
+
1248
+ export { FieldError }
1249
+
1250
+ export { FieldErrors }
1251
+
1252
+ export { FieldPath }
1253
+
1254
+ export { FieldValues }
1255
+
1092
1256
  /**
1093
1257
  * Drag-and-drop file dropzone. Pair with `uploadWithProgress` from the SDK
1094
1258
  * to wire actual uploads with byte-level progress.
@@ -1214,11 +1378,70 @@ export declare function formatPercent(value: number): string;
1214
1378
  */
1215
1379
  export declare function formatPhone(value: string): string;
1216
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
+
1217
1438
  export declare type FormLayout = "stack" | "inline" | "grid";
1218
1439
 
1219
1440
  export declare interface FormProps extends FormHTMLAttributes<HTMLFormElement>, LayoutProps {
1220
1441
  }
1221
1442
 
1443
+ export { FormProvider }
1444
+
1222
1445
  /**
1223
1446
  * Forces a horizontal row regardless of parent layout — useful for grouping
1224
1447
  * two short fields side-by-side inside an otherwise stacked form (e.g. CEP +
@@ -1286,6 +1509,71 @@ export declare interface GetInitialThemeOptions {
1286
1509
  defaultTheme?: ThemeMode;
1287
1510
  }
1288
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
+
1289
1577
  /** Simple CSS-Grid wrapper for equal-width or custom column layouts. */
1290
1578
  export declare function Grid({ columns, gap, className, style, children, ...props }: GridProps): JSX.Element;
1291
1579
 
@@ -1602,6 +1890,56 @@ export declare interface MoneyInputProps extends Omit<InputProps, "value" | "onC
1602
1890
  locale?: string;
1603
1891
  }
1604
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
+
1605
1943
  export declare interface OfflineStore<TItem, TKey extends string | number> {
1606
1944
  /** Insert or replace a record. */
1607
1945
  put: (item: TItem, owner?: string) => Promise<TKey>;
@@ -1650,6 +1988,35 @@ export declare interface OfflineStoreConfig<TItem> {
1650
1988
  ownerField?: keyof TItem & string;
1651
1989
  }
1652
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
+
1653
2020
  /**
1654
2021
  * Numeric pagination controls. Pair with {@link usePagination} for state.
1655
2022
  */
@@ -1682,6 +2049,8 @@ export declare interface PaginationProps {
1682
2049
  */
1683
2050
  export declare function parseResponse<TSchema extends z.ZodTypeAny>(schema: TSchema, raw: unknown, context: string): z.infer<TSchema>;
1684
2051
 
2052
+ export { Path }
2053
+
1685
2054
  export declare const PhoneInput: ForwardRefExoticComponent<Omit<InputProps, "value" | "onChange"> & {
1686
2055
  value: string;
1687
2056
  onChange: (value: string) => void;
@@ -1991,6 +2360,28 @@ export declare interface RetryOptions {
1991
2360
  signal?: AbortSignal;
1992
2361
  }
1993
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
+
1994
2385
  /**
1995
2386
  * Search input with magnifier icon and a clear button. Controlled component:
1996
2387
  * pass `value` and `onChange`.
@@ -2093,6 +2484,51 @@ export declare interface ShowProps {
2093
2484
  children: ReactNode;
2094
2485
  }
2095
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
+
2096
2532
  /** Loading placeholder block. Use `variant="text"` for inline lines, `circle` for avatars. */
2097
2533
  export declare function Skeleton({ variant, width, height, className, style }: SkeletonProps): JSX.Element;
2098
2534
 
@@ -2169,6 +2605,32 @@ export declare const STALE_TIME: {
2169
2605
  readonly INFINITE: number;
2170
2606
  };
2171
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
+
2172
2634
  export declare interface StepItem {
2173
2635
  label: ReactNode;
2174
2636
  }
@@ -2201,6 +2663,8 @@ export declare const storage: {
2201
2663
  remove(key: string): void;
2202
2664
  };
2203
2665
 
2666
+ export { SubmitHandler }
2667
+
2204
2668
  /** Toggle switch backed by a checkbox input. Accessible via keyboard. */
2205
2669
  export declare const Switch: ForwardRefExoticComponent<SwitchProps & RefAttributes<HTMLInputElement>>;
2206
2670
 
@@ -2275,6 +2739,33 @@ export declare interface TabsProps {
2275
2739
  className?: string;
2276
2740
  }
2277
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
+
2278
2769
  export declare interface TelemetryAdapter {
2279
2770
  /** Optional. Called when the provider mounts. */
2280
2771
  init?: () => void | Promise<void>;
@@ -2681,6 +3172,10 @@ export declare interface UseEventStreamResult<T> {
2681
3172
  */
2682
3173
  export declare function useFeatureFlag(key: string, defaultValue?: boolean): boolean;
2683
3174
 
3175
+ export { useFieldArray }
3176
+
3177
+ export { UseFieldArrayReturn }
3178
+
2684
3179
  /**
2685
3180
  * Read a typed flag value (string / number / boolean / null) and re-render
2686
3181
  * on change.
@@ -2694,6 +3189,18 @@ export declare function useFlagValue<T extends FlagValue = FlagValue>(key: strin
2694
3189
  */
2695
3190
  export declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, active: boolean): void;
2696
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
+
2697
3204
  /** React hook around the Geolocation API. */
2698
3205
  export declare function useGeolocation(options?: UseGeolocationOptions): GeolocationState;
2699
3206
 
@@ -2766,6 +3273,55 @@ export declare function useLocalStorage<T>(key: string, defaultValue: T, options
2766
3273
  */
2767
3274
  export declare function useMediaQuery(query: string): boolean;
2768
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
+
2769
3325
  /**
2770
3326
  * Track the browser's `navigator.onLine` value and re-render on changes.
2771
3327
  * Returns `true` during SSR (assumption: server is online).
@@ -2914,6 +3470,8 @@ export declare interface UseViaCEPResult {
2914
3470
  reset: () => void;
2915
3471
  }
2916
3472
 
3473
+ export { useWatch }
3474
+
2917
3475
  /**
2918
3476
  * React hook around {@link createWebSocket}. Manages the connection lifecycle
2919
3477
  * for the host component and tears it down on unmount.