Issue Cascade Board
A dark, ambient-glow issue list where cards cascade in, status pills re-layout on change and edges shimmer on hover — built for product launch sections.
This is a WebberUI Pro component
The install command below needs a licence to run; without one it returns 401.
Turn an issue list into a "work in motion" scene for a product launch section: two or three blurred glow orbs drift on a dark backdrop, and rows cascade in from top to bottom as the board scrolls into view. Clicking a status pill cycles it through to do, in progress, in review and done — the pill resizes, its text cross-fades and the status icon redraws. With grouping on, a row flies from its old group to the new one; with auto-play on, the next card advances one step every few seconds. Every icon and sub-part is implemented inside the component.
Bring this into your project
Run this command in your project folder. The CLI adds the source and dependencies; then follow the usage example below.
npx webberui@latest add "https://webberui.com/r/issue-cascade-board.en.json?t=<install token>"Playground
Tune the props live — the code snippet updates as you go, so you can dial in the look you want before copying it.
<IssueCascadeBoard/>
The complete example includes the preview layout and data. Install the component first, then paste this file into your project.
Installation
npx webberui@latest add "https://webberui.com/r/issue-cascade-board.en.json?t=<install token>"Or, once registries are configured in components.json, install it as @webberui/issue-cascade-board.
Usage
import * as React from "react";
import {
IssueCascadeBoard,
type IssueItem,
} from "@/components/ui/issue-cascade-board";
const initial: IssueItem[] = [
{ id: "1", key: "HX-142", title: "Checkout total rounds incorrectly", status: "doing", labels: ["Bug"], assignee: "Ivy Lin", priority: 3 },
{ id: "2", key: "HX-138", title: "Add a Traditional Chinese sort option", status: "review", labels: ["Feature"], assignee: "Ben Chen", priority: 2 },
{ id: "3", key: "HX-151", title: "Trip cards wrap badly on narrow screens", status: "todo", assignee: "Sam Chang", priority: 1 },
];
export function LaunchBoard() {
const [items, setItems] = React.useState(initial);
return (
<IssueCascadeBoard
items={items}
onStatusChange={(id, status) =>
setItems((prev) => prev.map((it) => (it.id === id ? { ...it, status } : it)))
}
groupBy="status"
autoPlay
/>
);
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
items | IssueItem[] | — | Controlled issue list; when provided, status changes are only reported via onStatusChange and the parent updates the list |
defaultItems | IssueItem[] | [] | Initial issue list for uncontrolled mode |
onStatusChange | (id: string, status: IssueStatus) => void | — | Called when a status pill is clicked or auto-play advances a card |
groupBy | "none" | "status" | "none" | status splits rows into four groups; rows fly between groups with a layout animation |
autoPlay | boolean | false | Every interval, advance the next unfinished card by one status |
interval | number | 2200 | Auto-play interval (ms, minimum 400) |
glow | boolean | true | Show the blurred glow orbs in the background |
theme | "dark" | "auto" | "dark" | dark is always dark; auto follows the page light/dark mode |
accent | string | "#6366f1" | Accent for the in-progress status and the glow; falls back to --wb-issue-cascade-accent |
statusLabels | Partial<Record<IssueStatus, string>> | To do / In progress / In review / Done | Override the status display text |
className | string | — | Merged into the root container |
IssueItem
| Field | Type | Default | Description |
|---|---|---|---|
id | string | — | Unique id |
key | string | — | Display identifier such as HX-142, rendered in a monospace font |
title | string | — | Issue title, truncated when too long |
status | "todo" | "doing" | "review" | "done" | — | Current status |
labels | string[] | — | Label chips (shown at 768px and wider) |
assignee | string | — | Assignee name, shown as an initials avatar (last character for CJK names) |
priority | 0 | 1 | 2 | 3 | 0 | Priority bars: none / low / medium / high |
The IssueItem, IssueStatus and IssueCascadeBoardProps types are also exported by name.
How it works
- CSS variables:
--wb-issue-cascade-stagger(default70ms, per-row entrance delay),--wb-issue-cascade-accent(default#6366f1) and--wb-issue-cascade-glow-duration(default1.6s, one turn of the hover edge glow). Override them at the theme level - Entrance: fires once when an IntersectionObserver sees the board enter the viewport; each row goes
y: 16 → 0while opacity andblur(6px)clear, with a spring (stiffness 260, damping 26) for the movement - Status icons: to do is a hollow ring, in progress a ring with a half fill, in review six dashed arcs, done a filled circle with a check — all redrawn with
pathLengthon change - Auto-play: picks the next unfinished card in order and advances it one step; once everything is done it cycles from the cursor back to to do. It pauses while the board is out of view, and the orb drift stops too
- Controlled mode: when you pass
items, the component never changes status on its own — update the array inonStatusChange. Auto-play advances through the same callback
Accessibility
- The issue list is
role="list"; in grouped mode each group is asectionlabelled by its heading - Status pills are
buttons with anaria-labelsuch as "HX-142 status: In progress, click to change"; they are reachable with Tab, toggle with Enter / Space and show afocus-visiblering - Status changes (click, auto-play or a controlled update from outside) are announced through an
aria-live="polite"region - During auto-play a "Pause auto-play" button is provided (WCAG 2.2.2), with
aria-pressedreflecting the paused state - Priority bars and assignee avatars have
role="img"with a text label - When the user has turned on reduce motion, the cascade entrance and layout animations are skipped, the orbs do not drift, the hover edge glow does not rotate, and statuses switch directly
Keycap Shortcut
A React component for keycap-styled shortcut labels — combine multiple keys, mod shows ⌘ or Ctrl per platform, and with listening enabled each keycap presses down and springs back when the user actually hits the matching key, with a ring flash once the whole combo is held.
Multi-Source Queue
A multi-source queue React component where requests from email, phone, forms and walk-ins fly from their source icons into one unified queue along an arc, each keeping a source badge, with multi-select source filtering plus autoplay and pause.