Voice UI Kit
Primitives

LED

Small on/off indicator with optional blinking or change-driven flash.

import { LED } from "@pipecat-ai/voice-ui-kit";

<LED />
PropTypeDefault
on?
boolean
false
blinking?
boolean
false
blinkIntervalMs?
number
100
watch?
unknown
undefined
watchBlinkDurationMs?
number
500
classNames?
{ on?: string; off?: string }
{}
className?
string
undefined

Usage

Basic States

import { LED } from "@pipecat-ai/voice-ui-kit";

<div className="flex flex-row gap-4 w-full justify-center items-center">
    <LED />
    <LED on />
    <LED blinking />
    <LED on blinking />
</div>

Styled with classes

import { LED } from "@pipecat-ai/voice-ui-kit";

<div className="flex flex-row gap-4 w-full justify-center items-center">
    <LED className="rounded-full" />
    <LED className="rounded-full" on />
    <LED className="rounded-full" blinking />
    <LED className="rounded-full" on blinking />
</div>

Custom Colors

import { LED } from "@pipecat-ai/voice-ui-kit";

<div className="flex flex-row gap-6 w-full justify-center items-center">
    <LED classNames={{ on: "bg-emerald-500", off: "bg-neutral-500" }} />
    <LED classNames={{ on: "bg-red-500", off: "bg-blue-500" }} />
</div>

Sizing

Use Tailwind's size-* utilities via className.

import { LED } from "@pipecat-ai/voice-ui-kit";

<div className="flex flex-row gap-6 w-full justify-center items-center">
    <LED className="size-3" />
    <LED />
    <LED className="size-6" />
    <LED className="size-10" />
</div>
import { LED } from "@pipecat-ai/voice-ui-kit";

<div className="flex flex-row gap-8 w-full justify-center items-center">
    <div className="flex flex-col items-center gap-2">
        <LED blinking blinkIntervalMs={100} />
        <span className="text-xs opacity-70">100ms</span>
    </div>
    <div className="flex flex-col items-center gap-2">
        <LED blinking blinkIntervalMs={500} />
        <span className="text-xs opacity-70">500ms</span>
    </div>
</div>

Watch-driven Flash

When watch changes, the LED blinks for watchBlinkDurationMs then returns to off.

import { LED, Button } from "@pipecat-ai/voice-ui-kit";

function Demo() {
  const [count, setCount] = React.useState(0);
  return (
    <div className="flex flex-col gap-3 items-center">
      <div className="flex items-center gap-6">
        <LED watch={count} />
        <LED watch={count} watchBlinkDurationMs={100} />
        <LED watch={count} classNames={{ on: "bg-yellow-400", off: "bg-zinc-600" }} />
      </div>
      <div className="flex items-center gap-2">
        <Button onClick={() => setCount((c) => c + 1)}>Ping</Button>
        <Button variant="outline" onClick={() => { for (let i = 0; i < 5; i++) { setTimeout(() => setCount((c) => c + 1), i * 60); } }}>Burst (5x)</Button>
        <span className="text-sm opacity-70">count: {count}</span>
      </div>
    </div>
  );
}

render(<Demo />)