tempest-react-sdk 0.43.0 → 0.45.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -5
- package/dist/app/AppProviders.cjs +1 -1
- package/dist/app/AppProviders.js +6 -6
- package/dist/audio/sfx-pool.cjs +2 -0
- package/dist/audio/sfx-pool.cjs.map +1 -0
- package/dist/audio/sfx-pool.js +62 -0
- package/dist/audio/sfx-pool.js.map +1 -0
- package/dist/audio/use-sfx-pool.cjs +2 -0
- package/dist/audio/use-sfx-pool.cjs.map +1 -0
- package/dist/audio/use-sfx-pool.js +18 -0
- package/dist/audio/use-sfx-pool.js.map +1 -0
- package/dist/auth/create-tempest-auth.cjs +1 -1
- package/dist/auth/create-tempest-auth.cjs.map +1 -1
- package/dist/auth/create-tempest-auth.js +47 -44
- package/dist/auth/create-tempest-auth.js.map +1 -1
- package/dist/auth/lazy-with-retry.cjs +1 -1
- package/dist/auth/lazy-with-retry.cjs.map +1 -1
- package/dist/auth/lazy-with-retry.js +8 -1
- package/dist/auth/lazy-with-retry.js.map +1 -1
- package/dist/components/AppBar/AppBar.cjs +1 -1
- package/dist/components/AppBar/AppBar.cjs.map +1 -1
- package/dist/components/AppBar/AppBar.js +27 -25
- package/dist/components/AppBar/AppBar.js.map +1 -1
- package/dist/components/AppBar/use-sticky-body-warning.cjs +2 -0
- package/dist/components/AppBar/use-sticky-body-warning.cjs.map +1 -0
- package/dist/components/AppBar/use-sticky-body-warning.js +16 -0
- package/dist/components/AppBar/use-sticky-body-warning.js.map +1 -0
- package/dist/components/BarList/BarList.cjs +2 -0
- package/dist/components/BarList/BarList.cjs.map +1 -0
- package/dist/components/BarList/BarList.js +42 -0
- package/dist/components/BarList/BarList.js.map +1 -0
- package/dist/components/BarList/BarList.module.cjs +2 -0
- package/dist/components/BarList/BarList.module.cjs.map +1 -0
- package/dist/components/BarList/BarList.module.js +15 -0
- package/dist/components/BarList/BarList.module.js.map +1 -0
- package/dist/components/BarList/bar-list-model.cjs +2 -0
- package/dist/components/BarList/bar-list-model.cjs.map +1 -0
- package/dist/components/BarList/bar-list-model.js +18 -0
- package/dist/components/BarList/bar-list-model.js.map +1 -0
- package/dist/components/DataTable/DataTable.cjs +1 -1
- package/dist/components/DataTable/DataTable.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.js +141 -108
- package/dist/components/DataTable/DataTable.js.map +1 -1
- package/dist/components/DataTable/DataTable.module.cjs +1 -1
- package/dist/components/DataTable/DataTable.module.cjs.map +1 -1
- package/dist/components/DataTable/DataTable.module.js +13 -10
- package/dist/components/DataTable/DataTable.module.js.map +1 -1
- package/dist/components/DataTable/LoadingRows.cjs +2 -0
- package/dist/components/DataTable/LoadingRows.cjs.map +1 -0
- package/dist/components/DataTable/LoadingRows.js +18 -0
- package/dist/components/DataTable/LoadingRows.js.map +1 -0
- package/dist/components/DataTable/use-dev-warnings.cjs +2 -0
- package/dist/components/DataTable/use-dev-warnings.cjs.map +1 -0
- package/dist/components/DataTable/use-dev-warnings.js +17 -0
- package/dist/components/DataTable/use-dev-warnings.js.map +1 -0
- package/dist/components/FilterBar/filter-apply.cjs +2 -0
- package/dist/components/FilterBar/filter-apply.cjs.map +1 -0
- package/dist/components/FilterBar/filter-apply.js +76 -0
- package/dist/components/FilterBar/filter-apply.js.map +1 -0
- package/dist/components/FilterBar/filter-query.cjs +2 -0
- package/dist/components/FilterBar/filter-query.cjs.map +1 -0
- package/dist/components/FilterBar/filter-query.js +38 -0
- package/dist/components/FilterBar/filter-query.js.map +1 -0
- package/dist/hooks/use-countdown.cjs +2 -0
- package/dist/hooks/use-countdown.cjs.map +1 -0
- package/dist/hooks/use-countdown.js +18 -0
- package/dist/hooks/use-countdown.js.map +1 -0
- package/dist/hooks/use-latest-ref.cjs +2 -0
- package/dist/hooks/use-latest-ref.cjs.map +1 -0
- package/dist/hooks/use-latest-ref.js +10 -0
- package/dist/hooks/use-latest-ref.js.map +1 -0
- package/dist/hooks/use-typewriter.cjs +2 -0
- package/dist/hooks/use-typewriter.cjs.map +1 -0
- package/dist/hooks/use-typewriter.js +28 -0
- package/dist/hooks/use-typewriter.js.map +1 -0
- package/dist/http/api-client.cjs +1 -1
- package/dist/http/api-client.cjs.map +1 -1
- package/dist/http/api-client.js +42 -43
- package/dist/http/api-client.js.map +1 -1
- package/dist/http/build-url.cjs +2 -0
- package/dist/http/build-url.cjs.map +1 -0
- package/dist/http/build-url.js +26 -0
- package/dist/http/build-url.js.map +1 -0
- package/dist/http/describe-api-error.cjs +2 -0
- package/dist/http/describe-api-error.cjs.map +1 -0
- package/dist/http/describe-api-error.js +22 -0
- package/dist/http/describe-api-error.js.map +1 -0
- package/dist/http/use-describe-api-error.cjs +2 -0
- package/dist/http/use-describe-api-error.cjs.map +1 -0
- package/dist/http/use-describe-api-error.js +15 -0
- package/dist/http/use-describe-api-error.js.map +1 -0
- package/dist/i18n/I18nProvider.cjs +1 -1
- package/dist/i18n/I18nProvider.cjs.map +1 -1
- package/dist/i18n/I18nProvider.js +4 -1
- package/dist/i18n/I18nProvider.js.map +1 -1
- package/dist/query/QueryProvider.cjs +1 -1
- package/dist/query/QueryProvider.cjs.map +1 -1
- package/dist/query/QueryProvider.js +13 -12
- package/dist/query/QueryProvider.js.map +1 -1
- package/dist/query/retry-policy.cjs +2 -0
- package/dist/query/retry-policy.cjs.map +1 -0
- package/dist/query/retry-policy.js +10 -0
- package/dist/query/retry-policy.js.map +1 -0
- package/dist/styles.css +1 -1
- package/dist/tempest-react-sdk.cjs +1 -1
- package/dist/tempest-react-sdk.d.ts +867 -10
- package/dist/tempest-react-sdk.js +276 -261
- package/dist/utils/compressed-storage.cjs +2 -0
- package/dist/utils/compressed-storage.cjs.map +1 -0
- package/dist/utils/compressed-storage.js +52 -0
- package/dist/utils/compressed-storage.js.map +1 -0
- package/dist/utils/csv.cjs +4 -0
- package/dist/utils/csv.cjs.map +1 -0
- package/dist/utils/csv.js +25 -0
- package/dist/utils/csv.js.map +1 -0
- package/dist/utils/format.cjs +1 -1
- package/dist/utils/format.cjs.map +1 -1
- package/dist/utils/format.js +11 -4
- package/dist/utils/format.js.map +1 -1
- package/dist/utils/numbers.cjs +1 -1
- package/dist/utils/numbers.cjs.map +1 -1
- package/dist/utils/numbers.js +5 -2
- package/dist/utils/numbers.js.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs +1 -1
- package/dist/vite/tempest-pwa-dev-sw.cjs.map +1 -1
- package/dist/vite/tempest-pwa-dev-sw.js +10 -5
- package/dist/vite/tempest-pwa-dev-sw.js.map +1 -1
- package/dist/vite/tempest-pwa-manifest.cjs +2 -2
- package/dist/vite/tempest-pwa-manifest.cjs.map +1 -1
- package/dist/vite/tempest-pwa-manifest.js +17 -13
- package/dist/vite/tempest-pwa-manifest.js.map +1 -1
- package/dist/vite.d.ts +19 -2
- package/package.json +1 -1
|
@@ -543,6 +543,16 @@ declare type AnyEventTarget = EventTarget | {
|
|
|
543
543
|
current: EventTarget | null;
|
|
544
544
|
} | null | undefined;
|
|
545
545
|
|
|
546
|
+
/**
|
|
547
|
+
* Translation key the {@link useDescribeApiError} hook looks up.
|
|
548
|
+
*
|
|
549
|
+
* A catalog that does not define it falls back to
|
|
550
|
+
* {@link DEFAULT_API_ERROR_STRINGS}, because `t` returns the key itself when the
|
|
551
|
+
* lookup misses and printing `tempest.error.offline` at the user would be worse
|
|
552
|
+
* than printing pt-BR at them.
|
|
553
|
+
*/
|
|
554
|
+
export declare const API_ERROR_OFFLINE_KEY = "tempest.error.offline";
|
|
555
|
+
|
|
546
556
|
export declare interface ApiClient {
|
|
547
557
|
request<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
548
558
|
get<T>(path: string, options?: RequestOptions): Promise<T>;
|
|
@@ -554,8 +564,28 @@ export declare interface ApiClient {
|
|
|
554
564
|
}
|
|
555
565
|
|
|
556
566
|
export declare interface ApiClientConfig {
|
|
557
|
-
/**
|
|
567
|
+
/**
|
|
568
|
+
* Base URL for every request. Required.
|
|
569
|
+
*
|
|
570
|
+
* May carry a path (`https://api.example.com/api`) — it is kept, and a
|
|
571
|
+
* request for `"/auth/login"` lands on `/api/auth/login`. May also be
|
|
572
|
+
* relative (`"/api"`), which resolves against the current origin and is the
|
|
573
|
+
* shape to use behind a dev-server or reverse proxy.
|
|
574
|
+
*/
|
|
558
575
|
baseURL: string;
|
|
576
|
+
/**
|
|
577
|
+
* Path segment every request is nested under, such as `"/api"` — the
|
|
578
|
+
* `root_path` a Tempest FastAPI service is usually mounted on.
|
|
579
|
+
*
|
|
580
|
+
* The alternative to writing it into `baseURL`, and the better one when the
|
|
581
|
+
* base comes from an environment variable that other things also use (an
|
|
582
|
+
* SSE endpoint, a media host): the variable stays the bare origin and only
|
|
583
|
+
* the client carries the prefix.
|
|
584
|
+
*
|
|
585
|
+
* Applied at most once — a path that already opens with the prefix is left
|
|
586
|
+
* alone, so call sites can migrate one at a time.
|
|
587
|
+
*/
|
|
588
|
+
prefix?: string;
|
|
559
589
|
/** Returns the current bearer token (or null/undefined). Called per request. */
|
|
560
590
|
getToken?: () => string | null | undefined;
|
|
561
591
|
/**
|
|
@@ -627,6 +657,12 @@ export declare interface ApiError {
|
|
|
627
657
|
body?: unknown;
|
|
628
658
|
}
|
|
629
659
|
|
|
660
|
+
/** The two fixed sentences {@link describeApiError} may need. */
|
|
661
|
+
export declare interface ApiErrorStrings {
|
|
662
|
+
/** Shown when the request never reached the server. */
|
|
663
|
+
offline: string;
|
|
664
|
+
}
|
|
665
|
+
|
|
630
666
|
/**
|
|
631
667
|
* Mobile-first top app bar for PWAs — leading (back / brand) + title +
|
|
632
668
|
* trailing actions, sticky with safe-area padding out of the box.
|
|
@@ -675,7 +711,14 @@ export declare interface AppBarProps extends Omit<HTMLAttributes<HTMLElement>, "
|
|
|
675
711
|
actions?: ReactNode;
|
|
676
712
|
/** Center the title (three-column grid). Default `false` (left-aligned). */
|
|
677
713
|
centered?: boolean;
|
|
678
|
-
/**
|
|
714
|
+
/**
|
|
715
|
+
* Stick to the top of the scroll container. Default `true`.
|
|
716
|
+
*
|
|
717
|
+
* The page has to leave the body out of the scrolling: `body { overflow-x:
|
|
718
|
+
* hidden }` makes the body a scroll container and the bar scrolls away with
|
|
719
|
+
* the content. Use `overflow-x: clip` on `html` and `body` instead — in
|
|
720
|
+
* development the bar says so in the console when it detects it.
|
|
721
|
+
*/
|
|
679
722
|
sticky?: boolean;
|
|
680
723
|
/** Visual tone. Default `"surface"`. */
|
|
681
724
|
tone?: AppBarTone;
|
|
@@ -687,6 +730,37 @@ export declare interface AppBarProps extends Omit<HTMLAttributes<HTMLElement>, "
|
|
|
687
730
|
|
|
688
731
|
export declare type AppBarTone = "surface" | "primary" | "transparent";
|
|
689
732
|
|
|
733
|
+
/**
|
|
734
|
+
* Run a filter set over an in-memory list.
|
|
735
|
+
*
|
|
736
|
+
* Closes the loop `FilterBar` opens: the bar produces `Filter[]`, this applies
|
|
737
|
+
* them. Filters combine with `AND`, matching the flat model the bar builds, and
|
|
738
|
+
* an incomplete filter is skipped rather than treated as a match of nothing — a
|
|
739
|
+
* half-filled form should not empty the table underneath it.
|
|
740
|
+
*
|
|
741
|
+
* Comparison follows the row's type, not the filter's: numbers compare
|
|
742
|
+
* numerically, dates compare by day, and everything else compares as text with
|
|
743
|
+
* `numeric: true` so `"item 2"` lands before `"item 10"`.
|
|
744
|
+
*
|
|
745
|
+
* A few behaviours differ from the SQL the server-side twin produces, and the
|
|
746
|
+
* difference is deliberate rather than accidental:
|
|
747
|
+
*
|
|
748
|
+
* - `ne` matches rows whose value is absent. In SQL, `column <> 'x'` is `NULL`
|
|
749
|
+
* for a `NULL` column and the row drops out. Here "is not paid" shows the rows
|
|
750
|
+
* with no status at all, which is what the chip claims.
|
|
751
|
+
* - `empty` matches `NULL`, blank text and empty lists; `__isnull` on the server
|
|
752
|
+
* only matches `NULL`. A column that stores `""` instead of `NULL` is where
|
|
753
|
+
* the two disagree.
|
|
754
|
+
*
|
|
755
|
+
* @example
|
|
756
|
+
* const visible = applyFilters(orders, filters);
|
|
757
|
+
*
|
|
758
|
+
* @param items - The full list.
|
|
759
|
+
* @param filters - Applied filters; incomplete ones are ignored.
|
|
760
|
+
* @returns A new array with the rows that satisfy every complete filter.
|
|
761
|
+
*/
|
|
762
|
+
export declare function applyFilters<T>(items: readonly T[], filters: readonly Filter[]): T[];
|
|
763
|
+
|
|
690
764
|
/**
|
|
691
765
|
* Apply a {@link KanbanMove} to a column list, returning new arrays.
|
|
692
766
|
*
|
|
@@ -1359,6 +1433,84 @@ export declare interface BarcodeScanResult {
|
|
|
1359
1433
|
cornerPoints: readonly BarcodePoint[];
|
|
1360
1434
|
}
|
|
1361
1435
|
|
|
1436
|
+
/**
|
|
1437
|
+
* A ranked distribution: label, proportional bar, value, optional share.
|
|
1438
|
+
*
|
|
1439
|
+
* The most common chart on an admin panel, and the one the SDK kept sending
|
|
1440
|
+
* people to write by hand — `Progress` is a single bar and `Sparkline` is a time
|
|
1441
|
+
* series, so a "users per plan" block ended up reimplemented per screen, each
|
|
1442
|
+
* with its own CSS and its own `.sort()`.
|
|
1443
|
+
*
|
|
1444
|
+
* It is a **list**, not a picture: `<ul>` / `<li>` with the value written as
|
|
1445
|
+
* text, the bar `aria-hidden` behind it. A screen reader reads "Free, 128, 62%"
|
|
1446
|
+
* because that text is there, not because an `aria-label` restates a drawing.
|
|
1447
|
+
* Which is also why the label never sits on top of the bar — text over a tinted
|
|
1448
|
+
* fill has to be re-verified against that fill, and the SDK has been caught by
|
|
1449
|
+
* that twice.
|
|
1450
|
+
*
|
|
1451
|
+
* Bar width is relative to the **largest** row, so the biggest bar fills the
|
|
1452
|
+
* track; the percentage is the row's share of the **total**. They are different
|
|
1453
|
+
* numbers on purpose: a width scaled by the total leaves every bar short in a
|
|
1454
|
+
* long list, which is when the chart is needed most.
|
|
1455
|
+
*
|
|
1456
|
+
* @example
|
|
1457
|
+
* <BarList
|
|
1458
|
+
* items={[{ label: "Free", value: 128 }, { label: "Pro", value: 32 }]}
|
|
1459
|
+
* valueFormatter={(n) => `${n} ativos`}
|
|
1460
|
+
* showPercentage
|
|
1461
|
+
* max={5}
|
|
1462
|
+
* otherLabel="Outros"
|
|
1463
|
+
* />
|
|
1464
|
+
*
|
|
1465
|
+
* @param props - Items plus presentation.
|
|
1466
|
+
* @returns The list.
|
|
1467
|
+
*/
|
|
1468
|
+
export declare function BarList({ items, valueFormatter, showPercentage, sort, max, otherLabel, className, ...rest }: BarListProps): JSX.Element;
|
|
1469
|
+
|
|
1470
|
+
/** One entry of a {@link BarList}. */
|
|
1471
|
+
export declare interface BarListItem {
|
|
1472
|
+
/** What the row is called. */
|
|
1473
|
+
label: string;
|
|
1474
|
+
/** The measured amount. */
|
|
1475
|
+
value: number;
|
|
1476
|
+
/** Override the bar colour. Defaults to the chart series token for its position. */
|
|
1477
|
+
color?: string;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
export declare interface BarListProps extends Omit<HTMLAttributes<HTMLUListElement>, "children"> {
|
|
1481
|
+
/** The rows. Entries whose value is not finite are dropped. */
|
|
1482
|
+
items: readonly BarListItem[];
|
|
1483
|
+
/** Render the number. Defaults to the value as-is. */
|
|
1484
|
+
valueFormatter?: (value: number) => string;
|
|
1485
|
+
/** Show each row's share of the total next to its value. Default `false`. */
|
|
1486
|
+
showPercentage?: boolean;
|
|
1487
|
+
/** Ordering. Default `"desc"`, which is what a ranking means. */
|
|
1488
|
+
sort?: BarListSort;
|
|
1489
|
+
/** Keep at most this many rows. */
|
|
1490
|
+
max?: number;
|
|
1491
|
+
/**
|
|
1492
|
+
* Label for one aggregated row holding everything `max` cut off.
|
|
1493
|
+
*
|
|
1494
|
+
* Without it, `max` simply truncates. The aggregate row only appears when more
|
|
1495
|
+
* than one row was cut — collapsing a single row into "others" hides its name
|
|
1496
|
+
* for nothing.
|
|
1497
|
+
*/
|
|
1498
|
+
otherLabel?: string;
|
|
1499
|
+
}
|
|
1500
|
+
|
|
1501
|
+
/** One row, with everything the component needs to draw it. */
|
|
1502
|
+
export declare interface BarListRow extends BarListItem {
|
|
1503
|
+
/** Share of the total, 0–100. */
|
|
1504
|
+
percentage: number;
|
|
1505
|
+
/** Bar width relative to the largest row, 0–100. */
|
|
1506
|
+
width: number;
|
|
1507
|
+
/** Position in the original palette cycle. */
|
|
1508
|
+
index: number;
|
|
1509
|
+
}
|
|
1510
|
+
|
|
1511
|
+
/** How the list orders itself before drawing. */
|
|
1512
|
+
export declare type BarListSort = "desc" | "asc" | "none";
|
|
1513
|
+
|
|
1362
1514
|
/**
|
|
1363
1515
|
* Decode a base64url string into bytes.
|
|
1364
1516
|
*
|
|
@@ -1552,6 +1704,79 @@ export declare const BREAKPOINTS: Record<Breakpoint, number>;
|
|
|
1552
1704
|
|
|
1553
1705
|
export { BrowserRouter }
|
|
1554
1706
|
|
|
1707
|
+
/**
|
|
1708
|
+
* Join a base URL, an optional prefix and a request path into an absolute URL.
|
|
1709
|
+
*
|
|
1710
|
+
* `new URL(path, base)` on its own is wrong for an API client. It follows the
|
|
1711
|
+
* URL spec, where a path starting with `/` is absolute against the *origin* and
|
|
1712
|
+
* therefore discards whatever path the base carried: a client on
|
|
1713
|
+
* `https://api.example.com/api` asked for `/auth/login` reaches
|
|
1714
|
+
* `https://api.example.com/auth/login`, and every request 404s with nothing in
|
|
1715
|
+
* the config that looks wrong. This function resolves the path against the base
|
|
1716
|
+
* *path* instead, so the leading slash is a matter of taste rather than a
|
|
1717
|
+
* silent 404, and `baseURL` + `prefix` are interchangeable ways to say the same
|
|
1718
|
+
* thing.
|
|
1719
|
+
*
|
|
1720
|
+
* The prefix is applied at most once: a path that already opens with it — say
|
|
1721
|
+
* `"/api/auth/login"` under a `"/api"` prefix — is left alone, so a codebase
|
|
1722
|
+
* migrating to `prefix` can move its call sites one at a time. The check is per
|
|
1723
|
+
* segment, so `/api-keys` is not mistaken for an already-prefixed path.
|
|
1724
|
+
*
|
|
1725
|
+
* A path that is itself an absolute URL wins over all of this, which is how a
|
|
1726
|
+
* client reaches a second host (a signed upload endpoint, a CDN) without a
|
|
1727
|
+
* second client.
|
|
1728
|
+
*
|
|
1729
|
+
* @example
|
|
1730
|
+
* buildApiUrl("https://api.example.com", "/auth/login", { prefix: "/api" });
|
|
1731
|
+
* // "https://api.example.com/api/auth/login"
|
|
1732
|
+
*
|
|
1733
|
+
* buildApiUrl("https://api.example.com/api", "auth/login");
|
|
1734
|
+
* // "https://api.example.com/api/auth/login"
|
|
1735
|
+
*
|
|
1736
|
+
* @param baseURL - Absolute base URL, or a path relative to the current origin.
|
|
1737
|
+
* @param path - The request path, or an absolute URL to use as-is.
|
|
1738
|
+
* @param options - Optional prefix and query params.
|
|
1739
|
+
* @returns The absolute URL to fetch.
|
|
1740
|
+
* @throws When `baseURL` is relative and there is no `location` to resolve it.
|
|
1741
|
+
*/
|
|
1742
|
+
export declare function buildApiUrl(baseURL: string, path: string, options?: BuildApiUrlOptions): string;
|
|
1743
|
+
|
|
1744
|
+
/** Options accepted by {@link buildApiUrl}. */
|
|
1745
|
+
export declare interface BuildApiUrlOptions {
|
|
1746
|
+
/**
|
|
1747
|
+
* Path segment every request is nested under, such as `"/api"`. Joined
|
|
1748
|
+
* after the path the `baseURL` already carries.
|
|
1749
|
+
*/
|
|
1750
|
+
prefix?: string;
|
|
1751
|
+
/** Query params to append. `undefined` and `null` values are skipped. */
|
|
1752
|
+
params?: Record<string, string | number | boolean | undefined | null>;
|
|
1753
|
+
}
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* Order, truncate and measure the rows.
|
|
1757
|
+
*
|
|
1758
|
+
* Two different numbers come out of this, and conflating them is the classic bug
|
|
1759
|
+
* in a hand-written bar list:
|
|
1760
|
+
*
|
|
1761
|
+
* - `percentage` is the row's share of the **total**, which is what the label
|
|
1762
|
+
* claims when it reads "32%".
|
|
1763
|
+
* - `width` is relative to the **largest** row, so the biggest bar fills the
|
|
1764
|
+
* track. Scaling width by the total instead leaves every bar short in a list of
|
|
1765
|
+
* many small values, and the chart stops being readable exactly when it has the
|
|
1766
|
+
* most rows.
|
|
1767
|
+
*
|
|
1768
|
+
* The total counts positive values only. A negative amount draws no bar (a bar of
|
|
1769
|
+
* negative width does not exist) and reports 0%, but its number is still shown —
|
|
1770
|
+
* hiding the row would be worse than showing an odd one.
|
|
1771
|
+
*
|
|
1772
|
+
* @param items - The rows as given.
|
|
1773
|
+
* @param sort - Ordering to apply. `"none"` keeps the caller's order.
|
|
1774
|
+
* @param max - Keep at most this many rows.
|
|
1775
|
+
* @param otherLabel - Aggregate what `max` cut into one row with this label.
|
|
1776
|
+
* @returns The rows to draw, in order.
|
|
1777
|
+
*/
|
|
1778
|
+
export declare function buildBarListRows(items: readonly BarListItem[], sort: BarListSort, max: number | undefined, otherLabel: string | undefined): BarListRow[];
|
|
1779
|
+
|
|
1555
1780
|
/**
|
|
1556
1781
|
* Builds an `intent://` URL that re-opens the current page inside Chrome on
|
|
1557
1782
|
* Android. When Chrome is missing, the fallback URL points to the Play Store so
|
|
@@ -2328,6 +2553,66 @@ export declare interface CommandProps {
|
|
|
2328
2553
|
*/
|
|
2329
2554
|
export declare function compareValues(a: unknown, b: unknown): number;
|
|
2330
2555
|
|
|
2556
|
+
/**
|
|
2557
|
+
* Typed `localStorage` wrapper that gzips what it writes.
|
|
2558
|
+
*
|
|
2559
|
+
* Mirrors {@link storage} so the two are interchangeable at the call site; the
|
|
2560
|
+
* difference is only in how the value is encoded.
|
|
2561
|
+
*/
|
|
2562
|
+
export declare const compressedStorage: {
|
|
2563
|
+
/**
|
|
2564
|
+
* Read and decompress a key.
|
|
2565
|
+
*
|
|
2566
|
+
* @typeParam T - The expected value shape.
|
|
2567
|
+
* @param key - Storage key.
|
|
2568
|
+
* @param fallback - Returned when the key is absent, unreadable, or corrupt.
|
|
2569
|
+
* @returns The stored value, or `fallback`.
|
|
2570
|
+
*/
|
|
2571
|
+
get<T>(key: string, fallback: T): T;
|
|
2572
|
+
/**
|
|
2573
|
+
* Compress and write a key.
|
|
2574
|
+
*
|
|
2575
|
+
* When compression itself fails the value is written as plain JSON rather
|
|
2576
|
+
* than dropped: a slightly larger record still loads, an absent one does
|
|
2577
|
+
* not. Only a storage-level failure — quota, blocked storage — loses the
|
|
2578
|
+
* write.
|
|
2579
|
+
*
|
|
2580
|
+
* @typeParam T - The value being stored.
|
|
2581
|
+
* @param key - Storage key.
|
|
2582
|
+
* @param value - Any JSON-serializable value.
|
|
2583
|
+
*/
|
|
2584
|
+
set<T>(key: string, value: T): void;
|
|
2585
|
+
};
|
|
2586
|
+
|
|
2587
|
+
/**
|
|
2588
|
+
* Codec pair for {@link useLocalStorage}, so a compressed key gets the hook's
|
|
2589
|
+
* cross-tab sync and SSR guard for free.
|
|
2590
|
+
*
|
|
2591
|
+
* @example
|
|
2592
|
+
* const [save, setSave] = useLocalStorage("save", EMPTY_SAVE, compressedStorageCodec);
|
|
2593
|
+
*/
|
|
2594
|
+
export declare const compressedStorageCodec: {
|
|
2595
|
+
serialize: typeof compressToString;
|
|
2596
|
+
deserialize: typeof decompressFromString;
|
|
2597
|
+
};
|
|
2598
|
+
|
|
2599
|
+
/**
|
|
2600
|
+
* Serialize a value to a gzipped, base64 string carrying the format marker.
|
|
2601
|
+
*
|
|
2602
|
+
* Base64 costs a third more characters than the raw compressed bytes, and
|
|
2603
|
+
* `localStorage` bills two bytes per character on top of that. Packing the
|
|
2604
|
+
* bytes into UTF-16 code units directly would be denser, but lone surrogates
|
|
2605
|
+
* survive neither every storage implementation nor a JSON round-trip, and a
|
|
2606
|
+
* save that decodes to garbage is far worse than one that is bigger. Even with
|
|
2607
|
+
* that overhead a typical JSON document lands well under a third of its
|
|
2608
|
+
* uncompressed size.
|
|
2609
|
+
*
|
|
2610
|
+
* @typeParam T - The value being stored.
|
|
2611
|
+
* @param value - Any JSON-serializable value.
|
|
2612
|
+
* @returns The encoded string, ready for `localStorage`.
|
|
2613
|
+
*/
|
|
2614
|
+
export declare function compressToString<T>(value: T): string;
|
|
2615
|
+
|
|
2331
2616
|
/**
|
|
2332
2617
|
* Conditionally wraps its children with `wrapper`.
|
|
2333
2618
|
*
|
|
@@ -3287,6 +3572,36 @@ export declare interface CreateSentryTelemetryAdapterOptions {
|
|
|
3287
3572
|
breadcrumbCategory?: string;
|
|
3288
3573
|
}
|
|
3289
3574
|
|
|
3575
|
+
/**
|
|
3576
|
+
* A pool of preallocated `<audio>` elements for short sound effects.
|
|
3577
|
+
*
|
|
3578
|
+
* `new Audio(src)` on every play allocates an element and re-enters the network
|
|
3579
|
+
* stack for a file the browser already has, which is the wrong shape for a
|
|
3580
|
+
* sound that fires dozens of times a minute — a UI blip, a hit, a pickup. The
|
|
3581
|
+
* pool allocates once per source and replays.
|
|
3582
|
+
*
|
|
3583
|
+
* This is deliberately not {@link createAudioPlayer}: that handle tracks a
|
|
3584
|
+
* single "current" clip with loop, sink routing and lifecycle callbacks, which
|
|
3585
|
+
* is what background music needs. Effects are the opposite case — many
|
|
3586
|
+
* sources, all short, fire-and-forget, and the only thing that matters is that
|
|
3587
|
+
* firing one is cheap.
|
|
3588
|
+
*
|
|
3589
|
+
* A blocked `play()` is swallowed. Browsers reject playback until the user has
|
|
3590
|
+
* interacted with the page, and a sound effect is by definition not worth
|
|
3591
|
+
* interrupting anything over; call {@link SfxPool.preload} after the first
|
|
3592
|
+
* interaction if you want the pool warm.
|
|
3593
|
+
*
|
|
3594
|
+
* @param options - Master volume, base URL, voices per source and pool size.
|
|
3595
|
+
* @returns The pool handle.
|
|
3596
|
+
*
|
|
3597
|
+
* @example
|
|
3598
|
+
* const sfx = createSfxPool({ volume: 0.6, baseUrl: import.meta.env.BASE_URL });
|
|
3599
|
+
* sfx.preload(["sfx/select.mp3", "sfx/back.mp3"]);
|
|
3600
|
+
*
|
|
3601
|
+
* <button onClick={() => sfx.play("sfx/select.mp3")}>Confirmar</button>
|
|
3602
|
+
*/
|
|
3603
|
+
export declare function createSfxPool(options?: SfxPoolOptions): SfxPool;
|
|
3604
|
+
|
|
3290
3605
|
/**
|
|
3291
3606
|
* Create a typed Zustand store with optional `persist` middleware, wired with
|
|
3292
3607
|
* Tempest defaults. This is the generic counterpart to `createAuthStore`: use
|
|
@@ -3377,6 +3692,16 @@ export declare function createTempestAuth<TUser, TCredentials = {
|
|
|
3377
3692
|
export declare interface CreateTempestAuthOptions<TUser> {
|
|
3378
3693
|
/** Base URL of the API. Required. */
|
|
3379
3694
|
baseURL: string;
|
|
3695
|
+
/**
|
|
3696
|
+
* Path segment the API is mounted under, such as `"/api"`, forwarded to
|
|
3697
|
+
* every client this preset builds — see the `prefix` option of
|
|
3698
|
+
* `createApiClient`.
|
|
3699
|
+
*
|
|
3700
|
+
* Safe to combine with the default paths below: the prefix is applied at
|
|
3701
|
+
* most once, so `"/api/auth/login"` under a `"/api"` prefix stays
|
|
3702
|
+
* `"/api/auth/login"`.
|
|
3703
|
+
*/
|
|
3704
|
+
prefix?: string;
|
|
3380
3705
|
/** Login route (`POST`). Default: `"/api/auth/login"`. */
|
|
3381
3706
|
loginPath?: string;
|
|
3382
3707
|
/** Refresh route (`POST`). Default: `"/api/auth/refresh"`. */
|
|
@@ -3586,6 +3911,36 @@ export declare interface CredentialsContainerLike {
|
|
|
3586
3911
|
}): Promise<Credential | null>;
|
|
3587
3912
|
}
|
|
3588
3913
|
|
|
3914
|
+
/** One column of the exported file. */
|
|
3915
|
+
export declare interface CsvColumn<T> {
|
|
3916
|
+
/** Property of the row this column reads from. Doubles as the column key. */
|
|
3917
|
+
key: keyof T;
|
|
3918
|
+
/** Column heading, written to the first line. */
|
|
3919
|
+
header: string;
|
|
3920
|
+
/**
|
|
3921
|
+
* Value for the file. Defaults to `String(row[key])`, with nullish becoming an
|
|
3922
|
+
* empty field.
|
|
3923
|
+
*
|
|
3924
|
+
* A `DataTableColumn` renders cells to `ReactNode`, which cannot be written to
|
|
3925
|
+
* a text file — a badge or a link would serialize as `[object Object]`. Give
|
|
3926
|
+
* the column this accessor and the export says what the badge said.
|
|
3927
|
+
*/
|
|
3928
|
+
csv?: (row: T) => string | number | boolean | null | undefined;
|
|
3929
|
+
}
|
|
3930
|
+
|
|
3931
|
+
/** Options for {@link toCsv}. */
|
|
3932
|
+
export declare interface CsvOptions {
|
|
3933
|
+
/**
|
|
3934
|
+
* Field separator. Default `","`.
|
|
3935
|
+
*
|
|
3936
|
+
* Use `";"` for Excel on a locale whose decimal separator is the comma —
|
|
3937
|
+
* which is every pt-BR install — otherwise it opens the file in one column.
|
|
3938
|
+
*/
|
|
3939
|
+
delimiter?: "," | ";";
|
|
3940
|
+
/** Prefix the output with a UTF-8 BOM. Default `true`. */
|
|
3941
|
+
bom?: boolean;
|
|
3942
|
+
}
|
|
3943
|
+
|
|
3589
3944
|
/** Cursor-paginated response envelope (`CursorPaginationSchema[T]`). */
|
|
3590
3945
|
export declare interface CursorPage<T> {
|
|
3591
3946
|
/** The rows for this batch. */
|
|
@@ -3744,7 +4099,7 @@ export declare interface DataProviderOptions {
|
|
|
3744
4099
|
* render without changing behaviour. That is why `exhaustive-deps` is silenced on
|
|
3745
4100
|
* that dependency array.
|
|
3746
4101
|
*/
|
|
3747
|
-
export declare function DataTable<T>({ data, columns, pageSize, searchable, searchKeys, initialSort, rowKey, emptyMessage, onCellChange, editLabels, className, ...rest }: DataTableProps<T>): JSX.Element;
|
|
4102
|
+
export declare function DataTable<T>({ data, columns, pageSize, searchable, searchKeys, initialSort, rowKey, emptyMessage, onCellChange, editLabels, totalItems, page: controlledPage, onPageChange, manualSort, onSortChange, manualSearch, onSearchChange, loading, className, ...rest }: DataTableProps<T>): JSX.Element;
|
|
3748
4103
|
|
|
3749
4104
|
/** One accepted cell edit, handed to `onCellChange`. */
|
|
3750
4105
|
export declare interface DataTableCellChange<T> {
|
|
@@ -3824,7 +4179,13 @@ export declare interface DataTableEditLabels {
|
|
|
3824
4179
|
export declare type DataTableEditorType = "text" | "number" | "date" | "email" | "tel" | "url";
|
|
3825
4180
|
|
|
3826
4181
|
export declare interface DataTableProps<T> extends HTMLAttributes<HTMLDivElement> {
|
|
3827
|
-
/**
|
|
4182
|
+
/**
|
|
4183
|
+
* The rows to work with.
|
|
4184
|
+
*
|
|
4185
|
+
* By default this is the **full** dataset and sorting, searching and paging
|
|
4186
|
+
* all happen in memory. Pass `totalItems` and it becomes the current page as
|
|
4187
|
+
* the server returned it, with those three delegated to the caller.
|
|
4188
|
+
*/
|
|
3828
4189
|
data: T[];
|
|
3829
4190
|
/** Column definitions. */
|
|
3830
4191
|
columns: DataTableColumn<T>[];
|
|
@@ -3851,6 +4212,51 @@ export declare interface DataTableProps<T> extends HTMLAttributes<HTMLDivElement
|
|
|
3851
4212
|
onCellChange?: (change: DataTableCellChange<T>) => void | Promise<void>;
|
|
3852
4213
|
/** Override the PT-BR copy of the editing affordances. */
|
|
3853
4214
|
editLabels?: Partial<DataTableEditLabels>;
|
|
4215
|
+
/**
|
|
4216
|
+
* Total row count across every page — the `total` of a paginated envelope.
|
|
4217
|
+
*
|
|
4218
|
+
* Passing it switches the table to **server mode**: `data` is read as the
|
|
4219
|
+
* current page, the page count comes from this number instead of
|
|
4220
|
+
* `data.length`, and sorting and searching are delegated to the caller
|
|
4221
|
+
* (see `manualSort` / `manualSearch`, which are implied here). Pair it with
|
|
4222
|
+
* `page` and `onPageChange`.
|
|
4223
|
+
*/
|
|
4224
|
+
totalItems?: number;
|
|
4225
|
+
/** Current page, 1-based. Controlled — required in server mode. */
|
|
4226
|
+
page?: number;
|
|
4227
|
+
/** Called with the next page. Required whenever `page` is controlled. */
|
|
4228
|
+
onPageChange?: (page: number) => void;
|
|
4229
|
+
/**
|
|
4230
|
+
* Sorting is the caller's job: clicking a header reports through
|
|
4231
|
+
* `onSortChange` and the rows are left in the order they arrived.
|
|
4232
|
+
*
|
|
4233
|
+
* Implied by `totalItems`, because sorting the page in memory would sort
|
|
4234
|
+
* *that page only* while the header claims the whole table is ordered.
|
|
4235
|
+
*/
|
|
4236
|
+
manualSort?: boolean;
|
|
4237
|
+
/** Called with the next sort state — `null` when the header cycles back to unsorted. */
|
|
4238
|
+
onSortChange?: (sort: DataTableSort<T> | null) => void;
|
|
4239
|
+
/**
|
|
4240
|
+
* Searching is the caller's job: typing reports through `onSearchChange` and
|
|
4241
|
+
* the rows are left as they arrived.
|
|
4242
|
+
*
|
|
4243
|
+
* Implied by `totalItems`. Filtering the current page would hide the rows
|
|
4244
|
+
* that do not match *on this page* and show nothing for a term that only
|
|
4245
|
+
* matches on page three — an empty table that looks like "no results".
|
|
4246
|
+
*/
|
|
4247
|
+
manualSearch?: boolean;
|
|
4248
|
+
/** Called with the current search term (debouncing, if any, is the caller's). */
|
|
4249
|
+
onSearchChange?: (term: string) => void;
|
|
4250
|
+
/**
|
|
4251
|
+
* A fetch is in flight.
|
|
4252
|
+
*
|
|
4253
|
+
* With rows already on screen they stay put, dimmed and `aria-busy`, so the
|
|
4254
|
+
* page does not jump under the cursor between pages. With no rows yet it
|
|
4255
|
+
* renders placeholder lines at full height, which is a different statement
|
|
4256
|
+
* from `emptyMessage`: "loading" and "there is nothing" are not the same
|
|
4257
|
+
* screen.
|
|
4258
|
+
*/
|
|
4259
|
+
loading?: boolean;
|
|
3854
4260
|
}
|
|
3855
4261
|
|
|
3856
4262
|
export declare interface DataTableSort<T> {
|
|
@@ -3953,6 +4359,20 @@ export declare interface DecodedJWT {
|
|
|
3953
4359
|
*/
|
|
3954
4360
|
export declare function decodeJWT(token: string): DecodedJWT;
|
|
3955
4361
|
|
|
4362
|
+
/**
|
|
4363
|
+
* Decode a string produced by {@link compressToString}.
|
|
4364
|
+
*
|
|
4365
|
+
* A string without the marker is parsed as plain JSON, so values written before
|
|
4366
|
+
* compression was enabled — or by a write that fell back after `gzipSync`
|
|
4367
|
+
* failed — still read back.
|
|
4368
|
+
*
|
|
4369
|
+
* @typeParam T - The expected value shape.
|
|
4370
|
+
* @param raw - The stored string.
|
|
4371
|
+
* @returns The decoded value.
|
|
4372
|
+
* @throws If the payload is neither valid compressed data nor valid JSON.
|
|
4373
|
+
*/
|
|
4374
|
+
export declare function decompressFromString<T>(raw: string): T;
|
|
4375
|
+
|
|
3956
4376
|
/**
|
|
3957
4377
|
* Recursively merge `source` into `target`, returning a new object.
|
|
3958
4378
|
*
|
|
@@ -3974,6 +4394,15 @@ export declare function decodeJWT(token: string): DecodedJWT;
|
|
|
3974
4394
|
*/
|
|
3975
4395
|
export declare function deepMerge<T>(target: T, source: Partial<T>): T;
|
|
3976
4396
|
|
|
4397
|
+
/**
|
|
4398
|
+
* PT-BR defaults, used when no strings are supplied and no catalog answers.
|
|
4399
|
+
*
|
|
4400
|
+
* The SDK's copy is pt-BR everywhere else (`FilterBar`, `DataTable`, `Chat`), so
|
|
4401
|
+
* the default here matches rather than introducing an English string that only
|
|
4402
|
+
* shows up on a network failure.
|
|
4403
|
+
*/
|
|
4404
|
+
export declare const DEFAULT_API_ERROR_STRINGS: ApiErrorStrings;
|
|
4405
|
+
|
|
3977
4406
|
/**
|
|
3978
4407
|
* What a scanner looks for when you do not say.
|
|
3979
4408
|
*
|
|
@@ -4035,6 +4464,36 @@ export declare const DEFAULT_PUB_KEY_CRED_PARAMS: {
|
|
|
4035
4464
|
*/
|
|
4036
4465
|
export declare function defineRoutes(routes: TempestRouteObject[]): TempestRouteObject[];
|
|
4037
4466
|
|
|
4467
|
+
/**
|
|
4468
|
+
* Turn any caught value into a sentence worth showing.
|
|
4469
|
+
*
|
|
4470
|
+
* The funnel, in order:
|
|
4471
|
+
*
|
|
4472
|
+
* 1. A request that never reached the server — `status === 0`, or a non-API
|
|
4473
|
+
* error thrown while the browser reports itself offline — produces the
|
|
4474
|
+
* offline sentence. This is the step apps skip, and skipping it renders
|
|
4475
|
+
* "erro 0" or a raw `TypeError` at the user.
|
|
4476
|
+
* 2. The backend's own `detail`, which is the most specific thing available and
|
|
4477
|
+
* is already written for a person.
|
|
4478
|
+
* 3. `fallback`, with `(HTTP <status>)` appended when a status is known, so the
|
|
4479
|
+
* screenshot in the support ticket carries the one fact a developer needs.
|
|
4480
|
+
*
|
|
4481
|
+
* Pure on purpose: it works in an interceptor, in a logger and anywhere outside
|
|
4482
|
+
* the React tree. {@link useDescribeApiError} is the same funnel with the
|
|
4483
|
+
* sentences resolved through `I18nProvider`.
|
|
4484
|
+
*
|
|
4485
|
+
* @example
|
|
4486
|
+
* catch (error) {
|
|
4487
|
+
* toast(describeApiError(error, "Não foi possível salvar o pedido"));
|
|
4488
|
+
* }
|
|
4489
|
+
*
|
|
4490
|
+
* @param error - The caught value, of any shape.
|
|
4491
|
+
* @param fallback - What to say when the error carries nothing better.
|
|
4492
|
+
* @param strings - Overrides for the fixed sentences.
|
|
4493
|
+
* @returns A sentence to show the user.
|
|
4494
|
+
*/
|
|
4495
|
+
export declare function describeApiError(error: unknown, fallback: string, strings?: Partial<ApiErrorStrings>): string;
|
|
4496
|
+
|
|
4038
4497
|
/**
|
|
4039
4498
|
* One filter, in words: `"Status é Pago"`.
|
|
4040
4499
|
*
|
|
@@ -4169,6 +4628,25 @@ export declare type DividerVariant = "solid" | "dashed";
|
|
|
4169
4628
|
|
|
4170
4629
|
export declare type DocumentVisibility = "visible" | "hidden";
|
|
4171
4630
|
|
|
4631
|
+
/**
|
|
4632
|
+
* Build a CSV and hand it to the user.
|
|
4633
|
+
*
|
|
4634
|
+
* Goes through {@link shareOrDownloadBlob}, so on a phone it opens the native
|
|
4635
|
+
* share sheet and everywhere else it downloads — the same path every other
|
|
4636
|
+
* generated artifact in the SDK takes, instead of a fourth hand-rolled `<a
|
|
4637
|
+
* download>`.
|
|
4638
|
+
*
|
|
4639
|
+
* @example
|
|
4640
|
+
* await downloadCsv(users, COLUMNS, "usuarios.csv");
|
|
4641
|
+
*
|
|
4642
|
+
* @param rows - The rows to export.
|
|
4643
|
+
* @param columns - Columns, in the order they should appear.
|
|
4644
|
+
* @param fileName - File name offered to the user. Default `"export.csv"`.
|
|
4645
|
+
* @param options - Delimiter and BOM, forwarded to {@link toCsv}.
|
|
4646
|
+
* @returns A promise that resolves once the share or download completes.
|
|
4647
|
+
*/
|
|
4648
|
+
export declare function downloadCsv<T>(rows: readonly T[], columns: readonly CsvColumn<T>[], fileName?: string, options?: CsvOptions): Promise<void>;
|
|
4649
|
+
|
|
4172
4650
|
/**
|
|
4173
4651
|
* Sliding side panel. Same building blocks as {@link Modal} but anchored to
|
|
4174
4652
|
* an edge. Locks body scroll while open.
|
|
@@ -4637,6 +5115,51 @@ export declare type FilterPredicate<T> = (item: T, search: string) => boolean;
|
|
|
4637
5115
|
*/
|
|
4638
5116
|
export declare function filtersFromSearchParams(params: URLSearchParams, fields: readonly FilterField[]): Filter[];
|
|
4639
5117
|
|
|
5118
|
+
/**
|
|
5119
|
+
* Encode filters as query params for a paginated backend.
|
|
5120
|
+
*
|
|
5121
|
+
* The counterpart of {@link applyFilters}: same filter set, evaluated by the
|
|
5122
|
+
* database instead of by the browser, which is the only option once the list is
|
|
5123
|
+
* paginated on the server and the page in memory is not the whole result.
|
|
5124
|
+
*
|
|
5125
|
+
* The encoding is the `<column>__<op>` convention `tempest-fastapi-sdk` already
|
|
5126
|
+
* reads (`BaseRepository._apply_filters` → `build_filter_condition`):
|
|
5127
|
+
*
|
|
5128
|
+
* | Operator | Param |
|
|
5129
|
+
* | --- | --- |
|
|
5130
|
+
* | `eq` | `field` (or `field__iexact` for the `name` column) |
|
|
5131
|
+
* | `ne` | `field__ne` |
|
|
5132
|
+
* | `contains` | `field__icontains` |
|
|
5133
|
+
* | `gt` `gte` `lt` `lte` | `field__gt` … `field__lte` |
|
|
5134
|
+
* | `between` | `field__between` twice, low value first |
|
|
5135
|
+
* | `in` | `field__in` once per value |
|
|
5136
|
+
* | `empty` / `notEmpty` | `field__isnull=true` / `=false` |
|
|
5137
|
+
*
|
|
5138
|
+
* Returns `URLSearchParams` rather than a plain object because `between` carries
|
|
5139
|
+
* a pair and `in` carries a list: an object would keep only the last value of
|
|
5140
|
+
* each, silently narrowing the filter. Repeated params are also how FastAPI
|
|
5141
|
+
* receives a `list[str]` declared with `Query`.
|
|
5142
|
+
*
|
|
5143
|
+
* Two things the backend has to hold up its end of, or the filter fails quietly:
|
|
5144
|
+
*
|
|
5145
|
+
* - **Every key must be declared.** `BasePaginationFilterSchema.get_conditions()`
|
|
5146
|
+
* only forwards fields the subclass declares, so a `status__ne` the schema
|
|
5147
|
+
* never mentions is dropped by FastAPI before the repository sees it — no
|
|
5148
|
+
* error, no filtering.
|
|
5149
|
+
* - **`isnull` matches `NULL` only.** A column that stores `""` for "no value"
|
|
5150
|
+
* will not answer an `empty` filter, while {@link applyFilters} treats blank
|
|
5151
|
+
* text as empty.
|
|
5152
|
+
*
|
|
5153
|
+
* @example
|
|
5154
|
+
* const params = filtersToQueryParams(filters);
|
|
5155
|
+
* params.set("page", String(page));
|
|
5156
|
+
* const data = await api.get(`/orders?${params}`);
|
|
5157
|
+
*
|
|
5158
|
+
* @param filters - Applied filters; incomplete ones are ignored.
|
|
5159
|
+
* @returns Params ready to append to a request URL.
|
|
5160
|
+
*/
|
|
5161
|
+
export declare function filtersToQueryParams(filters: readonly Filter[]): URLSearchParams;
|
|
5162
|
+
|
|
4640
5163
|
/**
|
|
4641
5164
|
* Serialize filters into URL search params.
|
|
4642
5165
|
*
|
|
@@ -4840,6 +5363,30 @@ export declare function formatCurrency(value: number): string;
|
|
|
4840
5363
|
*/
|
|
4841
5364
|
export declare function formatDate(value: string | Date): string;
|
|
4842
5365
|
|
|
5366
|
+
/**
|
|
5367
|
+
* Format an ISO date or Date instance as `yyyy-MM-dd`, the value an
|
|
5368
|
+
* `<input type="date">` accepts.
|
|
5369
|
+
*
|
|
5370
|
+
* Built from the **local** calendar parts rather than `toISOString().slice(0, 10)`,
|
|
5371
|
+
* which is the reflex and which is wrong: `toISOString` converts to UTC first, so
|
|
5372
|
+
* anything after 21:00 in UTC-3 reports the next day and the form opens on the
|
|
5373
|
+
* wrong date. `formatDate` cannot fill this role because a date input rejects
|
|
5374
|
+
* `dd/MM/yyyy` outright.
|
|
5375
|
+
*
|
|
5376
|
+
* A value that is already `yyyy-MM-dd` is returned untouched, and that shortcut
|
|
5377
|
+
* is load-bearing rather than an optimisation: `new Date("2026-05-16")` is parsed
|
|
5378
|
+
* as **UTC** midnight, which in UTC-3 is the 15th at 21:00, so round-tripping the
|
|
5379
|
+
* exact value a backend sent would move it back a day.
|
|
5380
|
+
*
|
|
5381
|
+
* @example
|
|
5382
|
+
* <input type="date" defaultValue={formatDateForInput(order.createdAt)} />
|
|
5383
|
+
*
|
|
5384
|
+
* @param value - ISO string or Date.
|
|
5385
|
+
* @returns The `yyyy-MM-dd` value, or an empty string when the input is invalid —
|
|
5386
|
+
* which is what a date input reads as "no value", unlike `"Invalid Date"`.
|
|
5387
|
+
*/
|
|
5388
|
+
export declare function formatDateForInput(value: string | Date): string;
|
|
5389
|
+
|
|
4843
5390
|
/**
|
|
4844
5391
|
* Format an ISO date or Date instance as `dd/MM/yyyy HH:mm`.
|
|
4845
5392
|
*
|
|
@@ -6186,17 +6733,22 @@ declare interface LayoutProps {
|
|
|
6186
6733
|
}
|
|
6187
6734
|
|
|
6188
6735
|
/**
|
|
6189
|
-
* Wrap `React.lazy` with automatic retry
|
|
6190
|
-
*
|
|
6191
|
-
*
|
|
6192
|
-
*
|
|
6736
|
+
* Wrap `React.lazy` with automatic retry and a `preload()` method.
|
|
6737
|
+
*
|
|
6738
|
+
* Common cause of failure: deployed-then-cached `index.html` references chunk
|
|
6739
|
+
* filenames that no longer exist. Retrying after a short delay typically picks
|
|
6740
|
+
* up the new bundle; a final `location.reload()` recovers from stale
|
|
6741
|
+
* `index.html`.
|
|
6193
6742
|
*
|
|
6194
6743
|
* @example
|
|
6195
6744
|
* const Settings = lazyWithRetry(() => import("./Settings"));
|
|
6745
|
+
*
|
|
6746
|
+
* // Warm the chunk when the route becomes likely, not when it is needed.
|
|
6747
|
+
* <a href="/settings" onMouseEnter={() => void Settings.preload()}>Settings</a>
|
|
6196
6748
|
*/
|
|
6197
6749
|
export declare function lazyWithRetry<T extends ComponentType<unknown>>(factory: () => Promise<{
|
|
6198
6750
|
default: T;
|
|
6199
|
-
}>, options?: LazyWithRetryOptions):
|
|
6751
|
+
}>, options?: LazyWithRetryOptions): PreloadableLazy<T>;
|
|
6200
6752
|
|
|
6201
6753
|
export declare interface LazyWithRetryOptions {
|
|
6202
6754
|
/** Max attempts. Default: 3. */
|
|
@@ -8005,6 +8557,33 @@ export declare interface PcmAudio {
|
|
|
8005
8557
|
sampleRate: number;
|
|
8006
8558
|
}
|
|
8007
8559
|
|
|
8560
|
+
/**
|
|
8561
|
+
* What percentage of `total` is `part`, with an empty base yielding `0`.
|
|
8562
|
+
*
|
|
8563
|
+
* The guard is the whole point: `(part / total) * 100` produces `NaN` when the
|
|
8564
|
+
* base is zero and `Infinity` when only the base is missing, and both reach the
|
|
8565
|
+
* screen as a broken label — `NaN%` on an empty dashboard is the single most
|
|
8566
|
+
* common way a panel announces that it has no data yet.
|
|
8567
|
+
*
|
|
8568
|
+
* Returns a **0–100** number, which is what a bar width and a label want.
|
|
8569
|
+
* `formatPercent` takes a 0–1 fraction instead, so pair them as
|
|
8570
|
+
* `formatPercent(percentOf(a, b) / 100)` — or skip `percentOf` and pass the
|
|
8571
|
+
* fraction straight in.
|
|
8572
|
+
*
|
|
8573
|
+
* The result is not clamped: 120% of a target is a real number somebody wants to
|
|
8574
|
+
* see, and capping it would hide the interesting case.
|
|
8575
|
+
*
|
|
8576
|
+
* @example
|
|
8577
|
+
* percentOf(3, 4); // 75
|
|
8578
|
+
* percentOf(5, 0); // 0
|
|
8579
|
+
* percentOf(12, 8); // 150
|
|
8580
|
+
*
|
|
8581
|
+
* @param part - The measured amount.
|
|
8582
|
+
* @param total - The base it is measured against.
|
|
8583
|
+
* @returns The percentage, or `0` when the base is zero or either input is not finite.
|
|
8584
|
+
*/
|
|
8585
|
+
export declare function percentOf(part: number, total: number): number;
|
|
8586
|
+
|
|
8008
8587
|
/**
|
|
8009
8588
|
* Extract a permission list from a JWT.
|
|
8010
8589
|
*
|
|
@@ -8181,6 +8760,12 @@ export declare interface PlayAudioOptions {
|
|
|
8181
8760
|
onError?: (error: unknown) => void;
|
|
8182
8761
|
}
|
|
8183
8762
|
|
|
8763
|
+
/** Per-play overrides. */
|
|
8764
|
+
export declare interface PlaySfxOptions {
|
|
8765
|
+
/** Volume for this play, `0`–`1`, multiplied by the pool's master. Default `1`. */
|
|
8766
|
+
volume?: number;
|
|
8767
|
+
}
|
|
8768
|
+
|
|
8184
8769
|
/**
|
|
8185
8770
|
* Pick the singular or plural form of a word based on `count`.
|
|
8186
8771
|
*
|
|
@@ -8276,6 +8861,29 @@ export declare interface PostHogLike {
|
|
|
8276
8861
|
reset?: () => void;
|
|
8277
8862
|
}
|
|
8278
8863
|
|
|
8864
|
+
/** A lazy component that can also be fetched ahead of being rendered. */
|
|
8865
|
+
export declare type PreloadableLazy<T extends ComponentType<unknown>> = ReturnType<typeof lazy<T>> & {
|
|
8866
|
+
/**
|
|
8867
|
+
* Start fetching the chunk now, before anything renders it.
|
|
8868
|
+
*
|
|
8869
|
+
* Call it on the interaction that makes the route likely — hovering the
|
|
8870
|
+
* link, opening the menu that holds it, finishing the step before it — so
|
|
8871
|
+
* the chunk is warm by the time the user commits and the suspense fallback
|
|
8872
|
+
* never appears.
|
|
8873
|
+
*
|
|
8874
|
+
* Shares its work with the render path: whichever fires first performs the
|
|
8875
|
+
* single fetch and the other awaits the same promise. Safe to call
|
|
8876
|
+
* repeatedly.
|
|
8877
|
+
*
|
|
8878
|
+
* @returns The module, once loaded. Rejects when every retry failed; that
|
|
8879
|
+
* rejection is already handled internally, so a fire-and-forget call
|
|
8880
|
+
* never surfaces as an unhandled rejection.
|
|
8881
|
+
*/
|
|
8882
|
+
preload: () => Promise<{
|
|
8883
|
+
default: T;
|
|
8884
|
+
}>;
|
|
8885
|
+
};
|
|
8886
|
+
|
|
8279
8887
|
/** A model whose cached size should appear in the report. */
|
|
8280
8888
|
export declare interface ProfiledModel {
|
|
8281
8889
|
/** Label for the report row, e.g. `"detector"`. */
|
|
@@ -8475,7 +9083,12 @@ export declare type QRMode = "numeric" | "alphanumeric" | "byte";
|
|
|
8475
9083
|
|
|
8476
9084
|
/**
|
|
8477
9085
|
* Wrapper around `QueryClientProvider` that bootstraps a `QueryClient` with
|
|
8478
|
-
* sane SDK defaults (5-minute stale time, 30-minute gc time,
|
|
9086
|
+
* sane SDK defaults (5-minute stale time, 30-minute gc time, one retry for
|
|
9087
|
+
* failures worth replaying).
|
|
9088
|
+
*
|
|
9089
|
+
* Retries follow {@link shouldRetryQuery} rather than a flat count: a 4xx other
|
|
9090
|
+
* than 408/429 is the server refusing on purpose, and replaying it only doubles
|
|
9091
|
+
* the network log while the spinner keeps turning.
|
|
8479
9092
|
*/
|
|
8480
9093
|
export declare function QueryProvider({ children, client, defaultOptions }: QueryProviderProps): JSX.Element;
|
|
8481
9094
|
|
|
@@ -9441,6 +10054,46 @@ export declare interface SequentialScaleOptions {
|
|
|
9441
10054
|
*/
|
|
9442
10055
|
export declare function setAudioOutput(element: HTMLMediaElement | null, sinkId: string): Promise<boolean>;
|
|
9443
10056
|
|
|
10057
|
+
/** Imperative handle over a pool of short sound effects. */
|
|
10058
|
+
export declare interface SfxPool {
|
|
10059
|
+
/** Play a clip, allocating and caching its element on first use. */
|
|
10060
|
+
play: (src: string, options?: PlaySfxOptions) => void;
|
|
10061
|
+
/** Fetch clips ahead of the first play, so it is not silent while the file downloads. */
|
|
10062
|
+
preload: (src: string | string[]) => void;
|
|
10063
|
+
/** Set the master volume, applying it to anything already sounding. */
|
|
10064
|
+
setVolume: (volume: number) => void;
|
|
10065
|
+
/** Stop one source, or every source when called with no argument. */
|
|
10066
|
+
stop: (src?: string) => void;
|
|
10067
|
+
/** Release every element. Call on unmount. */
|
|
10068
|
+
dispose: () => void;
|
|
10069
|
+
}
|
|
10070
|
+
|
|
10071
|
+
/** Options for {@link createSfxPool}. */
|
|
10072
|
+
export declare interface SfxPoolOptions {
|
|
10073
|
+
/**
|
|
10074
|
+
* Master volume, `0`–`1`, multiplied into every per-play volume. Default
|
|
10075
|
+
* `1`. Wire it to the app's sound setting so one value governs the lot.
|
|
10076
|
+
*/
|
|
10077
|
+
volume?: number;
|
|
10078
|
+
/**
|
|
10079
|
+
* Prefix applied to sources that are not absolute URLs — typically Vite's
|
|
10080
|
+
* `import.meta.env.BASE_URL`, so a build served from a subpath resolves.
|
|
10081
|
+
* Default `""`.
|
|
10082
|
+
*/
|
|
10083
|
+
baseUrl?: string;
|
|
10084
|
+
/**
|
|
10085
|
+
* Elements kept per source. `1` (the default) restarts the clip on every
|
|
10086
|
+
* play, which is what a menu blip wants. Raise it to let a sound overlap
|
|
10087
|
+
* itself — a hit landing while the previous one is still ringing.
|
|
10088
|
+
*/
|
|
10089
|
+
voices?: number;
|
|
10090
|
+
/**
|
|
10091
|
+
* Maximum number of distinct sources held. When exceeded, the least
|
|
10092
|
+
* recently played source is released. Default `48`.
|
|
10093
|
+
*/
|
|
10094
|
+
maxSources?: number;
|
|
10095
|
+
}
|
|
10096
|
+
|
|
9444
10097
|
/**
|
|
9445
10098
|
* Wrap the Web Share API with a uniform result object. Falls through to
|
|
9446
10099
|
* `unsupported: true` when the browser lacks `navigator.share`, leaving the
|
|
@@ -9493,6 +10146,25 @@ export declare interface ShareResult {
|
|
|
9493
10146
|
error?: unknown;
|
|
9494
10147
|
}
|
|
9495
10148
|
|
|
10149
|
+
/**
|
|
10150
|
+
* Default `retry` for SDK queries: replay transport and server failures, never a
|
|
10151
|
+
* deliberate client-side refusal.
|
|
10152
|
+
*
|
|
10153
|
+
* A flat `retry: 1` replays a 403 on an admin-only listing and a 404 for a record
|
|
10154
|
+
* somebody deleted. The server meant both — the second attempt returns the same
|
|
10155
|
+
* answer, doubles the network log and holds the spinner on screen for the length
|
|
10156
|
+
* of another round trip. A network failure or a 5xx is a different thing: it may
|
|
10157
|
+
* well succeed on the next try, so those keep the previous behaviour.
|
|
10158
|
+
*
|
|
10159
|
+
* @example
|
|
10160
|
+
* new QueryClient({ defaultOptions: { queries: { retry: shouldRetryQuery } } });
|
|
10161
|
+
*
|
|
10162
|
+
* @param failureCount - Attempts already made, as react-query counts them.
|
|
10163
|
+
* @param error - The rejection value from the query function.
|
|
10164
|
+
* @returns Whether react-query should try again.
|
|
10165
|
+
*/
|
|
10166
|
+
export declare function shouldRetryQuery(failureCount: number, error: unknown): boolean;
|
|
10167
|
+
|
|
9496
10168
|
/**
|
|
9497
10169
|
* Conditionally render children based on the viewport breakpoint.
|
|
9498
10170
|
*
|
|
@@ -10642,6 +11314,28 @@ export declare interface ToastProviderProps {
|
|
|
10642
11314
|
|
|
10643
11315
|
export declare type ToastVariant = "success" | "warning" | "error" | "info";
|
|
10644
11316
|
|
|
11317
|
+
/**
|
|
11318
|
+
* Serialize rows to CSV text, RFC 4180 style.
|
|
11319
|
+
*
|
|
11320
|
+
* Rows are separated by `\r\n` — the RFC's terminator and the one Excel is least
|
|
11321
|
+
* surprised by. A row is emitted for the header even when `rows` is empty, so the
|
|
11322
|
+
* person who opens the file sees which columns they asked for instead of a blank
|
|
11323
|
+
* document.
|
|
11324
|
+
*
|
|
11325
|
+
* @example
|
|
11326
|
+
* const csv = toCsv(users, [
|
|
11327
|
+
* { key: "name", header: "Nome" },
|
|
11328
|
+
* { key: "email", header: "E-mail" },
|
|
11329
|
+
* { key: "plan", header: "Plano", csv: (user) => user.plan.label },
|
|
11330
|
+
* ]);
|
|
11331
|
+
*
|
|
11332
|
+
* @param rows - The rows to export.
|
|
11333
|
+
* @param columns - Columns, in the order they should appear.
|
|
11334
|
+
* @param options - Delimiter and BOM.
|
|
11335
|
+
* @returns The complete file contents.
|
|
11336
|
+
*/
|
|
11337
|
+
export declare function toCsv<T>(rows: readonly T[], columns: readonly CsvColumn<T>[], options?: CsvOptions): string;
|
|
11338
|
+
|
|
10645
11339
|
/**
|
|
10646
11340
|
* A pressable two-state button — like a checkbox styled as a button.
|
|
10647
11341
|
*
|
|
@@ -11598,6 +12292,41 @@ export declare interface UseClipboardResult {
|
|
|
11598
12292
|
reset: () => void;
|
|
11599
12293
|
}
|
|
11600
12294
|
|
|
12295
|
+
/**
|
|
12296
|
+
* Counts down the time left on a window that started at a known instant.
|
|
12297
|
+
*
|
|
12298
|
+
* Written around a timestamp rather than a decrementing counter on purpose: the
|
|
12299
|
+
* remaining time is recomputed from `Date.now()` on every tick, so a throttled
|
|
12300
|
+
* background tab, a slow frame or a `setInterval` that drifts cannot make the
|
|
12301
|
+
* countdown disagree with the clock. Remounting recovers the correct value too,
|
|
12302
|
+
* which a counter held in state cannot do.
|
|
12303
|
+
*
|
|
12304
|
+
* The interval stops once it reaches zero instead of ticking forever behind a
|
|
12305
|
+
* clamp.
|
|
12306
|
+
*
|
|
12307
|
+
* @param durationMs - Length of the window.
|
|
12308
|
+
* @param startedAt - Epoch ms the window opened (`Date.now()` when it started).
|
|
12309
|
+
* @param options - Tick cadence.
|
|
12310
|
+
* @returns Milliseconds remaining, never below `0`.
|
|
12311
|
+
*
|
|
12312
|
+
* @example
|
|
12313
|
+
* const remaining = useCountdown(60_000, lastSentAt);
|
|
12314
|
+
*
|
|
12315
|
+
* <button disabled={remaining > 0}>
|
|
12316
|
+
* {remaining > 0 ? `Reenviar em ${Math.ceil(remaining / 1000)}s` : "Reenviar código"}
|
|
12317
|
+
* </button>
|
|
12318
|
+
*/
|
|
12319
|
+
export declare function useCountdown(durationMs: number, startedAt: number, options?: UseCountdownOptions): number;
|
|
12320
|
+
|
|
12321
|
+
/** Options for {@link useCountdown}. */
|
|
12322
|
+
export declare interface UseCountdownOptions {
|
|
12323
|
+
/**
|
|
12324
|
+
* How often the remaining time is recomputed, in ms. Default `1000`, which
|
|
12325
|
+
* suits a "try again in 3s" label; drop it to ~50 to drive a progress bar.
|
|
12326
|
+
*/
|
|
12327
|
+
tickMs?: number;
|
|
12328
|
+
}
|
|
12329
|
+
|
|
11601
12330
|
/**
|
|
11602
12331
|
* Numeric counter clamped to an optional `[min, max]` range.
|
|
11603
12332
|
*
|
|
@@ -11712,6 +12441,31 @@ export declare function useDelete<T>(resource: string, options?: UseDeleteOption
|
|
|
11712
12441
|
/** Options for the delete mutation (mutationFn + onSuccess are provided). */
|
|
11713
12442
|
export declare type UseDeleteOptions<T> = Omit<UseMutationOptions<T, Error, string | number>, "mutationFn">;
|
|
11714
12443
|
|
|
12444
|
+
/**
|
|
12445
|
+
* {@link describeApiError} with its fixed sentences resolved through the active
|
|
12446
|
+
* `I18nProvider`.
|
|
12447
|
+
*
|
|
12448
|
+
* The funnel is not duplicated — this hook only supplies the strings and calls
|
|
12449
|
+
* the pure function. Which is also why both exist: the pure one runs in an
|
|
12450
|
+
* interceptor or a logger, where there is no React tree to read a context from,
|
|
12451
|
+
* and this one runs in a component without every caller passing translations
|
|
12452
|
+
* down by hand.
|
|
12453
|
+
*
|
|
12454
|
+
* Works with no provider at all: i18n is opt-in in this SDK, so a missing
|
|
12455
|
+
* provider — or a catalog that never defined `tempest.error.offline` — falls
|
|
12456
|
+
* back to the pt-BR default rather than crashing or printing the raw key.
|
|
12457
|
+
*
|
|
12458
|
+
* @example
|
|
12459
|
+
* const describe = useDescribeApiError();
|
|
12460
|
+
* const { mutate } = useMutation({
|
|
12461
|
+
* mutationFn: save,
|
|
12462
|
+
* onError: (error) => toast(describe(error, t("orders.saveFailed"))),
|
|
12463
|
+
* });
|
|
12464
|
+
*
|
|
12465
|
+
* @returns A stable `(error, fallback) => string` function.
|
|
12466
|
+
*/
|
|
12467
|
+
export declare function useDescribeApiError(): (error: unknown, fallback: string) => string;
|
|
12468
|
+
|
|
11715
12469
|
/**
|
|
11716
12470
|
* Manage open/closed boolean state with stable `open`/`close`/`toggle` handlers.
|
|
11717
12471
|
*
|
|
@@ -12011,6 +12765,40 @@ export declare interface UseKeyboardShortcutOptions {
|
|
|
12011
12765
|
ignoreInput?: boolean;
|
|
12012
12766
|
}
|
|
12013
12767
|
|
|
12768
|
+
/**
|
|
12769
|
+
* Keeps a ref pointing at the most recent value it was given.
|
|
12770
|
+
*
|
|
12771
|
+
* The escape hatch for reading fresh state inside something that must not be
|
|
12772
|
+
* re-created when that state changes: an interval, a subscription, an event
|
|
12773
|
+
* listener registered once on mount. Listing the value in the effect's
|
|
12774
|
+
* dependencies would tear the effect down and set it back up on every change;
|
|
12775
|
+
* omitting it captures the value from the render that created the closure and
|
|
12776
|
+
* never sees another. The ref is neither — a stable object whose `current` is
|
|
12777
|
+
* always current.
|
|
12778
|
+
*
|
|
12779
|
+
* The assignment happens **during render**, for the same reason
|
|
12780
|
+
* {@link useStableCallback} does it: moving it into an effect opens a
|
|
12781
|
+
* one-commit staleness window, where an effect declared earlier in the same
|
|
12782
|
+
* commit reads the previous render's value.
|
|
12783
|
+
*
|
|
12784
|
+
* Reach for {@link useStableCallback} instead when the value is a function you
|
|
12785
|
+
* want to *call* — it hands back a callable with a stable identity, rather than
|
|
12786
|
+
* making every call site reach through `.current`.
|
|
12787
|
+
*
|
|
12788
|
+
* @typeParam T - The tracked value.
|
|
12789
|
+
* @param value - The value to track. Written on every render.
|
|
12790
|
+
* @returns A stable ref whose `current` holds the latest `value`.
|
|
12791
|
+
*
|
|
12792
|
+
* @example
|
|
12793
|
+
* const optionsRef = useLatestRef(options);
|
|
12794
|
+
*
|
|
12795
|
+
* useEffect(() => {
|
|
12796
|
+
* const id = setInterval(() => poll(optionsRef.current), 5_000);
|
|
12797
|
+
* return () => clearInterval(id);
|
|
12798
|
+
* }, []); // the interval survives every options change, and still reads the latest
|
|
12799
|
+
*/
|
|
12800
|
+
export declare function useLatestRef<T>(value: T): RefObject<T>;
|
|
12801
|
+
|
|
12014
12802
|
/**
|
|
12015
12803
|
* Query a paginated list of a resource through the active {@link useDataProvider}.
|
|
12016
12804
|
*
|
|
@@ -12609,6 +13397,18 @@ export declare interface UseOnlineOptions {
|
|
|
12609
13397
|
timeoutMs?: number;
|
|
12610
13398
|
}
|
|
12611
13399
|
|
|
13400
|
+
/**
|
|
13401
|
+
* Access translation helpers when there may be no {@link I18nProvider} above.
|
|
13402
|
+
*
|
|
13403
|
+
* Returns `null` instead of throwing, which is what a piece of the SDK needs
|
|
13404
|
+
* when it wants to be translated where a catalog exists and still work where one
|
|
13405
|
+
* does not — i18n is opt-in in this SDK, and a helper that demanded a provider
|
|
13406
|
+
* would turn "you did not configure translations" into a crash.
|
|
13407
|
+
*
|
|
13408
|
+
* @returns The context value, or `null` outside a provider.
|
|
13409
|
+
*/
|
|
13410
|
+
export declare function useOptionalI18n(): I18nContextValue | null;
|
|
13411
|
+
|
|
12612
13412
|
/**
|
|
12613
13413
|
* Offset-pagination hook over TanStack Query for the fastapi-pagination /
|
|
12614
13414
|
* Tempest envelope (`{ items, total, page, size, pages }`).
|
|
@@ -13187,6 +13987,30 @@ export declare interface UseSetResult<T> {
|
|
|
13187
13987
|
size: number;
|
|
13188
13988
|
}
|
|
13189
13989
|
|
|
13990
|
+
/**
|
|
13991
|
+
* Component-scoped {@link createSfxPool}, with the lifecycle wired up.
|
|
13992
|
+
*
|
|
13993
|
+
* The pool is created once — through a lazy `useState` initializer, so no
|
|
13994
|
+
* element is allocated on a render that gets discarded — and disposed on
|
|
13995
|
+
* unmount, so its elements do not outlive the screen that owns them.
|
|
13996
|
+
*
|
|
13997
|
+
* `volume` is tracked separately: changing it calls `setVolume` on the existing
|
|
13998
|
+
* pool rather than rebuilding it, which would throw away every clip the user
|
|
13999
|
+
* has already downloaded — exactly the cost the pool exists to avoid.
|
|
14000
|
+
* `baseUrl`, `voices` and `maxSources` are read once, at creation.
|
|
14001
|
+
*
|
|
14002
|
+
* @param options - Passed through to {@link createSfxPool}.
|
|
14003
|
+
* @returns A stable pool handle.
|
|
14004
|
+
*
|
|
14005
|
+
* @example
|
|
14006
|
+
* const sfx = useSfxPool({ volume: settings.sfxVolume / 100, baseUrl: import.meta.env.BASE_URL });
|
|
14007
|
+
*
|
|
14008
|
+
* useEffect(() => { sfx.preload(["sfx/select.mp3", "sfx/back.mp3"]); }, [sfx]);
|
|
14009
|
+
*
|
|
14010
|
+
* <button onClick={() => sfx.play("sfx/select.mp3")}>Confirmar</button>
|
|
14011
|
+
*/
|
|
14012
|
+
export declare function useSfxPool(options?: SfxPoolOptions): SfxPool;
|
|
14013
|
+
|
|
13190
14014
|
/**
|
|
13191
14015
|
* Drag-to-reorder for a list, with a **keyboard path of equal standing**.
|
|
13192
14016
|
*
|
|
@@ -13537,6 +14361,39 @@ export declare interface UseTorchResult {
|
|
|
13537
14361
|
*/
|
|
13538
14362
|
export declare function useTranslate(): I18nContextValue["t"];
|
|
13539
14363
|
|
|
14364
|
+
/**
|
|
14365
|
+
* Reveals a string one character at a time.
|
|
14366
|
+
*
|
|
14367
|
+
* Changing `text` restarts the reveal. The reset happens during render rather
|
|
14368
|
+
* than in an effect, so the new string never flashes in full for one frame
|
|
14369
|
+
* before the animation takes over.
|
|
14370
|
+
*
|
|
14371
|
+
* Always give the reader a way out: an animation that cannot be skipped is a
|
|
14372
|
+
* tax on anyone re-reading or moving fast, which is what `skip` is for.
|
|
14373
|
+
*
|
|
14374
|
+
* @param text - The full string to reveal. Nullish is treated as empty.
|
|
14375
|
+
* @param speedMs - Delay between characters. `0` or less renders instantly,
|
|
14376
|
+
* which is the hook-safe way to honour `prefers-reduced-motion`.
|
|
14377
|
+
* @returns The revealed prefix, whether it finished, and a `skip` action.
|
|
14378
|
+
*
|
|
14379
|
+
* @example
|
|
14380
|
+
* const reduced = useMediaQuery("(prefers-reduced-motion: reduce)");
|
|
14381
|
+
* const { displayedText, isComplete, skip } = useTypewriter(line, reduced ? 0 : 30);
|
|
14382
|
+
*
|
|
14383
|
+
* return <p onClick={skip}>{displayedText}{isComplete ? "" : "▌"}</p>;
|
|
14384
|
+
*/
|
|
14385
|
+
export declare function useTypewriter(text: string, speedMs: number): UseTypewriterResult;
|
|
14386
|
+
|
|
14387
|
+
/** State returned by {@link useTypewriter}. */
|
|
14388
|
+
export declare interface UseTypewriterResult {
|
|
14389
|
+
/** The prefix of `text` revealed so far. */
|
|
14390
|
+
displayedText: string;
|
|
14391
|
+
/** `true` once the whole string is on screen. */
|
|
14392
|
+
isComplete: boolean;
|
|
14393
|
+
/** Reveal the rest immediately — wire it to a tap or a key press. */
|
|
14394
|
+
skip: () => void;
|
|
14395
|
+
}
|
|
14396
|
+
|
|
13540
14397
|
/**
|
|
13541
14398
|
* Update a record and invalidate both the list and the single-record caches.
|
|
13542
14399
|
*
|