@medialane/ui 0.134.1 → 0.134.3
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/components/coin-guarantees.cjs +124 -0
- package/dist/components/coin-guarantees.cjs.map +1 -0
- package/dist/components/coin-guarantees.d.cts +23 -0
- package/dist/components/coin-guarantees.d.ts +23 -0
- package/dist/components/coin-guarantees.js +100 -0
- package/dist/components/coin-guarantees.js.map +1 -0
- package/dist/components/coin-row.cjs +14 -8
- package/dist/components/coin-row.cjs.map +1 -1
- package/dist/components/coin-row.d.cts +4 -1
- package/dist/components/coin-row.d.ts +4 -1
- package/dist/components/coin-row.js +15 -9
- package/dist/components/coin-row.js.map +1 -1
- package/dist/components/coins-explorer.d.cts +1 -0
- package/dist/components/coins-explorer.d.ts +1 -0
- package/dist/data/coins.cjs +46 -20
- package/dist/data/coins.cjs.map +1 -1
- package/dist/data/coins.d.cts +11 -6
- package/dist/data/coins.d.ts +11 -6
- package/dist/data/coins.js +41 -17
- package/dist/data/coins.js.map +1 -1
- package/dist/data/drop-create-schema.d.cts +2 -2
- package/dist/data/drop-create-schema.d.ts +2 -2
- package/dist/index.cjs +11 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +10 -4
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
"use client";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
var coin_guarantees_exports = {};
|
|
21
|
+
__export(coin_guarantees_exports, {
|
|
22
|
+
CoinGuarantees: () => CoinGuarantees
|
|
23
|
+
});
|
|
24
|
+
module.exports = __toCommonJS(coin_guarantees_exports);
|
|
25
|
+
var import_jsx_runtime = require("react/jsx-runtime");
|
|
26
|
+
var import_lucide_react = require("lucide-react");
|
|
27
|
+
var import_cn = require("../utils/cn.js");
|
|
28
|
+
function whole(raw, decimals) {
|
|
29
|
+
try {
|
|
30
|
+
const units = BigInt(raw);
|
|
31
|
+
if (units <= 0n) return null;
|
|
32
|
+
const v = Number(units) / 10 ** decimals;
|
|
33
|
+
return isFinite(v) && v >= 1 ? v : null;
|
|
34
|
+
} catch {
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const compact = (n) => new Intl.NumberFormat(void 0, { notation: "compact", maximumFractionDigits: 2 }).format(n);
|
|
39
|
+
function Line({
|
|
40
|
+
label,
|
|
41
|
+
value,
|
|
42
|
+
detail,
|
|
43
|
+
href
|
|
44
|
+
}) {
|
|
45
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
46
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-sm font-semibold tabular-nums", children: value }),
|
|
47
|
+
detail && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-muted-foreground", children: detail }),
|
|
48
|
+
href && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_lucide_react.ExternalLink, { className: "h-3 w-3 text-muted-foreground/60" })
|
|
49
|
+
] });
|
|
50
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex items-baseline justify-between gap-3 border-b border-border/40 py-2.5 last:border-b-0", children: [
|
|
51
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-xs text-muted-foreground", children: label }),
|
|
52
|
+
href ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
53
|
+
"a",
|
|
54
|
+
{
|
|
55
|
+
href,
|
|
56
|
+
target: "_blank",
|
|
57
|
+
rel: "noopener noreferrer",
|
|
58
|
+
className: "inline-flex items-baseline gap-1.5 transition-colors hover:text-primary active:opacity-70",
|
|
59
|
+
children: body
|
|
60
|
+
}
|
|
61
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "inline-flex items-baseline gap-1.5", children: body })
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
function CoinGuarantees({
|
|
65
|
+
data,
|
|
66
|
+
isLoading,
|
|
67
|
+
decimals = 18,
|
|
68
|
+
maxTeamAllocationPercent,
|
|
69
|
+
contractUrl,
|
|
70
|
+
liquidityUrl,
|
|
71
|
+
blockUrl,
|
|
72
|
+
className
|
|
73
|
+
}) {
|
|
74
|
+
if (isLoading) {
|
|
75
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: (0, import_cn.cn)("space-y-2.5", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-9 animate-pulse rounded bg-muted-foreground/10" }, i)) });
|
|
76
|
+
}
|
|
77
|
+
if (!data) return null;
|
|
78
|
+
const supply = whole(data.totalSupplyRaw, decimals);
|
|
79
|
+
const allocation = whole(data.teamAllocationRaw, decimals);
|
|
80
|
+
const pct = data.teamAllocationPercent;
|
|
81
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className, children: [
|
|
82
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "mb-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Guaranteed by the contract" }),
|
|
83
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
84
|
+
Line,
|
|
85
|
+
{
|
|
86
|
+
label: "Creator allocation",
|
|
87
|
+
value: pct != null ? `${pct}%` : allocation != null ? compact(allocation) : "\u2014",
|
|
88
|
+
detail: `capped at ${maxTeamAllocationPercent}%`,
|
|
89
|
+
href: contractUrl
|
|
90
|
+
}
|
|
91
|
+
),
|
|
92
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
93
|
+
Line,
|
|
94
|
+
{
|
|
95
|
+
label: "Total supply",
|
|
96
|
+
value: supply != null ? compact(supply) : "\u2014",
|
|
97
|
+
detail: "fixed, cannot be increased",
|
|
98
|
+
href: contractUrl
|
|
99
|
+
}
|
|
100
|
+
),
|
|
101
|
+
data.isLaunched ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
102
|
+
Line,
|
|
103
|
+
{
|
|
104
|
+
label: "Liquidity",
|
|
105
|
+
value: "Locked permanently",
|
|
106
|
+
detail: data.liquidityPositionId ? `position #${data.liquidityPositionId}` : void 0,
|
|
107
|
+
href: liquidityUrl
|
|
108
|
+
}
|
|
109
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Line, { label: "Liquidity", value: "Not launched yet" }),
|
|
110
|
+
data.launchedAtBlock != null && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
111
|
+
Line,
|
|
112
|
+
{
|
|
113
|
+
label: "Launched",
|
|
114
|
+
value: `Block ${data.launchedAtBlock.toLocaleString()}`,
|
|
115
|
+
href: blockUrl
|
|
116
|
+
}
|
|
117
|
+
)
|
|
118
|
+
] });
|
|
119
|
+
}
|
|
120
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
121
|
+
0 && (module.exports = {
|
|
122
|
+
CoinGuarantees
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=coin-guarantees.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-guarantees.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface CoinGuaranteesData {\n isLaunched: boolean;\n launchedAtBlock: number | null;\n totalSupplyRaw: string;\n teamAllocationRaw: string;\n teamAllocationPercent: number | null;\n liquidityPositionId: string | null;\n}\n\nexport interface CoinGuaranteesProps {\n data: CoinGuaranteesData | null;\n isLoading?: boolean;\n decimals?: number;\n maxTeamAllocationPercent: number;\n\n contractUrl?: string;\n liquidityUrl?: string;\n blockUrl?: string;\n className?: string;\n}\n\nfunction whole(raw: string, decimals: number): number | null {\n try {\n const units = BigInt(raw);\n if (units <= 0n) return null;\n const v = Number(units) / 10 ** decimals;\n return isFinite(v) && v >= 1 ? v : null;\n } catch {\n return null;\n }\n}\n\nconst compact = (n: number) =>\n new Intl.NumberFormat(undefined, { notation: \"compact\", maximumFractionDigits: 2 }).format(n);\n\nfunction Line({\n label,\n value,\n detail,\n href,\n}: {\n label: string;\n value: string;\n detail?: string;\n href?: string;\n}) {\n const body = (\n <>\n <span className=\"text-sm font-semibold tabular-nums\">{value}</span>\n {detail && <span className=\"text-xs text-muted-foreground\">{detail}</span>}\n {href && <ExternalLink className=\"h-3 w-3 text-muted-foreground/60\" />}\n </>\n );\n\n return (\n <div className=\"flex items-baseline justify-between gap-3 border-b border-border/40 py-2.5 last:border-b-0\">\n <span className=\"text-xs text-muted-foreground\">{label}</span>\n {href ? (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-baseline gap-1.5 transition-colors hover:text-primary active:opacity-70\"\n >\n {body}\n </a>\n ) : (\n <span className=\"inline-flex items-baseline gap-1.5\">{body}</span>\n )}\n </div>\n );\n}\n\nexport function CoinGuarantees({\n data,\n isLoading,\n decimals = 18,\n maxTeamAllocationPercent,\n contractUrl,\n liquidityUrl,\n blockUrl,\n className,\n}: CoinGuaranteesProps) {\n if (isLoading) {\n return (\n <div className={cn(\"space-y-2.5\", className)}>\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"h-9 animate-pulse rounded bg-muted-foreground/10\" />\n ))}\n </div>\n );\n }\n\n if (!data) return null;\n\n const supply = whole(data.totalSupplyRaw, decimals);\n const allocation = whole(data.teamAllocationRaw, decimals);\n const pct = data.teamAllocationPercent;\n\n return (\n <div className={className}>\n <p className=\"mb-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Guaranteed by the contract\n </p>\n\n <Line\n label=\"Creator allocation\"\n value={pct != null ? `${pct}%` : allocation != null ? compact(allocation) : \"—\"}\n detail={`capped at ${maxTeamAllocationPercent}%`}\n href={contractUrl}\n />\n\n <Line\n label=\"Total supply\"\n value={supply != null ? compact(supply) : \"—\"}\n detail=\"fixed, cannot be increased\"\n href={contractUrl}\n />\n\n {data.isLaunched ? (\n <Line\n label=\"Liquidity\"\n value=\"Locked permanently\"\n detail={data.liquidityPositionId ? `position #${data.liquidityPositionId}` : undefined}\n href={liquidityUrl}\n />\n ) : (\n <Line label=\"Liquidity\" value=\"Not launched yet\" />\n )}\n\n {data.launchedAtBlock != null && (\n <Line\n label=\"Launched\"\n value={`Block ${data.launchedAtBlock.toLocaleString()}`}\n href={blockUrl}\n />\n )}\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAoDI;AAlDJ,0BAA6B;AAC7B,gBAAmB;AAuBnB,SAAS,MAAM,KAAa,UAAiC;AAC3D,MAAI;AACF,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,SAAS,GAAI,QAAO;AACxB,UAAM,IAAI,OAAO,KAAK,IAAI,MAAM;AAChC,WAAO,SAAS,CAAC,KAAK,KAAK,IAAI,IAAI;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,MAAM,UAAU,CAAC,MACf,IAAI,KAAK,aAAa,QAAW,EAAE,UAAU,WAAW,uBAAuB,EAAE,CAAC,EAAE,OAAO,CAAC;AAE9F,SAAS,KAAK;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,OACJ,4EACE;AAAA,gDAAC,UAAK,WAAU,sCAAsC,iBAAM;AAAA,IAC3D,UAAU,4CAAC,UAAK,WAAU,iCAAiC,kBAAO;AAAA,IAClE,QAAQ,4CAAC,oCAAa,WAAU,oCAAmC;AAAA,KACtE;AAGF,SACE,6CAAC,SAAI,WAAU,8FACb;AAAA,gDAAC,UAAK,WAAU,iCAAiC,iBAAM;AAAA,IACtD,OACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,WAAU;AAAA,QAET;AAAA;AAAA,IACH,IAEA,4CAAC,UAAK,WAAU,sCAAsC,gBAAK;AAAA,KAE/D;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,MAAI,WAAW;AACb,WACE,4CAAC,SAAI,eAAW,cAAG,eAAe,SAAS,GACxC,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MACjC,4CAAC,SAAY,WAAU,sDAAb,CAAgE,CAC3E,GACH;AAAA,EAEJ;AAEA,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS,MAAM,KAAK,gBAAgB,QAAQ;AAClD,QAAM,aAAa,MAAM,KAAK,mBAAmB,QAAQ;AACzD,QAAM,MAAM,KAAK;AAEjB,SACE,6CAAC,SAAI,WACH;AAAA,gDAAC,OAAE,WAAU,6EAA4E,wCAEzF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,OAAO,OAAO,GAAG,GAAG,MAAM,cAAc,OAAO,QAAQ,UAAU,IAAI;AAAA,QAC5E,QAAQ,aAAa,wBAAwB;AAAA,QAC7C,MAAM;AAAA;AAAA,IACR;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,UAAU,OAAO,QAAQ,MAAM,IAAI;AAAA,QAC1C,QAAO;AAAA,QACP,MAAM;AAAA;AAAA,IACR;AAAA,IAEC,KAAK,aACJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAM;AAAA,QACN,QAAQ,KAAK,sBAAsB,aAAa,KAAK,mBAAmB,KAAK;AAAA,QAC7E,MAAM;AAAA;AAAA,IACR,IAEA,4CAAC,QAAK,OAAM,aAAY,OAAM,oBAAmB;AAAA,IAGlD,KAAK,mBAAmB,QACvB;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,SAAS,KAAK,gBAAgB,eAAe,CAAC;AAAA,QACrD,MAAM;AAAA;AAAA,IACR;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CoinGuaranteesData {
|
|
4
|
+
isLaunched: boolean;
|
|
5
|
+
launchedAtBlock: number | null;
|
|
6
|
+
totalSupplyRaw: string;
|
|
7
|
+
teamAllocationRaw: string;
|
|
8
|
+
teamAllocationPercent: number | null;
|
|
9
|
+
liquidityPositionId: string | null;
|
|
10
|
+
}
|
|
11
|
+
interface CoinGuaranteesProps {
|
|
12
|
+
data: CoinGuaranteesData | null;
|
|
13
|
+
isLoading?: boolean;
|
|
14
|
+
decimals?: number;
|
|
15
|
+
maxTeamAllocationPercent: number;
|
|
16
|
+
contractUrl?: string;
|
|
17
|
+
liquidityUrl?: string;
|
|
18
|
+
blockUrl?: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
declare function CoinGuarantees({ data, isLoading, decimals, maxTeamAllocationPercent, contractUrl, liquidityUrl, blockUrl, className, }: CoinGuaranteesProps): react_jsx_runtime.JSX.Element | null;
|
|
22
|
+
|
|
23
|
+
export { CoinGuarantees, type CoinGuaranteesData, type CoinGuaranteesProps };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
|
|
3
|
+
interface CoinGuaranteesData {
|
|
4
|
+
isLaunched: boolean;
|
|
5
|
+
launchedAtBlock: number | null;
|
|
6
|
+
totalSupplyRaw: string;
|
|
7
|
+
teamAllocationRaw: string;
|
|
8
|
+
teamAllocationPercent: number | null;
|
|
9
|
+
liquidityPositionId: string | null;
|
|
10
|
+
}
|
|
11
|
+
interface CoinGuaranteesProps {
|
|
12
|
+
data: CoinGuaranteesData | null;
|
|
13
|
+
isLoading?: boolean;
|
|
14
|
+
decimals?: number;
|
|
15
|
+
maxTeamAllocationPercent: number;
|
|
16
|
+
contractUrl?: string;
|
|
17
|
+
liquidityUrl?: string;
|
|
18
|
+
blockUrl?: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
declare function CoinGuarantees({ data, isLoading, decimals, maxTeamAllocationPercent, contractUrl, liquidityUrl, blockUrl, className, }: CoinGuaranteesProps): react_jsx_runtime.JSX.Element | null;
|
|
22
|
+
|
|
23
|
+
export { CoinGuarantees, type CoinGuaranteesData, type CoinGuaranteesProps };
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ExternalLink } from "lucide-react";
|
|
4
|
+
import { cn } from "../utils/cn.js";
|
|
5
|
+
function whole(raw, decimals) {
|
|
6
|
+
try {
|
|
7
|
+
const units = BigInt(raw);
|
|
8
|
+
if (units <= 0n) return null;
|
|
9
|
+
const v = Number(units) / 10 ** decimals;
|
|
10
|
+
return isFinite(v) && v >= 1 ? v : null;
|
|
11
|
+
} catch {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
const compact = (n) => new Intl.NumberFormat(void 0, { notation: "compact", maximumFractionDigits: 2 }).format(n);
|
|
16
|
+
function Line({
|
|
17
|
+
label,
|
|
18
|
+
value,
|
|
19
|
+
detail,
|
|
20
|
+
href
|
|
21
|
+
}) {
|
|
22
|
+
const body = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-semibold tabular-nums", children: value }),
|
|
24
|
+
detail && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: detail }),
|
|
25
|
+
href && /* @__PURE__ */ jsx(ExternalLink, { className: "h-3 w-3 text-muted-foreground/60" })
|
|
26
|
+
] });
|
|
27
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-baseline justify-between gap-3 border-b border-border/40 py-2.5 last:border-b-0", children: [
|
|
28
|
+
/* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: label }),
|
|
29
|
+
href ? /* @__PURE__ */ jsx(
|
|
30
|
+
"a",
|
|
31
|
+
{
|
|
32
|
+
href,
|
|
33
|
+
target: "_blank",
|
|
34
|
+
rel: "noopener noreferrer",
|
|
35
|
+
className: "inline-flex items-baseline gap-1.5 transition-colors hover:text-primary active:opacity-70",
|
|
36
|
+
children: body
|
|
37
|
+
}
|
|
38
|
+
) : /* @__PURE__ */ jsx("span", { className: "inline-flex items-baseline gap-1.5", children: body })
|
|
39
|
+
] });
|
|
40
|
+
}
|
|
41
|
+
function CoinGuarantees({
|
|
42
|
+
data,
|
|
43
|
+
isLoading,
|
|
44
|
+
decimals = 18,
|
|
45
|
+
maxTeamAllocationPercent,
|
|
46
|
+
contractUrl,
|
|
47
|
+
liquidityUrl,
|
|
48
|
+
blockUrl,
|
|
49
|
+
className
|
|
50
|
+
}) {
|
|
51
|
+
if (isLoading) {
|
|
52
|
+
return /* @__PURE__ */ jsx("div", { className: cn("space-y-2.5", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "h-9 animate-pulse rounded bg-muted-foreground/10" }, i)) });
|
|
53
|
+
}
|
|
54
|
+
if (!data) return null;
|
|
55
|
+
const supply = whole(data.totalSupplyRaw, decimals);
|
|
56
|
+
const allocation = whole(data.teamAllocationRaw, decimals);
|
|
57
|
+
const pct = data.teamAllocationPercent;
|
|
58
|
+
return /* @__PURE__ */ jsxs("div", { className, children: [
|
|
59
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground", children: "Guaranteed by the contract" }),
|
|
60
|
+
/* @__PURE__ */ jsx(
|
|
61
|
+
Line,
|
|
62
|
+
{
|
|
63
|
+
label: "Creator allocation",
|
|
64
|
+
value: pct != null ? `${pct}%` : allocation != null ? compact(allocation) : "\u2014",
|
|
65
|
+
detail: `capped at ${maxTeamAllocationPercent}%`,
|
|
66
|
+
href: contractUrl
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsx(
|
|
70
|
+
Line,
|
|
71
|
+
{
|
|
72
|
+
label: "Total supply",
|
|
73
|
+
value: supply != null ? compact(supply) : "\u2014",
|
|
74
|
+
detail: "fixed, cannot be increased",
|
|
75
|
+
href: contractUrl
|
|
76
|
+
}
|
|
77
|
+
),
|
|
78
|
+
data.isLaunched ? /* @__PURE__ */ jsx(
|
|
79
|
+
Line,
|
|
80
|
+
{
|
|
81
|
+
label: "Liquidity",
|
|
82
|
+
value: "Locked permanently",
|
|
83
|
+
detail: data.liquidityPositionId ? `position #${data.liquidityPositionId}` : void 0,
|
|
84
|
+
href: liquidityUrl
|
|
85
|
+
}
|
|
86
|
+
) : /* @__PURE__ */ jsx(Line, { label: "Liquidity", value: "Not launched yet" }),
|
|
87
|
+
data.launchedAtBlock != null && /* @__PURE__ */ jsx(
|
|
88
|
+
Line,
|
|
89
|
+
{
|
|
90
|
+
label: "Launched",
|
|
91
|
+
value: `Block ${data.launchedAtBlock.toLocaleString()}`,
|
|
92
|
+
href: blockUrl
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
] });
|
|
96
|
+
}
|
|
97
|
+
export {
|
|
98
|
+
CoinGuarantees
|
|
99
|
+
};
|
|
100
|
+
//# sourceMappingURL=coin-guarantees.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-guarantees.tsx"],"sourcesContent":["\"use client\";\n\nimport { ExternalLink } from \"lucide-react\";\nimport { cn } from \"../utils/cn.js\";\n\nexport interface CoinGuaranteesData {\n isLaunched: boolean;\n launchedAtBlock: number | null;\n totalSupplyRaw: string;\n teamAllocationRaw: string;\n teamAllocationPercent: number | null;\n liquidityPositionId: string | null;\n}\n\nexport interface CoinGuaranteesProps {\n data: CoinGuaranteesData | null;\n isLoading?: boolean;\n decimals?: number;\n maxTeamAllocationPercent: number;\n\n contractUrl?: string;\n liquidityUrl?: string;\n blockUrl?: string;\n className?: string;\n}\n\nfunction whole(raw: string, decimals: number): number | null {\n try {\n const units = BigInt(raw);\n if (units <= 0n) return null;\n const v = Number(units) / 10 ** decimals;\n return isFinite(v) && v >= 1 ? v : null;\n } catch {\n return null;\n }\n}\n\nconst compact = (n: number) =>\n new Intl.NumberFormat(undefined, { notation: \"compact\", maximumFractionDigits: 2 }).format(n);\n\nfunction Line({\n label,\n value,\n detail,\n href,\n}: {\n label: string;\n value: string;\n detail?: string;\n href?: string;\n}) {\n const body = (\n <>\n <span className=\"text-sm font-semibold tabular-nums\">{value}</span>\n {detail && <span className=\"text-xs text-muted-foreground\">{detail}</span>}\n {href && <ExternalLink className=\"h-3 w-3 text-muted-foreground/60\" />}\n </>\n );\n\n return (\n <div className=\"flex items-baseline justify-between gap-3 border-b border-border/40 py-2.5 last:border-b-0\">\n <span className=\"text-xs text-muted-foreground\">{label}</span>\n {href ? (\n <a\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"inline-flex items-baseline gap-1.5 transition-colors hover:text-primary active:opacity-70\"\n >\n {body}\n </a>\n ) : (\n <span className=\"inline-flex items-baseline gap-1.5\">{body}</span>\n )}\n </div>\n );\n}\n\nexport function CoinGuarantees({\n data,\n isLoading,\n decimals = 18,\n maxTeamAllocationPercent,\n contractUrl,\n liquidityUrl,\n blockUrl,\n className,\n}: CoinGuaranteesProps) {\n if (isLoading) {\n return (\n <div className={cn(\"space-y-2.5\", className)}>\n {Array.from({ length: 4 }).map((_, i) => (\n <div key={i} className=\"h-9 animate-pulse rounded bg-muted-foreground/10\" />\n ))}\n </div>\n );\n }\n\n if (!data) return null;\n\n const supply = whole(data.totalSupplyRaw, decimals);\n const allocation = whole(data.teamAllocationRaw, decimals);\n const pct = data.teamAllocationPercent;\n\n return (\n <div className={className}>\n <p className=\"mb-1 text-2xs font-semibold uppercase tracking-wide text-muted-foreground\">\n Guaranteed by the contract\n </p>\n\n <Line\n label=\"Creator allocation\"\n value={pct != null ? `${pct}%` : allocation != null ? compact(allocation) : \"—\"}\n detail={`capped at ${maxTeamAllocationPercent}%`}\n href={contractUrl}\n />\n\n <Line\n label=\"Total supply\"\n value={supply != null ? compact(supply) : \"—\"}\n detail=\"fixed, cannot be increased\"\n href={contractUrl}\n />\n\n {data.isLaunched ? (\n <Line\n label=\"Liquidity\"\n value=\"Locked permanently\"\n detail={data.liquidityPositionId ? `position #${data.liquidityPositionId}` : undefined}\n href={liquidityUrl}\n />\n ) : (\n <Line label=\"Liquidity\" value=\"Not launched yet\" />\n )}\n\n {data.launchedAtBlock != null && (\n <Line\n label=\"Launched\"\n value={`Block ${data.launchedAtBlock.toLocaleString()}`}\n href={blockUrl}\n />\n )}\n </div>\n );\n}\n"],"mappings":";AAoDI,mBACE,KADF;AAlDJ,SAAS,oBAAoB;AAC7B,SAAS,UAAU;AAuBnB,SAAS,MAAM,KAAa,UAAiC;AAC3D,MAAI;AACF,UAAM,QAAQ,OAAO,GAAG;AACxB,QAAI,SAAS,GAAI,QAAO;AACxB,UAAM,IAAI,OAAO,KAAK,IAAI,MAAM;AAChC,WAAO,SAAS,CAAC,KAAK,KAAK,IAAI,IAAI;AAAA,EACrC,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,MAAM,UAAU,CAAC,MACf,IAAI,KAAK,aAAa,QAAW,EAAE,UAAU,WAAW,uBAAuB,EAAE,CAAC,EAAE,OAAO,CAAC;AAE9F,SAAS,KAAK;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,OACJ,iCACE;AAAA,wBAAC,UAAK,WAAU,sCAAsC,iBAAM;AAAA,IAC3D,UAAU,oBAAC,UAAK,WAAU,iCAAiC,kBAAO;AAAA,IAClE,QAAQ,oBAAC,gBAAa,WAAU,oCAAmC;AAAA,KACtE;AAGF,SACE,qBAAC,SAAI,WAAU,8FACb;AAAA,wBAAC,UAAK,WAAU,iCAAiC,iBAAM;AAAA,IACtD,OACC;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA,QAAO;AAAA,QACP,KAAI;AAAA,QACJ,WAAU;AAAA,QAET;AAAA;AAAA,IACH,IAEA,oBAAC,UAAK,WAAU,sCAAsC,gBAAK;AAAA,KAE/D;AAEJ;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwB;AACtB,MAAI,WAAW;AACb,WACE,oBAAC,SAAI,WAAW,GAAG,eAAe,SAAS,GACxC,gBAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,CAAC,GAAG,MACjC,oBAAC,SAAY,WAAU,sDAAb,CAAgE,CAC3E,GACH;AAAA,EAEJ;AAEA,MAAI,CAAC,KAAM,QAAO;AAElB,QAAM,SAAS,MAAM,KAAK,gBAAgB,QAAQ;AAClD,QAAM,aAAa,MAAM,KAAK,mBAAmB,QAAQ;AACzD,QAAM,MAAM,KAAK;AAEjB,SACE,qBAAC,SAAI,WACH;AAAA,wBAAC,OAAE,WAAU,6EAA4E,wCAEzF;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,OAAO,OAAO,GAAG,GAAG,MAAM,cAAc,OAAO,QAAQ,UAAU,IAAI;AAAA,QAC5E,QAAQ,aAAa,wBAAwB;AAAA,QAC7C,MAAM;AAAA;AAAA,IACR;AAAA,IAEA;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,UAAU,OAAO,QAAQ,MAAM,IAAI;AAAA,QAC1C,QAAO;AAAA,QACP,MAAM;AAAA;AAAA,IACR;AAAA,IAEC,KAAK,aACJ;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAM;AAAA,QACN,QAAQ,KAAK,sBAAsB,aAAa,KAAK,mBAAmB,KAAK;AAAA,QAC7E,MAAM;AAAA;AAAA,IACR,IAEA,oBAAC,QAAK,OAAM,aAAY,OAAM,oBAAmB;AAAA,IAGlD,KAAK,mBAAmB,QACvB;AAAA,MAAC;AAAA;AAAA,QACC,OAAM;AAAA,QACN,OAAO,SAAS,KAAK,gBAAgB,eAAe,CAAC;AAAA,QACrD,MAAM;AAAA;AAAA,IACR;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -49,12 +49,12 @@ function CoinAvatar({ collection, size = 36 }) {
|
|
|
49
49
|
const logoUri = collection.profile?.image ?? collection.image;
|
|
50
50
|
const logo = logoUri ? (0, import_ipfs.ipfsToHttp)(logoUri) : null;
|
|
51
51
|
const initials = (collection.symbol ?? collection.name ?? "?").trim().slice(0, 2).toUpperCase();
|
|
52
|
-
const
|
|
52
|
+
const accent = (0, import_coins.coinAccentToken)(collection.symbol ?? collection.name ?? collection.contractAddress);
|
|
53
53
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
54
54
|
"div",
|
|
55
55
|
{
|
|
56
|
-
className: "relative shrink-0 overflow-hidden rounded-full",
|
|
57
|
-
style: { width: size, height: size
|
|
56
|
+
className: (0, import_cn.cn)("relative shrink-0 overflow-hidden rounded-full", accent),
|
|
57
|
+
style: { width: size, height: size },
|
|
58
58
|
children: logo ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_image.default, { src: logo, alt: "", fill: true, sizes: `${size}px`, className: "object-cover", unoptimized: true }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
59
59
|
"span",
|
|
60
60
|
{
|
|
@@ -66,9 +66,11 @@ function CoinAvatar({ collection, size = 36 }) {
|
|
|
66
66
|
}
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
|
-
function PriceCell({ price, isLoading }) {
|
|
69
|
+
function PriceCell({ price, status, isLoading }) {
|
|
70
70
|
if (isLoading) return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20" });
|
|
71
|
-
if (!price)
|
|
71
|
+
if (!price) {
|
|
72
|
+
return status === "pre-launch" ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block text-right text-xs text-muted-foreground", children: "Not trading yet" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block text-right text-muted-foreground", children: "\u2014" });
|
|
73
|
+
}
|
|
72
74
|
const usd = price.quoteUsdRate != null ? (0, import_format.formatUsdPrice)(price.quotePerCoin * price.quoteUsdRate) : null;
|
|
73
75
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "block text-right leading-tight", children: [
|
|
74
76
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "block font-semibold tabular-nums", children: usd ?? (0, import_coins.formatCoinPrice)(price.quotePerCoin) }),
|
|
@@ -79,12 +81,16 @@ function PriceCell({ price, isLoading }) {
|
|
|
79
81
|
] });
|
|
80
82
|
}
|
|
81
83
|
function CoinRow({ collection, usePrice, href, showKind = false }) {
|
|
82
|
-
const { price, isLoading } = usePrice(collection);
|
|
84
|
+
const { price, status, isLoading } = usePrice(collection);
|
|
83
85
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
84
86
|
import_link.default,
|
|
85
87
|
{
|
|
86
88
|
href,
|
|
87
|
-
className: (0, import_cn.cn)(
|
|
89
|
+
className: (0, import_cn.cn)(
|
|
90
|
+
COIN_GRID,
|
|
91
|
+
"border-b border-border/40 px-2 py-2.5 text-sm transition-colors",
|
|
92
|
+
"hover:bg-muted/40 active:bg-muted/60"
|
|
93
|
+
),
|
|
88
94
|
children: [
|
|
89
95
|
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
90
96
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(CoinAvatar, { collection }),
|
|
@@ -99,7 +105,7 @@ function CoinRow({ collection, usePrice, href, showKind = false }) {
|
|
|
99
105
|
] })
|
|
100
106
|
] })
|
|
101
107
|
] }),
|
|
102
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PriceCell, { price, isLoading })
|
|
108
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(PriceCell, { price, status, isLoading })
|
|
103
109
|
]
|
|
104
110
|
}
|
|
105
111
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport {\n coinKind,
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport {\n coinKind, coinAccentToken, formatCoinPrice,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_8rem] items-center gap-3 sm:gap-4\";\n\nconst kindLabel = (kind: string) => (kind === \"creator\" ? \"Creator Coin\" : \"Memecoin\");\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = logoUri ? ipfsToHttp(logoUri) : null;\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span className=\"block text-right text-muted-foreground\">—</span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"block text-right leading-tight\">\n <span className=\"block font-semibold tabular-nums\">{usd ?? formatCoinPrice(price.quotePerCoin)}</span>\n <span className=\"mt-0.5 inline-flex items-center justify-end gap-1 text-2xs tabular-nums text-muted-foreground\">\n <CurrencyIcon symbol={price.quoteSymbol} size={10} />\n {formatCoinPrice(price.quotePerCoin)}\n </span>\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {kindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":["Image","Link"]}
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { CoinCollectionLike, CoinPriceLike } from '../data/coins.cjs';
|
|
3
|
+
import '@medialane/sdk';
|
|
3
4
|
|
|
5
|
+
type CoinMarketStatus = "live" | "pre-launch" | "unavailable";
|
|
4
6
|
type UseCoinPrice = (collection: CoinCollectionLike) => {
|
|
5
7
|
price: CoinPriceLike | null;
|
|
8
|
+
status?: CoinMarketStatus;
|
|
6
9
|
isLoading: boolean;
|
|
7
10
|
};
|
|
8
11
|
declare const COIN_GRID = "grid grid-cols-[minmax(0,1fr)_8rem] items-center gap-3 sm:gap-4";
|
|
@@ -19,4 +22,4 @@ declare function CoinAvatar({ collection, size }: {
|
|
|
19
22
|
declare function CoinRow({ collection, usePrice, href, showKind }: CoinRowProps): react_jsx_runtime.JSX.Element;
|
|
20
23
|
declare function CoinRowSkeleton(): react_jsx_runtime.JSX.Element;
|
|
21
24
|
|
|
22
|
-
export { COIN_GRID, CoinAvatar, CoinRow, type CoinRowProps, CoinRowSkeleton, type UseCoinPrice };
|
|
25
|
+
export { COIN_GRID, CoinAvatar, type CoinMarketStatus, CoinRow, type CoinRowProps, CoinRowSkeleton, type UseCoinPrice };
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { CoinCollectionLike, CoinPriceLike } from '../data/coins.js';
|
|
3
|
+
import '@medialane/sdk';
|
|
3
4
|
|
|
5
|
+
type CoinMarketStatus = "live" | "pre-launch" | "unavailable";
|
|
4
6
|
type UseCoinPrice = (collection: CoinCollectionLike) => {
|
|
5
7
|
price: CoinPriceLike | null;
|
|
8
|
+
status?: CoinMarketStatus;
|
|
6
9
|
isLoading: boolean;
|
|
7
10
|
};
|
|
8
11
|
declare const COIN_GRID = "grid grid-cols-[minmax(0,1fr)_8rem] items-center gap-3 sm:gap-4";
|
|
@@ -19,4 +22,4 @@ declare function CoinAvatar({ collection, size }: {
|
|
|
19
22
|
declare function CoinRow({ collection, usePrice, href, showKind }: CoinRowProps): react_jsx_runtime.JSX.Element;
|
|
20
23
|
declare function CoinRowSkeleton(): react_jsx_runtime.JSX.Element;
|
|
21
24
|
|
|
22
|
-
export { COIN_GRID, CoinAvatar, CoinRow, type CoinRowProps, CoinRowSkeleton, type UseCoinPrice };
|
|
25
|
+
export { COIN_GRID, CoinAvatar, type CoinMarketStatus, CoinRow, type CoinRowProps, CoinRowSkeleton, type UseCoinPrice };
|
|
@@ -7,7 +7,7 @@ import { ipfsToHttp } from "../utils/ipfs.js";
|
|
|
7
7
|
import { CurrencyIcon } from "./currency-icon.js";
|
|
8
8
|
import {
|
|
9
9
|
coinKind,
|
|
10
|
-
|
|
10
|
+
coinAccentToken,
|
|
11
11
|
formatCoinPrice
|
|
12
12
|
} from "../data/coins.js";
|
|
13
13
|
import { formatUsdPrice } from "../utils/format.js";
|
|
@@ -17,12 +17,12 @@ function CoinAvatar({ collection, size = 36 }) {
|
|
|
17
17
|
const logoUri = collection.profile?.image ?? collection.image;
|
|
18
18
|
const logo = logoUri ? ipfsToHttp(logoUri) : null;
|
|
19
19
|
const initials = (collection.symbol ?? collection.name ?? "?").trim().slice(0, 2).toUpperCase();
|
|
20
|
-
const
|
|
20
|
+
const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);
|
|
21
21
|
return /* @__PURE__ */ jsx(
|
|
22
22
|
"div",
|
|
23
23
|
{
|
|
24
|
-
className: "relative shrink-0 overflow-hidden rounded-full",
|
|
25
|
-
style: { width: size, height: size
|
|
24
|
+
className: cn("relative shrink-0 overflow-hidden rounded-full", accent),
|
|
25
|
+
style: { width: size, height: size },
|
|
26
26
|
children: logo ? /* @__PURE__ */ jsx(Image, { src: logo, alt: "", fill: true, sizes: `${size}px`, className: "object-cover", unoptimized: true }) : /* @__PURE__ */ jsx(
|
|
27
27
|
"span",
|
|
28
28
|
{
|
|
@@ -34,9 +34,11 @@ function CoinAvatar({ collection, size = 36 }) {
|
|
|
34
34
|
}
|
|
35
35
|
);
|
|
36
36
|
}
|
|
37
|
-
function PriceCell({ price, isLoading }) {
|
|
37
|
+
function PriceCell({ price, status, isLoading }) {
|
|
38
38
|
if (isLoading) return /* @__PURE__ */ jsx("span", { className: "ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20" });
|
|
39
|
-
if (!price)
|
|
39
|
+
if (!price) {
|
|
40
|
+
return status === "pre-launch" ? /* @__PURE__ */ jsx("span", { className: "block text-right text-xs text-muted-foreground", children: "Not trading yet" }) : /* @__PURE__ */ jsx("span", { className: "block text-right text-muted-foreground", children: "\u2014" });
|
|
41
|
+
}
|
|
40
42
|
const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;
|
|
41
43
|
return /* @__PURE__ */ jsxs("span", { className: "block text-right leading-tight", children: [
|
|
42
44
|
/* @__PURE__ */ jsx("span", { className: "block font-semibold tabular-nums", children: usd ?? formatCoinPrice(price.quotePerCoin) }),
|
|
@@ -47,12 +49,16 @@ function PriceCell({ price, isLoading }) {
|
|
|
47
49
|
] });
|
|
48
50
|
}
|
|
49
51
|
function CoinRow({ collection, usePrice, href, showKind = false }) {
|
|
50
|
-
const { price, isLoading } = usePrice(collection);
|
|
52
|
+
const { price, status, isLoading } = usePrice(collection);
|
|
51
53
|
return /* @__PURE__ */ jsxs(
|
|
52
54
|
Link,
|
|
53
55
|
{
|
|
54
56
|
href,
|
|
55
|
-
className: cn(
|
|
57
|
+
className: cn(
|
|
58
|
+
COIN_GRID,
|
|
59
|
+
"border-b border-border/40 px-2 py-2.5 text-sm transition-colors",
|
|
60
|
+
"hover:bg-muted/40 active:bg-muted/60"
|
|
61
|
+
),
|
|
56
62
|
children: [
|
|
57
63
|
/* @__PURE__ */ jsxs("span", { className: "flex min-w-0 items-center gap-3", children: [
|
|
58
64
|
/* @__PURE__ */ jsx(CoinAvatar, { collection }),
|
|
@@ -67,7 +73,7 @@ function CoinRow({ collection, usePrice, href, showKind = false }) {
|
|
|
67
73
|
] })
|
|
68
74
|
] })
|
|
69
75
|
] }),
|
|
70
|
-
/* @__PURE__ */ jsx(PriceCell, { price, isLoading })
|
|
76
|
+
/* @__PURE__ */ jsx(PriceCell, { price, status, isLoading })
|
|
71
77
|
]
|
|
72
78
|
}
|
|
73
79
|
);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport {\n coinKind,
|
|
1
|
+
{"version":3,"sources":["../../src/components/coin-row.tsx"],"sourcesContent":["\"use client\";\n\nimport Link from \"./link.js\";\nimport Image from \"./image.js\";\nimport { cn } from \"../utils/cn.js\";\nimport { ipfsToHttp } from \"../utils/ipfs.js\";\nimport { CurrencyIcon } from \"./currency-icon.js\";\nimport {\n coinKind, coinAccentToken, formatCoinPrice,\n type CoinCollectionLike, type CoinPriceLike,\n} from \"../data/coins.js\";\nimport { formatUsdPrice } from \"../utils/format.js\";\n\nexport type CoinMarketStatus = \"live\" | \"pre-launch\" | \"unavailable\";\n\nexport type UseCoinPrice = (collection: CoinCollectionLike) => {\n price: CoinPriceLike | null;\n status?: CoinMarketStatus;\n isLoading: boolean;\n};\n\nexport const COIN_GRID = \"grid grid-cols-[minmax(0,1fr)_8rem] items-center gap-3 sm:gap-4\";\n\nconst kindLabel = (kind: string) => (kind === \"creator\" ? \"Creator Coin\" : \"Memecoin\");\n\nexport interface CoinRowProps {\n collection: CoinCollectionLike;\n usePrice: UseCoinPrice;\n href: string;\n showKind?: boolean;\n}\n\nexport function CoinAvatar({ collection, size = 36 }: { collection: CoinCollectionLike; size?: number }) {\n const logoUri = collection.profile?.image ?? collection.image;\n const logo = logoUri ? ipfsToHttp(logoUri) : null;\n const initials = (collection.symbol ?? collection.name ?? \"?\").trim().slice(0, 2).toUpperCase();\n const accent = coinAccentToken(collection.symbol ?? collection.name ?? collection.contractAddress);\n\n return (\n <div\n className={cn(\"relative shrink-0 overflow-hidden rounded-full\", accent)}\n style={{ width: size, height: size }}\n >\n {logo ? (\n <Image src={logo} alt=\"\" fill sizes={`${size}px`} className=\"object-cover\" unoptimized />\n ) : (\n <span\n className=\"flex h-full w-full items-center justify-center font-bold leading-none text-white\"\n style={{ fontSize: size * 0.36 }}\n >\n {initials}\n </span>\n )}\n </div>\n );\n}\n\nfunction PriceCell({ price, status, isLoading }: { price: CoinPriceLike | null; status?: CoinMarketStatus; isLoading: boolean }) {\n if (isLoading) return <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />;\n if (!price) {\n return status === \"pre-launch\" ? (\n <span className=\"block text-right text-xs text-muted-foreground\">Not trading yet</span>\n ) : (\n <span className=\"block text-right text-muted-foreground\">—</span>\n );\n }\n\n const usd = price.quoteUsdRate != null ? formatUsdPrice(price.quotePerCoin * price.quoteUsdRate) : null;\n\n return (\n <span className=\"block text-right leading-tight\">\n <span className=\"block font-semibold tabular-nums\">{usd ?? formatCoinPrice(price.quotePerCoin)}</span>\n <span className=\"mt-0.5 inline-flex items-center justify-end gap-1 text-2xs tabular-nums text-muted-foreground\">\n <CurrencyIcon symbol={price.quoteSymbol} size={10} />\n {formatCoinPrice(price.quotePerCoin)}\n </span>\n </span>\n );\n}\n\nexport function CoinRow({ collection, usePrice, href, showKind = false }: CoinRowProps) {\n const { price, status, isLoading } = usePrice(collection);\n\n return (\n <Link\n href={href}\n className={cn(\n COIN_GRID,\n \"border-b border-border/40 px-2 py-2.5 text-sm transition-colors\",\n \"hover:bg-muted/40 active:bg-muted/60\"\n )}\n >\n <span className=\"flex min-w-0 items-center gap-3\">\n <CoinAvatar collection={collection} />\n <span className=\"min-w-0\">\n <span className=\"block truncate font-semibold leading-tight\">{collection.name ?? \"Untitled coin\"}</span>\n <span className=\"block truncate text-xs text-muted-foreground\">\n {collection.symbol ?? \"—\"}\n {showKind && <span className=\"text-muted-foreground/60\"> · {kindLabel(coinKind(collection.service))}</span>}\n </span>\n </span>\n </span>\n\n <PriceCell price={price} status={status} isLoading={isLoading} />\n </Link>\n );\n}\n\nexport function CoinRowSkeleton() {\n return (\n <div className={cn(COIN_GRID, \"border-b border-border/40 px-2 py-2.5\")}>\n <span className=\"flex items-center gap-3\">\n <span className=\"h-9 w-9 shrink-0 animate-pulse rounded-full bg-muted-foreground/20\" />\n <span className=\"space-y-1.5\">\n <span className=\"block h-4 w-28 animate-pulse rounded bg-muted-foreground/20\" />\n <span className=\"block h-3 w-14 animate-pulse rounded bg-muted-foreground/10\" />\n </span>\n </span>\n <span className=\"ml-auto block h-4 w-16 animate-pulse rounded bg-muted-foreground/20\" />\n </div>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { UseCoinPrice } from './coin-row.cjs';
|
|
3
3
|
import { CoinCollectionLike } from '../data/coins.cjs';
|
|
4
|
+
import '@medialane/sdk';
|
|
4
5
|
|
|
5
6
|
type CoinFilter = "all" | "creator" | "memecoin";
|
|
6
7
|
type CoinSort = "recent" | "name";
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { UseCoinPrice } from './coin-row.js';
|
|
3
3
|
import { CoinCollectionLike } from '../data/coins.js';
|
|
4
|
+
import '@medialane/sdk';
|
|
4
5
|
|
|
5
6
|
type CoinFilter = "all" | "creator" | "memecoin";
|
|
6
7
|
type CoinSort = "recent" | "name";
|