@gearbox-protocol/ui-kit 4.0.0-next.12 → 4.0.0-next.14

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 (36) hide show
  1. package/dist/cjs/components/index.cjs +1 -1
  2. package/dist/cjs/components/layout/app-footer/app-footer.cjs +1 -1
  3. package/dist/cjs/components/sync-status-pill/constants.cjs +1 -0
  4. package/dist/cjs/components/sync-status-pill/get-sync-status.cjs +1 -0
  5. package/dist/cjs/components/sync-status-pill/index.cjs +1 -0
  6. package/dist/cjs/components/sync-status-pill/sync-status-pill.cjs +1 -0
  7. package/dist/cjs/index.cjs +1 -1
  8. package/dist/cjs/locale/en.json.cjs +1 -1
  9. package/dist/esm/components/index.js +586 -581
  10. package/dist/esm/components/layout/app-footer/app-footer.js +20 -23
  11. package/dist/esm/components/sync-status-pill/constants.js +10 -0
  12. package/dist/esm/components/sync-status-pill/get-sync-status.js +78 -0
  13. package/dist/esm/components/sync-status-pill/index.js +9 -0
  14. package/dist/esm/components/sync-status-pill/sync-status-pill.js +137 -0
  15. package/dist/esm/index.js +732 -727
  16. package/dist/esm/locale/en.json.js +8 -3
  17. package/dist/globals.css +1 -1
  18. package/dist/types/components/index.d.ts +1 -1
  19. package/dist/types/components/layout/app-footer/app-footer.d.ts +9 -15
  20. package/dist/types/components/sync-status-pill/constants.d.ts +7 -0
  21. package/dist/types/components/sync-status-pill/get-sync-status.d.ts +100 -0
  22. package/dist/types/components/sync-status-pill/index.d.ts +3 -0
  23. package/dist/types/components/sync-status-pill/sync-status-pill.d.ts +42 -0
  24. package/dist/types/index.d.ts +2 -2
  25. package/dist/types/locale/en.json.d.ts +8 -3
  26. package/dist/types/types/footer.d.ts +1 -45
  27. package/package.json +3 -3
  28. package/dist/cjs/components/block-sync-pill/block-sync-pill.cjs +0 -1
  29. package/dist/cjs/components/block-sync-pill/block-sync-status.cjs +0 -1
  30. package/dist/cjs/components/block-sync-pill/index.cjs +0 -1
  31. package/dist/esm/components/block-sync-pill/block-sync-pill.js +0 -211
  32. package/dist/esm/components/block-sync-pill/block-sync-status.js +0 -12
  33. package/dist/esm/components/block-sync-pill/index.js +0 -4
  34. package/dist/types/components/block-sync-pill/block-sync-pill.d.ts +0 -35
  35. package/dist/types/components/block-sync-pill/block-sync-status.d.ts +0 -29
  36. package/dist/types/components/block-sync-pill/index.d.ts +0 -1
@@ -1,37 +1,34 @@
1
- import { jsx as e, jsxs as a, Fragment as f } from "react/jsx-runtime";
2
- import * as d from "react";
3
- import { BlockSyncPill as x } from "../../block-sync-pill/block-sync-pill.js";
4
- import { cn as h } from "../../../utils/cn.js";
5
- const u = [
1
+ import { jsx as e, jsxs as t, Fragment as p } from "react/jsx-runtime";
2
+ import * as i from "react";
3
+ import { cn as f } from "../../../utils/cn.js";
4
+ const d = [
6
5
  { label: "Docs", href: "https://docs.gearbox.finance" },
7
6
  { label: "Support", href: "https://discord.com/invite/gearbox" },
8
7
  { label: "Terms", href: "https://gearbox.finance/terms" },
9
8
  { label: "Privacy Policy", href: "https://gearbox.finance/privacy" }
10
- ], g = d.forwardRef(
9
+ ], x = i.forwardRef(
11
10
  ({
12
- links: o = u,
11
+ links: o = d,
13
12
  copyright: s,
14
13
  year: l = (/* @__PURE__ */ new Date()).getFullYear(),
15
- showStatus: c = !0,
16
- statusLabel: m = "Status",
17
- blockSyncProps: t,
18
- className: n,
19
- ...i
20
- }, p) => /* @__PURE__ */ e(
14
+ status: a,
15
+ className: c,
16
+ ...n
17
+ }, m) => /* @__PURE__ */ e(
21
18
  "footer",
22
19
  {
23
- ref: p,
24
- className: h(
20
+ ref: m,
21
+ className: f(
25
22
  "border-t border-border/60 px-4 sm:px-6 lg:px-8",
26
- n
23
+ c
27
24
  ),
28
- ...i,
29
- children: /* @__PURE__ */ a("div", { className: "flex flex-wrap items-center justify-center gap-x-4 gap-y-3 py-3 text-xs text-muted-foreground sm:justify-start sm:gap-x-6 sm:gap-y-2", children: [
30
- /* @__PURE__ */ e("span", { className: "order-1", children: s ?? /* @__PURE__ */ a(f, { children: [
25
+ ...n,
26
+ children: /* @__PURE__ */ t("div", { className: "flex flex-wrap items-center justify-center gap-x-4 gap-y-3 py-3 text-xs text-muted-foreground sm:justify-start sm:gap-x-6 sm:gap-y-2", children: [
27
+ /* @__PURE__ */ e("span", { className: "order-1", children: s ?? /* @__PURE__ */ t(p, { children: [
31
28
  "© Gearbox Protocol, ",
32
29
  l
33
30
  ] }) }),
34
- c && t ? /* @__PURE__ */ e("div", { className: "order-2 sm:order-3", children: /* @__PURE__ */ e(x, { ...t, statusLabel: m }) }) : null,
31
+ a ? /* @__PURE__ */ e("div", { className: "order-2 sm:order-3", children: a }) : null,
35
32
  /* @__PURE__ */ e("nav", { className: "order-3 flex w-full flex-wrap items-center justify-center gap-4 sm:order-2 sm:ml-auto sm:w-auto sm:justify-start", children: o.map((r) => /* @__PURE__ */ e(
36
33
  "a",
37
34
  {
@@ -47,8 +44,8 @@ const u = [
47
44
  }
48
45
  )
49
46
  );
50
- g.displayName = "AppFooter";
47
+ x.displayName = "AppFooter";
51
48
  export {
52
- g as AppFooter,
53
- u as DEFAULT_APP_FOOTER_LINKS
49
+ x as AppFooter,
50
+ d as DEFAULT_APP_FOOTER_LINKS
54
51
  };
@@ -0,0 +1,10 @@
1
+ class s {
2
+ static root = "sync-status-pill-root";
3
+ static dot = "sync-status-pill-dot";
4
+ static tooltip = "sync-status-pill-tooltip";
5
+ static headline = "sync-status-pill-headline";
6
+ static chainRow = "sync-status-pill-chain-row";
7
+ }
8
+ export {
9
+ s as SyncStatusPillTest
10
+ };
@@ -0,0 +1,78 @@
1
+ function p({
2
+ onchain: t,
3
+ offchain: e,
4
+ attach: n = "ready",
5
+ now: r,
6
+ staleAfterMs: a
7
+ }) {
8
+ if (n === "loading")
9
+ return { health: "starting", chains: [], syncedAt: void 0 };
10
+ if (n === "error")
11
+ return { health: "none", chains: [], syncedAt: void 0 };
12
+ const i = f({ onchain: t, offchain: e, now: r, staleAfterMs: a });
13
+ if (i.length === 0)
14
+ return { health: "starting", chains: i, syncedAt: void 0 };
15
+ const u = v(i);
16
+ return { health: u, chains: i, syncedAt: y(u, t, e) };
17
+ }
18
+ function f({
19
+ onchain: t,
20
+ offchain: e,
21
+ now: n,
22
+ staleAfterMs: r
23
+ }) {
24
+ const a = d(t.meta), i = d(e.meta);
25
+ return [
26
+ .../* @__PURE__ */ new Set([...a.keys(), ...i.keys()])
27
+ ].map((o) => {
28
+ const c = h(
29
+ a.get(o),
30
+ t.updatedAt,
31
+ n,
32
+ r
33
+ ), s = h(
34
+ i.get(o),
35
+ e.updatedAt,
36
+ n,
37
+ r
38
+ );
39
+ return {
40
+ chainId: o,
41
+ onchain: c,
42
+ offchain: s,
43
+ health: l(c, s)
44
+ };
45
+ });
46
+ }
47
+ function d(t) {
48
+ const e = /* @__PURE__ */ new Map();
49
+ for (const n of t?.chains ?? [])
50
+ e.set(n.chainId, n);
51
+ return e;
52
+ }
53
+ function h(t, e, n, r) {
54
+ return t ? t.status === "error" ? "failed" : !e || n - e > r || n - t.timestamp * 1e3 > r ? "stale" : "ok" : "unknown";
55
+ }
56
+ function l(t, e) {
57
+ return t === "ok" ? "live" : t === "stale" || e === "ok" || e === "stale" ? "cached" : "none";
58
+ }
59
+ function v(t) {
60
+ return t.every((e) => e.health === "none") ? "none" : t.some((e) => e.health === "live") ? "live" : "cached";
61
+ }
62
+ function y(t, e, n) {
63
+ if (t === "live")
64
+ return e.updatedAt || void 0;
65
+ if (t === "cached") {
66
+ const r = [e.updatedAt, n.updatedAt].filter(
67
+ (a) => !!a
68
+ );
69
+ return r.length ? Math.max(...r) : void 0;
70
+ }
71
+ }
72
+ function g(t) {
73
+ return t === "live" ? "success" : "default";
74
+ }
75
+ export {
76
+ p as getSyncStatus,
77
+ g as syncStatusDotVariant
78
+ };
@@ -0,0 +1,9 @@
1
+ import { SyncStatusPillTest as r } from "./constants.js";
2
+ import { getSyncStatus as a, syncStatusDotVariant as s } from "./get-sync-status.js";
3
+ import { SyncStatusPill as n } from "./sync-status-pill.js";
4
+ export {
5
+ n as SyncStatusPill,
6
+ r as SyncStatusPillTest,
7
+ a as getSyncStatus,
8
+ s as syncStatusDotVariant
9
+ };
@@ -0,0 +1,137 @@
1
+ import { jsx as a, jsxs as h } from "react/jsx-runtime";
2
+ import { useMemo as S, useState as y, useEffect as g } from "react";
3
+ import { StatusDot as x } from "../status-dot/status-dot.js";
4
+ import { SimpleTooltip as I } from "../tooltip/simple-tooltip.js";
5
+ import "../tooltip/tooltip.js";
6
+ import { useIntlTyped as v } from "../typed-intl/index.js";
7
+ import "@gearbox-protocol/sdk/common-utils";
8
+ import { useMediaQuery as w } from "../../hooks/use-media-query.js";
9
+ import { SyncStatusPillTest as c } from "./constants.js";
10
+ import { getSyncStatus as $, syncStatusDotVariant as A } from "./get-sync-status.js";
11
+ const E = 6e4 * 2.5, M = 1e3, N = "(hover: none)";
12
+ function F({
13
+ onchain: e,
14
+ offchain: t,
15
+ attach: n,
16
+ isSyncing: i = !1,
17
+ networkById: u
18
+ }) {
19
+ const { formatMessage: s } = v(), d = D(), p = !w(N), o = S(
20
+ () => $({
21
+ onchain: e,
22
+ offchain: t,
23
+ attach: n,
24
+ now: d,
25
+ staleAfterMs: E
26
+ }),
27
+ [e, t, n, d]
28
+ ), l = s({
29
+ messageId: T[o.health]
30
+ }), m = o.syncedAt ? `${l} · ${s(
31
+ { messageId: "components.syncStatus.ago" },
32
+ { age: R(d - o.syncedAt) }
33
+ )}` : l, f = (
34
+ // `<output>` rather than a span with role="status": same implicit live
35
+ // region, and the status is announced without the dot being focusable.
36
+ //
37
+ // The box is `size-6`, not the dot's 6px: a 6px hover/tap target is far
38
+ // under the 24px WCAG 2.5.8 minimum and genuinely hard to hit, while the
39
+ // dot itself has to stay small to keep the footer quiet. So the target is
40
+ // the padding around it.
41
+ //
42
+ // `-m-1.5` keeps that out of the layout in both axes: the box contributes
43
+ // 12px, less than the 16px line beside it, so the footer row keeps its
44
+ // height and the links do not shift.
45
+ /* @__PURE__ */ a(
46
+ "output",
47
+ {
48
+ className: "-m-1.5 flex size-6 cursor-pointer items-center justify-center",
49
+ "data-testid": c.root,
50
+ "aria-label": m,
51
+ children: /* @__PURE__ */ a(
52
+ x,
53
+ {
54
+ variant: A(o.health),
55
+ size: "xs",
56
+ pulse: o.health === "starting" || i,
57
+ "data-testid": c.dot
58
+ }
59
+ )
60
+ }
61
+ )
62
+ );
63
+ return /* @__PURE__ */ a(
64
+ I,
65
+ {
66
+ title: f,
67
+ trigger: p ? "hover" : "click",
68
+ placement: "top",
69
+ maxWidth: "280px",
70
+ children: /* @__PURE__ */ h(
71
+ "div",
72
+ {
73
+ className: "flex flex-col gap-1 text-left text-xs",
74
+ "data-testid": c.tooltip,
75
+ children: [
76
+ /* @__PURE__ */ a("span", { className: "font-medium", "data-testid": c.headline, children: m }),
77
+ o.chains.map((r) => /* @__PURE__ */ a(
78
+ "span",
79
+ {
80
+ className: "text-muted-foreground",
81
+ "data-testid": c.chainRow,
82
+ children: `${u[r.chainId] ?? String(r.chainId)} ${_(r, s)}`
83
+ },
84
+ r.chainId
85
+ ))
86
+ ]
87
+ }
88
+ )
89
+ }
90
+ );
91
+ }
92
+ const T = {
93
+ live: "components.syncStatus.live",
94
+ starting: "components.syncStatus.starting",
95
+ cached: "components.syncStatus.cached",
96
+ none: "components.syncStatus.none"
97
+ };
98
+ function _(e, t) {
99
+ if (e.health === "none")
100
+ return t({ messageId: "components.syncStatus.unavailable" });
101
+ const [n, i, u] = e.health === "live" ? [
102
+ t({ messageId: "components.syncStatus.live" }),
103
+ "offchain",
104
+ e.offchain
105
+ ] : [
106
+ t({ messageId: "components.syncStatus.cached" }),
107
+ "onchain",
108
+ e.onchain
109
+ ], s = b(i, u, t);
110
+ return s ? `${n} · ${s}` : n;
111
+ }
112
+ function b(e, t, n) {
113
+ if (t === "stale")
114
+ return n(
115
+ { messageId: "components.syncStatus.sourceOutdated" },
116
+ { source: e }
117
+ );
118
+ if (t === "failed" || t === "unknown")
119
+ return n(
120
+ { messageId: "components.syncStatus.sourceMissing" },
121
+ { source: e }
122
+ );
123
+ }
124
+ function R(e) {
125
+ const t = Math.max(0, Math.round(e / 1e3));
126
+ return t < 60 ? `${t}s` : t < 3600 ? `${Math.round(t / 60)}m` : `${Math.round(t / 3600)}h`;
127
+ }
128
+ function D() {
129
+ const [e, t] = y(() => Date.now());
130
+ return g(() => {
131
+ const n = window.setInterval(() => t(Date.now()), M);
132
+ return () => window.clearInterval(n);
133
+ }, []), e;
134
+ }
135
+ export {
136
+ F as SyncStatusPill
137
+ };