@gearbox-protocol/ui-kit 4.0.0-next.13 → 4.0.0-next.15
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/dist/cjs/components/checkbox/checkbox-labeled.cjs +1 -1
- package/dist/cjs/components/client-adapters/styled-rounded-image/styled-rounded-image.cjs +1 -1
- package/dist/cjs/components/index.cjs +1 -1
- package/dist/cjs/components/layout/app-footer/app-footer.cjs +1 -1
- package/dist/cjs/components/sdk-status-pill/constants.cjs +1 -0
- package/dist/cjs/components/sdk-status-pill/index.cjs +1 -0
- package/dist/cjs/components/sdk-status-pill/sdk-status-pill.cjs +1 -0
- package/dist/cjs/components/sdk-status-pill/sdk-status.cjs +1 -0
- package/dist/cjs/components/with-copy/with-copy.cjs +1 -1
- package/dist/cjs/index.cjs +1 -1
- package/dist/cjs/locale/en.json.cjs +1 -1
- package/dist/esm/components/checkbox/checkbox-labeled.js +1 -1
- package/dist/esm/components/client-adapters/styled-rounded-image/styled-rounded-image.js +1 -1
- package/dist/esm/components/index.js +591 -587
- package/dist/esm/components/layout/app-footer/app-footer.js +20 -23
- package/dist/esm/components/sdk-status-pill/constants.js +8 -0
- package/dist/esm/components/sdk-status-pill/index.js +8 -0
- package/dist/esm/components/sdk-status-pill/sdk-status-pill.js +59 -0
- package/dist/esm/components/sdk-status-pill/sdk-status.js +6 -0
- package/dist/esm/components/with-copy/with-copy.js +1 -1
- package/dist/esm/index.js +732 -728
- package/dist/esm/locale/en.json.js +3 -3
- package/dist/globals.css +1 -1
- package/dist/types/components/index.d.ts +1 -1
- package/dist/types/components/layout/app-footer/app-footer.d.ts +9 -15
- package/dist/types/components/sdk-status-pill/constants.d.ts +5 -0
- package/dist/types/components/sdk-status-pill/index.d.ts +3 -0
- package/dist/types/components/sdk-status-pill/sdk-status-pill.d.ts +27 -0
- package/dist/types/components/sdk-status-pill/sdk-status.d.ts +11 -0
- package/dist/types/index.d.ts +1 -2
- package/dist/types/locale/en.json.d.ts +3 -3
- package/dist/types/types/index.d.ts +0 -1
- package/package.json +1 -1
- package/dist/cjs/components/block-sync-pill/block-sync-pill.cjs +0 -1
- package/dist/cjs/components/block-sync-pill/block-sync-status.cjs +0 -1
- package/dist/cjs/components/block-sync-pill/index.cjs +0 -1
- package/dist/cjs/types/footer.cjs +0 -1
- package/dist/esm/components/block-sync-pill/block-sync-pill.js +0 -211
- package/dist/esm/components/block-sync-pill/block-sync-status.js +0 -12
- package/dist/esm/components/block-sync-pill/index.js +0 -4
- package/dist/esm/types/footer.js +0 -1
- package/dist/types/components/block-sync-pill/block-sync-pill.d.ts +0 -35
- package/dist/types/components/block-sync-pill/block-sync-status.d.ts +0 -29
- package/dist/types/components/block-sync-pill/index.d.ts +0 -1
- package/dist/types/types/footer.d.ts +0 -51
|
@@ -7,7 +7,6 @@ export * from './badge';
|
|
|
7
7
|
export * from './base';
|
|
8
8
|
export * from './base-link';
|
|
9
9
|
export * from './base-table';
|
|
10
|
-
export * from './block-sync-pill';
|
|
11
10
|
export * from './breadcrumbs';
|
|
12
11
|
export * from './breakpoint-provider';
|
|
13
12
|
export * from './buttons';
|
|
@@ -56,6 +55,7 @@ export * from './pool-points-indicator';
|
|
|
56
55
|
export * from './rounded-image';
|
|
57
56
|
export * from './rwa-feature';
|
|
58
57
|
export * from './rwa-styles';
|
|
58
|
+
export * from './sdk-status-pill';
|
|
59
59
|
export * from './search-line';
|
|
60
60
|
export * from './segmented-control';
|
|
61
61
|
export * from './select';
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { BlockSyncProps } from '../../../types/footer';
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
/**
|
|
4
3
|
* A single legal/navigation link rendered in {@link AppFooter}.
|
|
@@ -30,20 +29,14 @@ export interface AppFooterProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
30
29
|
*/
|
|
31
30
|
year?: number;
|
|
32
31
|
/**
|
|
33
|
-
*
|
|
32
|
+
* Slot between the copyright and the links — typically a
|
|
33
|
+
* {@link SyncStatusPill}. The footer knows nothing about what goes in it.
|
|
34
|
+
*
|
|
35
|
+
* A slot rather than sync-specific props: the footer used to accept a fixed
|
|
36
|
+
* `blockSyncProps` shape and render its own pill from it, which made every
|
|
37
|
+
* change to the indicator a change to the footer's API.
|
|
34
38
|
*/
|
|
35
|
-
|
|
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;
|
|
39
|
+
status?: React.ReactNode;
|
|
47
40
|
}
|
|
48
41
|
/**
|
|
49
42
|
* AppFooter — minimal, Hyperliquid-style footer used by the Gearbox App
|
|
@@ -56,7 +49,8 @@ export interface AppFooterProps extends React.HTMLAttributes<HTMLElement> {
|
|
|
56
49
|
* @example
|
|
57
50
|
* ```tsx
|
|
58
51
|
* <AppFooter />
|
|
59
|
-
* <AppFooter links={myLinks} copyright="© Acme, 2026"
|
|
52
|
+
* <AppFooter links={myLinks} copyright="© Acme, 2026" />
|
|
53
|
+
* <AppFooter status={<SyncStatusPill {...syncProps} />} />
|
|
60
54
|
* ```
|
|
61
55
|
*/
|
|
62
56
|
export declare const AppFooter: React.ForwardRefExoticComponent<AppFooterProps & React.RefAttributes<HTMLElement>>;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { SdkAttachStatus } from './sdk-status';
|
|
2
|
+
import type * as React from "react";
|
|
3
|
+
export interface SdkStatusPillProps {
|
|
4
|
+
/** Where the SDK is in its attach lifecycle. */
|
|
5
|
+
status: SdkAttachStatus;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* SdkStatusPill — whether the SDK is connected, as one dot in an app footer.
|
|
9
|
+
*
|
|
10
|
+
* Deliberately narrow: it reports the **SDK's attach lifecycle** and nothing
|
|
11
|
+
* else. It is not a data-freshness indicator — it will not go grey because a
|
|
12
|
+
* chain lagged or the backend failed, and it says nothing about what is on
|
|
13
|
+
* screen. Screens surface their own failures.
|
|
14
|
+
*
|
|
15
|
+
* Two constraints, both product decisions:
|
|
16
|
+
*
|
|
17
|
+
* - **The palette is green and muted grey only**, never red or amber. See
|
|
18
|
+
* {@link sdkStatusDotVariant}.
|
|
19
|
+
* - **No visible label**, so the tooltip carries the wording and is mirrored
|
|
20
|
+
* into `aria-label` — a screen reader cannot see the colour.
|
|
21
|
+
*
|
|
22
|
+
* @example
|
|
23
|
+
* ```tsx
|
|
24
|
+
* <AppFooter status={<SdkStatusPill status={attach.status} />} />
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export declare function SdkStatusPill({ status, }: SdkStatusPillProps): React.ReactElement;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Where the SDK is in its attach lifecycle. */
|
|
2
|
+
export type SdkAttachStatus = "loading" | "error" | "ready";
|
|
3
|
+
/** Dot variants this indicator is allowed to use. */
|
|
4
|
+
export type SdkStatusDotVariant = "success" | "default";
|
|
5
|
+
/**
|
|
6
|
+
* The palette rule, as a function rather than a comment: green once the SDK is
|
|
7
|
+
* usable, muted grey otherwise. Never `alert` or `warning` — an alarming dot in
|
|
8
|
+
* permanent view teaches people to ignore it, and the screens surface their own
|
|
9
|
+
* failures. Exported so the rule is pinned by a test rather than by review.
|
|
10
|
+
*/
|
|
11
|
+
export declare function sdkStatusDotVariant(status: SdkAttachStatus): SdkStatusDotVariant;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -9,7 +9,6 @@ export * from './components/assets-list-cell';
|
|
|
9
9
|
export * from './components/badge';
|
|
10
10
|
export * from './components/base-link';
|
|
11
11
|
export * from './components/base-table';
|
|
12
|
-
export * from './components/block-sync-pill';
|
|
13
12
|
export * from './components/breadcrumbs';
|
|
14
13
|
export * from './components/breakpoint-provider';
|
|
15
14
|
export * from './components/buttons';
|
|
@@ -58,6 +57,7 @@ export * from './components/pool-points-indicator';
|
|
|
58
57
|
export * from './components/rounded-image';
|
|
59
58
|
export * from './components/rwa-feature';
|
|
60
59
|
export * from './components/rwa-styles';
|
|
60
|
+
export * from './components/sdk-status-pill';
|
|
61
61
|
export * from './components/search-line';
|
|
62
62
|
export * from './components/segmented-control';
|
|
63
63
|
export * from './components/select';
|
|
@@ -96,7 +96,6 @@ export * from './configs/variants';
|
|
|
96
96
|
export * from './hooks';
|
|
97
97
|
export type { LocaleKeys } from './locale';
|
|
98
98
|
export * from './locale';
|
|
99
|
-
export type { BlockSyncProps } from './types/footer';
|
|
100
99
|
export { EnglishLocale };
|
|
101
100
|
export * from './utils';
|
|
102
101
|
export * from './utils/a11y';
|
|
@@ -20,9 +20,9 @@ declare const _default: {
|
|
|
20
20
|
"components.footer.built": "Built at ETHGlobal MarketMake hackathon.",
|
|
21
21
|
"components.footer.version": "Version {value}",
|
|
22
22
|
|
|
23
|
-
"components.
|
|
24
|
-
"components.
|
|
25
|
-
"components.
|
|
23
|
+
"components.sdkStatus.connecting": "Connecting…",
|
|
24
|
+
"components.sdkStatus.connected": "Connected",
|
|
25
|
+
"components.sdkStatus.disconnected": "Not connected",
|
|
26
26
|
|
|
27
27
|
"components.creditAccountHistory.table.protocol": "Protocol",
|
|
28
28
|
"components.creditAccountHistory.table.operation": "Operation",
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),o=require("react"),E=require("../tooltip/simple-tooltip.cjs");require("../tooltip/tooltip.cjs");const M=require("../typed-intl/index.cjs"),g=require("../../utils/cn.cjs");require("../accordion/accordion.cjs");require("../alert-badge/alert-badge.cjs");require("../alert-dialog/alert-dialog.cjs");require("../alert-modal/alert-modal.cjs");require("@gearbox-protocol/static");require("../buttons/back-button/back-button.cjs");require("../buttons/button/button.cjs");require("../buttons/copy-button/copy-button.cjs");require("../buttons/external-button/external-button.cjs");require("../buttons/filter-button/filter-button.cjs");require("../buttons/navigation-button/navigation-button.cjs");require("@gearbox-protocol/sdk");require("sonner");require("@gearbox-protocol/sdk/common-utils");require("luxon");require("../../utils/z-index.cjs");require("../buttons/tab-button/tab-button.cjs");require("@fortawesome/free-solid-svg-icons");require("../icons/fa-icon.cjs");require("../token-icon/token-icon.cjs");require("../badge/badge.cjs");require("../badge/chip.cjs");require("../base/amount-input/amount-input.cjs");require("../confirm-menu/confirm-menu.cjs");require("react-intl");require("../table/grid-table.cjs");require("../skeleton/skeleton.cjs");require("../table/table.cjs");require("../token-symbol/token-symbol.cjs");require("../simple-accordion/simple-accordion.cjs");require("../tip-card/tip-card.cjs");require("../typography/typography.cjs");require("../points-icon/points-icon.cjs");require("../vertical-indicator/vertical-indicator.cjs");require("../base/page-title/page-title.cjs");require("../detailed-page-title/detailed-page-title-copy-button.cjs");require("../detailed-page-title/detailed-page-title-explorer-dropdown.cjs");require("../base/details-view/detail-aside/detail-aside-scope.cjs");require("../layout/main-aside-layout/main-aside-layout.cjs");require("../base/details-view/details-view.cjs");require("../fadeout-loading/fadeout-loading.cjs");require("../health-factor/health-factor.cjs");require("@gearbox-protocol/sdk/model");require("../checkbox/checkbox.cjs");require("../checkbox/checkbox-labeled.cjs");require("../select/select.cjs");require("../breakpoint-provider.cjs");require("lightweight-charts");require("../graph/formatters.cjs");require("../graph/graph-view.cjs");require("../base/info-portal/info-portal.cjs");require("../edit-input/edit-input.cjs");require("../slider/slider.cjs");require("../slider/slider-context.cjs");require("../text-button/text-button.cjs");require("../with-title/with-title.cjs");require("react-router-dom");require("../status-elements/status-elements.cjs");require("../client-adapters/styled-dialog-container/styled-dialog-container.cjs");require("../modal/modal.cjs");require("@radix-ui/react-dialog");require("../dialog/dialog-container.cjs");require("../dialog/dialog-content.cjs");require("../dialog/dialog-description.cjs");require("../dialog/dialog-footer.cjs");require("../dialog/dialog-header.cjs");require("../dialog/dialog-title.cjs");require("../dialog/dialog-modal-container.cjs");require("../dialog/dialog-overlay.cjs");require("viem");require("../input/input.cjs");require("../label/label.cjs");require("../simple-dropdown/simple-dropdown.cjs");require("../simple-dropdown/simple-dropdown-menu-item.cjs");require("../base/tabber/tabber.cjs");require("../link/link.cjs");require("../rounded-image/rounded-image.cjs");require("../network-icon/network-indicator.cjs");require("../base-link/base-link.cjs");require("../help-tip/help-tip.cjs");require("../base-table/base-table-line.cjs");require("../navigation-context/navigation-context.cjs");require("../cards/card/card.cjs");require("../checkbox-item/checkbox-item.cjs");require("../client-adapters/styled-button/styled-button.cjs");require("../client-adapters/styled-rounded-image/styled-rounded-image.cjs");require("../composites/tx-preview/confirm/amounts/TransactionConfirmAmountField.cjs");require("../composites/tx-preview/confirm/dialog/constants.cjs");require("../spinner/spinner.cjs");require("../spinner-loader/spinner-loader.cjs");require("../detailed-apy/detailed-apy.cjs");require("../dropdown-menu/dropdown-menu.cjs");require("../dropdown-menu/dropdown-menu-checkbox-item.cjs");require("../dropdown-menu/dropdown-menu-content.cjs");require("../dropdown-menu/dropdown-menu-item.cjs");require("../dropdown-menu/dropdown-menu-label.cjs");require("../dropdown-menu/dropdown-menu-radio-item.cjs");require("../dropdown-menu/dropdown-menu-separator.cjs");require("../dropdown-menu/dropdown-menu-shortcut.cjs");require("../dropdown-menu/dropdown-menu-sub-content.cjs");require("../dropdown-menu/dropdown-menu-sub-trigger.cjs");require("../filter/filter-block.cjs");require("../filter/filter-checkbox-item.cjs");require("../filter/filter-chip.cjs");require("../filter/filter-chips.cjs");require("../filter/filter-dropdown-item.cjs");require("../filter/filter-group.cjs");require("../filter/filter-label.cjs");require("../search-line/search-line.cjs");require("../tabs/tabs.cjs");require("../filter/filter-modal-item.cjs");require("../filter/filter-radio-item.cjs");require("../filter/filter-separator.cjs");require("../filter/variants.cjs");require("../icon-button/icon-button.cjs");require("../layout/app-footer/app-footer.cjs");require("../layout/app-header/app-header.cjs");require("../layout/col/col.cjs");require("../layout/container/container.cjs");require("../layout/grid/grid.cjs");require("../layout/layout/layout.cjs");require("../legal-agreement/legal-agreement-theme.cjs");require("../loader/loader.cjs");require("../loading/loading.cjs");require("../loading-bar/loading-bar.cjs");require("../segmented-control/segmented-control.cjs");require("../separate-line/separate-line.cjs");require("../split-list/split-list.cjs");const R=require("../status-dot/status-dot.cjs");require("../textarea/textarea.cjs");require("../theme-provider.cjs");const U=require("./block-sync-status.cjs"),$=300*1e3,F=2.5;function O({blockByChain:n,explorerAddresses:y,networkById:f,syncIntervalMs:b=$,staleMultiplier:j=F,statusLabel:T="Status",className:_}){const{formatMessage:s}=M.useIntlTyped(),[c,k]=o.useState(Date.now());o.useEffect(()=>{const t=()=>{k(Date.now())},r=window.setInterval(t,1e3);return()=>{clearInterval(r)}},[]);const l=b*j,{state:u,isSyncing:h}=o.useMemo(()=>U.getBlockSyncStatus({blockByChain:n,now:c,staleAfterMs:l}),[n,c,l]),v=u==="error"?"alert":u==="loading"?"default":"success",L=u==="loading"||u==="synced"&&h,a=()=>e.jsxs("span",{className:g.cn("inline-flex items-center gap-1.5 rounded-md border border-border px-2 py-1 text-xs",u==="error"?"text-destructive":"text-muted-foreground",_),children:[e.jsx(R.StatusDot,{variant:v,size:"xs",pulse:L}),T]}),d=(()=>{if(!n)return null;const t=Object.entries(n).filter(r=>!!r[1]);return t.length===0?null:e.jsx("div",{className:"flex flex-col text-left text-xs",children:t.map(([r,N],P)=>{const{lastSyncBlock:p,error:w}=N,q=p?.block||0n,m=p?.localTimestamp,i=y[Number(r)],x=typeof i=="string"?i:i&&typeof i=="object"&&"url"in i?i.url:void 0,D=f[Number(r)]||"Unknown",S=`[${q.toString()}]`,I=P===t.length-1,A=q>0n&&!!m;return e.jsxs("div",{className:g.cn(!I&&"mb-2"),children:[e.jsxs("span",{children:[D," "]}),x&&q>0?e.jsx("a",{href:`${x}/block/${q}`,target:"_blank",rel:"noopener noreferrer",className:"underline hover:text-foreground",children:S}):e.jsx("span",{children:S}),w?e.jsx("span",{className:"text-destructive",children:s({messageId:"components.blockSyncPill.syncError"})}):A?e.jsx("span",{children:s({messageId:"components.blockSyncPill.syncedAt"},{time:new Date(m).toLocaleTimeString()})}):e.jsx("span",{children:s({messageId:"components.blockSyncPill.syncing"})})]},r)})})})();return d?e.jsx(E.SimpleTooltip,{title:a(),children:d}):e.jsx("div",{className:"select-none",children:a()})}exports.BlockSyncPill=O;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});function m({blockByChain:l,now:o,staleAfterMs:a}){const s=l?Object.values(l).filter(t=>!!t):[],i=s.some(t=>!!t.error),r=s.some(t=>!!t.loading),n=s.filter(t=>t.lastSyncBlock.block>0n&&t.lastSyncBlock.localTimestamp).map(t=>t.lastSyncBlock.localTimestamp),c=n.length?Math.min(...n):0,S=c>0&&o-c>a;let e;return i||S?e="error":c===0?e="loading":e="synced",{state:e,isSyncing:r}}exports.getBlockSyncStatus=m;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const l=require("./block-sync-pill.cjs");exports.BlockSyncPill=l.BlockSyncPill;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { jsx as t, jsxs as s } from "react/jsx-runtime";
|
|
2
|
-
import { useState as U, useEffect as j, useMemo as R } from "react";
|
|
3
|
-
import { SimpleTooltip as $ } from "../tooltip/simple-tooltip.js";
|
|
4
|
-
import "../tooltip/tooltip.js";
|
|
5
|
-
import { useIntlTyped as F } from "../typed-intl/index.js";
|
|
6
|
-
import { cn as S } from "../../utils/cn.js";
|
|
7
|
-
import "../accordion/accordion.js";
|
|
8
|
-
import "../alert-badge/alert-badge.js";
|
|
9
|
-
import "../alert-dialog/alert-dialog.js";
|
|
10
|
-
import "../alert-modal/alert-modal.js";
|
|
11
|
-
import "@gearbox-protocol/static";
|
|
12
|
-
import "../buttons/back-button/back-button.js";
|
|
13
|
-
import "../buttons/button/button.js";
|
|
14
|
-
import "../buttons/copy-button/copy-button.js";
|
|
15
|
-
import "../buttons/external-button/external-button.js";
|
|
16
|
-
import "../buttons/filter-button/filter-button.js";
|
|
17
|
-
import "../buttons/navigation-button/navigation-button.js";
|
|
18
|
-
import "@gearbox-protocol/sdk";
|
|
19
|
-
import "sonner";
|
|
20
|
-
import "@gearbox-protocol/sdk/common-utils";
|
|
21
|
-
import "luxon";
|
|
22
|
-
import "../../utils/z-index.js";
|
|
23
|
-
import "../buttons/tab-button/tab-button.js";
|
|
24
|
-
import "@fortawesome/free-solid-svg-icons";
|
|
25
|
-
import "../icons/fa-icon.js";
|
|
26
|
-
import "../token-icon/token-icon.js";
|
|
27
|
-
import "../badge/badge.js";
|
|
28
|
-
import "../badge/chip.js";
|
|
29
|
-
import "../base/amount-input/amount-input.js";
|
|
30
|
-
import "../confirm-menu/confirm-menu.js";
|
|
31
|
-
import "react-intl";
|
|
32
|
-
import "../table/grid-table.js";
|
|
33
|
-
import "../skeleton/skeleton.js";
|
|
34
|
-
import "../table/table.js";
|
|
35
|
-
import "../token-symbol/token-symbol.js";
|
|
36
|
-
import "../simple-accordion/simple-accordion.js";
|
|
37
|
-
import "../tip-card/tip-card.js";
|
|
38
|
-
import "../typography/typography.js";
|
|
39
|
-
import "../points-icon/points-icon.js";
|
|
40
|
-
import "../vertical-indicator/vertical-indicator.js";
|
|
41
|
-
import "../base/page-title/page-title.js";
|
|
42
|
-
import "../detailed-page-title/detailed-page-title-copy-button.js";
|
|
43
|
-
import "../detailed-page-title/detailed-page-title-explorer-dropdown.js";
|
|
44
|
-
import "../base/details-view/detail-aside/detail-aside-scope.js";
|
|
45
|
-
import "../layout/main-aside-layout/main-aside-layout.js";
|
|
46
|
-
import "../base/details-view/details-view.js";
|
|
47
|
-
import "../fadeout-loading/fadeout-loading.js";
|
|
48
|
-
import "../health-factor/health-factor.js";
|
|
49
|
-
import "@gearbox-protocol/sdk/model";
|
|
50
|
-
import "../checkbox/checkbox.js";
|
|
51
|
-
import "../checkbox/checkbox-labeled.js";
|
|
52
|
-
import "../select/select.js";
|
|
53
|
-
import "../breakpoint-provider.js";
|
|
54
|
-
import "lightweight-charts";
|
|
55
|
-
import "../graph/formatters.js";
|
|
56
|
-
import "../graph/graph-view.js";
|
|
57
|
-
import "../base/info-portal/info-portal.js";
|
|
58
|
-
import "../edit-input/edit-input.js";
|
|
59
|
-
import "../slider/slider.js";
|
|
60
|
-
import "../slider/slider-context.js";
|
|
61
|
-
import "../text-button/text-button.js";
|
|
62
|
-
import "../with-title/with-title.js";
|
|
63
|
-
import "react-router-dom";
|
|
64
|
-
import "../status-elements/status-elements.js";
|
|
65
|
-
import "../client-adapters/styled-dialog-container/styled-dialog-container.js";
|
|
66
|
-
import "../modal/modal.js";
|
|
67
|
-
import "@radix-ui/react-dialog";
|
|
68
|
-
import "../dialog/dialog-container.js";
|
|
69
|
-
import "../dialog/dialog-content.js";
|
|
70
|
-
import "../dialog/dialog-description.js";
|
|
71
|
-
import "../dialog/dialog-footer.js";
|
|
72
|
-
import "../dialog/dialog-header.js";
|
|
73
|
-
import "../dialog/dialog-title.js";
|
|
74
|
-
import "../dialog/dialog-modal-container.js";
|
|
75
|
-
import "../dialog/dialog-overlay.js";
|
|
76
|
-
import "viem";
|
|
77
|
-
import "../input/input.js";
|
|
78
|
-
import "../label/label.js";
|
|
79
|
-
import "../simple-dropdown/simple-dropdown.js";
|
|
80
|
-
import "../simple-dropdown/simple-dropdown-menu-item.js";
|
|
81
|
-
import "../base/tabber/tabber.js";
|
|
82
|
-
import "../link/link.js";
|
|
83
|
-
import "../rounded-image/rounded-image.js";
|
|
84
|
-
import "../network-icon/network-indicator.js";
|
|
85
|
-
import "../base-link/base-link.js";
|
|
86
|
-
import "../help-tip/help-tip.js";
|
|
87
|
-
import "../base-table/base-table-line.js";
|
|
88
|
-
import "../navigation-context/navigation-context.js";
|
|
89
|
-
import "../cards/card/card.js";
|
|
90
|
-
import "../checkbox-item/checkbox-item.js";
|
|
91
|
-
import "../client-adapters/styled-button/styled-button.js";
|
|
92
|
-
import "../client-adapters/styled-rounded-image/styled-rounded-image.js";
|
|
93
|
-
import "../composites/tx-preview/confirm/amounts/TransactionConfirmAmountField.js";
|
|
94
|
-
import "../composites/tx-preview/confirm/dialog/constants.js";
|
|
95
|
-
import "../spinner/spinner.js";
|
|
96
|
-
import "../spinner-loader/spinner-loader.js";
|
|
97
|
-
import "../detailed-apy/detailed-apy.js";
|
|
98
|
-
import "../dropdown-menu/dropdown-menu.js";
|
|
99
|
-
import "../dropdown-menu/dropdown-menu-checkbox-item.js";
|
|
100
|
-
import "../dropdown-menu/dropdown-menu-content.js";
|
|
101
|
-
import "../dropdown-menu/dropdown-menu-item.js";
|
|
102
|
-
import "../dropdown-menu/dropdown-menu-label.js";
|
|
103
|
-
import "../dropdown-menu/dropdown-menu-radio-item.js";
|
|
104
|
-
import "../dropdown-menu/dropdown-menu-separator.js";
|
|
105
|
-
import "../dropdown-menu/dropdown-menu-shortcut.js";
|
|
106
|
-
import "../dropdown-menu/dropdown-menu-sub-content.js";
|
|
107
|
-
import "../dropdown-menu/dropdown-menu-sub-trigger.js";
|
|
108
|
-
import "../filter/filter-block.js";
|
|
109
|
-
import "../filter/filter-checkbox-item.js";
|
|
110
|
-
import "../filter/filter-chip.js";
|
|
111
|
-
import "../filter/filter-chips.js";
|
|
112
|
-
import "../filter/filter-dropdown-item.js";
|
|
113
|
-
import "../filter/filter-group.js";
|
|
114
|
-
import "../filter/filter-label.js";
|
|
115
|
-
import "../search-line/search-line.js";
|
|
116
|
-
import "../tabs/tabs.js";
|
|
117
|
-
import "../filter/filter-modal-item.js";
|
|
118
|
-
import "../filter/filter-radio-item.js";
|
|
119
|
-
import "../filter/filter-separator.js";
|
|
120
|
-
import "../filter/variants.js";
|
|
121
|
-
import "../icon-button/icon-button.js";
|
|
122
|
-
import "../layout/app-footer/app-footer.js";
|
|
123
|
-
import "../layout/app-header/app-header.js";
|
|
124
|
-
import "../layout/col/col.js";
|
|
125
|
-
import "../layout/container/container.js";
|
|
126
|
-
import "../layout/grid/grid.js";
|
|
127
|
-
import "../layout/layout/layout.js";
|
|
128
|
-
import "../legal-agreement/legal-agreement-theme.js";
|
|
129
|
-
import "../loader/loader.js";
|
|
130
|
-
import "../loading/loading.js";
|
|
131
|
-
import "../loading-bar/loading-bar.js";
|
|
132
|
-
import "../segmented-control/segmented-control.js";
|
|
133
|
-
import "../separate-line/separate-line.js";
|
|
134
|
-
import "../split-list/split-list.js";
|
|
135
|
-
import { StatusDot as V } from "../status-dot/status-dot.js";
|
|
136
|
-
import "../textarea/textarea.js";
|
|
137
|
-
import "../theme-provider.js";
|
|
138
|
-
import { getBlockSyncStatus as z } from "./block-sync-status.js";
|
|
139
|
-
const C = 300 * 1e3, O = 2.5;
|
|
140
|
-
function ho({
|
|
141
|
-
blockByChain: p,
|
|
142
|
-
explorerAddresses: y,
|
|
143
|
-
networkById: T,
|
|
144
|
-
syncIntervalMs: b = C,
|
|
145
|
-
staleMultiplier: h = O,
|
|
146
|
-
statusLabel: k = "Status",
|
|
147
|
-
className: v
|
|
148
|
-
}) {
|
|
149
|
-
const { formatMessage: n } = F(), [c, L] = U(Date.now());
|
|
150
|
-
j(() => {
|
|
151
|
-
const m = () => {
|
|
152
|
-
L(Date.now());
|
|
153
|
-
}, r = window.setInterval(m, 1e3);
|
|
154
|
-
return () => {
|
|
155
|
-
clearInterval(r);
|
|
156
|
-
};
|
|
157
|
-
}, []);
|
|
158
|
-
const l = b * h, { state: i, isSyncing: N } = R(
|
|
159
|
-
() => z({ blockByChain: p, now: c, staleAfterMs: l }),
|
|
160
|
-
[p, c, l]
|
|
161
|
-
), w = i === "error" ? "alert" : i === "loading" ? "default" : "success", A = i === "loading" || i === "synced" && N, a = () => /* @__PURE__ */ s(
|
|
162
|
-
"span",
|
|
163
|
-
{
|
|
164
|
-
className: S(
|
|
165
|
-
"inline-flex items-center gap-1.5 rounded-md border border-border px-2 py-1 text-xs",
|
|
166
|
-
i === "error" ? "text-destructive" : "text-muted-foreground",
|
|
167
|
-
v
|
|
168
|
-
),
|
|
169
|
-
children: [
|
|
170
|
-
/* @__PURE__ */ t(V, { variant: w, size: "xs", pulse: A }),
|
|
171
|
-
k
|
|
172
|
-
]
|
|
173
|
-
}
|
|
174
|
-
), d = (() => {
|
|
175
|
-
if (!p) return null;
|
|
176
|
-
const m = Object.entries(p).filter(
|
|
177
|
-
(r) => !!r[1]
|
|
178
|
-
);
|
|
179
|
-
return m.length === 0 ? null : /* @__PURE__ */ t("div", { className: "flex flex-col text-left text-xs", children: m.map(([r, E], I) => {
|
|
180
|
-
const { lastSyncBlock: u, error: D } = E, e = u?.block || 0n, f = u?.localTimestamp, o = y[Number(r)], g = typeof o == "string" ? o : o && typeof o == "object" && "url" in o ? o.url : void 0, P = T[Number(r)] || "Unknown", x = `[${e.toString()}]`, _ = I === m.length - 1, M = e > 0n && !!f;
|
|
181
|
-
return /* @__PURE__ */ s("div", { className: S(!_ && "mb-2"), children: [
|
|
182
|
-
/* @__PURE__ */ s("span", { children: [
|
|
183
|
-
P,
|
|
184
|
-
" "
|
|
185
|
-
] }),
|
|
186
|
-
g && e > 0 ? /* @__PURE__ */ t(
|
|
187
|
-
"a",
|
|
188
|
-
{
|
|
189
|
-
href: `${g}/block/${e}`,
|
|
190
|
-
target: "_blank",
|
|
191
|
-
rel: "noopener noreferrer",
|
|
192
|
-
className: "underline hover:text-foreground",
|
|
193
|
-
children: x
|
|
194
|
-
}
|
|
195
|
-
) : /* @__PURE__ */ t("span", { children: x }),
|
|
196
|
-
D ? /* @__PURE__ */ t("span", { className: "text-destructive", children: n({
|
|
197
|
-
messageId: "components.blockSyncPill.syncError"
|
|
198
|
-
}) }) : M ? /* @__PURE__ */ t("span", { children: n(
|
|
199
|
-
{ messageId: "components.blockSyncPill.syncedAt" },
|
|
200
|
-
{ time: new Date(f).toLocaleTimeString() }
|
|
201
|
-
) }) : /* @__PURE__ */ t("span", { children: n({
|
|
202
|
-
messageId: "components.blockSyncPill.syncing"
|
|
203
|
-
}) })
|
|
204
|
-
] }, r);
|
|
205
|
-
}) });
|
|
206
|
-
})();
|
|
207
|
-
return d ? /* @__PURE__ */ t($, { title: a(), children: d }) : /* @__PURE__ */ t("div", { className: "select-none", children: a() });
|
|
208
|
-
}
|
|
209
|
-
export {
|
|
210
|
-
ho as BlockSyncPill
|
|
211
|
-
};
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
function S({
|
|
2
|
-
blockByChain: c,
|
|
3
|
-
now: o,
|
|
4
|
-
staleAfterMs: a
|
|
5
|
-
}) {
|
|
6
|
-
const e = c ? Object.values(c).filter((t) => !!t) : [], i = e.some((t) => !!t.error), r = e.some((t) => !!t.loading), l = e.filter((t) => t.lastSyncBlock.block > 0n && t.lastSyncBlock.localTimestamp).map((t) => t.lastSyncBlock.localTimestamp), n = l.length ? Math.min(...l) : 0, m = n > 0 && o - n > a;
|
|
7
|
-
let s;
|
|
8
|
-
return i || m ? s = "error" : n === 0 ? s = "loading" : s = "synced", { state: s, isSyncing: r };
|
|
9
|
-
}
|
|
10
|
-
export {
|
|
11
|
-
S as getBlockSyncStatus
|
|
12
|
-
};
|
package/dist/esm/types/footer.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
|
|
@@ -1,35 +0,0 @@
|
|
|
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;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { BlockByChain } from '../../types/footer';
|
|
2
|
-
/**
|
|
3
|
-
* Liveness state of the data-refresh loop, derived from per-chain sync info:
|
|
4
|
-
* - `loading` — nothing has successfully synced yet (initial state);
|
|
5
|
-
* - `synced` — at least one chain synced and none are stale/failing;
|
|
6
|
-
* - `error` — a chain reported an error, or the oldest sync is stale.
|
|
7
|
-
*/
|
|
8
|
-
export type BlockSyncState = "loading" | "synced" | "error";
|
|
9
|
-
export interface BlockSyncStatus {
|
|
10
|
-
state: BlockSyncState;
|
|
11
|
-
/** True while any chain has a refresh in flight. */
|
|
12
|
-
isSyncing: boolean;
|
|
13
|
-
}
|
|
14
|
-
export interface GetBlockSyncStatusProps {
|
|
15
|
-
blockByChain: BlockByChain | undefined;
|
|
16
|
-
/** Reference "now" timestamp (ms) used to evaluate staleness. */
|
|
17
|
-
now: number;
|
|
18
|
-
/** Age (ms) after which the oldest sync is considered stale. */
|
|
19
|
-
staleAfterMs: number;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Pure derivation of the {@link BlockSyncState} from chain sync info.
|
|
23
|
-
*
|
|
24
|
-
* A chain counts as "synced" only when it has both a real block (`> 0`) and a
|
|
25
|
-
* local sync timestamp. Staleness is measured against the **oldest** synced
|
|
26
|
-
* chain, so a single lagging chain is enough to flag the whole indicator.
|
|
27
|
-
* Errors take priority over everything else.
|
|
28
|
-
*/
|
|
29
|
-
export declare function getBlockSyncStatus({ blockByChain, now, staleAfterMs, }: GetBlockSyncStatusProps): BlockSyncStatus;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './block-sync-pill';
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Types for Footer component
|
|
3
|
-
*/
|
|
4
|
-
export interface LastSyncBlock {
|
|
5
|
-
block: bigint;
|
|
6
|
-
/** Local wall-clock time (ms) of the last successful sync for this chain. */
|
|
7
|
-
localTimestamp: number;
|
|
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
|
-
}
|
|
20
|
-
export interface BlockByChain {
|
|
21
|
-
[chainId: number]: ChainSyncInfo | undefined;
|
|
22
|
-
}
|
|
23
|
-
export interface ExplorerInfo {
|
|
24
|
-
url: string;
|
|
25
|
-
name?: string;
|
|
26
|
-
}
|
|
27
|
-
export interface ExplorerAddresses {
|
|
28
|
-
[chainId: number]: string | ExplorerInfo;
|
|
29
|
-
}
|
|
30
|
-
export interface NetworkById {
|
|
31
|
-
[chainId: number]: string;
|
|
32
|
-
}
|
|
33
|
-
export interface BlockSyncProps {
|
|
34
|
-
blockByChain: BlockByChain | undefined;
|
|
35
|
-
explorerAddresses: ExplorerAddresses;
|
|
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;
|
|
48
|
-
}
|
|
49
|
-
export interface FooterProps {
|
|
50
|
-
blockSyncProps?: BlockSyncProps;
|
|
51
|
-
}
|