@loafmarkets/ui 0.1.208 → 0.1.210

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/index.js CHANGED
@@ -8523,6 +8523,7 @@ function PropertyOverview({
8523
8523
  }) {
8524
8524
  const [isDescExpanded, setDescExpanded] = React5.useState(false);
8525
8525
  const [showDividendHistory, setShowDividendHistory] = React5.useState(false);
8526
+ const [showHolders, setShowHolders] = React5.useState(false);
8526
8527
  const [copiedAddress, setCopiedAddress] = React5.useState(false);
8527
8528
  const description = descriptionProp ?? overviewData?.description ?? DEFAULT_DESCRIPTION;
8528
8529
  const landSize = landProp ?? overviewData?.landSizeSqm ?? null;
@@ -8627,46 +8628,30 @@ function PropertyOverview({
8627
8628
  /* @__PURE__ */ jsxRuntime.jsx(PrimaryBtn, { onClick: onTradeClick, children: tradeButtonLabel })
8628
8629
  ] })
8629
8630
  ] }),
8630
- /* @__PURE__ */ jsxRuntime.jsxs(AboutRight, { children: [
8631
- /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailsCard, { children: [
8632
- /* @__PURE__ */ jsxRuntime.jsx(TokenDetailsTitle, { children: "Token Details" }),
8633
- tokenDetailsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailRow, { children: [
8634
- /* @__PURE__ */ jsxRuntime.jsx(TokenDetailLabel, { children: item.label }),
8635
- /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailValue, { $mono: !!item.mono, children: [
8636
- item.link ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value,
8637
- item.copyValue && /* @__PURE__ */ jsxRuntime.jsx(
8638
- CopyBtn,
8639
- {
8640
- onClick: () => {
8641
- navigator.clipboard.writeText(item.copyValue);
8642
- setCopiedAddress(true);
8643
- setTimeout(() => setCopiedAddress(false), 1500);
8644
- },
8645
- title: copiedAddress ? "Copied!" : "Copy address",
8646
- children: copiedAddress ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
8647
- /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
8648
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
8649
- ] })
8650
- }
8651
- )
8652
- ] })
8653
- ] }, item.label))
8654
- ] }),
8655
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgesCard, { children: /* @__PURE__ */ jsxRuntime.jsxs(TrustBadgesRow, { children: [
8656
- /* @__PURE__ */ jsxRuntime.jsxs(TrustBadge, { children: [
8657
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: "/Baker_McKenzie.png", alt: "Baker McKenzie", style: { height: 38, filter: "grayscale(1) brightness(10)", opacity: 0.5 } }) }),
8658
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLabel, { children: "Legal Structuring" })
8659
- ] }),
8660
- /* @__PURE__ */ jsxRuntime.jsxs(TrustBadge, { children: [
8661
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: "/NSW_registry.png", alt: "NSW Land Registry", style: { height: 40, filter: "grayscale(1) brightness(10)", opacity: 0.5 } }) }),
8662
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLabel, { children: "Land Title" })
8663
- ] }),
8664
- /* @__PURE__ */ jsxRuntime.jsxs(TrustBadge, { children: [
8665
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLogoWrap, { children: /* @__PURE__ */ jsxRuntime.jsx("img", { src: "/savills.png", alt: "Savills", style: { height: 38, borderRadius: 3, filter: "grayscale(1) brightness(1.2) contrast(1.6)", opacity: 0.7 } }) }),
8666
- /* @__PURE__ */ jsxRuntime.jsx(TrustBadgeLabel, { children: "Valuation" })
8631
+ /* @__PURE__ */ jsxRuntime.jsx(AboutRight, { children: /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailsCard, { children: [
8632
+ /* @__PURE__ */ jsxRuntime.jsx(TokenDetailsTitle, { children: "Token Details" }),
8633
+ tokenDetailsItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailRow, { children: [
8634
+ /* @__PURE__ */ jsxRuntime.jsx(TokenDetailLabel, { children: item.label }),
8635
+ /* @__PURE__ */ jsxRuntime.jsxs(TokenDetailValue, { $mono: !!item.mono, children: [
8636
+ item.link ? /* @__PURE__ */ jsxRuntime.jsx("a", { href: item.link, target: "_blank", rel: "noopener noreferrer", style: { color: "#3380FF", textDecoration: "none" }, children: item.value }) : item.value,
8637
+ item.copyValue && /* @__PURE__ */ jsxRuntime.jsx(
8638
+ CopyBtn,
8639
+ {
8640
+ onClick: () => {
8641
+ navigator.clipboard.writeText(item.copyValue);
8642
+ setCopiedAddress(true);
8643
+ setTimeout(() => setCopiedAddress(false), 1500);
8644
+ },
8645
+ title: copiedAddress ? "Copied!" : "Copy address",
8646
+ children: copiedAddress ? /* @__PURE__ */ jsxRuntime.jsx("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M20 6L9 17l-5-5" }) }) : /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", children: [
8647
+ /* @__PURE__ */ jsxRuntime.jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
8648
+ /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
8649
+ ] })
8650
+ }
8651
+ )
8667
8652
  ] })
8668
- ] }) })
8669
- ] })
8653
+ ] }, item.label))
8654
+ ] }) })
8670
8655
  ] })
8671
8656
  ] }),
8672
8657
  /* @__PURE__ */ jsxRuntime.jsxs(Section, { children: [
@@ -8676,7 +8661,7 @@ function PropertyOverview({
8676
8661
  /* @__PURE__ */ jsxRuntime.jsx(StatsColumnHeader, { children: "Token Performance" }),
8677
8662
  tokenStats.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(StatRow, { $gold: !!item.gold, children: [
8678
8663
  /* @__PURE__ */ jsxRuntime.jsx(StatLabel, { children: item.label }),
8679
- /* @__PURE__ */ jsxRuntime.jsx(StatValue, { $gold: !!item.gold, children: item.value })
8664
+ item.label === "Holders" && holderCount != null ? /* @__PURE__ */ jsxRuntime.jsx(StatValueClickable, { onClick: () => setShowHolders(true), children: item.value }) : /* @__PURE__ */ jsxRuntime.jsx(StatValue, { $gold: !!item.gold, children: item.value })
8680
8665
  ] }, item.label)),
8681
8666
  holdRatio && /* @__PURE__ */ jsxRuntime.jsxs(HoldRatioWrap, { children: [
8682
8667
  /* @__PURE__ */ jsxRuntime.jsxs(HoldRatioTitle, { children: [
@@ -8723,6 +8708,14 @@ function PropertyOverview({
8723
8708
  onClose: () => setShowDividendHistory(false)
8724
8709
  }
8725
8710
  ),
8711
+ showHolders && /* @__PURE__ */ jsxRuntime.jsx(
8712
+ HoldersPopup,
8713
+ {
8714
+ contractAddress,
8715
+ ticker,
8716
+ onClose: () => setShowHolders(false)
8717
+ }
8718
+ ),
8726
8719
  galleryImages.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(GalleryBreakout, { children: /* @__PURE__ */ jsxRuntime.jsx(
8727
8720
  GalleryMapSection,
8728
8721
  {
@@ -9108,6 +9101,65 @@ function DividendHistoryPopup({
9108
9101
  ] }) })
9109
9102
  ] }) });
9110
9103
  }
9104
+ var MOCK_HOLDERS = [
9105
+ { rank: 1, address: "0xA1b2...9F3e", label: "Loaf Treasury", tokens: 12500, pct: 25 },
9106
+ { rank: 2, address: "0xC4d5...1A7b", label: null, tokens: 6200, pct: 12.4 },
9107
+ { rank: 3, address: "0xE8f9...3C2d", label: null, tokens: 4800, pct: 9.6 },
9108
+ { rank: 4, address: "0x2B3c...7D4e", label: "Market Maker", tokens: 3500, pct: 7 },
9109
+ { rank: 5, address: "0x5F6a...8E1c", label: null, tokens: 2900, pct: 5.8 },
9110
+ { rank: 6, address: "0x7A8b...0F2d", label: null, tokens: 2400, pct: 4.8 },
9111
+ { rank: 7, address: "0x9C0d...4A3e", label: null, tokens: 1800, pct: 3.6 },
9112
+ { rank: 8, address: "0xB1e2...6C5f", label: null, tokens: 1500, pct: 3 },
9113
+ { rank: 9, address: "0xD3f4...8E7a", label: null, tokens: 1200, pct: 2.4 },
9114
+ { rank: 10, address: "0xF5a6...2B9c", label: null, tokens: 950, pct: 1.9 }
9115
+ ];
9116
+ function HoldersPopup({
9117
+ contractAddress,
9118
+ ticker,
9119
+ onClose
9120
+ }) {
9121
+ React5.useEffect(() => {
9122
+ const handleEsc = (e) => {
9123
+ if (e.key === "Escape") onClose();
9124
+ };
9125
+ window.addEventListener("keydown", handleEsc);
9126
+ return () => window.removeEventListener("keydown", handleEsc);
9127
+ }, [onClose]);
9128
+ const basescanUrl = contractAddress ? `https://basescan.org/token/${contractAddress}#balances` : "https://basescan.org";
9129
+ return /* @__PURE__ */ jsxRuntime.jsx(DivPopupOverlay, { onClick: onClose, children: /* @__PURE__ */ jsxRuntime.jsxs(HoldersPanel, { onClick: (e) => e.stopPropagation(), children: [
9130
+ /* @__PURE__ */ jsxRuntime.jsxs(DivPopupHeader, { children: [
9131
+ /* @__PURE__ */ jsxRuntime.jsxs(DivPopupTitle, { children: [
9132
+ "Top Holders",
9133
+ ticker ? ` (${ticker})` : ""
9134
+ ] }),
9135
+ /* @__PURE__ */ jsxRuntime.jsxs(HoldersHeaderRight, { children: [
9136
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersBasescanLink, { href: basescanUrl, target: "_blank", rel: "noopener noreferrer", children: "View on BaseScan\xA0\u2197" }),
9137
+ /* @__PURE__ */ jsxRuntime.jsx(DivPopupClose, { onClick: onClose, "aria-label": "Close holders", children: "\u2715" })
9138
+ ] })
9139
+ ] }),
9140
+ /* @__PURE__ */ jsxRuntime.jsxs(HoldersTableWrap, { children: [
9141
+ /* @__PURE__ */ jsxRuntime.jsxs(HoldersTableHeader, { children: [
9142
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColRank, { children: "#" }),
9143
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColAddr, { children: "Address" }),
9144
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColTokens, { children: "Tokens" }),
9145
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColPct, { children: "%" })
9146
+ ] }),
9147
+ MOCK_HOLDERS.map((h) => /* @__PURE__ */ jsxRuntime.jsxs(HoldersTableRow, { children: [
9148
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColRank, { children: h.rank }),
9149
+ /* @__PURE__ */ jsxRuntime.jsxs(HoldersColAddr, { children: [
9150
+ /* @__PURE__ */ jsxRuntime.jsx(HolderAddrLink, { href: `https://basescan.org/address/${h.address.replace("...", "")}`, target: "_blank", rel: "noopener noreferrer", children: h.address }),
9151
+ h.label && /* @__PURE__ */ jsxRuntime.jsx(HolderLabel, { children: h.label })
9152
+ ] }),
9153
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersColTokens, { children: h.tokens.toLocaleString() }),
9154
+ /* @__PURE__ */ jsxRuntime.jsxs(HoldersColPct, { children: [
9155
+ h.pct.toFixed(1),
9156
+ "%"
9157
+ ] })
9158
+ ] }, h.rank))
9159
+ ] }),
9160
+ /* @__PURE__ */ jsxRuntime.jsx(HoldersFooter, { children: /* @__PURE__ */ jsxRuntime.jsx(HoldersFullListBtn, { href: basescanUrl, target: "_blank", rel: "noopener noreferrer", children: "See Full List of Holders\xA0\u2197" }) })
9161
+ ] }) });
9162
+ }
9111
9163
  var Wrapper = styled9__default.default.div`
9112
9164
  display: flex;
9113
9165
  flex-direction: column;
@@ -9243,7 +9295,7 @@ var TokenDetailValue = styled9__default.default.span`
9243
9295
  font-weight: 500;
9244
9296
  font-family: ${(p) => p.$mono ? "'SF Mono', 'Fira Code', monospace" : "inherit"};
9245
9297
  `;
9246
- var TrustBadgesCard = styled9__default.default.div`
9298
+ styled9__default.default.div`
9247
9299
  background: rgba(255,255,255,0.025);
9248
9300
  border: 1px solid rgba(255,255,255,0.06);
9249
9301
  border-radius: 10px;
@@ -9257,12 +9309,12 @@ styled9__default.default.div`
9257
9309
  font-weight: 500;
9258
9310
  margin-bottom: 0.85rem;
9259
9311
  `;
9260
- var TrustBadgesRow = styled9__default.default.div`
9312
+ styled9__default.default.div`
9261
9313
  display: flex;
9262
9314
  gap: 0.5rem;
9263
9315
  justify-content: space-between;
9264
9316
  `;
9265
- var TrustBadge = styled9__default.default.div`
9317
+ styled9__default.default.div`
9266
9318
  display: flex;
9267
9319
  flex-direction: column;
9268
9320
  align-items: center;
@@ -9270,13 +9322,13 @@ var TrustBadge = styled9__default.default.div`
9270
9322
  flex: 1;
9271
9323
  min-width: 0;
9272
9324
  `;
9273
- var TrustBadgeLogoWrap = styled9__default.default.div`
9325
+ styled9__default.default.div`
9274
9326
  display: flex;
9275
9327
  align-items: center;
9276
9328
  justify-content: center;
9277
9329
  height: 44px;
9278
9330
  `;
9279
- var TrustBadgeLabel = styled9__default.default.span`
9331
+ styled9__default.default.span`
9280
9332
  font-size: 0.62rem;
9281
9333
  color: rgba(255,255,255,0.35);
9282
9334
  font-weight: 400;
@@ -9892,6 +9944,133 @@ var DivTableTD = styled9__default.default.td`
9892
9944
  font-size: 0.82rem;
9893
9945
  color: rgba(255,255,255,0.75);
9894
9946
  `;
9947
+ var HoldersPanel = styled9__default.default.div`
9948
+ background: #111;
9949
+ border: 1px solid rgba(255,255,255,0.08);
9950
+ border-radius: 14px;
9951
+ width: 90%;
9952
+ max-width: 520px;
9953
+ max-height: 85vh;
9954
+ overflow-y: auto;
9955
+ display: flex;
9956
+ flex-direction: column;
9957
+ `;
9958
+ var HoldersHeaderRight = styled9__default.default.div`
9959
+ display: flex;
9960
+ align-items: center;
9961
+ gap: 1rem;
9962
+ `;
9963
+ var HoldersBasescanLink = styled9__default.default.a`
9964
+ font-size: 0.75rem;
9965
+ color: rgba(255,255,255,0.4);
9966
+ text-decoration: none;
9967
+ transition: color 0.15s;
9968
+ &:hover { color: rgba(212,175,55,0.9); }
9969
+ `;
9970
+ var HoldersTableWrap = styled9__default.default.div`
9971
+ padding: 0 1.5rem;
9972
+ `;
9973
+ var HoldersTableHeader = styled9__default.default.div`
9974
+ display: flex;
9975
+ align-items: center;
9976
+ padding: 0.6rem 0;
9977
+ border-bottom: 1px solid rgba(255,255,255,0.08);
9978
+ font-size: 0.65rem;
9979
+ font-weight: 500;
9980
+ color: rgba(255,255,255,0.4);
9981
+ text-transform: uppercase;
9982
+ letter-spacing: 0.06em;
9983
+ `;
9984
+ var HoldersTableRow = styled9__default.default.div`
9985
+ display: flex;
9986
+ align-items: center;
9987
+ padding: 0.6rem 0;
9988
+ border-bottom: 1px solid rgba(255,255,255,0.03);
9989
+ font-size: 0.82rem;
9990
+ color: rgba(255,255,255,0.75);
9991
+ border-radius: 6px;
9992
+ transition: background 0.15s;
9993
+ &:hover { background: rgba(255,255,255,0.03); }
9994
+ &:last-child { border-bottom: none; }
9995
+ `;
9996
+ var HoldersColRank = styled9__default.default.span`
9997
+ width: 32px;
9998
+ flex-shrink: 0;
9999
+ color: rgba(255,255,255,0.35);
10000
+ font-size: 0.75rem;
10001
+ `;
10002
+ var HoldersColAddr = styled9__default.default.span`
10003
+ flex: 1;
10004
+ min-width: 0;
10005
+ display: flex;
10006
+ align-items: center;
10007
+ gap: 0.5rem;
10008
+ `;
10009
+ var HolderAddrLink = styled9__default.default.a`
10010
+ font-family: monospace;
10011
+ font-size: 0.8rem;
10012
+ color: rgba(255,255,255,0.7);
10013
+ text-decoration: none;
10014
+ &:hover { color: rgba(212,175,55,0.9); }
10015
+ `;
10016
+ var HolderLabel = styled9__default.default.span`
10017
+ font-size: 0.68rem;
10018
+ color: rgba(212,175,55,0.7);
10019
+ background: rgba(212,175,55,0.08);
10020
+ padding: 1px 6px;
10021
+ border-radius: 4px;
10022
+ white-space: nowrap;
10023
+ `;
10024
+ var HoldersColTokens = styled9__default.default.span`
10025
+ width: 90px;
10026
+ text-align: right;
10027
+ flex-shrink: 0;
10028
+ font-variant-numeric: tabular-nums;
10029
+ `;
10030
+ var HoldersColPct = styled9__default.default.span`
10031
+ width: 55px;
10032
+ text-align: right;
10033
+ flex-shrink: 0;
10034
+ font-variant-numeric: tabular-nums;
10035
+ color: rgba(255,255,255,0.5);
10036
+ `;
10037
+ var HoldersFooter = styled9__default.default.div`
10038
+ padding: 1rem 1.5rem 1.25rem;
10039
+ display: flex;
10040
+ justify-content: center;
10041
+ `;
10042
+ var HoldersFullListBtn = styled9__default.default.a`
10043
+ display: inline-flex;
10044
+ align-items: center;
10045
+ padding: 0.55rem 1.5rem;
10046
+ border: 1px solid rgba(255,255,255,0.1);
10047
+ border-radius: 8px;
10048
+ background: rgba(255,255,255,0.03);
10049
+ color: rgba(255,255,255,0.6);
10050
+ font-size: 0.78rem;
10051
+ font-weight: 500;
10052
+ text-decoration: none;
10053
+ transition: border-color 0.15s, color 0.15s, background 0.15s;
10054
+ &:hover {
10055
+ border-color: rgba(212,175,55,0.4);
10056
+ color: rgba(212,175,55,0.9);
10057
+ background: rgba(212,175,55,0.05);
10058
+ }
10059
+ `;
10060
+ var StatValueClickable = styled9__default.default.span`
10061
+ font-size: 0.88rem;
10062
+ font-weight: 600;
10063
+ color: #fff;
10064
+ cursor: pointer;
10065
+ text-decoration: underline;
10066
+ text-underline-offset: 3px;
10067
+ text-decoration-color: rgba(255,255,255,0.15);
10068
+ transition: color 0.15s, text-decoration-color 0.15s;
10069
+ &:hover {
10070
+ color: rgba(212,175,55,0.9);
10071
+ text-decoration-color: rgba(212,175,55,0.5);
10072
+ }
10073
+ `;
9895
10074
  var STATUS_BG = {
9896
10075
  active: "rgba(14,203,129,0.18)",
9897
10076
  rejected: "rgba(246,70,93,0.18)",