┌─────────────────────────────────────────────────────────────────┐
│ Live Streams [Export CSV] │
├─────────────────────────────────────────────────────────────────┤
│ [✓] │ ID │ Route │ Asset │ Progress │ Status │ Actions│
├─────┼─────┼────────────┼───────┼──────────┼───────────┼────────┤
│ [✓] │ v 1 │ SENDER... │ 1000 │ ████ 40% │ active │ Cancel │
│ │ │ RECIPIENT..│ USDC │ │ │ │
├─────┼─────┼────────────┼───────┼──────────┼───────────┼────────┤
│ [✓] │ v 2 │ SENDER... │ 500 │ ██ 20% │ scheduled │ Edit │
│ │ │ RECIPIENT..│ XLM │ │ │ Cancel │
├─────┼─────┼────────────┼───────┼──────────┼───────────┼────────┤
│ │ v 3 │ SENDER... │ 2000 │ ████████ │ completed │ Cancel │
│ │ │ RECIPIENT..│ USDC │ 100% │ │ (disabled)
└─────────────────────────────────────────────────────────────────┘
Key Points:
- Checkbox in header selects/deselects all eligible streams
- Only active and scheduled streams show checkboxes
- Completed and canceled streams have no checkbox
┌─────────────────────────────────┐
│ 2 streams selected │
│ [Cancel 2 Streams] │
└─────────────────────────────────┘
During Cancellation:
┌─────────────────────────────────┐
│ 2 streams selected │
│ [Canceling 1/2...] (disabled) │
└─────────────────────────────────┘
- User clicks header checkbox
- All active/scheduled streams get selected
- Floating action bar appears at bottom
- User clicks "Cancel X Streams"
- Button shows progress: "Canceling 1/5...", "Canceling 2/5...", etc.
- After completion:
- Selection cleared
- Action bar disappears
- Table refreshes automatically
- User clicks individual checkboxes
- Action bar appears after first selection
- Count updates: "1 stream selected", "2 streams selected", etc.
- When all eligible streams selected, header checkbox auto-checks
- User can deselect individual streams or use header to deselect all
- User selects 5 streams
- User applies filter that removes 2 of those streams
- Selection automatically cleaned up to only show 3 selected
- Action bar updates count accordingly
- User clicks anywhere inside the table to give it focus context
- User presses Ctrl/Cmd + A — all eligible streams are selected, action bar appears
- User presses Delete — focus moves to the "Cancel X Streams" button (no action taken yet)
- User presses Enter — bulk cancellation begins
- Alternatively, pressing Escape at any point before confirming clears the selection and dismisses the action bar
// Set-based for O(1) lookup
const [selectedStreamIds, setSelectedStreamIds] = useState<Set<string>>(new Set());
// Example state:
// Set { "stream-1", "stream-3", "stream-7" }const [isBulkCanceling, setIsBulkCanceling] = useState(false);
const [bulkCancelProgress, setBulkCancelProgress] = useState({
current: 0,
total: 0
});
// During operation:
// { current: 3, total: 10 }User clicks "Cancel 5 Streams"
↓
Set isBulkCanceling = true
↓
Loop through selected IDs:
↓
┌─────────────────────┐
│ Cancel stream 1 │ → Success ✓
└─────────────────────┘
↓
Update progress: 1/5
↓
┌─────────────────────┐
│ Cancel stream 2 │ → Success ✓
└─────────────────────┘
↓
Update progress: 2/5
↓
┌─────────────────────┐
│ Cancel stream 3 │ → Failed ✗ (logged, continue)
└─────────────────────┘
↓
Update progress: 3/5
↓
... continue for all streams
↓
Clear selection
↓
Refresh table
↓
Set isBulkCanceling = false
↓
Action bar disappears
.bulk-action-bar- Container with fixed positioning.bulk-action-bar__content- Inner content with dark background.bulk-action-bar__count- Text showing selection count.bulk-action-bar__button- Red cancel button
@keyframes bulk-action-slide-up- Smooth entrance animation
- Desktop: Centered, min-width 320px
- Mobile (<768px): Full width with padding
<!-- Header checkbox -->
<input
type="checkbox"
aria-label="Select all streams"
/>
<!-- Row checkbox -->
<input
type="checkbox"
aria-label="Select stream 123"
/>- Tab through checkboxes
- Space to toggle selection
- Tab to action bar button
- Enter to execute bulk cancel
- Ctrl/Cmd + A: Select or deselect all eligible (active/scheduled) streams at once
- Escape: Clear the current selection entirely
- Delete / Backspace: When streams are selected, moves focus to the "Cancel X Streams" button rather than canceling immediately — requires an explicit Enter/click to confirm
- "2 streams selected"
- "Canceling 3 of 10"
- Button disabled state announced
- No Selectable Streams: Header checkbox hidden
- All Streams Completed: No checkboxes shown
- Filter Changes: Selection auto-cleaned
- API Failures: Logged, operation continues
- Rapid Clicking: Button disabled during operation
- Empty Selection: Action bar hidden
- Single Stream: Proper singular text ("1 stream selected")