@loafmarkets/ui 0.1.411 → 0.1.413

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.mjs CHANGED
@@ -15097,6 +15097,9 @@ var STATUS_COLOR2 = {
15097
15097
  CLOSED: "#848e9c",
15098
15098
  CANCELLED: "#f6465d"
15099
15099
  };
15100
+ var STUCK_SETTLING_MS = 7e3;
15101
+ var SETTLING_MESSAGE = "Trade settling on-chain";
15102
+ var STUCK_SETTLING_MESSAGE = "Attention: Trade taking longer than usual to settle on chain. Please wait up to 10 seconds before trading. This is reflected in your locked balance.";
15100
15103
  var settlingSpin = keyframes`
15101
15104
  to { transform: rotate(360deg); }
15102
15105
  `;
@@ -15110,41 +15113,55 @@ var SettlingSpinner = styled10.span`
15110
15113
  animation: ${settlingSpin} 0.7s linear infinite;
15111
15114
  flex-shrink: 0;
15112
15115
  `;
15116
+ var StuckSettlingGlyph = styled10.span`
15117
+ display: inline-block;
15118
+ font-size: 11px;
15119
+ line-height: 1;
15120
+ flex-shrink: 0;
15121
+ `;
15113
15122
  var SettlingTip = styled10.span`
15114
15123
  position: relative;
15115
15124
  display: inline-flex;
15116
15125
  align-items: center;
15117
15126
  cursor: help;
15118
- &::after {
15119
- content: 'Trade settling on-chain';
15120
- position: absolute;
15121
- left: 50%;
15122
- bottom: calc(100% + 8px);
15123
- transform: translateX(-50%) translateY(3px);
15124
- padding: 6px 8px;
15125
- background: rgba(20, 22, 28, 0.97);
15126
- border: 1px solid rgba(255, 255, 255, 0.1);
15127
- border-radius: 6px;
15128
- color: rgba(255, 255, 255, 0.78);
15129
- font-size: 0.66rem;
15130
- font-weight: 400;
15131
- line-height: 1.3;
15132
- letter-spacing: normal;
15133
- text-transform: none;
15134
- white-space: nowrap;
15135
- box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
15136
- opacity: 0;
15137
- visibility: hidden;
15138
- transition: opacity 0.15s ease, transform 0.15s ease;
15139
- pointer-events: none;
15140
- z-index: 2000;
15141
- }
15142
- &:hover::after {
15127
+ `;
15128
+ var SettlingTipBubble = styled10.span`
15129
+ position: absolute;
15130
+ bottom: calc(100% + 8px);
15131
+ /* Stuck copy is a paragraph, so it anchors to the icon's left edge instead of
15132
+ centring centred it would hang off the left of the row. */
15133
+ left: ${(p) => p.$stuck ? "0" : "50%"};
15134
+ transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(3px);
15135
+ width: ${(p) => p.$stuck ? "224px" : "auto"};
15136
+ white-space: ${(p) => p.$stuck ? "normal" : "nowrap"};
15137
+ padding: 6px 8px;
15138
+ background: rgba(20, 22, 28, 0.97);
15139
+ border: 1px solid rgba(255, 255, 255, 0.1);
15140
+ border-radius: 6px;
15141
+ color: rgba(255, 255, 255, 0.78);
15142
+ font-size: 0.66rem;
15143
+ font-weight: 400;
15144
+ line-height: 1.35;
15145
+ letter-spacing: normal;
15146
+ text-transform: none;
15147
+ text-align: left;
15148
+ box-shadow: 0 6px 18px rgba(0, 0, 0, 0.45);
15149
+ opacity: 0;
15150
+ visibility: hidden;
15151
+ transition: opacity 0.15s ease, transform 0.15s ease;
15152
+ pointer-events: none;
15153
+ z-index: 2000;
15154
+
15155
+ ${SettlingTip}:hover & {
15143
15156
  opacity: 1;
15144
15157
  visibility: visible;
15145
- transform: translateX(-50%) translateY(0);
15158
+ transform: ${(p) => p.$stuck ? "translateX(0)" : "translateX(-50%)"} translateY(0);
15146
15159
  }
15147
15160
  `;
15161
+ var SettlingIndicator = ({ stuck, style }) => /* @__PURE__ */ jsxs(SettlingTip, { role: "img", "aria-label": stuck ? "Settlement delayed" : SETTLING_MESSAGE, style, children: [
15162
+ stuck ? /* @__PURE__ */ jsx(StuckSettlingGlyph, { "aria-hidden": "true", children: "\u26A0\uFE0F" }) : /* @__PURE__ */ jsx(SettlingSpinner, { "aria-hidden": "true" }),
15163
+ /* @__PURE__ */ jsx(SettlingTipBubble, { $stuck: stuck, children: stuck ? STUCK_SETTLING_MESSAGE : SETTLING_MESSAGE })
15164
+ ] });
15148
15165
  var ACTIVITY_PAGE_SIZE_DEFAULT = 8;
15149
15166
  var formatCurrency4 = (value, opts) => {
15150
15167
  const min = opts?.minimumFractionDigits ?? 2;
@@ -15152,14 +15169,21 @@ var formatCurrency4 = (value, opts) => {
15152
15169
  return `$${value.toLocaleString("en-US", { minimumFractionDigits: min, maximumFractionDigits: max })}`;
15153
15170
  };
15154
15171
  var formatNumber2 = (value, maximumFractionDigits = 2) => value.toLocaleString("en-US", { minimumFractionDigits: 0, maximumFractionDigits });
15172
+ var toMillis = (unix) => {
15173
+ if (unix > 1e18) return Math.floor(unix / 1e6);
15174
+ if (unix > 1e14) return Math.floor(unix / 1e3);
15175
+ if (unix > 1e12) return unix;
15176
+ return unix * 1e3;
15177
+ };
15178
+ var SETTLED_TRADE_STATUSES = ["SETTLED", "CONFIRMED", "FILLED", "ALLOCATED"];
15179
+ var FAILED_TRADE_STATUSES = ["SETTLEMENT_FAILED", "REJECTED", "CANCELLED", "CANCELED"];
15180
+ var tradeIsSettling = (status) => {
15181
+ const s = status?.toUpperCase();
15182
+ return !!s && !SETTLED_TRADE_STATUSES.includes(s) && !FAILED_TRADE_STATUSES.includes(s);
15183
+ };
15155
15184
  var formatTimestamp = (unix) => {
15156
15185
  if (!unix) return "\u2014";
15157
- let sec;
15158
- if (unix > 1e18) sec = Math.floor(unix / 1e9);
15159
- else if (unix > 1e14) sec = Math.floor(unix / 1e6);
15160
- else if (unix > 1e12) sec = Math.floor(unix / 1e3);
15161
- else sec = unix;
15162
- return new Date(sec * 1e3).toLocaleString("en-AU", {
15186
+ return new Date(toMillis(unix)).toLocaleString("en-AU", {
15163
15187
  day: "2-digit",
15164
15188
  month: "short",
15165
15189
  hour: "2-digit",
@@ -15197,6 +15221,7 @@ function PortfolioActivityPanel({
15197
15221
  onSharePosition,
15198
15222
  onAssetClick,
15199
15223
  onClosePosition,
15224
+ onCloseAllPositions,
15200
15225
  offeringOrders = [],
15201
15226
  openOrders = [],
15202
15227
  orderHistory = [],
@@ -15221,6 +15246,42 @@ function PortfolioActivityPanel({
15221
15246
  const [cancellingAll, setCancellingAll] = useState(false);
15222
15247
  const [closeAllOpen, setCloseAllOpen] = useState(false);
15223
15248
  const [closeAllType, setCloseAllType] = useState("market");
15249
+ const [closingAll, setClosingAll] = useState(false);
15250
+ const settlingPositionIds = positions.filter((p) => p.settling).map((p) => p.propertyId);
15251
+ const settlingKey = settlingPositionIds.join(",");
15252
+ const settlingTradeStartByProperty = /* @__PURE__ */ new Map();
15253
+ const settlingTradeDeadlines = [];
15254
+ for (const trade of tradeHistory) {
15255
+ if (!tradeIsSettling(trade.status)) continue;
15256
+ const startedAt = toMillis(trade.executedAt);
15257
+ settlingTradeDeadlines.push(startedAt + STUCK_SETTLING_MS);
15258
+ const earliest = settlingTradeStartByProperty.get(trade.propertyId);
15259
+ if (earliest === void 0 || startedAt < earliest) settlingTradeStartByProperty.set(trade.propertyId, startedAt);
15260
+ }
15261
+ const tradeDeadlineKey = settlingTradeDeadlines.join(",");
15262
+ const settlingSinceRef = useRef(/* @__PURE__ */ new Map());
15263
+ const [now, setNow] = useState(() => Date.now());
15264
+ useEffect(() => {
15265
+ const since = settlingSinceRef.current;
15266
+ const seenAt = Date.now();
15267
+ for (const id of settlingPositionIds) if (!since.has(id)) since.set(id, seenAt);
15268
+ for (const id of [...since.keys()]) if (!settlingPositionIds.includes(id)) since.delete(id);
15269
+ setNow(seenAt);
15270
+ }, [settlingKey]);
15271
+ const positionSettlingStart = (propertyId) => settlingTradeStartByProperty.get(propertyId) ?? settlingSinceRef.current.get(propertyId) ?? now;
15272
+ useEffect(() => {
15273
+ const pending = [
15274
+ ...settlingPositionIds.map((id) => positionSettlingStart(id) + STUCK_SETTLING_MS),
15275
+ ...settlingTradeDeadlines
15276
+ ].filter((deadline) => deadline > now);
15277
+ if (pending.length === 0) return;
15278
+ const delay = Math.min(Math.min(...pending) - now + 50, 2147483647);
15279
+ const timer = setTimeout(() => setNow(Date.now()), delay);
15280
+ return () => clearTimeout(timer);
15281
+ }, [settlingKey, tradeDeadlineKey, now]);
15282
+ const isPositionStuck = (pos) => !!pos.settling && now - positionSettlingStart(pos.propertyId) >= STUCK_SETTLING_MS;
15283
+ const isTradeStuck = (trade) => now - toMillis(trade.executedAt) >= STUCK_SETTLING_MS;
15284
+ const hasPositionActions = !!(onClosePosition || onSharePosition || onCloseAllPositions);
15224
15285
  const [posSortKey, setPosSortKey] = useState("asset");
15225
15286
  const [posSortAsc, setPosSortAsc] = useState(true);
15226
15287
  const handlePosSort = (key) => {
@@ -15399,7 +15460,6 @@ function PortfolioActivityPanel({
15399
15460
  const pagedTradeHistory = sortedTradeHistory.slice(currentPage * pageSize, (currentPage + 1) * pageSize);
15400
15461
  const pagedTransfers = sortedTransfers.slice(currentPage * pageSize, (currentPage + 1) * pageSize);
15401
15462
  return /* @__PURE__ */ jsxs(Container2, { className, style, children: [
15402
- /* @__PURE__ */ jsx(PanelTitle, { children: "Activity" }),
15403
15463
  /* @__PURE__ */ jsxs(TabContainer, { children: [
15404
15464
  showPositionsTab && /* @__PURE__ */ jsxs(Tab, { $active: activeTab === "positions", onClick: () => handleTabChange("positions"), children: [
15405
15465
  "Trading Positions",
@@ -15455,7 +15515,7 @@ function PortfolioActivityPanel({
15455
15515
  ] }),
15456
15516
  /* @__PURE__ */ jsxs(CToolbarActions, { children: [
15457
15517
  /* @__PURE__ */ jsx(CToolbarLink, { onClick: toggleExpandAll, children: allExpanded ? "Collapse All" : "Expand All" }),
15458
- onClosePosition && /* @__PURE__ */ jsx(CToolbarLink, { onClick: () => setCloseAllOpen(true), children: "Sell All" })
15518
+ onCloseAllPositions && /* @__PURE__ */ jsx(CToolbarLink, { onClick: () => setCloseAllOpen(true), children: "Sell All" })
15459
15519
  ] })
15460
15520
  ] }),
15461
15521
  sortedPositions.map((pos) => {
@@ -15475,7 +15535,7 @@ function PortfolioActivityPanel({
15475
15535
  /* @__PURE__ */ jsx(CCellLabel, { children: "Asset" }),
15476
15536
  /* @__PURE__ */ jsxs(CAssetName, { children: [
15477
15537
  pos.tokenName,
15478
- pos.settling && /* @__PURE__ */ jsx(SettlingTip, { style: { marginLeft: 6 }, children: /* @__PURE__ */ jsx(SettlingSpinner, {}) })
15538
+ pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos), style: { marginLeft: 6 } })
15479
15539
  ] })
15480
15540
  ] }),
15481
15541
  /* @__PURE__ */ jsxs(CUnitsCell, { children: [
@@ -15531,7 +15591,7 @@ function PortfolioActivityPanel({
15531
15591
  })
15532
15592
  ] }),
15533
15593
  positions.length > 0 && !compactPositions && /* @__PURE__ */ jsxs(Fragment, { children: [
15534
- /* @__PURE__ */ jsxs(PositionsHeader, { $hasClose: !!(onClosePosition || onSharePosition), children: [
15594
+ /* @__PURE__ */ jsxs(PositionsHeader, { $hasClose: hasPositionActions, children: [
15535
15595
  /* @__PURE__ */ jsxs(SortableHeaderCell, { $active: posSortKey === "asset", onClick: () => handlePosSort("asset"), children: [
15536
15596
  "Asset ",
15537
15597
  posSortKey === "asset" && (posSortAsc ? "\u2191" : "\u2193")
@@ -15556,7 +15616,7 @@ function PortfolioActivityPanel({
15556
15616
  "PNL (%) ",
15557
15617
  posSortKey === "pnl" && (posSortAsc ? "\u2191" : "\u2193")
15558
15618
  ] }),
15559
- onClosePosition && /* @__PURE__ */ jsx(PositionsHeaderCell, { children: /* @__PURE__ */ jsx(CloseAllHeaderBtn, { onClick: () => setCloseAllOpen(true), children: "Sell All" }) })
15619
+ onCloseAllPositions && /* @__PURE__ */ jsx(PositionsHeaderCell, { children: /* @__PURE__ */ jsx(CloseAllHeaderBtn, { onClick: () => setCloseAllOpen(true), children: "Sell All" }) })
15560
15620
  ] }),
15561
15621
  sortedPositions.map((pos) => {
15562
15622
  const currentValue = pos.totalQuantity * pos.marketPrice;
@@ -15564,10 +15624,10 @@ function PortfolioActivityPanel({
15564
15624
  const pnl = pos.propertyPnl ?? currentValue - costBasis;
15565
15625
  const pnlPercent = pos.propertyPnlPercent ?? pos.percentChange ?? 0;
15566
15626
  const isPositive = pnl >= 0;
15567
- return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: !!(onClosePosition || onSharePosition), children: [
15627
+ return /* @__PURE__ */ jsxs(PositionsRow, { $hasClose: hasPositionActions, children: [
15568
15628
  /* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
15569
15629
  /* @__PURE__ */ jsx(HoldingsPropertyLink, { onClick: () => onPositionClick?.(pos.tokenName, pos.isIpoAllocation), children: pos.tokenName }),
15570
- pos.settling && /* @__PURE__ */ jsx(SettlingTip, { children: /* @__PURE__ */ jsx(SettlingSpinner, {}) })
15630
+ pos.settling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: isPositionStuck(pos) })
15571
15631
  ] }) }),
15572
15632
  /* @__PURE__ */ jsx(PositionsCell, { children: /* @__PURE__ */ jsxs("span", { style: { color: "#fff", fontSize: "0.8rem" }, children: [
15573
15633
  formatNumber2(pos.totalQuantity),
@@ -15611,11 +15671,15 @@ function PortfolioActivityPanel({
15611
15671
  ] }, pos.tokenName);
15612
15672
  })
15613
15673
  ] }),
15614
- positions.length > 0 && closeAllOpen && onClosePosition && typeof document !== "undefined" && createPortal(
15615
- /* @__PURE__ */ jsx(CloseAllOverlay, { onClick: () => setCloseAllOpen(false), children: /* @__PURE__ */ jsxs(CloseAllModal, { onClick: (e) => e.stopPropagation(), children: [
15616
- /* @__PURE__ */ jsx(CloseAllModalX, { onClick: () => setCloseAllOpen(false), children: "\xD7" }),
15674
+ positions.length > 0 && closeAllOpen && onCloseAllPositions && typeof document !== "undefined" && createPortal(
15675
+ /* @__PURE__ */ jsx(CloseAllOverlay, { onClick: () => {
15676
+ if (!closingAll) setCloseAllOpen(false);
15677
+ }, children: /* @__PURE__ */ jsxs(CloseAllModal, { onClick: (e) => e.stopPropagation(), children: [
15678
+ /* @__PURE__ */ jsx(CloseAllModalX, { onClick: () => {
15679
+ if (!closingAll) setCloseAllOpen(false);
15680
+ }, children: "\xD7" }),
15617
15681
  /* @__PURE__ */ jsx(CloseAllTitle, { children: "Confirm Sell All" }),
15618
- /* @__PURE__ */ jsx(CloseAllDesc, { children: "This will sell all your positions and cancel their associated TP/SL orders." }),
15682
+ /* @__PURE__ */ jsx(CloseAllDesc, { children: "This places a sell order for every position you hold, one at a time." }),
15619
15683
  /* @__PURE__ */ jsxs(CloseAllOption, { onClick: () => setCloseAllType("market"), children: [
15620
15684
  /* @__PURE__ */ jsx(CloseAllRadio, { $selected: closeAllType === "market" }),
15621
15685
  /* @__PURE__ */ jsx("span", { children: "Market Sell" })
@@ -15624,14 +15688,22 @@ function PortfolioActivityPanel({
15624
15688
  /* @__PURE__ */ jsx(CloseAllRadio, { $selected: closeAllType === "limit" }),
15625
15689
  /* @__PURE__ */ jsx("span", { children: "Limit Sell at Mid Price" })
15626
15690
  ] }),
15627
- /* @__PURE__ */ jsxs(CloseAllConfirmBtn, { onClick: () => {
15628
- positions.forEach((pos) => onClosePosition(pos.tokenName, closeAllType, pos.quantity, pos.marketPrice));
15629
- setCloseAllOpen(false);
15630
- }, children: [
15631
- "Confirm ",
15632
- closeAllType === "market" ? "Market" : "Limit",
15633
- " Sell"
15634
- ] })
15691
+ /* @__PURE__ */ jsx(
15692
+ CloseAllConfirmBtn,
15693
+ {
15694
+ disabled: closingAll,
15695
+ onClick: async () => {
15696
+ setClosingAll(true);
15697
+ try {
15698
+ await onCloseAllPositions(closeAllType);
15699
+ } finally {
15700
+ setClosingAll(false);
15701
+ setCloseAllOpen(false);
15702
+ }
15703
+ },
15704
+ children: closingAll ? "Selling\u2026" : `Confirm ${closeAllType === "market" ? "Market" : "Limit"} Sell`
15705
+ }
15706
+ )
15635
15707
  ] }) }),
15636
15708
  document.body
15637
15709
  )
@@ -15936,7 +16008,8 @@ function PortfolioActivityPanel({
15936
16008
  const s = trade.status?.toUpperCase();
15937
16009
  const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
15938
16010
  const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
15939
- const isSettling = !isSettled && !isFailed && !!trade.status;
16011
+ const isSettling = tradeIsSettling(trade.status);
16012
+ const stuckSettling = isSettling && isTradeStuck(trade);
15940
16013
  const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
15941
16014
  const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
15942
16015
  const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
@@ -15979,7 +16052,10 @@ function PortfolioActivityPanel({
15979
16052
  ] }),
15980
16053
  /* @__PURE__ */ jsxs(CDetailItem, { children: [
15981
16054
  /* @__PURE__ */ jsx(CDLabel, { children: "Settlement" }),
15982
- /* @__PURE__ */ jsx(CDValue, { children: settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : "\u2014" })
16055
+ /* @__PURE__ */ jsxs(CDValue, { children: [
16056
+ settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : "\u2014",
16057
+ stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true, style: { marginLeft: 6 } })
16058
+ ] })
15983
16059
  ] }),
15984
16060
  /* @__PURE__ */ jsxs(CDetailItem, { children: [
15985
16061
  /* @__PURE__ */ jsx(CDLabel, { children: "Date" }),
@@ -16004,7 +16080,8 @@ function PortfolioActivityPanel({
16004
16080
  const s = trade.status?.toUpperCase();
16005
16081
  const isSettled = s === "SETTLED" || s === "CONFIRMED" || s === "FILLED" || s === "ALLOCATED";
16006
16082
  const isFailed = s === "SETTLEMENT_FAILED" || s === "REJECTED" || s === "CANCELLED" || s === "CANCELED";
16007
- const isSettling = !isSettled && !isFailed && !!trade.status;
16083
+ const isSettling = tradeIsSettling(trade.status);
16084
+ const stuckSettling = isSettling && isTradeStuck(trade);
16008
16085
  const settlementLabel = isSettled ? "Settled" : isFailed ? "Settlement Failed" : isSettling ? prettyLabel(trade.status) : "\u2014";
16009
16086
  const settlementMeta = isSettled ? { color: "#0ecb81", bg: "rgba(14,203,129,0.1)" } : isFailed ? { color: "#f6465d", bg: "rgba(246,70,93,0.12)" } : isSettling ? { color: "#E6C87E", bg: "rgba(240,185,11,0.15)" } : null;
16010
16087
  const sideColor = sideLabel(trade.side) === "Buy" ? "#0ecb81" : "#f6465d";
@@ -16021,7 +16098,10 @@ function PortfolioActivityPanel({
16021
16098
  ] }) }),
16022
16099
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price) }) }),
16023
16100
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { children: formatCurrency4(trade.price * trade.quantity) }) }),
16024
- /* @__PURE__ */ jsx(GridCell, { children: settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }) }),
16101
+ /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsxs("span", { style: { display: "inline-flex", alignItems: "center", gap: "0.35rem" }, children: [
16102
+ settlementMeta ? /* @__PURE__ */ jsx(ActivityTag, { $color: settlementMeta.color, $bg: settlementMeta.bg, children: settlementLabel }) : /* @__PURE__ */ jsx(CellText, { $muted: true, children: "\u2014" }),
16103
+ stuckSettling && /* @__PURE__ */ jsx(SettlingIndicator, { stuck: true })
16104
+ ] }) }),
16025
16105
  /* @__PURE__ */ jsx(GridCell, { children: /* @__PURE__ */ jsx(CellText, { $muted: true, children: formatTimestamp(trade.executedAt) }) }),
16026
16106
  /* @__PURE__ */ jsx(GridCell, { children: trade.txHash && /* @__PURE__ */ jsx(TxLink, { href: `${_blockExplorerBaseUrl}/${trade.txHash}`, target: "_blank", rel: "noopener noreferrer", title: "View on Arbiscan", children: /* @__PURE__ */ jsxs("svg", { width: "15", height: "15", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
16027
16107
  /* @__PURE__ */ jsx("path", { d: "M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" }),
@@ -16190,17 +16270,6 @@ var ContentScroll = styled10.div`
16190
16270
  &::-webkit-scrollbar-track { background: transparent; }
16191
16271
  &::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.1); border-radius: 2px; }
16192
16272
  `;
16193
- var PanelTitle = styled10.h3`
16194
- font-size: 1rem;
16195
- font-weight: 600;
16196
- color: var(--color-text, #fff);
16197
- margin: 0 0 0.75rem;
16198
- padding-left: 1rem;
16199
- /* Redundant on mobile — the tab row already says what this is. Reclaim the space. */
16200
- @media (max-width: 768px) {
16201
- display: none;
16202
- }
16203
- `;
16204
16273
  var TabContainer = styled10.div`
16205
16274
  display: flex;
16206
16275
  gap: 0;
@@ -16653,9 +16722,14 @@ var CloseAllConfirmBtn = styled10.button`
16653
16722
  cursor: pointer;
16654
16723
  transition: all 0.15s ease;
16655
16724
 
16656
- &:hover {
16725
+ &:hover:not(:disabled) {
16657
16726
  background: rgba(246, 70, 93, 0.25);
16658
16727
  }
16728
+
16729
+ &:disabled {
16730
+ opacity: 0.5;
16731
+ cursor: not-allowed;
16732
+ }
16659
16733
  `;
16660
16734
  var CToolbar = styled10.div`
16661
16735
  display: flex;