Primitives
Separator
Technical divider with an optional centered mono label, and an optional live signal pulse that travels along the rule.
● LIVE
Primary uplink stable. Carrier locked to grid reference.
SEC
Secondary channel armed. Standing by for handshake.
"use client";import { Separator } from "@/registry/okibi/ui/separator";export default function SeparatorDemo() { return ( <div className="w-72 max-w-full space-y-4"> <p className="text-sm text-muted-foreground"> Primary uplink stable. Carrier locked to grid reference. </p> <Separator label="SEC" /> <p className="text-sm text-muted-foreground"> Secondary channel armed. Standing by for handshake. </p> </div> );}npx shadcn@latest add https://okibi.cndr.dev/r/separator.jsonInstallation
Install the theme first, then add the component:
npx shadcn@latest add https://okibi.cndr.dev/r/separator.jsonInstall the required dependencies:
npm install @radix-ui/react-separatorCopy the source from the Code tab above into components/ui/separator.tsx. It uses the cn helper and the okibi theme tokens — install the theme first if you haven't.
Usage
import { Separator } from "@/components/ui/separator"
<Separator />
<Separator orientation="vertical" />Examples
Pulse
Set pulse to energize the rule with a live signal current — a periodic pulse travels along its length (horizontal or vertical), so a section break reads as a charged bus under load. Reduced motion freezes it back to a plain hairline.
● LIVE
CHANNEL // 0x4A2
import { Separator } from "@/registry/okibi/ui/separator";export default function SeparatorPulseDemo() { return ( <div className="flex w-full max-w-md flex-col gap-6"> <Separator pulse /> <Separator pulse label="CHANNEL // 0x4A2" /> </div> );}API Reference
Separator
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | "horizontal" | "vertical" | "horizontal" | Rule direction. |
label | string | – | Centered mono micro-label (horizontal only). |
decorative | boolean | true | Mark as decorative for assistive tech. |
pulse | boolean | false | Run a live signal pulse travelling along the rule. |
pulseSpeed | number | 1.2 | Pulse loop duration, in seconds. |
Accessibility
- Wraps Radix
Separator;decorativedefaults totrue, so by default the rule exposes no role and is skipped by assistive tech. - Set
decorative={false}to announce it as a realseparator— every branch (plain, labelled, pulsed) now honors the flag and emitsrole='separator'only then. - A non-decorative vertical rule reports
aria-orientation='vertical'; horizontal is the implicit default and needs no attribute. - The labelled flanks and the traveling pulse rail are decorative chrome — each is
aria-hidden— so only the mono micro-label text is read. - The
pulsecurrent is CSS-keyframe motion, neutralized by the global reduced-motion rule, so it freezes to a static hairline when motion is reduced.
Guidelines
Do
- Default to decorative — most rules are visual grouping, and a silent divider keeps the reading order clean.
- Reach for
decorative={false}only when the line is the sole cue separating two distinct regions. - Use
labelfor HUD-style section breaks; keep the micro-label to a short uppercase token.
Don't
- Do not expect
labelon a vertical separator — the labelled branch only renders fororientation='horizontal'. - Do not lean on
pulseto carry meaning; it is purely decorative and disappears under reduced motion. - Do not stack separators to fake spacing — use layout gap or padding instead.