@trackunit/react-components 3.12.4-alpha-07efa4379b2.0 → 4.0.1

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.
Files changed (75) hide show
  1. package/index.cjs.js +104 -959
  2. package/index.esm.js +102 -952
  3. package/migrations/assets/react-router-components/package.json +23 -0
  4. package/migrations/entry.js.map +1 -0
  5. package/migrations/utils/jsx-utils.js.map +1 -0
  6. package/migrations/utils/move-named-imports.js +409 -0
  7. package/migrations/utils/move-named-imports.js.map +1 -0
  8. package/migrations/utils/package-json-utils.js +73 -0
  9. package/migrations/utils/package-json-utils.js.map +1 -0
  10. package/migrations/v2-0-0/breadcrumb-remove-deprecated-props.js.map +1 -0
  11. package/migrations/v2-0-0/cardheader-onclickclose-to-actions.js.map +1 -0
  12. package/migrations/v2-0-0/iconbutton-add-required-name.js.map +1 -0
  13. package/migrations/v2-0-0/kpi-tooltiplabel-to-wrapper.js.map +1 -0
  14. package/migrations/v2-0-0/notice-tooltiplabel-to-wrapper.js.map +1 -0
  15. package/migrations/v2-0-0/pagination-add-required-titles.js.map +1 -0
  16. package/migrations/v2-0-0/tag-add-removetaglabel.js.map +1 -0
  17. package/migrations/v2-0-0/togglegroup-remove-item-style.js.map +1 -0
  18. package/migrations/v3-0-0/copyabletext-to-text-copybutton.js.map +1 -0
  19. package/migrations/v3-0-0/menulist-rename-to-menucontent.js.map +1 -0
  20. package/migrations/v4-0-0/move-to-router-components.js +71 -0
  21. package/migrations/v4-0-0/move-to-router-components.js.map +1 -0
  22. package/migrations.json +5 -0
  23. package/package.json +6 -7
  24. package/src/components/ExternalLink/ExternalLink.d.ts +2 -2
  25. package/src/index.d.ts +0 -4
  26. package/translation.cjs.js +0 -1
  27. package/translation.esm.js +0 -1
  28. package/translation10.cjs.js +0 -1
  29. package/translation10.esm.js +0 -1
  30. package/translation11.cjs.js +0 -1
  31. package/translation11.esm.js +0 -1
  32. package/translation12.cjs.js +0 -1
  33. package/translation12.esm.js +0 -1
  34. package/translation13.cjs.js +0 -1
  35. package/translation13.esm.js +0 -1
  36. package/translation14.cjs.js +0 -1
  37. package/translation14.esm.js +0 -1
  38. package/translation15.cjs.js +0 -1
  39. package/translation15.esm.js +0 -1
  40. package/translation16.cjs.js +0 -1
  41. package/translation16.esm.js +0 -1
  42. package/translation17.cjs.js +0 -1
  43. package/translation17.esm.js +0 -1
  44. package/translation2.cjs.js +0 -1
  45. package/translation2.esm.js +0 -1
  46. package/translation3.cjs.js +0 -1
  47. package/translation3.esm.js +0 -1
  48. package/translation4.cjs.js +0 -1
  49. package/translation4.esm.js +0 -1
  50. package/translation5.cjs.js +0 -1
  51. package/translation5.esm.js +0 -1
  52. package/translation6.cjs.js +0 -1
  53. package/translation6.esm.js +0 -1
  54. package/translation7.cjs.js +0 -1
  55. package/translation7.esm.js +0 -1
  56. package/translation8.cjs.js +0 -1
  57. package/translation8.esm.js +0 -1
  58. package/translation9.cjs.js +0 -1
  59. package/translation9.esm.js +0 -1
  60. package/src/components/Breadcrumb/Breadcrumb.d.ts +0 -39
  61. package/src/components/Breadcrumb/Breadcrumb.variant.d.ts +0 -45
  62. package/src/components/Breadcrumb/BreadcrumbContainer.d.ts +0 -8
  63. package/src/components/Breadcrumb/BreadcrumbForLargeScreen.d.ts +0 -6
  64. package/src/components/Breadcrumb/BreadcrumbForMediumScreen.d.ts +0 -6
  65. package/src/components/Breadcrumb/BreadcrumbForSmallScreen.d.ts +0 -6
  66. package/src/components/Breadcrumb/BreadcrumbItem.d.ts +0 -6
  67. package/src/components/Breadcrumb/utils/types.d.ts +0 -28
  68. package/src/components/Breadcrumb/utils/useBreadcrumbItemsToRender.d.ts +0 -6
  69. package/src/hooks/persistence/hashFragment.d.ts +0 -70
  70. package/src/hooks/persistence/readPrimitiveSearchParam.d.ts +0 -8
  71. package/src/hooks/persistence/urlIdentity.d.ts +0 -64
  72. package/src/hooks/persistence/usePersistedState.d.ts +0 -117
  73. package/src/hooks/persistence/useSearchParamSync.d.ts +0 -17
  74. package/src/hooks/persistence/useUrlParamSync.d.ts +0 -71
  75. package/src/hooks/useCursorUrlSync.d.ts +0 -23
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "uitklappen",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "uitklappen",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "développer",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "développer",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "laajenna",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "laajenna",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "kibontás",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "kibontás",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "espandi",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "espandi",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -2,7 +2,6 @@
2
2
 
3
3
  var translation = {
4
4
  "breadcrumb.backButton": "Back",
5
- "breadcrumb.expandButton": "utvid",
6
5
  "copyableValue.copyValue": "Copy {{value}}",
7
6
  "copyButton.copied": "Copied!",
8
7
  "copyButton.copy": "Copy",
@@ -1,6 +1,5 @@
1
1
  var translation = {
2
2
  "breadcrumb.backButton": "Back",
3
- "breadcrumb.expandButton": "utvid",
4
3
  "copyableValue.copyValue": "Copy {{value}}",
5
4
  "copyButton.copied": "Copied!",
6
5
  "copyButton.copy": "Copy",
@@ -1,39 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbProps } from "./utils/types";
3
- /**
4
- * The breadcrumb component shows a user's location in a website or application. Breadcrumbs are particularly useful when a large amount of content is organized in a hierarchical manner. They streamline navigation, minimize the steps required to revisit previous pages, and offer contextual insights to the users.
5
- *
6
- * All items except the last are rendered as clickable links. The last item is rendered as plain text representing the current page.
7
- * The component automatically adapts to the screen size: on large screens all items are visible, on medium screens middle items collapse behind an ellipsis button, and on small screens only the current page is shown.
8
- *
9
- * ### When to use
10
- * Use breadcrumbs when deep navigation is available, on apps or pages where users might dive into content and could benefit from a quick way to return to higher levels. Breadcrumbs display the current screen as the final item in the list to make it clear where the user is.
11
- *
12
- * ### When not to use
13
- * Do not use on the first hierarchal level, such as a home page or a main page, as there is no previous step the user can get to.
14
- * Avoid using breadcrumbs to indicate forthcoming steps. For processes with sequential steps, use a wizard flow instead.
15
- *
16
- * @example Basic breadcrumb navigation
17
- * ```tsx
18
- * import { Breadcrumb } from "@trackunit/react-components";
19
- * import { useNavigate } from "@tanstack/react-router";
20
- *
21
- * const AssetDetailBreadcrumb = () => {
22
- * const navigate = useNavigate();
23
- *
24
- * return (
25
- * <Breadcrumb
26
- * breadcrumbItems={[
27
- * { label: "Fleet", to: "/fleet" },
28
- * { label: "Assets", to: "/fleet/assets" },
29
- * { label: "Excavator 001", to: "/fleet/assets/123" },
30
- * ]}
31
- * onClickBack={() => navigate({ to: "/fleet/assets" })}
32
- * />
33
- * );
34
- * };
35
- * ```
36
- * @param {BreadcrumbProps} props - The props for the Breadcrumb component
37
- * @returns {ReactElement} Breadcrumb component
38
- */
39
- export declare const Breadcrumb: ({ className, "data-testid": dataTestId, breadcrumbItems, onClickBack, style, ref, }: BreadcrumbProps) => ReactElement;
@@ -1,45 +0,0 @@
1
- export declare const cvaBreadcrumb: import("cva").CVAComponent<Omit<{
2
- base: string[];
3
- }, "defaultVariants"> & {
4
- variants: unknown;
5
- defaultVariants: Omit<{}, never>;
6
- }, unknown>;
7
- export declare const cvaBreadcrumbItem: import("cva").CVAComponent<Omit<{
8
- base: string[];
9
- }, "defaultVariants"> & {
10
- variants: unknown;
11
- defaultVariants: Omit<{}, never>;
12
- }, unknown>;
13
- export declare const cvaBreadcrumbForLargeScreen: import("cva").CVAComponent<Omit<{
14
- base: string[];
15
- }, "defaultVariants"> & {
16
- variants: unknown;
17
- defaultVariants: Omit<{}, never>;
18
- }, unknown>;
19
- export declare const cvaBreadcrumbForMediumScreen: import("cva").CVAComponent<Omit<{
20
- base: string[];
21
- variants: {
22
- expanded: {
23
- true: string;
24
- false: string;
25
- };
26
- };
27
- defaultVariants: {
28
- expanded: false;
29
- };
30
- }, "defaultVariants"> & {
31
- variants: {
32
- expanded: {
33
- true: string;
34
- false: string;
35
- };
36
- };
37
- defaultVariants: Omit<{}, "expanded"> & {
38
- expanded: false;
39
- };
40
- }, {
41
- expanded: {
42
- true: string;
43
- false: string;
44
- };
45
- }>;
@@ -1,8 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbContainerProps } from "./utils/types";
3
- /**
4
- * BreadcrumbContainer is a helper component that renders the breadcrumb items based on the screen size.
5
- *
6
- * @param {BreadcrumbContainerProps} props - The props for the BreadcrumbContainer component
7
- */
8
- export declare const BreadcrumbContainer: ({ className, "data-testid": dataTestId, breadcrumbItems, style, ref, }: BreadcrumbContainerProps) => ReactElement;
@@ -1,6 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbContainerProps } from "./utils/types";
3
- /**
4
- * BreadcrumbForLargeScreen is a helper component that renders the breadcrumb items for large screens.
5
- */
6
- export declare const BreadcrumbForLargeScreen: ({ "data-testid": dataTestId, breadcrumbItems, className, style, }: BreadcrumbContainerProps) => ReactElement;
@@ -1,6 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbForMediumScreenProps } from "./utils/types";
3
- /**
4
- * BreadcrumbForMediumScreen is a helper component that renders the breadcrumb items for medium screens.
5
- */
6
- export declare const BreadcrumbForMediumScreen: ({ "data-testid": dataTestId, breadcrumbItems, className, style, }: BreadcrumbForMediumScreenProps) => ReactElement;
@@ -1,6 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbContainerProps } from "./utils/types";
3
- /**
4
- * BreadcrumbForSmallScreen is a helper component that renders the breadcrumb items for small screens.
5
- */
6
- export declare const BreadcrumbForSmallScreen: ({ "data-testid": dataTestId, breadcrumbItems, className, style, }: BreadcrumbContainerProps) => ReactElement;
@@ -1,6 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbItemRenderProps } from "./utils/types";
3
- /**
4
- * BreadcrumbItem is a helper component that renders the individual breadcrumb item.
5
- */
6
- export declare const BreadcrumbItem: ({ item, "data-testid": dataTestId, className, style, }: BreadcrumbItemRenderProps) => ReactElement;
@@ -1,28 +0,0 @@
1
- import { MouseEventHandler, ReactElement } from "react";
2
- import { CommonProps } from "../../../common/CommonProps";
3
- import { Refable } from "../../../common/Refable";
4
- import type { Styleable } from "../../../common/Styleable";
5
- export interface BreadcrumbItemProps {
6
- /** The display text for this breadcrumb item. */
7
- label: string;
8
- /** The route path this breadcrumb item links to. */
9
- to: string;
10
- }
11
- export interface BreadcrumbProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
12
- /**
13
- * The ordered list of breadcrumb items representing the navigation hierarchy.
14
- * The last item is rendered as plain text (the current page), all preceding items are rendered as clickable links.
15
- */
16
- breadcrumbItems: Array<BreadcrumbItemProps>;
17
- /**
18
- * Click handler for the back arrow button. Typically navigates to the previous breadcrumb item (second-to-last in the list).
19
- */
20
- onClickBack: MouseEventHandler<HTMLButtonElement>;
21
- }
22
- export interface BreadcrumbContainerProps extends CommonProps, Styleable, Refable<HTMLDivElement> {
23
- breadcrumbItems: Array<ReactElement<BreadcrumbItemProps>>;
24
- }
25
- export type BreadcrumbForMediumScreenProps = BreadcrumbContainerProps;
26
- export interface BreadcrumbItemRenderProps extends CommonProps, Styleable {
27
- item: ReactElement<BreadcrumbItemProps>;
28
- }
@@ -1,6 +0,0 @@
1
- import { ReactElement } from "react";
2
- import { BreadcrumbItemProps } from "./types";
3
- /**
4
- * useBreadcrumbItemsToRender is a custom hook that takes an array of BreadcrumbItemProps and returns an array of React.ReactElement
5
- */
6
- export declare const useBreadcrumbItemsToRender: (breadcrumbItems: Array<BreadcrumbItemProps>) => Array<ReactElement<BreadcrumbItemProps>>;
@@ -1,70 +0,0 @@
1
- /**
2
- * Pure utilities for reading and writing single named entries inside a URL
3
- * fragment (the part after `#`).
4
- *
5
- * # Format contract
6
- *
7
- * The fragment body (after the leading `#`) is treated as a sequence of
8
- * `&`-separated tokens. A token may be:
9
- * - **A named entry** — `<key>=<value>` (the first `=` separates key from
10
- * value; later `=` chars are part of the value).
11
- * - **Foreign content** — anything else (bare scroll anchors like
12
- * `section`, hash routes, third-party data, malformed tokens). Foreign
13
- * tokens are preserved byte-for-byte, in their original positions.
14
- *
15
- * # Single-key ownership
16
- *
17
- * Callers operate on **one** named key per invocation. Every token whose
18
- * key does not match the supplied key is foreign — the utility never
19
- * categorises or rewrites it. This mirrors how `useSearchParamSync`
20
- * treats a single named search param.
21
- *
22
- * # Value-encoding invariant
23
- *
24
- * Values passed to {@link writeHashKey} must not contain `&`, `=`, or `#`.
25
- * The standard producer for this codebase is `useCustomEncoding`, whose
26
- * base64url alphabet (`[A-Za-z0-9_-]`) satisfies the invariant by
27
- * construction. Keys are restricted by the existing persistence-key
28
- * schema (camelCase, ≤15 chars), so they are likewise safe.
29
- *
30
- * # Anchor-scroll caveat
31
- *
32
- * Browsers locate scroll targets by matching the entire fragment string
33
- * against element IDs. Appending a named entry to a fragment containing
34
- * a bare anchor (e.g. `#section` becoming `#section&userTableTp=...`)
35
- * therefore breaks anchor scrolling on that page. This is unavoidable
36
- * for any hash-backed shared state. Consumers that rely on scroll
37
- * anchors should not also persist state to the hash on the same route.
38
- */
39
- /**
40
- * Reads the value of a single named entry from a URL fragment.
41
- *
42
- * @param hash - The fragment string, with or without the leading `#`.
43
- * @param key - The entry key to look up.
44
- * @returns {string | undefined} The raw value (everything after the first
45
- * `=` in the matching token), or `undefined` when the key is absent. An
46
- * entry whose token has no `=` is treated as foreign content and ignored.
47
- */
48
- export declare const readHashKey: (hash: string, key: string) => string | undefined;
49
- /**
50
- * Lists the key of every named entry in a URL fragment, in order of first
51
- * appearance. Foreign tokens (no `=`) are skipped and duplicates collapse.
52
- *
53
- * @param hash - The fragment string, with or without the leading `#`.
54
- * @returns {Array<string>} The distinct entry keys.
55
- */
56
- export declare const listHashKeys: (hash: string) => Array<string>;
57
- /**
58
- * Returns a new fragment string with the named entry written, replaced,
59
- * or removed. Foreign tokens are preserved in their original order; the
60
- * named entry retains its position if it already exists, and is appended
61
- * to the end when newly inserted. Empty tokens (e.g. produced by
62
- * consecutive `&`) are dropped on the way out.
63
- *
64
- * @param hash - The current fragment string, with or without the leading `#`.
65
- * @param key - The entry key to write.
66
- * @param value - The value to set, or `undefined` to remove the entry.
67
- * @returns {string} The new fragment string, including a leading `#` when
68
- * non-empty, or an empty string when the result has no tokens left.
69
- */
70
- export declare const writeHashKey: (hash: string, key: string, value: string | undefined) => string;
@@ -1,8 +0,0 @@
1
- /**
2
- * Reads one search param from a TanStack `useSearch({ strict: false })` result.
3
- *
4
- * The registered route tree often has an empty or closed search schema, so a
5
- * string key cannot index that type. Parsing to a string record keeps the
6
- * lookup valid for every app router.
7
- */
8
- export declare const readPrimitiveSearchParam: (search: unknown, key: string) => string | undefined;
@@ -1,64 +0,0 @@
1
- /**
2
- * Pure utilities for stamping a URL-persisted value with the identity that
3
- * wrote it.
4
- *
5
- * A URL (hash or search param) is shared by every account that uses the same
6
- * browser: it survives login redirects, history and bookmarks, and it takes
7
- * precedence over per-user localStorage when a page loads. Without a stamp
8
- * there is no way to tell "a colleague shared this link" from "the previous
9
- * account on this PC left its layout in the address bar" — and the second
10
- * case silently replaces the current user's saved state (GLU-2396).
11
- *
12
- * The stamp is a short, non-reversible fingerprint of `clientSideUserId`.
13
- * It is not a secret and not a security boundary; it only lets a reader
14
- * recognise a value written by a *different* identity on the same device.
15
- */
16
- import { z } from "zod";
17
- /**
18
- * Wire shape of a stamped URL value: `{ o: <fingerprint>, v: <payload> }`.
19
- * Values written before stamping existed are bare payloads and decode as
20
- * unowned (see {@link unwrapUrlOwner}).
21
- */
22
- declare const stampedUrlValueSchema: z.ZodObject<{
23
- o: z.ZodString;
24
- v: z.ZodUnknown;
25
- }, "strip", z.ZodTypeAny, {
26
- o: string;
27
- v?: unknown;
28
- }, {
29
- o: string;
30
- v?: unknown;
31
- }>;
32
- type StampedUrlValue = z.infer<typeof stampedUrlValueSchema>;
33
- /**
34
- * 32-bit FNV-1a of `identity`, rendered in base36 (≤ 7 chars).
35
- *
36
- * Synchronous and dependency-free so it can run inside a `useState`
37
- * initializer. Collisions are possible in theory but irrelevant here: a
38
- * collision can only make a foreign value look like the reader's own, which
39
- * is today's behaviour for every value.
40
- *
41
- * @param identity - The client-side user id to fingerprint.
42
- * @returns {string} A short stable fingerprint of `identity`.
43
- */
44
- export declare const identityFingerprint: (identity: string) => string;
45
- /**
46
- * Wraps a URL payload with the fingerprint of the identity writing it.
47
- *
48
- * @param value - The payload that would otherwise be encoded into the URL.
49
- * @param owner - Fingerprint of the writing identity (see {@link identityFingerprint}).
50
- * @returns {StampedUrlValue} The payload wrapped in its ownership envelope.
51
- */
52
- export declare const wrapUrlOwner: (value: unknown, owner: string) => StampedUrlValue;
53
- /**
54
- * Splits a decoded URL value into its owner fingerprint and payload.
55
- * Bare (pre-stamping) payloads come back with `owner: undefined`.
56
- *
57
- * @param decoded - The decoded URL value, stamped or bare.
58
- * @returns {{ owner: string | undefined; value: unknown }} The owner fingerprint (if any) and the payload.
59
- */
60
- export declare const unwrapUrlOwner: (decoded: unknown) => {
61
- readonly owner: string | undefined;
62
- readonly value: unknown;
63
- };
64
- export {};
@@ -1,117 +0,0 @@
1
- import { type UrlParamLocation } from "./useUrlParamSync";
2
- /**
3
- * Selects which part of the URL backs the persisted state.
4
- *
5
- * - `"search"` (default): `?<key>=<encoded>`. Subject to the AWS WAF
6
- * managed-rule cap (~5000 bytes) — large states are dropped from the URL.
7
- * - `"hash"`: `#<key>=<encoded>`. Stays on the client, so the cap is
8
- * driven only by browser URL limits.
9
- */
10
- export type UrlPersistenceLocation = UrlParamLocation;
11
- type UsePersistedStateOptions<TState> = {
12
- readonly key: string;
13
- readonly validate: (raw: unknown) => TState | undefined;
14
- readonly toUrlValue?: (state: TState) => string | object | Array<object>;
15
- readonly fromUrlValue?: (decoded: unknown) => unknown;
16
- readonly localStorageEnabled?: boolean;
17
- readonly replace?: boolean;
18
- readonly clientSideUserId?: string;
19
- /**
20
- * When `true` and both URL and localStorage have valid state, the read
21
- * returns a shallow merge `{ ...storage, ...url }` where URL fields take
22
- * precedence and storage fills in fields the URL omits.
23
- *
24
- * Use this when `toUrlValue` deliberately omits some fields from the URL
25
- * (e.g. per-user layout details that shouldn't be shareable) so the
26
- * omitted fields still survive reloads via localStorage.
27
- *
28
- * Default is `false`: URL state fully replaces localStorage state on read.
29
- */
30
- readonly mergeWithStorageOnRead?: boolean;
31
- /**
32
- * Which slot of the URL backs the persisted value. Default `"search"`.
33
- * See {@link UrlPersistenceLocation} for the trade-offs.
34
- */
35
- readonly urlLocation?: UrlPersistenceLocation;
36
- /**
37
- * When `true`, every URL write is stamped with a fingerprint of
38
- * `clientSideUserId` (`{ o: <fingerprint>, v: <payload> }`). Reads are
39
- * unaffected: the URL still wins on load for everyone, so links and
40
- * bookmarks render for whoever opens them.
41
- *
42
- * The stamp exists for the login redirect. The URL is shared by every
43
- * account that signs in from the same browser and `redirectToLogin`
44
- * carries it through to the next account, which is how one account's
45
- * state replaced another's on a shared PC (GLU-2396). At that boundary
46
- * `useStripForeignIdentityHash` drops entries stamped by a different
47
- * identity that has state stored in this browser. Default `false`.
48
- */
49
- readonly stampUrlWithIdentity?: boolean;
50
- };
51
- type UsePersistedStateReturn<TState> = {
52
- readonly initialState: TState | undefined;
53
- /** Writes `state` to localStorage and the URL; each slot skips a value equal to its last write. */
54
- readonly persistState: (state: TState) => void;
55
- /**
56
- * Writes `state` to localStorage only; `undefined` removes the entry.
57
- * Use together with `persistToUrl` when the two writes should not share a
58
- * schedule — e.g. storage immediately, URL debounced.
59
- */
60
- readonly persistToStorage: (state: TState | undefined) => void;
61
- /** Writes `state` to the URL only; `undefined` removes the entry. */
62
- readonly persistToUrl: (state: TState | undefined) => void;
63
- };
64
- /**
65
- * Generic persistence hook that loads state from a URL slot (search param
66
- * or hash fragment, depending on `urlLocation`) with localStorage fallback,
67
- * and writes changes to both.
68
- *
69
- * On mount the hook resolves the initial state as follows:
70
- * - If the URL slot holds a value, decode it and pass through `validate`.
71
- * - If localStorage is enabled, read and validate its value.
72
- * - When `mergeWithStorageOnRead` is `false` (default): URL state wins
73
- * entirely when present, otherwise fall back to localStorage.
74
- * - When `mergeWithStorageOnRead` is `true`: shallow-merge URL fields over
75
- * localStorage so fields stripped by `toUrlValue` survive via storage.
76
- *
77
- * A value that comes only from localStorage is never written to the URL on
78
- * load. Copying it left a layout in history, bookmarks, and login redirects,
79
- * which then replayed an older layout over the saved one (GLU-2396). The URL
80
- * is written when the consumer persists a change.
81
- *
82
- * `persistState` writes to localStorage (`storageSerializer`) and to the URL
83
- * (via `toUrlValue` + encoding).
84
- * Each slot skips a value equal to its last write. The URL side compares what
85
- * would land in the URL (the `toUrlValue` projection and the identity stamp),
86
- * starting from the projection of the hydrated state and the stamp the URL
87
- * carries: echoing `initialState`, or changing only a field the projection
88
- * strips, writes no URL entry, while an equal state persisted after the
89
- * identity resolves rewrites the URL with its stamp. The storage side starts
90
- * from what localStorage held, so a consumer that persists `initialState`
91
- * after opening a link saves that link's state for the account that opened
92
- * it, and a reload of the account's own link writes nothing.
93
- * `persistToStorage` and `persistToUrl` are the same two halves exposed
94
- * separately for consumers that schedule them differently; passing `undefined`
95
- * removes the entry rather than writing an empty value.
96
- *
97
- * The snapshot is re-read when the storage key or the storage/merge options
98
- * change, in the same render, so a write in that commit already sees the
99
- * state for the new key.
100
- *
101
- * @param options - Configuration for the persisted state.
102
- * @param options.key - Unique identifier used for both the URL slot and the localStorage key.
103
- * @param options.validate - Called with the decoded/parsed value; must return `TState` or `undefined`.
104
- * @param options.toUrlValue - Transform applied before URL encoding (default: encode state as-is).
105
- * @param options.fromUrlValue - Transform applied after URL decoding, before validation (default: identity).
106
- * @param options.localStorageEnabled - When `false` localStorage is neither read nor written (default `true`).
107
- * @param options.replace - Forwarded to the underlying URL sync hook.
108
- * @param options.clientSideUserId - The user ID to use for the localStorage key.
109
- * @param options.mergeWithStorageOnRead - Merge URL state on top of localStorage
110
- * state on read (URL wins on shared keys). Use when `toUrlValue` deliberately
111
- * omits fields so they still survive via localStorage. Default `false`.
112
- * @param options.urlLocation - Which URL slot backs the value (`"search"` or `"hash"`). Default `"search"`.
113
- * @param options.stampUrlWithIdentity - Stamp URL writes with the current identity so the login
114
- * redirect can drop entries left by another account on this browser. Default `false`.
115
- */
116
- export declare const usePersistedState: <TState extends object>({ key, validate, toUrlValue, fromUrlValue, localStorageEnabled, replace, clientSideUserId, mergeWithStorageOnRead, urlLocation, stampUrlWithIdentity, }: UsePersistedStateOptions<TState>) => UsePersistedStateReturn<TState>;
117
- export {};
@@ -1,17 +0,0 @@
1
- import { type UseUrlParamSyncOptions, type UseUrlParamSyncReturn } from "./useUrlParamSync";
2
- export { MAX_URL_LENGTH } from "./useUrlParamSync";
3
- type UseSearchParamSyncOptions = Omit<UseUrlParamSyncOptions, "location">;
4
- /**
5
- * Syncs an encoded string value with a URL search parameter via Tanstack Router.
6
- *
7
- * Thin wrapper over {@link useUrlParamSync} with `location: "search"`; see it
8
- * for the write queue, the size guard (`MAX_URL_LENGTH`), and external-change
9
- * detection.
10
- *
11
- * @param options - Configuration for the search param sync.
12
- * @param options.key - The URL search parameter name.
13
- * @param options.enabled - Set to `false` to disable all URL interaction (default `true`).
14
- * @param options.onExternalChange - Called when the param changes externally.
15
- * @param options.replace - `true` to always use `replaceState`.
16
- */
17
- export declare const useSearchParamSync: (options: UseSearchParamSyncOptions) => UseUrlParamSyncReturn;
@@ -1,71 +0,0 @@
1
- /**
2
- * Maximum full URL length after adding one persisted search param before the
3
- * URL write is skipped (localStorage still persists the full state).
4
- *
5
- * Sized to stay safely below the AWS WAF managed-rule default
6
- * `SizeRestrictions_QUERYSTRING` cap of 5000 bytes for the entire
7
- * host + path + query + hash string.
8
- */
9
- export declare const MAX_URL_LENGTH = 5000;
10
- /**
11
- * Maximum length of the URL fragment after adding one persisted entry.
12
- * Oversized new entries are skipped; oversized replacements remove the stale
13
- * entry so localStorage remains authoritative.
14
- *
15
- * The fragment is never sent to the server, so the WAF cap above does not
16
- * apply. 64 KB stays well below typical browser URL limits (Chromium ≳ 100 KB,
17
- * Firefox ≳ 64 KB on the address bar) while leaving generous headroom for any
18
- * realistic table state.
19
- */
20
- export declare const MAX_HASH_LENGTH: number;
21
- /**
22
- * Which part of the URL a persisted value lives in.
23
- *
24
- * - `"search"`: `?<key>=<encoded>`. Subject to the AWS WAF cap
25
- * ({@link MAX_URL_LENGTH}); large states are dropped from the URL.
26
- * - `"hash"`: `#<key>=<encoded>`. Client-only, capped by
27
- * {@link MAX_HASH_LENGTH}.
28
- */
29
- export type UrlParamLocation = "search" | "hash";
30
- export type UseUrlParamSyncOptions = {
31
- readonly key: string;
32
- readonly location: UrlParamLocation;
33
- readonly enabled?: boolean;
34
- readonly onExternalChange?: () => void;
35
- readonly replace?: boolean;
36
- };
37
- export type UseUrlParamSyncReturn = {
38
- /** The raw encoded value currently in the URL slot, or `undefined` when absent or disabled. */
39
- readonly searchValue: string | undefined;
40
- /** Writes `encodedValue` into the URL slot; `undefined` removes the entry. */
41
- readonly updateSearchParam: (encodedValue: string | undefined) => void;
42
- };
43
- /**
44
- * Syncs an encoded string value with a single named entry in the URL — either
45
- * a search param or an entry inside the hash fragment — via Tanstack Router.
46
- *
47
- * Writes go through the application router so other search params and
48
- * foreign fragment content are preserved. Each slot has a size guard
49
- * ({@link MAX_URL_LENGTH} for search, {@link MAX_HASH_LENGTH} for hash); an
50
- * oversized value is dropped from the URL and localStorage stays
51
- * authoritative. External changes to the entry (browser back/forward, a
52
- * pasted link, a foreign router push) fire `onExternalChange`.
53
- *
54
- * Writes are dispatched via a pending-write queue rather than calling
55
- * `navigate` directly. Tanstack Router's `router.state.status === "pending"`
56
- * is common during the first paint of a route (loaders, suspense), and an
57
- * implementation that simply returned in that case lost the write outright.
58
- * `updateSearchParam` stores the latest attempted write and schedules an rAF
59
- * flush; the flush only navigates when the router is idle, and an effect
60
- * retries whenever the router settles. A queued write is dropped on unmount so
61
- * it cannot drain onto the next route.
62
- *
63
- * @param options - Configuration for the URL entry sync.
64
- * @param options.key - The search param name or fragment entry name.
65
- * @param options.location - `"search"` or `"hash"`.
66
- * @param options.enabled - Set to `false` to disable all URL interaction (default `true`).
67
- * @param options.onExternalChange - Called when the entry changes externally.
68
- * @param options.replace - `true` to always use `replaceState`; `false` to always push.
69
- * Default: replace when the entry is being added, push when it already has a value.
70
- */
71
- export declare const useUrlParamSync: ({ key, location: urlLocation, enabled, onExternalChange, replace: replaceOption, }: UseUrlParamSyncOptions) => UseUrlParamSyncReturn;
@@ -1,23 +0,0 @@
1
- type UseCursorUrlSyncOptions = {
2
- readonly paramName?: string;
3
- readonly debounceMs?: number;
4
- };
5
- type UseCursorUrlSyncResult = {
6
- readonly initialCursor: string | undefined;
7
- readonly updateCursor: (cursor: string | undefined) => void;
8
- };
9
- /**
10
- * Reads a cursor from the URL search params on mount and provides a debounced
11
- * updater for writing it back. Uses `replace: true` to avoid polluting browser
12
- * history with every scroll position change.
13
- *
14
- * Wire `initialCursor` into `usePaginationQuery` and `updateCursor` into
15
- * `useBidirectionalScroll`'s `onTopItemChange` callback (mapping index to cursor).
16
- *
17
- * A pending write is dropped whenever a path-changing navigation starts or the
18
- * location has moved on: the write targets `to: "."`, so landing it after the
19
- * user opened a row would replace their destination with the list they came
20
- * from.
21
- */
22
- export declare const useCursorUrlSync: ({ paramName, debounceMs, }?: UseCursorUrlSyncOptions) => UseCursorUrlSyncResult;
23
- export {};