Requests passing browser, edge, auth, API and database, each stage lighting as one pauses there; auth turns some away in red, the rest come back as responses, and a log lists the latest with method, status and time. Pauses, and stacks on phones.
When to use
- Requests passing browser, edge, auth, API and database, the bad ones turned away at auth.
- API, security and edge products; a live view of real traffic.
When not to use
- Products without an API or an edge to talk about.
- Investigating a single request: a log with its timings says more.
Usage
Request flow with your own data: every prop has the sample as its default, so pass only what you have.
import { useEffect, useRef } from "react"
import { RequestFlow, type ChainHandle } from "@/components/dashral/blocks/request-flow"
const chain = useRef<ChainHandle>(null)
useEffect(() => logs.on("request", (r) => chain.current?.send({ method: r.method, path: r.path, status: r.status, ms: r.ms })), [])
<RequestFlow ref={chain} mode="live" stages={stages} />API reference
RequestFlow
The section: a heading, the chain in a dotted panel with a Live badge and Pause, the latest requests under it, and a row of figures. Every part comes from props, with a sample chain by default.
| Prop | Type | Default |
|---|---|---|
eyebrow | React.ReactNode | "Security" |
title | React.ReactNode | sample |
description | React.ReactNode | sample |
stages | Stage[]The stages a request passes, in order; the one at | sample |
check | number | 2 |
log | Entry[]The log's first rows, newest first, before any request finishes. | sample |
allowed | numberWhere the log's allowed and blocked counts start. | 18_204 |
blocked | number | 312 |
stats | { value: string; label: string }[]The figures under the diagram; none hides the row. | sample |
mode | ChainProps["mode"]With your own traffic instead of sample requests (see Chain's mode="live"); finished ones fill the log. | — |
ref | React.Ref<ChainHandle> | — |
Chain
Requests passing a chain of stages, one after another: each goes forward as a hollow dot, pausing at every stage (it lights up), and comes back as a solid square; the stage at check turns some away (the dot reddens and fades, the stage flashes red). In a row when there's room, stacked on a narrow container. One requestAnimationFrame loop writes the SVG directly; React only hears about finished requests. Sample requests by default; with mode="live", only the ones you send (see ChainHandle). It stops off screen, in a hidden tab, when paused and (live) with nothing on its way; with reduced motion it holds still.
| Prop | Type | Default |
|---|---|---|
stages | Stage[]Required. The stages a request passes, in order. The one at | — |
check | numberRequired. | — |
speed | numberHow fast it runs: 1 is the usual pace, 2 twice as fast, 0 holds it still. | 1 |
paused | booleanBrings it to rest where it is (easing down, not stopping in one frame). | false |
onFinish | (entry: Entry) => voidCalled as each request finishes: back at the start with its response, or turned away at the check. | — |
mode | "demo" | "live""demo" plays sample requests on its own; "live" moves one only when you send it (see ChainHandle). | "demo" |
ref | React.Ref<ChainHandle> | — |
className | string | — |
type Stage
| Prop | Type | Default |
|---|---|---|
id | string | — |
label | string | — |
description | string | — |
detail | string | — |
icon | LucideIcon | — |
metric | { unit: string; value?: number; base?: number }A count on the card, then | — |
type Entry
One request, for the log: let through (with its status and time) or turned away at the check, with why (reason).
| Prop | Type | Default |
|---|---|---|
id | number | — |
method | string | — |
path | string | — |
status | number | — |
ms | number | — |
reason | string | — |
type ChainHandle
Moves requests through a live chain (mode="live").
| Prop | Type | Default |
|---|---|---|
send | (request: { method: string; path: string; status?: number; ms?: number; reason?: string; id?: number }) => voidSends one request along the chain. With a | — |