Skip to content

Fee Selector

Three tier cards — Economy, Standard, Priority — with live sat/vB rates and confirmation ETAs. The primary ring glides between selections on the shared-layout spring; loading shows skeleton rows; stale rates raise an amber refresh bar and dim the cards.

Tier selected

One specimen per selection. The ring is a layoutId border, so in the live product it slides — it never blinks.

economy selected
<FeeSelector tiers={tiers} selected="economy" />
  • --ch-primary
  • --ch-surface
  • --ch-border

2 sat/vB · ~2 hours — patient consolidation.

standard selected
<FeeSelector tiers={tiers} selected="standard" />
  • --ch-primary
  • --ch-surface
  • --ch-border

6 sat/vB · ~30 minutes — the default.

priority selected
<FeeSelector tiers={tiers} selected="priority" />
  • --ch-primary
  • --ch-surface
  • --ch-border

14 sat/vB · ~10 minutes — next-block intent.

Custom rate

Power users type their own sat/vB. The row is a fourth radio; the numeric input stays editable without stealing the selection click.

custom selected
<FeeSelector tiers={tiers} selected="custom" custom={{ satPerVb: 11 }} />
  • --ch-primary
  • --ch-bg-raised
  • --ch-font-family-mono

Custom row active at 11 sat/vB — between standard and priority.

Loading and stale

Loading renders three skeleton rows at tier-card height, so nothing jumps when rates land. Stale keeps the last-known tiers usable but dimmed under an amber refresh bar — old rates are a warning, not an error.

loading
<FeeSelector tiers={tiers} selected="standard" state="loading" />
  • --ch-bg-raised
  • --ch-radius-lg

Fetching estimates from the connected node.

stale
Rates updated 4m ago
<FeeSelector tiers={tiers} selected="standard" state="stale" staleMessage="Rates updated 4m ago" />
  • --ch-warning
  • --ch-warning-muted
  • --ch-border

Rates aged past the refresh window; cards dim to 70% and the bar offers Refresh.

Live selection

Interactive — click between tiers and the custom row to watch the ring glide on springs.glide, and edit the custom rate.

live
<FeeSelector tiers={tiers} selected={selected} onSelect={setSelected} custom={{ satPerVb }} onCustomChange={setSatPerVb} />
  • --ch-primary
  • --ch-surface-raised
  • --ch-focus

Selection and custom rate held in local state; everything else identical to the forced specimens.

Across themes

Standard selected under dark, light, and Harbor Mode — the ring stays primary; only the surfaces shift.

<FeeSelector tiers={tiers} selected="standard" />
  • --ch-primary
  • --ch-surface
  • --ch-border
  • --ch-fg-muted