kaleido-ui 0.1.106 → 0.1.108

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,
@@ -3800,6 +3852,42 @@ function readableTagColor(color) {
3800
3852
  const luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
3801
3853
  return luminance < 0.45 ? `color-mix(in srgb, ${color} 45%, white)` : color;
3802
3854
  }
3855
+ var chipBaseClass = "shrink-0 rounded-full text-tiny font-bold uppercase tracking-wide shadow-inner transition-colors";
3856
+ var chipActiveClass = "bg-primary/[0.14] text-primary";
3857
+ var chipIdleClass = "bg-surface-card text-text-dimmed hover:text-white/75";
3858
+ function AssetSelectorNetworkMark({ network }) {
3859
+ return network.iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("img", { src: network.iconUrl, alt: "", className: "size-4 shrink-0 rounded-full" }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-xxs font-bold uppercase leading-none text-muted-foreground", children: network.label.charAt(0) });
3860
+ }
3861
+ function AssetSelectorNetworkFilterTrigger({
3862
+ activeNetworkOption,
3863
+ open,
3864
+ onClick
3865
+ }) {
3866
+ return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
3867
+ "button",
3868
+ {
3869
+ type: "button",
3870
+ onClick,
3871
+ className: cn(
3872
+ chipBaseClass,
3873
+ "flex items-center gap-1.5 py-1.5 pl-2 pr-2.5",
3874
+ activeNetworkOption || open ? chipActiveClass : chipIdleClass
3875
+ ),
3876
+ children: [
3877
+ activeNetworkOption && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AssetSelectorNetworkMark, { network: activeNetworkOption }),
3878
+ activeNetworkOption ? activeNetworkOption.label : "All",
3879
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3880
+ Icon,
3881
+ {
3882
+ name: "expand_more",
3883
+ size: "xs",
3884
+ className: cn("shrink-0 transition-transform duration-200", open && "rotate-180")
3885
+ }
3886
+ )
3887
+ ]
3888
+ }
3889
+ );
3890
+ }
3803
3891
  function AssetSelector({
3804
3892
  label,
3805
3893
  selectedTicker,
@@ -3858,36 +3946,13 @@ function AssetSelector({
3858
3946
  disabled: option.id === disabledId || option.ticker === disabledTicker
3859
3947
  }));
3860
3948
  const categoryLabelById = new Map(categories.map((category) => [category.id, category.label]));
3861
- const chipBaseClass = "shrink-0 rounded-full text-tiny font-bold uppercase tracking-wide shadow-inner transition-colors";
3862
- const chipActiveClass = "bg-primary/[0.14] text-primary";
3863
- const chipIdleClass = "bg-surface-card text-text-dimmed hover:text-white/75";
3864
- const networkMark = (network) => network.iconUrl ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("img", { src: network.iconUrl, alt: "", className: "size-4 shrink-0 rounded-full" }) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-xxs font-bold uppercase leading-none text-muted-foreground", children: network.label.charAt(0) });
3865
3949
  const networkFilterButton = hasNetworkFilter && /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "relative shrink-0", children: [
3866
- /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)(
3867
- "button",
3950
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3951
+ AssetSelectorNetworkFilterTrigger,
3868
3952
  {
3869
- type: "button",
3870
- onClick: () => setNetworkMenuOpen((value) => !value),
3871
- className: cn(
3872
- chipBaseClass,
3873
- "flex items-center gap-1.5 py-1.5 pl-2 pr-2.5",
3874
- activeNetworkOption || networkMenuOpen ? chipActiveClass : chipIdleClass
3875
- ),
3876
- children: [
3877
- activeNetworkOption ? networkMark(activeNetworkOption) : /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "hub", size: "xs", className: "shrink-0" }),
3878
- activeNetworkOption ? activeNetworkOption.label : "All",
3879
- /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(
3880
- Icon,
3881
- {
3882
- name: "expand_more",
3883
- size: "xs",
3884
- className: cn(
3885
- "shrink-0 transition-transform duration-200",
3886
- networkMenuOpen && "rotate-180"
3887
- )
3888
- }
3889
- )
3890
- ]
3953
+ activeNetworkOption,
3954
+ open: networkMenuOpen,
3955
+ onClick: () => setNetworkMenuOpen((value) => !value)
3891
3956
  }
3892
3957
  ),
3893
3958
  networkMenuOpen && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("div", { className: "absolute right-0 top-full z-10 mt-1.5 w-48 overflow-hidden rounded-xl border border-white/[0.08] bg-popover shadow-popover", children: /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "max-h-60 overflow-y-auto p-1", children: [
@@ -3925,7 +3990,7 @@ function AssetSelector({
3925
3990
  isActive ? "bg-primary/[0.14] text-primary" : "text-white/75 hover:bg-accent hover:text-white"
3926
3991
  ),
3927
3992
  children: [
3928
- networkMark(network),
3993
+ /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(AssetSelectorNetworkMark, { network }),
3929
3994
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)("span", { className: "min-w-0 flex-1 truncate text-left", children: network.label }),
3930
3995
  isActive && /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Icon, { name: "check", size: "xs", className: "shrink-0 text-primary" })
3931
3996
  ]
@@ -395,18 +395,26 @@ interface BottomNavProps<TValue extends string = string> {
395
395
  }
396
396
  declare function BottomNav<TValue extends string = string>({ activeView, items, onChange, position, className, }: BottomNavProps<TValue>): react_jsx_runtime.JSX.Element;
397
397
 
398
+ interface AccountStatusDetail {
399
+ label: string;
400
+ value: string;
401
+ }
398
402
  interface AccountStatusTabItem<TId extends string = string> {
399
403
  id: TId;
400
404
  label: string;
401
405
  state: string;
402
406
  detail: string;
403
407
  icon: ReactNode;
408
+ /** Optional larger protocol mark used only in the read-only details modal. */
409
+ detailIcon?: ReactNode;
404
410
  dotTone: string;
405
411
  title: string;
406
412
  description: string;
407
413
  capabilityBullets: string[];
408
414
  networkLabel: string;
409
415
  networkBannerClassName: string;
416
+ /** Extra read-only connection fields mirrored from the account settings page. */
417
+ details?: AccountStatusDetail[];
410
418
  accentBg?: string;
411
419
  /** @deprecated Borderless sweep (DESIGN.md Coherence Rules): the icon tile is tinted via `accentBg` only. Kept for source compat. */
412
420
  accentBorder?: string;
@@ -415,12 +423,13 @@ interface AccountStatusTabsProps<TId extends string = string> {
415
423
  accounts: AccountStatusTabItem<TId>[];
416
424
  /**
417
425
  * If provided, tapping an account chip calls this with the account id
418
- * instead of opening the built-in modal. Use to navigate to a dedicated
419
- * account/network settings page.
426
+ * instead of opening the built-in modal. Use to navigate directly.
420
427
  */
421
428
  onSelect?: (id: TId) => void;
429
+ /** Adds a primary Edit action to the built-in read-only account modal. */
430
+ onEdit?: (id: TId) => void;
422
431
  }
423
- declare function AccountStatusTabs<TId extends string = string>({ accounts, onSelect, }: AccountStatusTabsProps<TId>): react_jsx_runtime.JSX.Element;
432
+ declare function AccountStatusTabs<TId extends string = string>({ accounts, onSelect, onEdit, }: AccountStatusTabsProps<TId>): react_jsx_runtime.JSX.Element;
424
433
 
425
434
  interface InlineSelectorOption {
426
435
  id: string;
@@ -668,7 +677,11 @@ interface BalanceBreakdownAccounts {
668
677
  RGB?: {
669
678
  connected?: boolean;
670
679
  /** RLN is set up on this wallet (node URL / NWC saved) even if the node
671
- * is currently offline. Gates the "BTC on RLN" row. */
680
+ * is currently offline. Gates the RLN-specific BTC rows. */
681
+ configured?: boolean;
682
+ };
683
+ RGB_L1?: {
684
+ connected?: boolean;
672
685
  configured?: boolean;
673
686
  };
674
687
  }
@@ -395,18 +395,26 @@ interface BottomNavProps<TValue extends string = string> {
395
395
  }
396
396
  declare function BottomNav<TValue extends string = string>({ activeView, items, onChange, position, className, }: BottomNavProps<TValue>): react_jsx_runtime.JSX.Element;
397
397
 
398
+ interface AccountStatusDetail {
399
+ label: string;
400
+ value: string;
401
+ }
398
402
  interface AccountStatusTabItem<TId extends string = string> {
399
403
  id: TId;
400
404
  label: string;
401
405
  state: string;
402
406
  detail: string;
403
407
  icon: ReactNode;
408
+ /** Optional larger protocol mark used only in the read-only details modal. */
409
+ detailIcon?: ReactNode;
404
410
  dotTone: string;
405
411
  title: string;
406
412
  description: string;
407
413
  capabilityBullets: string[];
408
414
  networkLabel: string;
409
415
  networkBannerClassName: string;
416
+ /** Extra read-only connection fields mirrored from the account settings page. */
417
+ details?: AccountStatusDetail[];
410
418
  accentBg?: string;
411
419
  /** @deprecated Borderless sweep (DESIGN.md Coherence Rules): the icon tile is tinted via `accentBg` only. Kept for source compat. */
412
420
  accentBorder?: string;
@@ -415,12 +423,13 @@ interface AccountStatusTabsProps<TId extends string = string> {
415
423
  accounts: AccountStatusTabItem<TId>[];
416
424
  /**
417
425
  * If provided, tapping an account chip calls this with the account id
418
- * instead of opening the built-in modal. Use to navigate to a dedicated
419
- * account/network settings page.
426
+ * instead of opening the built-in modal. Use to navigate directly.
420
427
  */
421
428
  onSelect?: (id: TId) => void;
429
+ /** Adds a primary Edit action to the built-in read-only account modal. */
430
+ onEdit?: (id: TId) => void;
422
431
  }
423
- declare function AccountStatusTabs<TId extends string = string>({ accounts, onSelect, }: AccountStatusTabsProps<TId>): react_jsx_runtime.JSX.Element;
432
+ declare function AccountStatusTabs<TId extends string = string>({ accounts, onSelect, onEdit, }: AccountStatusTabsProps<TId>): react_jsx_runtime.JSX.Element;
424
433
 
425
434
  interface InlineSelectorOption {
426
435
  id: string;
@@ -668,7 +677,11 @@ interface BalanceBreakdownAccounts {
668
677
  RGB?: {
669
678
  connected?: boolean;
670
679
  /** RLN is set up on this wallet (node URL / NWC saved) even if the node
671
- * is currently offline. Gates the "BTC on RLN" row. */
680
+ * is currently offline. Gates the RLN-specific BTC rows. */
681
+ configured?: boolean;
682
+ };
683
+ RGB_L1?: {
684
+ connected?: boolean;
672
685
  configured?: boolean;
673
686
  };
674
687
  }
package/dist/web/index.js CHANGED
@@ -1196,6 +1196,7 @@ function StatusBadge({ status, className }) {
1196
1196
  return /* @__PURE__ */ jsxs6(
1197
1197
  "div",
1198
1198
  {
1199
+ "data-slot": "status-badge",
1199
1200
  className: cn(
1200
1201
  "inline-flex items-center gap-1.5 pl-1 pr-2.5 py-1 rounded-full font-medium text-xs",
1201
1202
  bg,
@@ -1656,7 +1657,9 @@ function AssetCard({
1656
1657
  children: displayShown
1657
1658
  }
1658
1659
  ),
1659
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-end gap-1 mt-0.5", children: [
1660
+ /* @__PURE__ */ jsxs9("div", { className: "mt-0.5 flex min-h-6 items-center justify-end gap-1", children: [
1661
+ status && /* @__PURE__ */ jsx20(StatusBadge, { status }),
1662
+ status && ticker && /* @__PURE__ */ jsx20("span", { className: "text-tiny text-muted-foreground", children: "\xB7" }),
1660
1663
  /* @__PURE__ */ jsx20("p", { className: "truncate text-tiny font-medium uppercase tracking-wide text-muted-foreground", children: ticker }),
1661
1664
  showYield && /* @__PURE__ */ jsx20("div", { title: "Yield Generating Asset", className: "text-success/90 flex items-center justify-center bg-success/10 rounded-full p-0.5", children: /* @__PURE__ */ jsxs9(
1662
1665
  "svg",
@@ -1675,8 +1678,7 @@ function AssetCard({
1675
1678
  ]
1676
1679
  }
1677
1680
  ) })
1678
- ] }),
1679
- status && /* @__PURE__ */ jsx20(StatusBadge, { status, className: "mt-2" })
1681
+ ] })
1680
1682
  ] })
1681
1683
  ] })
1682
1684
  ]
@@ -2299,9 +2301,80 @@ function BottomNav({
2299
2301
  // src/web/components/account-status-tabs.tsx
2300
2302
  import { useState as useState7 } from "react";
2301
2303
  import { Fragment as Fragment2, jsx as jsx29, jsxs as jsxs16 } from "react/jsx-runtime";
2304
+ function AccountStatusDetails({
2305
+ account,
2306
+ onEdit
2307
+ }) {
2308
+ return /* @__PURE__ */ jsxs16("div", { className: "p-6", "data-testid": `account-status-details-${account.id}`, children: [
2309
+ /* @__PURE__ */ jsx29(DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3", children: [
2310
+ /* @__PURE__ */ jsx29(
2311
+ "div",
2312
+ {
2313
+ "data-testid": `account-status-protocol-logo-${account.id}`,
2314
+ className: cn(
2315
+ "flex size-16 shrink-0 items-center justify-center rounded-2xl",
2316
+ account.accentBg
2317
+ ),
2318
+ children: account.detailIcon ?? account.icon
2319
+ }
2320
+ ),
2321
+ /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
2322
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
2323
+ /* @__PURE__ */ jsx29("span", { className: "text-xxs font-black uppercase tracking-[0.18em] text-muted-foreground", children: account.label }),
2324
+ /* @__PURE__ */ jsx29("span", { className: cn("size-2 rounded-full", account.dotTone) })
2325
+ ] }),
2326
+ /* @__PURE__ */ jsx29(DialogTitle, { className: "mt-1 text-xl font-bold text-white", children: account.title }),
2327
+ /* @__PURE__ */ jsx29(DialogDescription, { className: "mt-2 text-sm leading-relaxed text-white/60", children: account.description })
2328
+ ] })
2329
+ ] }) }),
2330
+ /* @__PURE__ */ jsxs16("div", { className: "mt-5 grid grid-cols-2 gap-3", children: [
2331
+ /* @__PURE__ */ jsxs16("div", { className: cn("rounded-2xl px-4 py-3", account.networkBannerClassName), children: [
2332
+ /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em]", children: "Network" }),
2333
+ /* @__PURE__ */ jsx29("div", { className: "mt-1 break-words text-sm font-semibold", children: account.networkLabel })
2334
+ ] }),
2335
+ /* @__PURE__ */ jsxs16("div", { className: "rounded-2xl bg-muted/40 px-4 py-3", children: [
2336
+ /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Status" }),
2337
+ /* @__PURE__ */ jsx29("div", { className: "mt-1 break-words text-sm font-semibold text-white/90", children: account.state })
2338
+ ] })
2339
+ ] }),
2340
+ /* @__PURE__ */ jsx29("p", { className: "mt-5 text-sm leading-relaxed text-muted-foreground", children: account.detail }),
2341
+ account.details && account.details.length > 0 && /* @__PURE__ */ jsx29("dl", { className: "mt-5 space-y-2 rounded-2xl bg-muted/25 px-4 py-3", children: account.details.map((item) => /* @__PURE__ */ jsxs16("div", { className: "grid grid-cols-[max-content_minmax(0,1fr)] gap-3 text-xs", children: [
2342
+ /* @__PURE__ */ jsx29("dt", { className: "text-muted-foreground", children: item.label }),
2343
+ /* @__PURE__ */ jsx29("dd", { className: "min-w-0 break-words text-right font-medium text-white/90", children: item.value })
2344
+ ] }, item.label)) }),
2345
+ /* @__PURE__ */ jsxs16("div", { className: "mt-5", children: [
2346
+ /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Capabilities" }),
2347
+ /* @__PURE__ */ jsx29("div", { className: "mt-3 flex flex-wrap gap-2", children: account.capabilityBullets.map((capability) => /* @__PURE__ */ jsxs16(
2348
+ "span",
2349
+ {
2350
+ 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",
2351
+ children: [
2352
+ /* @__PURE__ */ jsx29("span", { className: "size-1.5 rounded-full bg-primary/70" }),
2353
+ capability
2354
+ ]
2355
+ },
2356
+ capability
2357
+ )) })
2358
+ ] }),
2359
+ onEdit && /* @__PURE__ */ jsxs16(
2360
+ Button,
2361
+ {
2362
+ type: "button",
2363
+ "data-testid": `account-status-edit-${account.id}`,
2364
+ onClick: () => onEdit(account.id),
2365
+ className: "mt-6 w-full bg-primary text-primary-foreground hover:bg-primary/90",
2366
+ children: [
2367
+ /* @__PURE__ */ jsx29(Icon, { name: "settings", size: "sm" }),
2368
+ "Edit Settings"
2369
+ ]
2370
+ }
2371
+ )
2372
+ ] });
2373
+ }
2302
2374
  function AccountStatusTabs({
2303
2375
  accounts,
2304
- onSelect
2376
+ onSelect,
2377
+ onEdit
2305
2378
  }) {
2306
2379
  const [selectedAccountId, setSelectedAccountId] = useState7(null);
2307
2380
  const selectedAccount = selectedAccountId ? accounts.find((account) => account.id === selectedAccountId) : null;
@@ -2353,53 +2426,16 @@ function AccountStatusTabs({
2353
2426
  {
2354
2427
  open: selectedAccountId !== null,
2355
2428
  onOpenChange: (open) => !open && setSelectedAccountId(null),
2356
- children: selectedAccount && /* @__PURE__ */ jsx29(DialogContent, { className: "bg-popover p-0 text-white", children: /* @__PURE__ */ jsxs16("div", { className: "p-6", children: [
2357
- /* @__PURE__ */ jsx29(DialogHeader, { className: "text-left", children: /* @__PURE__ */ jsxs16("div", { className: "flex items-start gap-3", children: [
2358
- /* @__PURE__ */ jsx29("div", { className: cn("rounded-2xl p-3", selectedAccount.accentBg), children: selectedAccount.icon }),
2359
- /* @__PURE__ */ jsxs16("div", { className: "min-w-0", children: [
2360
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
2361
- /* @__PURE__ */ jsx29("span", { className: "text-xxs font-black uppercase tracking-[0.18em] text-muted-foreground", children: selectedAccount.label }),
2362
- /* @__PURE__ */ jsx29("span", { className: cn("size-2 rounded-full", selectedAccount.dotTone) })
2363
- ] }),
2364
- /* @__PURE__ */ jsx29(DialogTitle, { className: "mt-1 text-xl font-bold text-white", children: selectedAccount.title }),
2365
- /* @__PURE__ */ jsx29(DialogDescription, { className: "mt-2 text-sm leading-relaxed text-white/60", children: selectedAccount.description })
2366
- ] })
2367
- ] }) }),
2368
- /* @__PURE__ */ jsxs16("div", { className: "mt-5 grid grid-cols-2 gap-3", children: [
2369
- /* @__PURE__ */ jsxs16(
2370
- "div",
2371
- {
2372
- className: cn(
2373
- "rounded-2xl px-4 py-3",
2374
- selectedAccount.networkBannerClassName
2375
- ),
2376
- children: [
2377
- /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em]", children: "Network" }),
2378
- /* @__PURE__ */ jsx29("div", { className: "mt-1 text-sm font-semibold", children: selectedAccount.networkLabel })
2379
- ]
2380
- }
2381
- ),
2382
- /* @__PURE__ */ jsxs16("div", { className: "rounded-2xl bg-muted/40 px-4 py-3", children: [
2383
- /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Status" }),
2384
- /* @__PURE__ */ jsx29("div", { className: "mt-1 text-sm font-semibold text-white/90", children: selectedAccount.state })
2385
- ] })
2386
- ] }),
2387
- /* @__PURE__ */ jsx29("p", { className: "mt-5 text-sm leading-relaxed text-muted-foreground", children: selectedAccount.detail }),
2388
- /* @__PURE__ */ jsxs16("div", { className: "mt-5", children: [
2389
- /* @__PURE__ */ jsx29("div", { className: "text-icon-xxs font-black uppercase tracking-[0.18em] text-white/45", children: "Capabilities" }),
2390
- /* @__PURE__ */ jsx29("div", { className: "mt-3 flex flex-wrap gap-2", children: selectedAccount.capabilityBullets.map((capability) => /* @__PURE__ */ jsxs16(
2391
- "span",
2392
- {
2393
- 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",
2394
- children: [
2395
- /* @__PURE__ */ jsx29("span", { className: "size-1.5 rounded-full bg-primary/70" }),
2396
- capability
2397
- ]
2398
- },
2399
- capability
2400
- )) })
2401
- ] })
2402
- ] }) })
2429
+ children: selectedAccount && /* @__PURE__ */ jsx29(DialogContent, { className: "bg-popover p-0 text-white", children: /* @__PURE__ */ jsx29(
2430
+ AccountStatusDetails,
2431
+ {
2432
+ account: selectedAccount,
2433
+ onEdit: onEdit ? (id) => {
2434
+ setSelectedAccountId(null);
2435
+ onEdit(id);
2436
+ } : void 0
2437
+ }
2438
+ ) })
2403
2439
  }
2404
2440
  )
2405
2441
  ] });
@@ -3203,6 +3239,19 @@ function WalletAssetList({
3203
3239
  // src/web/components/balance-breakdown.tsx
3204
3240
  import { useState as useState10 } from "react";
3205
3241
  import { Fragment as Fragment5, jsx as jsx37, jsxs as jsxs24 } from "react/jsx-runtime";
3242
+ function getRgbBtcBreakdownLabels(accounts) {
3243
+ const rlnConnected = Boolean(accounts.RGB?.connected);
3244
+ const rgbL1Connected = Boolean(accounts.RGB_L1?.connected);
3245
+ const rlnEnabled = rlnConnected || !rgbL1Connected && Boolean(accounts.RGB?.configured);
3246
+ const rgbL1Enabled = rgbL1Connected || !rlnConnected && Boolean(accounts.RGB_L1?.configured);
3247
+ return {
3248
+ onchainLabel: rlnEnabled ? "BTC wallet on RLN" : rgbL1Enabled ? "BTC on RGB L1" : "BTC on-chain",
3249
+ onchainSublabel: rlnEnabled ? "RLN on-chain wallet" : rgbL1Enabled ? "RGB L1 wallet balance" : "Standard Bitcoin balance",
3250
+ showLightning: rlnEnabled,
3251
+ lightningLabel: "BTC channels on RLN",
3252
+ lightningSublabel: "RLN channel balance"
3253
+ };
3254
+ }
3206
3255
  function OnchainIcon({ className = "" }) {
3207
3256
  return /* @__PURE__ */ jsx37(
3208
3257
  "span",
@@ -3254,6 +3303,7 @@ function BalanceBreakdown({
3254
3303
  }) {
3255
3304
  const [expanded, setExpanded] = useState10(false);
3256
3305
  const fiatTotal = formatFiatValue(totalBTC);
3306
+ const rgbBtcLabels = getRgbBtcBreakdownLabels(accounts);
3257
3307
  return /* @__PURE__ */ jsx37("div", { className: `flex flex-col ${compact ? "gap-2" : "gap-3"}`, children: /* @__PURE__ */ jsxs24(
3258
3308
  "div",
3259
3309
  {
@@ -3315,13 +3365,15 @@ function BalanceBreakdown({
3315
3365
  "button",
3316
3366
  {
3317
3367
  onClick: () => setExpanded(!expanded),
3368
+ "aria-label": expanded ? "Collapse balance breakdown" : "Expand balance breakdown",
3369
+ "aria-expanded": expanded,
3318
3370
  className: "flex size-7 items-center justify-center rounded-full bg-white/[0.08] transition-all hover:bg-white/[0.12]",
3319
3371
  children: /* @__PURE__ */ jsx37(
3320
3372
  Icon,
3321
3373
  {
3322
3374
  name: expanded ? "expand_less" : "expand_more",
3323
- size: "sm",
3324
- className: "text-white/60"
3375
+ size: "md",
3376
+ className: "size-7 text-white/60"
3325
3377
  }
3326
3378
  )
3327
3379
  }
@@ -3340,8 +3392,8 @@ function BalanceBreakdown({
3340
3392
  icon: /* @__PURE__ */ jsx37(OnchainIcon, { className: "text-icon-sm" }),
3341
3393
  iconColor: "text-network-spark",
3342
3394
  dotColor: "bg-network-spark",
3343
- label: "BTC on-chain",
3344
- sublabel: "Standard Bitcoin balance",
3395
+ label: rgbBtcLabels.onchainLabel,
3396
+ sublabel: rgbBtcLabels.onchainSublabel,
3345
3397
  amount: btcOnchain,
3346
3398
  isPending: btcOnchainPending,
3347
3399
  visible: balanceVisible,
@@ -3349,7 +3401,7 @@ function BalanceBreakdown({
3349
3401
  formatFiat: formatFiatValue
3350
3402
  }
3351
3403
  ),
3352
- (accounts.RGB?.connected || accounts.RGB?.configured) && /* @__PURE__ */ jsx37(
3404
+ rgbBtcLabels.showLightning && /* @__PURE__ */ jsx37(
3353
3405
  NetworkRow,
3354
3406
  {
3355
3407
  icon: /* @__PURE__ */ jsx37(
@@ -3362,8 +3414,8 @@ function BalanceBreakdown({
3362
3414
  ),
3363
3415
  iconColor: "text-network-lightning",
3364
3416
  dotColor: "bg-network-lightning",
3365
- label: "BTC on RLN",
3366
- sublabel: "RLN balance",
3417
+ label: rgbBtcLabels.lightningLabel,
3418
+ sublabel: rgbBtcLabels.lightningSublabel,
3367
3419
  amount: btcLightning,
3368
3420
  isPending: btcLightningPending,
3369
3421
  visible: balanceVisible,
@@ -3618,6 +3670,42 @@ function readableTagColor(color) {
3618
3670
  const luminance = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;
3619
3671
  return luminance < 0.45 ? `color-mix(in srgb, ${color} 45%, white)` : color;
3620
3672
  }
3673
+ var chipBaseClass = "shrink-0 rounded-full text-tiny font-bold uppercase tracking-wide shadow-inner transition-colors";
3674
+ var chipActiveClass = "bg-primary/[0.14] text-primary";
3675
+ var chipIdleClass = "bg-surface-card text-text-dimmed hover:text-white/75";
3676
+ function AssetSelectorNetworkMark({ network }) {
3677
+ return network.iconUrl ? /* @__PURE__ */ jsx38("img", { src: network.iconUrl, alt: "", className: "size-4 shrink-0 rounded-full" }) : /* @__PURE__ */ jsx38("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-xxs font-bold uppercase leading-none text-muted-foreground", children: network.label.charAt(0) });
3678
+ }
3679
+ function AssetSelectorNetworkFilterTrigger({
3680
+ activeNetworkOption,
3681
+ open,
3682
+ onClick
3683
+ }) {
3684
+ return /* @__PURE__ */ jsxs25(
3685
+ "button",
3686
+ {
3687
+ type: "button",
3688
+ onClick,
3689
+ className: cn(
3690
+ chipBaseClass,
3691
+ "flex items-center gap-1.5 py-1.5 pl-2 pr-2.5",
3692
+ activeNetworkOption || open ? chipActiveClass : chipIdleClass
3693
+ ),
3694
+ children: [
3695
+ activeNetworkOption && /* @__PURE__ */ jsx38(AssetSelectorNetworkMark, { network: activeNetworkOption }),
3696
+ activeNetworkOption ? activeNetworkOption.label : "All",
3697
+ /* @__PURE__ */ jsx38(
3698
+ Icon,
3699
+ {
3700
+ name: "expand_more",
3701
+ size: "xs",
3702
+ className: cn("shrink-0 transition-transform duration-200", open && "rotate-180")
3703
+ }
3704
+ )
3705
+ ]
3706
+ }
3707
+ );
3708
+ }
3621
3709
  function AssetSelector({
3622
3710
  label,
3623
3711
  selectedTicker,
@@ -3676,36 +3764,13 @@ function AssetSelector({
3676
3764
  disabled: option.id === disabledId || option.ticker === disabledTicker
3677
3765
  }));
3678
3766
  const categoryLabelById = new Map(categories.map((category) => [category.id, category.label]));
3679
- const chipBaseClass = "shrink-0 rounded-full text-tiny font-bold uppercase tracking-wide shadow-inner transition-colors";
3680
- const chipActiveClass = "bg-primary/[0.14] text-primary";
3681
- const chipIdleClass = "bg-surface-card text-text-dimmed hover:text-white/75";
3682
- const networkMark = (network) => network.iconUrl ? /* @__PURE__ */ jsx38("img", { src: network.iconUrl, alt: "", className: "size-4 shrink-0 rounded-full" }) : /* @__PURE__ */ jsx38("span", { className: "flex size-4 shrink-0 items-center justify-center rounded-full bg-muted text-xxs font-bold uppercase leading-none text-muted-foreground", children: network.label.charAt(0) });
3683
3767
  const networkFilterButton = hasNetworkFilter && /* @__PURE__ */ jsxs25("div", { className: "relative shrink-0", children: [
3684
- /* @__PURE__ */ jsxs25(
3685
- "button",
3768
+ /* @__PURE__ */ jsx38(
3769
+ AssetSelectorNetworkFilterTrigger,
3686
3770
  {
3687
- type: "button",
3688
- onClick: () => setNetworkMenuOpen((value) => !value),
3689
- className: cn(
3690
- chipBaseClass,
3691
- "flex items-center gap-1.5 py-1.5 pl-2 pr-2.5",
3692
- activeNetworkOption || networkMenuOpen ? chipActiveClass : chipIdleClass
3693
- ),
3694
- children: [
3695
- activeNetworkOption ? networkMark(activeNetworkOption) : /* @__PURE__ */ jsx38(Icon, { name: "hub", size: "xs", className: "shrink-0" }),
3696
- activeNetworkOption ? activeNetworkOption.label : "All",
3697
- /* @__PURE__ */ jsx38(
3698
- Icon,
3699
- {
3700
- name: "expand_more",
3701
- size: "xs",
3702
- className: cn(
3703
- "shrink-0 transition-transform duration-200",
3704
- networkMenuOpen && "rotate-180"
3705
- )
3706
- }
3707
- )
3708
- ]
3771
+ activeNetworkOption,
3772
+ open: networkMenuOpen,
3773
+ onClick: () => setNetworkMenuOpen((value) => !value)
3709
3774
  }
3710
3775
  ),
3711
3776
  networkMenuOpen && /* @__PURE__ */ jsx38("div", { className: "absolute right-0 top-full z-10 mt-1.5 w-48 overflow-hidden rounded-xl border border-white/[0.08] bg-popover shadow-popover", children: /* @__PURE__ */ jsxs25("div", { className: "max-h-60 overflow-y-auto p-1", children: [
@@ -3743,7 +3808,7 @@ function AssetSelector({
3743
3808
  isActive ? "bg-primary/[0.14] text-primary" : "text-white/75 hover:bg-accent hover:text-white"
3744
3809
  ),
3745
3810
  children: [
3746
- networkMark(network),
3811
+ /* @__PURE__ */ jsx38(AssetSelectorNetworkMark, { network }),
3747
3812
  /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate text-left", children: network.label }),
3748
3813
  isActive && /* @__PURE__ */ jsx38(Icon, { name: "check", size: "xs", className: "shrink-0 text-primary" })
3749
3814
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kaleido-ui",
3
- "version": "0.1.106",
3
+ "version": "0.1.108",
4
4
  "description": "KaleidoSwap shared UI library — design tokens, web components (Tailwind + Radix), and React Native components extending WDK UI Kit",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -43,6 +43,7 @@
43
43
  "showcase": "vite --config showcase/vite.config.ts",
44
44
  "showcase:build": "npm run generate:css && vite build --config showcase/vite.config.ts",
45
45
  "type-check": "tsc --noEmit",
46
+ "test": "node --import tsx --test tests/*.test.tsx",
46
47
  "clean": "rm -rf dist"
47
48
  },
48
49
  "dependencies": {