Skip to content

No.69 · Controls· New

Patch Bay

Routing drawn as cables between jacks. Drag from a source and the cable hangs with real slack (a solved catenary, not a bezier guess); a destination that can't take the signal refuses the plug and says why; click a cable to pull it. Fully usable from the keyboard, with the patch also listed as a table.

The prompt

Copy this text

Automatic copying is unavailable. Copy the selected text using your device’s copy command.

Written for the variant you picked above: Light

Build a patch bay for routing signals (a fictional 'Masar studio routing'). Outputs are { id, name, type } (Signup form → JSON, Studio camera → video, Desk mic → audio, Humidity sensor → number, Docs export → text); inputs are { id, name, accepts[] } (Webhook: JSON; Recorder: video, audio; Dashboard chart: number; Search index: text, JSON; Speakers: audio). Cables are { from, to }; an input holds one cable, an output can feed many. Layout: a 14px-radius panel in Geist. The rack is a three-column grid: source rows on the left (name plus the type in its cable colour), an empty middle for cables, destination rows on the right (name plus what it accepts in mono). Each row is a white tab with a 24px jack on its inner edge: a dark socket with a 4px ring, coloured by the plugged signal. Cables are drawn in an SVG overlay: a 5px coloured line with a soft offset shadow, hanging as a true catenary for a cable 22% longer than the gap (solve 2a·sinh(h/2a) = √(L²−v²) by bisection, sample 28 points). When a cable is plugged in it swings once and settles (slack oscillating and decaying over a second). While carrying a cable, compatible destinations glow green and the rest dim; dropping on an incompatible one shakes the row and shows a red note under it: 'Webhook expects JSON, not video'. Hovering a cable dashes it; clicking pulls it. A collapsible table lists the connections with Unplug buttons. Selected variant — Light (light): Palette for this theme (Light): --pbay-bg #ecebe6; --pbay-face #ffffff; --pbay-focus #2f6fd0; --pbay-ink #1f1f1d; --pbay-line rgb(31 31 29 / 0.12); --pbay-muted #7a7872; --pbay-no #c23d2b; --pbay-ok #2f8a57; --pbay-panel #f8f7f3; --pbay-ring #c9c6bd; --pbay-shadow rgb(0 0 0 / 0.16); --pbay-socket #2b2a27. Treat these as the root colour tokens, one value per role, and name them to suit your code. Select it with the theme option set to "light". Keep every dimension, spacing value, state and motion from the brief unchanged, and keep text at 4.5:1 contrast or better on these surfaces. This selection takes precedence over references to other themes or options in the general brief. Implement this selected appearance; do not add a variant picker or alternative appearances unless requested. Implementation requirements: Use React and TypeScript. Keep the component self-contained, with uniquely scoped CSS and no animation libraries. Include required imports, styles and font setup in the result. Interaction: Drag from a source jack to a destination, or click a source and then a destination. Keyboard: Enter on a source picks up its cable and moves focus to the first compatible destination; ↑/↓ walk the jacks in a column; Enter plugs (or announces the refusal); Escape puts the cable down and returns focus. On a plugged destination, Enter or Delete unplugs. Motion: Plugging in swings the cable once and lets it settle; a refusal shakes the destination row. Both are skipped with reduced motion. Accessibility: Jacks are buttons whose labels say what they carry or take, what is plugged in, and, while carrying a cable, whether this destination will take it. Every change is announced politely. The connections table gives the whole patch without the drawing. Responsive behavior: Columns and padding tighten below 560px; the cable area keeps at least 3.5rem. Cable geometry is re-measured on every resize. Touch: Tap a source then a destination; drag also works with touch. Preserve keyboard access, visible focus and reduced-motion behavior. Keep fictional demo data and simulated service calls in a separate usage example; expose callbacks for real actions and recover from rejected requests. Keep usage-example links inside the demo: use local buttons or prevent navigation. Demonstration links must not navigate to Vitrine routes or open other pages; preserve real URL support in the reusable component itself. Verify the result at narrow and wide viewport sizes, with keyboard input and reduced motion enabled.

Notes

Interaction
Drag from a source jack to a destination, or click a source and then a destination. Keyboard: Enter on a source picks up its cable and moves focus to the first compatible destination; ↑/↓ walk the jacks in a column; Enter plugs (or announces the refusal); Escape puts the cable down and returns focus. On a plugged destination, Enter or Delete unplugs.
Motion
Plugging in swings the cable once and lets it settle; a refusal shakes the destination row. Both are skipped with reduced motion.
Accessibility
Jacks are buttons whose labels say what they carry or take, what is plugged in, and, while carrying a cable, whether this destination will take it. Every change is announced politely. The connections table gives the whole patch without the drawing.
Responsive
Columns and padding tighten below 560px; the cable area keeps at least 3.5rem. Cable geometry is re-measured on every resize.
On touch
Tap a source then a destination; drag also works with touch.

Featured

363 components