KQ-659 · BRIDGE/HOP
Bridge Hop
Two chain cards over a hop whose rail carries one node per stage, and a single token puck that crosses it: each completed stage slides the puck to the next node on glide, and the rail itself never fills, so the only thing travelling is the token. The rail's width is measured with a ResizeObserver and the puck moves by x in pixels off that measurement, so it can never overhang at any width; in flight it breathes on drift between two keyframes and stops for a hidden tab. Arrival lands on recoil while the destination balance rolls up on snap, and the stage nodes are real buttons with a roving tabindex whose focus writes the same read-out as hovering.
Attested · Signed by 9 of 12 guards · 0xb7e3…05aa
Bridge locked · 1/4
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/bridge-hop
Props
- stages
- BridgeStage[]
- default locked / attested / relayed / minted
- The hop's nodes source to destination: id, label, and an optional detail and hash for the read-out.
- stage
- number
- default 0
- How many stages have completed; stages.length means arrived.
- from / to
- BridgeChain
- default —
- The two chain cards: a name and a short ticker each.
- amount
- number
- default —
- The sum crossing, printed as a debit on the source card.
- destinationBalance
- number
- default —
- The destination's balance; its digits roll when the transfer lands.
- format
- (value: number) => string
- default Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })
- Formats the amount and the destination balance. The default pins an explicit locale so server and client agree.
- asset
- string
- default "BSN"
- Ticker for the amounts; its first letter is the mark on the token.
- failed
- boolean
- default false
- Stops the token on the stage in flight and marks it danger. Nothing bounces on a failure.
- onStageFocus
- (id: string) => void
- default —
- Fires from the hover or focus that changed the read-out under the rail.
- onArrive
- () => void
- default —
- Fires once, from the effect that observes the last stage completing.
- label
- React.ReactNode
- default —
- Visible caption; omit it and pass aria-label.
| Prop | Type | Default | Description |
|---|---|---|---|
| stages | BridgeStage[] | locked / attested / relayed / minted | The hop's nodes source to destination: id, label, and an optional detail and hash for the read-out. |
| stage | number | 0 | How many stages have completed; stages.length means arrived. |
| from / to | BridgeChain | — | The two chain cards: a name and a short ticker each. |
| amount | number | — | The sum crossing, printed as a debit on the source card. |
| destinationBalance | number | — | The destination's balance; its digits roll when the transfer lands. |
| format | (value: number) => string | Intl.NumberFormat("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 }) | Formats the amount and the destination balance. The default pins an explicit locale so server and client agree. |
| asset | string | "BSN" | Ticker for the amounts; its first letter is the mark on the token. |
| failed | boolean | false | Stops the token on the stage in flight and marks it danger. Nothing bounces on a failure. |
| onStageFocus | (id: string) => void | — | Fires from the hover or focus that changed the read-out under the rail. |
| onArrive | () => void | — | Fires once, from the effect that observes the last stage completing. |
| label | React.ReactNode | — | Visible caption; omit it and pass aria-label. |