kaleido-ui 0.1.107 → 0.1.109

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.
@@ -1384,6 +1384,7 @@ function StatusBadge({ status, className }) {
1384
1384
  return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
1385
1385
  "div",
1386
1386
  {
1387
+ "data-slot": "status-badge",
1387
1388
  className: cn(
1388
1389
  "inline-flex items-center gap-1.5 pl-1 pr-2.5 py-1 rounded-full font-medium text-xs",
1389
1390
  bg,
@@ -1844,7 +1845,9 @@ function AssetCard({
1844
1845
  children: displayShown
1845
1846
  }
1846
1847
  ),
1847
- /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex items-center justify-end gap-1 mt-0.5", children: [
1848
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "mt-0.5 flex min-h-6 items-center justify-end gap-1", children: [
1849
+ status && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { status }),
1850
+ status && ticker && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "text-tiny text-muted-foreground", children: "\xB7" }),
1848
1851
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("p", { className: "truncate text-tiny font-medium uppercase tracking-wide text-muted-foreground", children: ticker }),
1849
1852
  showYield && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("div", { title: "Yield Generating Asset", className: "text-success/90 flex items-center justify-center bg-success/10 rounded-full p-0.5", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
1850
1853
  "svg",
@@ -1863,8 +1866,7 @@ function AssetCard({
1863
1866
  ]
1864
1867
  }
1865
1868
  ) })
1866
- ] }),
1867
- status && /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(StatusBadge, { status, className: "mt-2" })
1869
+ ] })
1868
1870
  ] })
1869
1871
  ] })
1870
1872
  ]
@@ -2481,9 +2483,80 @@ function BottomNav({
2481
2483
  // src/web/components/account-status-tabs.tsx
2482
2484
  var import_react7 = require("react");
2483
2485
  var import_jsx_runtime29 = require("react/jsx-runtime");
2486
+ function AccountStatusDetails({
2487
+ account,
2488
+ onEdit
2489
+ }) {
2490
+ return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-6", "data-testid": `account-status-details-${account.id}`, children: [
2491
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogHeader, { className: "text-left", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-start gap-3", children: [
2492
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2493
+ "div",
2494
+ {
2495
+ "data-testid": `account-status-protocol-logo-${account.id}`,
2496
+ className: cn(
2497
+ "flex size-16 shrink-0 items-center justify-center rounded-2xl",
2498
+ account.accentBg
2499
+ ),
2500
+ children: account.detailIcon ?? account.icon
2501
+ }
2502
+ ),
2503
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0", children: [
2504
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
2505
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xxs font-black uppercase tracking-[0.18em] text-muted-foreground", children: account.label }),
2506
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cn("size-2 rounded-full", account.dotTone) })
2507
+ ] }),
2508
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogTitle, { className: "mt-1 text-xl font-bold text-white", children: account.title }),
2509
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogDescription, { className: "mt-2 text-sm leading-relaxed text-white/60", children: account.description })
2510
+ ] })
2511
+ ] }) }),
2512
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-5 grid grid-cols-2 gap-3", children: [
2513
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: cn("rounded-2xl px-4 py-3", account.networkBannerClassName), children: [
2514
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em]", children: "Network" }),
2515
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-1 break-words text-sm font-semibold", children: account.networkLabel })
2516
+ ] }),
2517
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "rounded-2xl bg-muted/40 px-4 py-3", children: [
2518
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Status" }),
2519
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-1 break-words text-sm font-semibold text-white/90", children: account.state })
2520
+ ] })
2521
+ ] }),
2522
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mt-5 text-sm leading-relaxed text-muted-foreground", children: account.detail }),
2523
+ account.details && account.details.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dl", { className: "mt-5 space-y-2 rounded-2xl bg-muted/25 px-4 py-3", children: account.details.map((item) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "grid grid-cols-[max-content_minmax(0,1fr)] gap-3 text-xs", children: [
2524
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dt", { className: "text-muted-foreground", children: item.label }),
2525
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("dd", { className: "min-w-0 break-words text-right font-medium text-white/90", children: item.value })
2526
+ ] }, item.label)) }),
2527
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-5", children: [
2528
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Capabilities" }),
2529
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-3 flex flex-wrap gap-2", children: account.capabilityBullets.map((capability) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2530
+ "span",
2531
+ {
2532
+ className: "inline-flex items-center gap-1.5 rounded-full bg-white/8 px-2.5 py-1 text-xxs font-medium text-white/70",
2533
+ children: [
2534
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "size-1.5 rounded-full bg-primary/70" }),
2535
+ capability
2536
+ ]
2537
+ },
2538
+ capability
2539
+ )) })
2540
+ ] }),
2541
+ onEdit && /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2542
+ Button,
2543
+ {
2544
+ type: "button",
2545
+ "data-testid": `account-status-edit-${account.id}`,
2546
+ onClick: () => onEdit(account.id),
2547
+ className: "mt-6 w-full bg-primary text-primary-foreground hover:bg-primary/90",
2548
+ children: [
2549
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Icon, { name: "settings", size: "sm" }),
2550
+ "Edit Settings"
2551
+ ]
2552
+ }
2553
+ )
2554
+ ] });
2555
+ }
2484
2556
  function AccountStatusTabs({
2485
2557
  accounts,
2486
- onSelect
2558
+ onSelect,
2559
+ onEdit
2487
2560
  }) {
2488
2561
  const [selectedAccountId, setSelectedAccountId] = (0, import_react7.useState)(null);
2489
2562
  const selectedAccount = selectedAccountId ? accounts.find((account) => account.id === selectedAccountId) : null;
@@ -2535,53 +2608,16 @@ function AccountStatusTabs({
2535
2608
  {
2536
2609
  open: selectedAccountId !== null,
2537
2610
  onOpenChange: (open) => !open && setSelectedAccountId(null),
2538
- children: selectedAccount && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogContent, { className: "bg-popover p-0 text-white", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "p-6", children: [
2539
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogHeader, { className: "text-left", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-start gap-3", children: [
2540
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: cn("rounded-2xl p-3", selectedAccount.accentBg), children: selectedAccount.icon }),
2541
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "min-w-0", children: [
2542
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex items-center gap-2", children: [
2543
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "text-xxs font-black uppercase tracking-[0.18em] text-muted-foreground", children: selectedAccount.label }),
2544
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: cn("size-2 rounded-full", selectedAccount.dotTone) })
2545
- ] }),
2546
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogTitle, { className: "mt-1 text-xl font-bold text-white", children: selectedAccount.title }),
2547
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogDescription, { className: "mt-2 text-sm leading-relaxed text-white/60", children: selectedAccount.description })
2548
- ] })
2549
- ] }) }),
2550
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-5 grid grid-cols-2 gap-3", children: [
2551
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2552
- "div",
2553
- {
2554
- className: cn(
2555
- "rounded-2xl px-4 py-3",
2556
- selectedAccount.networkBannerClassName
2557
- ),
2558
- children: [
2559
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em]", children: "Network" }),
2560
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-1 text-sm font-semibold", children: selectedAccount.networkLabel })
2561
- ]
2562
- }
2563
- ),
2564
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "rounded-2xl bg-muted/40 px-4 py-3", children: [
2565
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Status" }),
2566
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-1 text-sm font-semibold text-white/90", children: selectedAccount.state })
2567
- ] })
2568
- ] }),
2569
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("p", { className: "mt-5 text-sm leading-relaxed text-muted-foreground", children: selectedAccount.detail }),
2570
- /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "mt-5", children: [
2571
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Capabilities" }),
2572
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("div", { className: "mt-3 flex flex-wrap gap-2", children: selectedAccount.capabilityBullets.map((capability) => /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)(
2573
- "span",
2574
- {
2575
- className: "inline-flex items-center gap-1.5 rounded-full bg-white/8 px-2.5 py-1 text-xxs font-medium text-white/70",
2576
- children: [
2577
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "size-1.5 rounded-full bg-primary/70" }),
2578
- capability
2579
- ]
2580
- },
2581
- capability
2582
- )) })
2583
- ] })
2584
- ] }) })
2611
+ children: selectedAccount && /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(DialogContent, { className: "bg-popover p-0 text-white", children: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(
2612
+ AccountStatusDetails,
2613
+ {
2614
+ account: selectedAccount,
2615
+ onEdit: onEdit ? (id) => {
2616
+ setSelectedAccountId(null);
2617
+ onEdit(id);
2618
+ } : void 0
2619
+ }
2620
+ ) })
2585
2621
  }
2586
2622
  )
2587
2623
  ] });
@@ -3385,6 +3421,19 @@ function WalletAssetList({
3385
3421
  // src/web/components/balance-breakdown.tsx
3386
3422
  var import_react10 = require("react");
3387
3423
  var import_jsx_runtime37 = require("react/jsx-runtime");
3424
+ function getRgbBtcBreakdownLabels(accounts) {
3425
+ const rlnConnected = Boolean(accounts.RGB?.connected);
3426
+ const rgbL1Connected = Boolean(accounts.RGB_L1?.connected);
3427
+ const rlnEnabled = rlnConnected || !rgbL1Connected && Boolean(accounts.RGB?.configured);
3428
+ const rgbL1Enabled = rgbL1Connected || !rlnConnected && Boolean(accounts.RGB_L1?.configured);
3429
+ return {
3430
+ onchainLabel: rlnEnabled ? "BTC wallet on RLN" : rgbL1Enabled ? "BTC on RGB L1" : "BTC on-chain",
3431
+ onchainSublabel: rlnEnabled ? "RLN on-chain wallet" : rgbL1Enabled ? "RGB L1 wallet balance" : "Standard Bitcoin balance",
3432
+ showLightning: rlnEnabled,
3433
+ lightningLabel: "BTC channels on RLN",
3434
+ lightningSublabel: "RLN channel balance"
3435
+ };
3436
+ }
3388
3437
  function OnchainIcon({ className = "" }) {
3389
3438
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3390
3439
  "span",
@@ -3436,6 +3485,7 @@ function BalanceBreakdown({
3436
3485
  }) {
3437
3486
  const [expanded, setExpanded] = (0, import_react10.useState)(false);
3438
3487
  const fiatTotal = formatFiatValue(totalBTC);
3488
+ const rgbBtcLabels = getRgbBtcBreakdownLabels(accounts);
3439
3489
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: `flex flex-col ${compact ? "gap-2" : "gap-3"}`, children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)(
3440
3490
  "div",
3441
3491
  {
@@ -3497,13 +3547,15 @@ function BalanceBreakdown({
3497
3547
  "button",
3498
3548
  {
3499
3549
  onClick: () => setExpanded(!expanded),
3550
+ "aria-label": expanded ? "Collapse balance breakdown" : "Expand balance breakdown",
3551
+ "aria-expanded": expanded,
3500
3552
  className: "flex size-7 items-center justify-center rounded-full bg-white/[0.08] transition-all hover:bg-white/[0.12]",
3501
3553
  children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3502
3554
  Icon,
3503
3555
  {
3504
3556
  name: expanded ? "expand_less" : "expand_more",
3505
- size: "sm",
3506
- className: "text-white/60"
3557
+ size: "md",
3558
+ className: "size-7 text-white/60"
3507
3559
  }
3508
3560
  )
3509
3561
  }
@@ -3522,8 +3574,8 @@ function BalanceBreakdown({
3522
3574
  icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(OnchainIcon, { className: "text-icon-sm" }),
3523
3575
  iconColor: "text-network-spark",
3524
3576
  dotColor: "bg-network-spark",
3525
- label: "BTC on-chain",
3526
- sublabel: "Standard Bitcoin balance",
3577
+ label: rgbBtcLabels.onchainLabel,
3578
+ sublabel: rgbBtcLabels.onchainSublabel,
3527
3579
  amount: btcOnchain,
3528
3580
  isPending: btcOnchainPending,
3529
3581
  visible: balanceVisible,
@@ -3531,7 +3583,7 @@ function BalanceBreakdown({
3531
3583
  formatFiat: formatFiatValue
3532
3584
  }
3533
3585
  ),
3534
- (accounts.RGB?.connected || accounts.RGB?.configured) && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3586
+ rgbBtcLabels.showLightning && /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
3535
3587
  NetworkRow,
3536
3588
  {
3537
3589
  icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
@@ -3544,8 +3596,8 @@ function BalanceBreakdown({
3544
3596
  ),
3545
3597
  iconColor: "text-network-lightning",
3546
3598
  dotColor: "bg-network-lightning",
3547
- label: "BTC on RLN",
3548
- sublabel: "RLN balance",
3599
+ label: rgbBtcLabels.lightningLabel,
3600
+ sublabel: rgbBtcLabels.lightningSublabel,
3549
3601
  amount: btcLightning,
3550
3602
  isPending: btcLightningPending,
3551
3603
  visible: balanceVisible,
@@ -4659,7 +4711,7 @@ function ActivityList({
4659
4711
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "flex flex-col items-center justify-center py-16", children: [
4660
4712
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "mb-4 flex size-16 items-center justify-center rounded-full bg-white/5", children: emptyIcon ?? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(DefaultEmptyIcon, { name: "receipt_long" }) }),
4661
4713
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("h3", { className: "mb-1 text-base font-semibold", children: hasActiveFilters ? filteredEmptyTitle : emptyTitle }),
4662
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "mb-4 max-w-[240px] text-center text-xs text-muted-foreground", children: hasActiveFilters ? filteredEmptyDescription : emptyDescription }),
4714
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("p", { className: "mb-4 max-w-[240px] text-center text-xs text-white/70", children: hasActiveFilters ? filteredEmptyDescription : emptyDescription }),
4663
4715
  hasActiveFilters && onClearFilters ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(Button, { variant: "surface", size: "sm", onClick: onClearFilters, children: "Clear Filters" }) : renderEmptyActions?.()
4664
4716
  ] });
4665
4717
  }
@@ -4669,7 +4721,7 @@ function ActivityList({
4669
4721
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
4670
4722
  "div",
4671
4723
  {
4672
- className: "relative overflow-hidden rounded-2xl bg-surface-card bg-gradient-to-b from-white/[0.025] to-primary/[0.035] shadow-inner transition-all animate-in fade-in slide-in-from-bottom-2 duration-500",
4724
+ className: "relative overflow-hidden rounded-2xl bg-card bg-none shadow-inner transition-all animate-in fade-in slide-in-from-bottom-2 duration-500",
4673
4725
  children: [
4674
4726
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4675
4727
  TransactionCard,
@@ -4682,7 +4734,7 @@ function ActivityList({
4682
4734
  onSubAmountInfo: item.onSubAmountInfo,
4683
4735
  timestamp: item.timestamp,
4684
4736
  onClick: () => onExpandedChange?.(isExpanded ? null : item.id),
4685
- className: "relative z-[1]"
4737
+ className: cn("relative z-[1] bg-card", isExpanded && "shadow-none")
4686
4738
  }
4687
4739
  ),
4688
4740
  isExpanded && // -mt-4/pt-4 slides the details up behind the card's bottom
@@ -4714,63 +4766,69 @@ function ActivityFilterBar({
4714
4766
  onClearFilters,
4715
4767
  searchPlaceholder = "Search by txid, asset..."
4716
4768
  }) {
4717
- return (
4718
- // All three controls (search input, status dropdown, clear button) share
4719
- // the same h-11 height and rounded-2xl card radius so the bar reads as
4720
- // one family with the cards below it.
4721
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex h-11 items-center gap-2", children: [
4722
- /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative h-full flex-1", children: [
4723
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4724
- AppIcon,
4725
- {
4726
- name: "search",
4727
- className: "absolute left-3 top-1/2 size-4 -translate-y-1/2 text-white/40"
4728
- }
4729
- ),
4730
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4731
- "input",
4732
- {
4733
- type: "text",
4734
- placeholder: searchPlaceholder,
4735
- value: searchTerm,
4736
- onChange: (event) => onSearchTermChange(event.target.value),
4737
- className: "h-full w-full rounded-2xl bg-surface-card pl-9 pr-8 text-xs text-white shadow-inner backdrop-blur-xl transition-all placeholder:text-white/30 focus:bg-surface-elevated focus:outline-none"
4738
- }
4739
- ),
4740
- searchTerm && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4741
- "button",
4742
- {
4743
- type: "button",
4744
- onClick: () => onSearchTermChange(""),
4745
- className: "absolute right-2 top-1/2 -translate-y-1/2 text-white/40 transition-colors hover:text-white",
4746
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(AppIcon, { name: "close", className: "size-icon-sm" })
4747
- }
4748
- )
4749
- ] }),
4750
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "h-full w-28 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
4751
- Select,
4769
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "flex h-11 items-center gap-2", children: [
4770
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "relative h-full flex-1", children: [
4771
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4772
+ AppIcon,
4752
4773
  {
4753
- value: statusFilter,
4754
- onValueChange: (value) => onStatusFilterChange(value),
4755
- children: [
4756
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectTrigger, { className: "h-full rounded-2xl border-0 bg-surface-card px-3 py-0 text-xs font-bold text-white shadow-inner backdrop-blur-xl hover:bg-surface-elevated focus:ring-0 data-[state=open]:bg-surface-elevated", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectValue, {}) }),
4757
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectContent, { className: "bg-popover/95 p-1.5 shadow-popover", children: statusOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectItem, { value: option.value, className: "py-2 text-xs", children: option.label }, option.value)) })
4758
- ]
4774
+ name: "search",
4775
+ size: "sm",
4776
+ className: "absolute left-3 top-1/2 -translate-y-1/2 text-white/30"
4759
4777
  }
4760
- ) }),
4761
- hasActiveFilters && onClearFilters && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4762
- Button,
4778
+ ),
4779
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4780
+ "input",
4763
4781
  {
4764
- variant: "surface",
4765
- size: "icon-lg",
4766
- onClick: onClearFilters,
4767
- title: "Clear Filters",
4768
- className: "h-11 w-11 shrink-0 rounded-2xl",
4769
- children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(AppIcon, { name: "close", className: "size-icon-lg" })
4782
+ type: "text",
4783
+ "data-testid": "activity-search",
4784
+ placeholder: searchPlaceholder,
4785
+ value: searchTerm,
4786
+ onChange: (event) => onSearchTermChange(event.target.value),
4787
+ className: "h-full w-full rounded-xl border border-transparent bg-white/5 py-2.5 pl-10 pr-8 text-sm text-white outline-none transition-all placeholder:text-white/25 focus:border-primary/25 focus:bg-white/8"
4788
+ }
4789
+ ),
4790
+ searchTerm && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4791
+ "button",
4792
+ {
4793
+ type: "button",
4794
+ "aria-label": "Clear search",
4795
+ onClick: () => onSearchTermChange(""),
4796
+ className: "absolute right-2 top-1/2 -translate-y-1/2 rounded-md p-1 text-white/40 transition-colors hover:text-white",
4797
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(AppIcon, { name: "close", size: "sm" })
4770
4798
  }
4771
4799
  )
4772
- ] })
4773
- );
4800
+ ] }),
4801
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "h-full w-28 shrink-0", children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
4802
+ Select,
4803
+ {
4804
+ value: statusFilter,
4805
+ onValueChange: (value) => onStatusFilterChange(value),
4806
+ children: [
4807
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4808
+ SelectTrigger,
4809
+ {
4810
+ "aria-label": "Filter activity by status",
4811
+ className: "h-full rounded-xl border-0 bg-white/5 px-3 py-0 text-xs font-bold text-white shadow-none hover:bg-white/8 focus:ring-0 data-[state=open]:bg-white/8",
4812
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectValue, {})
4813
+ }
4814
+ ),
4815
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectContent, { className: "bg-popover/95 p-1.5 shadow-popover", children: statusOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(SelectItem, { value: option.value, className: "py-2 text-xs", children: option.label }, option.value)) })
4816
+ ]
4817
+ }
4818
+ ) }),
4819
+ hasActiveFilters && onClearFilters && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
4820
+ Button,
4821
+ {
4822
+ variant: "surface",
4823
+ size: "icon-lg",
4824
+ onClick: onClearFilters,
4825
+ "aria-label": "Clear filters",
4826
+ title: "Clear Filters",
4827
+ className: "h-11 w-11 shrink-0 rounded-xl",
4828
+ children: /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(AppIcon, { name: "close", size: "lg" })
4829
+ }
4830
+ )
4831
+ ] });
4774
4832
  }
4775
4833
 
4776
4834
  // src/web/components/activity-network-filters.tsx
@@ -4793,118 +4851,81 @@ function ActivityNetworkFilters({
4793
4851
  filters,
4794
4852
  activeFilter,
4795
4853
  onChange,
4796
- className
4854
+ className,
4855
+ ariaLabel = "Filter activity by network"
4797
4856
  }) {
4798
4857
  if (filters.length <= 1) return null;
4799
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("div", { className: cn("flex gap-1.5 overflow-x-auto py-0.5 no-scrollbar", className), children: filters.map((filter) => {
4800
- const isActive = activeFilter === filter.value;
4801
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
4802
- "button",
4803
- {
4804
- type: "button",
4805
- onClick: () => onChange(filter.value),
4806
- className: cn(
4807
- // `leading-none` on the button normalizes the line-box for
4808
- // both the icon span and the label span; without it the
4809
- // icon (now `leading-none` from Icon primitive) and the text
4810
- // (default leading) get center-aligned along different
4811
- // visual axes and the glyph drifts above the text.
4812
- "inline-flex shrink-0 items-center gap-1.5 rounded-full px-2.5 py-1.5 text-xxs font-bold uppercase tracking-wider leading-none transition-all active:scale-95",
4813
- isActive ? "bg-primary/15 text-primary shadow-inner hover:bg-primary/20" : "bg-surface-card text-white/45 hover:bg-surface-elevated hover:text-white/80"
4814
- ),
4815
- children: [
4816
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4817
- "span",
4818
- {
4819
- className: cn(
4820
- "flex items-center justify-center",
4821
- isActive ? "opacity-100" : "scale-90 opacity-70"
4858
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4859
+ "div",
4860
+ {
4861
+ role: "group",
4862
+ "aria-label": ariaLabel,
4863
+ className: cn("flex gap-1.5 overflow-x-auto pb-0.5 no-scrollbar", className),
4864
+ children: filters.map((filter) => {
4865
+ const isActive = activeFilter === filter.value;
4866
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsxs)(
4867
+ "button",
4868
+ {
4869
+ type: "button",
4870
+ "aria-pressed": isActive,
4871
+ onClick: () => onChange(filter.value),
4872
+ className: cn(
4873
+ "flex shrink-0 items-center gap-1 rounded-full px-2.5 py-1.5 text-xxs font-bold uppercase tracking-wider transition-all",
4874
+ isActive ? "bg-primary/15 text-primary ring-1 ring-primary/20" : "bg-white/5 text-muted-foreground hover:bg-white/8 hover:text-white"
4875
+ ),
4876
+ children: [
4877
+ /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
4878
+ "span",
4879
+ {
4880
+ "aria-hidden": true,
4881
+ className: "flex size-3 items-center justify-center",
4882
+ children: filter.icon ?? getActivityNetworkFilterIcon(filter.value)
4883
+ }
4822
4884
  ),
4823
- children: filter.icon ?? getActivityNetworkFilterIcon(filter.value)
4824
- }
4825
- ),
4826
- /* @__PURE__ */ (0, import_jsx_runtime43.jsx)("span", { children: filter.label })
4827
- ]
4828
- },
4829
- filter.value
4830
- );
4831
- }) });
4885
+ filter.label
4886
+ ]
4887
+ },
4888
+ filter.value
4889
+ );
4890
+ })
4891
+ }
4892
+ );
4832
4893
  }
4833
4894
 
4834
4895
  // src/web/components/activity-type-tabs.tsx
4835
4896
  var import_jsx_runtime44 = require("react/jsx-runtime");
4836
4897
  function ActivityTypeTabs({ counts = {} }) {
4837
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(TabsList, { className: "grid h-12 w-full grid-cols-4 gap-1 rounded-2xl bg-surface-card p-1 backdrop-blur-xl", children: [
4838
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
4839
- TabsTrigger,
4840
- {
4841
- value: "all",
4842
- className: "h-full rounded-xl px-2 text-xs font-bold tracking-wide transition-all data-[state=active]:bg-surface-elevated data-[state=active]:text-white",
4843
- children: [
4844
- "All",
4845
- counts.all ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "ml-1 opacity-60", children: [
4846
- "(",
4847
- counts.all,
4848
- ")"
4849
- ] }) : null
4850
- ]
4851
- }
4852
- ),
4853
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
4854
- TabsTrigger,
4855
- {
4856
- value: "received",
4857
- className: "group h-full rounded-xl px-1.5 text-xs font-bold tracking-wide transition-all hover:text-tx-receive data-[state=active]:bg-tx-receive/15 data-[state=active]:text-tx-receive data-[state=active]:hover:bg-tx-receive/20 data-[state=active]:hover:text-tx-receive",
4858
- children: [
4859
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4860
- AppIcon,
4861
- {
4862
- name: "receive",
4863
- size: "sm",
4864
- className: "mr-1 shrink-0 leading-none text-muted-foreground transition-colors group-hover:text-tx-receive group-data-[state=active]:text-tx-receive"
4865
- }
4866
- ),
4867
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: "In" })
4868
- ]
4869
- }
4870
- ),
4871
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
4872
- TabsTrigger,
4873
- {
4874
- value: "sent",
4875
- className: "group h-full rounded-xl px-1.5 text-xs font-bold tracking-wide transition-all hover:text-tx-sent data-[state=active]:bg-tx-sent/15 data-[state=active]:text-tx-sent data-[state=active]:hover:bg-tx-sent/20 data-[state=active]:hover:text-tx-sent",
4876
- children: [
4877
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4878
- AppIcon,
4879
- {
4880
- name: "send",
4881
- size: "sm",
4882
- className: "mr-1 shrink-0 leading-none text-muted-foreground transition-colors group-hover:text-tx-sent group-data-[state=active]:text-tx-sent"
4883
- }
4884
- ),
4885
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: "Out" })
4886
- ]
4887
- }
4888
- ),
4889
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
4890
- TabsTrigger,
4891
- {
4892
- value: "swaps",
4893
- className: "group h-full rounded-xl px-1.5 text-xs font-bold tracking-wide transition-all hover:text-network-arkade data-[state=active]:bg-network-arkade/15 data-[state=active]:text-network-arkade data-[state=active]:hover:bg-network-arkade/20 data-[state=active]:hover:text-network-arkade",
4894
- children: [
4895
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4896
- AppIcon,
4897
- {
4898
- name: "swap",
4899
- size: "sm",
4900
- className: "mr-1 shrink-0 leading-none text-muted-foreground transition-colors group-hover:text-network-arkade group-data-[state=active]:text-network-arkade"
4901
- }
4902
- ),
4903
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: "Swaps" })
4904
- ]
4905
- }
4906
- )
4907
- ] });
4898
+ const actions = [
4899
+ { value: "all", label: "All" },
4900
+ { value: "received", label: "In", icon: "receive", actionIcon: "call_received" },
4901
+ { value: "swaps", label: "Swap", icon: "swap", actionIcon: "swap_horiz" },
4902
+ { value: "sent", label: "Out", icon: "send", actionIcon: "arrow_outward" }
4903
+ ];
4904
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(TabsList, { className: "grid h-12 w-full grid-cols-4 gap-1 rounded-2xl bg-surface-card p-1 backdrop-blur-xl", children: actions.map((action) => /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
4905
+ TabsTrigger,
4906
+ {
4907
+ value: action.value,
4908
+ "data-action-icon": action.actionIcon,
4909
+ className: "group h-full rounded-xl px-1.5 text-xs font-bold tracking-wide text-muted-foreground transition-all hover:text-primary data-[state=active]:bg-primary/15 data-[state=active]:text-primary data-[state=active]:hover:bg-primary/20 data-[state=active]:hover:text-primary",
4910
+ children: [
4911
+ action.icon && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
4912
+ AppIcon,
4913
+ {
4914
+ name: action.icon,
4915
+ size: "sm",
4916
+ className: "mr-1 shrink-0 leading-none text-muted-foreground transition-colors group-hover:text-primary group-data-[state=active]:text-primary"
4917
+ }
4918
+ ),
4919
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: action.label }),
4920
+ action.value === "all" && counts.all ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("span", { className: "ml-1", children: [
4921
+ "(",
4922
+ counts.all,
4923
+ ")"
4924
+ ] }) : null
4925
+ ]
4926
+ },
4927
+ action.value
4928
+ )) });
4908
4929
  }
4909
4930
 
4910
4931
  // src/web/components/activity-detail-row.tsx