@gearbox-protocol/ui-kit 3.14.0-next.25 → 3.14.0-next.27

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 (80) hide show
  1. package/dist/cjs/components/app-bar/app-bar.cjs +1 -1
  2. package/dist/cjs/components/assets-list-cell/assets-list-cell.cjs +1 -1
  3. package/dist/cjs/components/block-sync/block-sync.cjs +1 -1
  4. package/dist/cjs/components/block-sync-pill/block-sync-pill.cjs +1 -0
  5. package/dist/cjs/components/block-sync-pill/index.cjs +1 -0
  6. package/dist/cjs/components/checkbox/checkbox-labeled.cjs +1 -1
  7. package/dist/cjs/components/client-adapters/styled-rounded-image/styled-rounded-image.cjs +1 -1
  8. package/dist/cjs/components/complex-input/complex-input.cjs +1 -1
  9. package/dist/cjs/components/composites/pool-table/columns.cjs +1 -1
  10. package/dist/cjs/components/composites/tx-preview/confirm/amounts/TransactionConfirmAmountField.cjs +1 -1
  11. package/dist/cjs/components/composites/tx-preview/confirm/preview/OperationPreviewContent.cjs +1 -1
  12. package/dist/cjs/components/composites/tx-preview/operations/OperationsCard.cjs +1 -1
  13. package/dist/cjs/components/composites/tx-preview/operations/PoolDepositView.cjs +1 -1
  14. package/dist/cjs/components/composites/tx-preview/operations/PoolWithdrawView.cjs +1 -1
  15. package/dist/cjs/components/composites/tx-preview/state-change/BalanceChangeGroup.cjs +1 -1
  16. package/dist/cjs/components/composites/tx-preview/state-change/StateChangeCard.cjs +1 -1
  17. package/dist/cjs/components/compound-apy/compound-apy.cjs +1 -1
  18. package/dist/cjs/components/detailed-page-title/detailed-page-title.cjs +1 -1
  19. package/dist/cjs/components/index.cjs +1 -1
  20. package/dist/cjs/components/layout/app-footer/app-footer.cjs +1 -0
  21. package/dist/cjs/components/layout/app-footer/index.cjs +1 -0
  22. package/dist/cjs/components/layout/app-header/app-header.cjs +1 -0
  23. package/dist/cjs/components/layout/app-header/index.cjs +1 -0
  24. package/dist/cjs/components/layout/index.cjs +1 -1
  25. package/dist/cjs/components/loader-guard/loader-guard.cjs +1 -1
  26. package/dist/cjs/components/markdown-viewer/markdown-viewer.cjs +1 -1
  27. package/dist/cjs/components/time-to-liquidation/time-to-liquidation.cjs +1 -1
  28. package/dist/cjs/components/tokens-list-cell/tokens-list-cell.cjs +1 -1
  29. package/dist/cjs/components/with-copy/with-copy.cjs +1 -1
  30. package/dist/cjs/hooks/index.cjs +1 -1
  31. package/dist/cjs/hooks/use-filter.cjs +1 -1
  32. package/dist/cjs/index.cjs +1 -1
  33. package/dist/cjs/locale/en.json.cjs +1 -1
  34. package/dist/esm/components/app-bar/app-bar.js +1 -1
  35. package/dist/esm/components/assets-list-cell/assets-list-cell.js +4 -2
  36. package/dist/esm/components/block-sync/block-sync.js +4 -2
  37. package/dist/esm/components/block-sync-pill/block-sync-pill.js +241 -0
  38. package/dist/esm/components/block-sync-pill/index.js +4 -0
  39. package/dist/esm/components/checkbox/checkbox-labeled.js +2 -0
  40. package/dist/esm/components/client-adapters/styled-rounded-image/styled-rounded-image.js +2 -0
  41. package/dist/esm/components/complex-input/complex-input.js +4 -2
  42. package/dist/esm/components/composites/pool-table/columns.js +20 -18
  43. package/dist/esm/components/composites/tx-preview/confirm/amounts/TransactionConfirmAmountField.js +4 -2
  44. package/dist/esm/components/composites/tx-preview/confirm/preview/OperationPreviewContent.js +4 -2
  45. package/dist/esm/components/composites/tx-preview/operations/OperationsCard.js +4 -2
  46. package/dist/esm/components/composites/tx-preview/operations/PoolDepositView.js +4 -2
  47. package/dist/esm/components/composites/tx-preview/operations/PoolWithdrawView.js +4 -2
  48. package/dist/esm/components/composites/tx-preview/state-change/BalanceChangeGroup.js +4 -2
  49. package/dist/esm/components/composites/tx-preview/state-change/StateChangeCard.js +4 -2
  50. package/dist/esm/components/compound-apy/compound-apy.js +4 -2
  51. package/dist/esm/components/detailed-page-title/detailed-page-title.js +2 -0
  52. package/dist/esm/components/index.js +735 -728
  53. package/dist/esm/components/layout/app-footer/app-footer.js +54 -0
  54. package/dist/esm/components/layout/app-footer/index.js +5 -0
  55. package/dist/esm/components/layout/app-header/app-header.js +98 -0
  56. package/dist/esm/components/layout/app-header/index.js +4 -0
  57. package/dist/esm/components/layout/index.js +32 -27
  58. package/dist/esm/components/loader-guard/loader-guard.js +7 -5
  59. package/dist/esm/components/markdown-viewer/markdown-viewer.js +4 -2
  60. package/dist/esm/components/time-to-liquidation/time-to-liquidation.js +2 -0
  61. package/dist/esm/components/tokens-list-cell/tokens-list-cell.js +4 -2
  62. package/dist/esm/components/with-copy/with-copy.js +4 -2
  63. package/dist/esm/hooks/index.js +50 -47
  64. package/dist/esm/hooks/use-filter.js +63 -29
  65. package/dist/esm/index.js +898 -888
  66. package/dist/esm/locale/en.json.js +3 -0
  67. package/dist/globals.css +1 -1
  68. package/dist/types/components/block-sync-pill/block-sync-pill.d.ts +35 -0
  69. package/dist/types/components/block-sync-pill/index.d.ts +1 -0
  70. package/dist/types/components/index.d.ts +1 -0
  71. package/dist/types/components/layout/app-footer/app-footer.d.ts +62 -0
  72. package/dist/types/components/layout/app-footer/index.d.ts +1 -0
  73. package/dist/types/components/layout/app-header/app-header.d.ts +63 -0
  74. package/dist/types/components/layout/app-header/index.d.ts +1 -0
  75. package/dist/types/components/layout/index.d.ts +2 -0
  76. package/dist/types/hooks/use-filter.d.ts +46 -0
  77. package/dist/types/index.d.ts +2 -0
  78. package/dist/types/locale/en.json.d.ts +4 -0
  79. package/dist/types/types/footer.d.ts +24 -3
  80. package/package.json +1 -1
@@ -0,0 +1,35 @@
1
+ import { BlockSyncProps } from '../../types/footer';
2
+ import type * as React from "react";
3
+ export interface BlockSyncPillProps extends BlockSyncProps {
4
+ /**
5
+ * Label rendered inside the status pill. Defaults to `Status`.
6
+ */
7
+ statusLabel?: React.ReactNode;
8
+ /**
9
+ * Additional class names applied to the pill wrapper.
10
+ */
11
+ className?: string;
12
+ }
13
+ /**
14
+ * BlockSyncPill — backend-sync status rendered as an {@link AppFooter}-style
15
+ * pill: a thin bordered, rounded badge with a status dot and a label.
16
+ *
17
+ * Reflects the **liveness** of the data-refresh loop rather than raw block age:
18
+ * - **loading** (no successful sync yet): the dot is a pulsing neutral gray;
19
+ * - **synced** (within `syncIntervalMs * staleMultiplier`, no errors): green,
20
+ * pulsing while a refresh is in flight;
21
+ * - **error / stalled**: red.
22
+ *
23
+ * Hovering reveals per-chain block numbers and the local time of the last sync.
24
+ *
25
+ * @example
26
+ * ```tsx
27
+ * <BlockSyncPill
28
+ * blockByChain={blockByChain}
29
+ * explorerAddresses={explorerAddresses}
30
+ * networkById={networkById}
31
+ * syncIntervalMs={300000}
32
+ * />
33
+ * ```
34
+ */
35
+ export declare function BlockSyncPill({ blockByChain, explorerAddresses, networkById, syncIntervalMs, staleMultiplier, statusLabel, className, }: BlockSyncPillProps): React.ReactElement;
@@ -0,0 +1 @@
1
+ export * from './block-sync-pill';
@@ -13,6 +13,7 @@ export * from './avatar';
13
13
  export * from './badge';
14
14
  export * from './base-link';
15
15
  export * from './block-sync';
16
+ export * from './block-sync-pill';
16
17
  export * from './breadcrumbs';
17
18
  export * from './button-checkbox';
18
19
  export * from './buttons';
@@ -0,0 +1,62 @@
1
+ import { BlockSyncProps } from '../../../types/footer';
2
+ import * as React from "react";
3
+ /**
4
+ * A single legal/navigation link rendered in {@link AppFooter}.
5
+ */
6
+ export interface AppFooterLink {
7
+ label: string;
8
+ href: string;
9
+ }
10
+ /**
11
+ * Default footer links used by the Gearbox App (client-v3) shell footer.
12
+ *
13
+ * `Support` points to the Gearbox Discord invite, matching `DISCORD_ADDR`
14
+ * in the app config.
15
+ */
16
+ export declare const DEFAULT_APP_FOOTER_LINKS: ReadonlyArray<AppFooterLink>;
17
+ export interface AppFooterProps extends React.HTMLAttributes<HTMLElement> {
18
+ /**
19
+ * Legal / navigation links rendered on the right side.
20
+ * Defaults to {@link DEFAULT_APP_FOOTER_LINKS}.
21
+ */
22
+ links?: ReadonlyArray<AppFooterLink>;
23
+ /**
24
+ * Copyright node on the left. Defaults to
25
+ * `© Gearbox Protocol, {year}`.
26
+ */
27
+ copyright?: React.ReactNode;
28
+ /**
29
+ * Year used in the default copyright. Defaults to the current year.
30
+ */
31
+ year?: number;
32
+ /**
33
+ * Whether to show the status pill on the far right. Defaults to `true`.
34
+ */
35
+ showStatus?: boolean;
36
+ /**
37
+ * Label rendered inside the status pill. Defaults to `Status`.
38
+ */
39
+ statusLabel?: React.ReactNode;
40
+ /**
41
+ * When provided, the status pill becomes a live network-synchronization
42
+ * indicator ({@link BlockSyncPill}): the dot color reflects the time since
43
+ * the last block update and hovering reveals per-chain block details.
44
+ * Without it, a static green status pill is rendered.
45
+ */
46
+ blockSyncProps?: BlockSyncProps;
47
+ }
48
+ /**
49
+ * AppFooter — minimal, Hyperliquid-style footer used by the Gearbox App
50
+ * (client-v3): one thin line with copyright on the left and legal links plus a
51
+ * status pill on the right.
52
+ *
53
+ * Presentational port of client-v3 `AppFooter`. All dynamic content is
54
+ * controlled through props; defaults reproduce the app exactly.
55
+ *
56
+ * @example
57
+ * ```tsx
58
+ * <AppFooter />
59
+ * <AppFooter links={myLinks} copyright="© Acme, 2026" showStatus={false} />
60
+ * ```
61
+ */
62
+ export declare const AppFooter: React.ForwardRefExoticComponent<AppFooterProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1 @@
1
+ export * from './app-footer';
@@ -0,0 +1,63 @@
1
+ import * as React from "react";
2
+ export interface AppHeaderProps extends React.HTMLAttributes<HTMLElement> {
3
+ /**
4
+ * Home link target used by the default logos. Defaults to `/`.
5
+ */
6
+ homeHref?: string;
7
+ /**
8
+ * Desktop logo block (visible at `lg` and up). Defaults to the full Gearbox
9
+ * wordmark linking to {@link AppHeaderProps.homeHref}.
10
+ */
11
+ desktopLogo?: React.ReactNode;
12
+ /**
13
+ * Mobile logo block (visible below `lg`). Defaults to the Gearbox sign mark
14
+ * linking to {@link AppHeaderProps.homeHref}.
15
+ */
16
+ mobileLogo?: React.ReactNode;
17
+ /**
18
+ * Mobile menu trigger (hamburger dropdown), visible below `lg`.
19
+ */
20
+ mobileMenu?: React.ReactNode;
21
+ /**
22
+ * Center navigation tabs — typically a `TabControl`. Visible at `lg` and up.
23
+ */
24
+ tabs?: React.ReactNode;
25
+ /**
26
+ * Optional actions placed left of the wallet button (e.g. migration button).
27
+ */
28
+ actions?: React.ReactNode;
29
+ /**
30
+ * Wallet / connect button area, rendered on the right.
31
+ */
32
+ wallet?: React.ReactNode;
33
+ /**
34
+ * Optional `data-testid` applied to the left side panel.
35
+ */
36
+ leftTestId?: string;
37
+ /**
38
+ * Optional `data-testid` applied to the center navigation area.
39
+ */
40
+ centerTestId?: string;
41
+ /**
42
+ * Optional `data-testid` applied to the right side panel.
43
+ */
44
+ rightTestId?: string;
45
+ }
46
+ /**
47
+ * AppHeader — three-column top navigation bar used by the **Gearbox App
48
+ * (client-v3)** shell: logo on the left, center `TabControl`, and wallet
49
+ * (plus optional actions) on the right.
50
+ *
51
+ * Presentational port of client-v3 `AppBarView`. Dynamic regions are exposed as
52
+ * slots; the logos default to the exact Gearbox assets used by the app.
53
+ *
54
+ * @example
55
+ * ```tsx
56
+ * <AppHeader
57
+ * mobileMenu={<HamburgerDropdown />}
58
+ * tabs={<TabControl state={tabState} tabs={tabs} showBorder={false} />}
59
+ * wallet={<Button variant="outline">Connect wallet</Button>}
60
+ * />
61
+ * ```
62
+ */
63
+ export declare const AppHeader: React.ForwardRefExoticComponent<AppHeaderProps & React.RefAttributes<HTMLElement>>;
@@ -0,0 +1 @@
1
+ export * from './app-header';
@@ -1,3 +1,5 @@
1
+ export * from './app-footer';
2
+ export * from './app-header';
1
3
  export * from './app-logo';
2
4
  export * from './block';
3
5
  export * from './col';
@@ -23,6 +23,52 @@ export type SortSetterFunction<T> = (field: T, startFromSort?: SortType) => void
23
23
  * Hook for managing sort state
24
24
  */
25
25
  export declare function useSort<T>(initialState?: FilterSortField<T> | null): readonly [FilterSortField<T> | null, SortSetterFunction<T>];
26
+ /**
27
+ * Ordered list of active sort keys. The first entry is the primary sort key,
28
+ * the second is the tie-breaker, and so on. An empty array means "no sort".
29
+ */
30
+ export type MultiSortField<T> = ReadonlyArray<FilterSortField<T>>;
31
+ /** Resolved sort state for a single column inside a {@link MultiSortField}. */
32
+ export interface MultiSortFieldState {
33
+ /** Sort direction for this field, or `undefined` when the field is inactive. */
34
+ sort: SortType | undefined;
35
+ /**
36
+ * 1-based position of the field within the active sort keys, or `undefined`
37
+ * when the field is inactive. Use it to render a priority badge (1, 2, …).
38
+ */
39
+ priority: number | undefined;
40
+ }
41
+ export type MultiSortSetterFunction<T> = (field: T, startFromSort?: SortType) => void;
42
+ /**
43
+ * Resolve the direction and priority of a single field within a multi-sort.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * const { sort, priority } = getSortForFields("type", state);
48
+ * <HeadCell sortDirection={sort} sortPriority={state.length > 1 ? priority : undefined} />
49
+ * ```
50
+ */
51
+ export declare const getSortForFields: <T>(field: T, state: MultiSortField<T> | null) => MultiSortFieldState;
52
+ /**
53
+ * Pure reducer behind {@link useMultiSort}. Each field cycles through three
54
+ * states on successive clicks: `startFromSort` → the opposite direction →
55
+ * removed. Clicking a brand-new field makes it the primary key (existing keys
56
+ * become tie-breakers) and the lowest-priority key is dropped once `maxFields`
57
+ * is reached.
58
+ */
59
+ export declare function nextMultiSortState<T>(prev: MultiSortField<T>, field: T, startFromSort?: SortType, maxFields?: number): MultiSortField<T>;
60
+ export interface UseMultiSortOptions {
61
+ /** Maximum number of simultaneously active sort keys. Defaults to `2`. */
62
+ maxFields?: number;
63
+ }
64
+ /**
65
+ * Hook for managing sort state across multiple fields (e.g. sort by `type`,
66
+ * then by `apy`). Mirrors {@link useSort} but keeps an ordered list of keys.
67
+ */
68
+ export declare function useMultiSort<T>(initialState?: MultiSortField<T> | null, { maxFields }?: UseMultiSortOptions): readonly [MultiSortField<T>, MultiSortSetterFunction<T>, {
69
+ readonly removeSortField: (field: T) => void;
70
+ readonly resetSort: () => void;
71
+ }];
26
72
  interface GeneralRangeFilterState {
27
73
  state: FilterRange | null;
28
74
  }
@@ -14,6 +14,7 @@ export * from './components/avatar';
14
14
  export * from './components/badge';
15
15
  export * from './components/base-link';
16
16
  export * from './components/block-sync';
17
+ export * from './components/block-sync-pill';
17
18
  export * from './components/breadcrumbs';
18
19
  export * from './components/button-checkbox';
19
20
  export * from './components/buttons';
@@ -142,6 +143,7 @@ export * from './configs/variants';
142
143
  export * from './hooks';
143
144
  export type { LocaleKeys } from './locale';
144
145
  export * from './locale';
146
+ export type { BlockSyncProps } from './types/footer';
145
147
  export { EnglishLocale };
146
148
  export * from './test-ids';
147
149
  export * from './utils';
@@ -18,6 +18,10 @@ declare const _default: {
18
18
  "components.footer.built": "Built at ETHGlobal MarketMake hackathon.",
19
19
  "components.footer.version": "Version {value}",
20
20
 
21
+ "components.blockSyncPill.syncError": ", sync error",
22
+ "components.blockSyncPill.syncedAt": ", synced at {time}",
23
+ "components.blockSyncPill.syncing": ", syncing…",
24
+
21
25
  "components.liquidationPrice.check": "Check Area",
22
26
 
23
27
  "components.loading.loading": "Loading",
@@ -3,12 +3,22 @@
3
3
  */
4
4
  export interface LastSyncBlock {
5
5
  block: bigint;
6
+ /** Local wall-clock time (ms) of the last successful sync for this chain. */
6
7
  localTimestamp: number;
7
8
  }
9
+ /**
10
+ * Per-chain sync info: the last synced block plus the live refresh state, so the
11
+ * sync indicator can reflect whether the refresh loop is alive / failing.
12
+ */
13
+ export interface ChainSyncInfo {
14
+ lastSyncBlock: LastSyncBlock;
15
+ /** True while a refresh for this chain is currently in flight. */
16
+ loading?: boolean;
17
+ /** Human-readable error if the last refresh for this chain failed. */
18
+ error?: string;
19
+ }
8
20
  export interface BlockByChain {
9
- [chainId: number]: {
10
- lastSyncBlock: LastSyncBlock;
11
- } | undefined;
21
+ [chainId: number]: ChainSyncInfo | undefined;
12
22
  }
13
23
  export interface ExplorerInfo {
14
24
  url: string;
@@ -24,6 +34,17 @@ export interface BlockSyncProps {
24
34
  blockByChain: BlockByChain | undefined;
25
35
  explorerAddresses: ExplorerAddresses;
26
36
  networkById: NetworkById;
37
+ /**
38
+ * Expected refresh cadence in ms. The indicator is considered stale only after
39
+ * `syncIntervalMs * staleMultiplier`, so a healthy loop never flips to red.
40
+ * Defaults to 5 minutes.
41
+ */
42
+ syncIntervalMs?: number;
43
+ /**
44
+ * Stale-threshold multiplier applied to {@link BlockSyncProps.syncIntervalMs}.
45
+ * Defaults to 2.5 (allows for missed/throttled cycles before flagging stale).
46
+ */
47
+ staleMultiplier?: number;
27
48
  }
28
49
  export interface FooterProps {
29
50
  blockSyncProps?: BlockSyncProps;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gearbox-protocol/ui-kit",
3
- "version": "3.14.0-next.25",
3
+ "version": "3.14.0-next.27",
4
4
  "description": "Internal UI components",
5
5
  "repository": {
6
6
  "type": "git",