// portfolio-atoms.jsx — shared themeable atoms (CSS-var driven)
// Each screen wrapper defines: --bg --card --card2 --border --border-soft
// --text --muted --dim --accent --accent-soft --pos --neg --pos-soft --neg-soft
// Exports to window: Dot, Pnl, ShareBar, RangeBadge, Ticker, Sparkdots, signClass
const { useState } = React;
function signClass(v) {
return v >= 0 ? "pos" : "neg";
}
// colored status dot
function Dot({ color, size = 8, glow }) {
return (
);
}
// PnL value text, colored
function Pnl({ children, v, weight = 600, size }) {
const pos = v >= 0;
return (
{children}
);
}
// mini share-of-portfolio bar with number
function ShareBar({ pct, width = 56, accent = "var(--bar, var(--accent))", showNum = true, max = 50 }) {
const w = Math.max(2, Math.min(100, (pct / max) * 100));
return (
{showNum && (
{window.fmt.pct(pct)}
)}
);
}
// LP range status badge
function RangeBadge({ inRange }) {
return (
{inRange ? "в диапазоне" : "вне диапазона"}
);
}
// real crypto coin logos — crisp inline SVG brand marks
function Glyph({ ch, dx = 16, dy = 21.5, fs = 17 }) {
return (
{ch}
);
}
const LOGOS = {
BTC: () => (
),
cbBTC: () => (
),
ETH: () => (
),
SOL: () => (
),
USDC: () => (
),
USDT: () => (
),
};
// Логотипы остальных монет — настоящие иконки CoinGecko (для тех, у кого нет
// рисованного SVG выше). Грузятся как
. Новую монету достаточно добавить сюда.
const LOGO_URLS = {
APT: "https://coin-images.coingecko.com/coins/images/26455/large/Aptos-Network-Symbol-Black-RGB-1x.png?1761789140",
ARB: "https://coin-images.coingecko.com/coins/images/16547/large/arb.jpg?1721358242",
CFG: "https://coin-images.coingecko.com/coins/images/15380/large/centrifuge.PNG?1696515027",
DAI: "https://coin-images.coingecko.com/coins/images/9956/large/Badge_Dai.png?1696509996",
EYWA: "https://coin-images.coingecko.com/coins/images/51242/large/Eywa.png?1730449129",
FDUSD: "https://coin-images.coingecko.com/coins/images/31079/large/FDUSD_icon_black.png?1731097953",
FRAX: "https://coin-images.coingecko.com/coins/images/13422/large/LFRAX.png?1751911193",
GHO: "https://coin-images.coingecko.com/coins/images/30663/large/gho-token-logo.png?1720517092",
GUSD: "https://coin-images.coingecko.com/coins/images/5992/large/gemini-dollar-gusd.png?1696506408",
HBAR: "https://coin-images.coingecko.com/coins/images/3688/large/hbar.png?1696504364",
LUSD: "https://coin-images.coingecko.com/coins/images/14666/large/Group_3.png?1696514341",
ONDO: "https://coin-images.coingecko.com/coins/images/26580/large/ONDO.png?1696525656",
PYUSD: "https://coin-images.coingecko.com/coins/images/31212/large/PYUSD_Token_Logo_2x.png?1765987788",
RLUSD: "https://coin-images.coingecko.com/coins/images/39651/large/RLUSD_200x200_%281%29.png?1727376633",
STRK: "https://coin-images.coingecko.com/coins/images/26433/large/starknet.png?1696525507",
TUSD: "https://coin-images.coingecko.com/coins/images/3449/large/tusd.png?1696504140",
USD0: "https://coin-images.coingecko.com/coins/images/38272/large/USD0LOGO.png?1716962811",
USDD: "https://coin-images.coingecko.com/coins/images/25380/large/UUSD.jpg?1696524513",
USDE: "https://coin-images.coingecko.com/coins/images/33613/large/usde.png?1733810059",
USDP: "https://coin-images.coingecko.com/coins/images/6013/large/Pax_Dollar.png?1696506427",
USDS: "https://coin-images.coingecko.com/coins/images/39926/large/usds.webp?1726666683",
ZK: "https://coin-images.coingecko.com/coins/images/38043/large/ZKTokenBlack.png?1718614502",
crvUSD: "https://coin-images.coingecko.com/coins/images/30118/large/crvusd.jpg?1746670973",
};
function Ticker({ sym, size = 28 }) {
const draw = LOGOS[sym];
if (draw) {
return (
);
}
// настоящая иконка CoinGecko на белой подложке (чтобы чёрные логотипы вроде
// APT/ZK были видны и на тёмной теме); при ошибке загрузки — fallback на букву
const url = LOGO_URLS[sym];
if (url) {
return (
{
e.currentTarget.style.display = "none";
if (e.currentTarget.nextSibling) e.currentTarget.nextSibling.style.display = "inline-flex";
}}
/>
{sym.slice(0, 1)}
);
}
// fallback: neutral circle with first letter
return (
{sym.slice(0, 1)}
);
}
Object.assign(window, { Dot, Pnl, ShareBar, RangeBadge, Ticker, signClass });