Native monochrome waveform, fluid orb, and ring visuals with five conversational states, live intensity, and a custom renderer.
Preview
In action
Show the assistant’s current state
The native monochrome visual represents idle, listening, thinking, speaking, and asleep states. It respects reduced motion and visibility. Supply children for an application-owned visual such as the original monochrome orb avatar.
When to use
Use it for
Drive state from actual application recording, generation and playback events.
Choose waveform, orb, or rings. Waveform remains the default. All five states work with each native visual without an external graphics runtime.
Supply intensity from zero to one for measured input or output energy; it is clamped, and asleep always settles to zero. Otherwise each state provides a representative intensity.
Motion pauses when offscreen, the document is hidden, paused is true, or state is asleep. Reduced motion and forced colors keep a static visual.
onMotionChange reports the effective motion policy initially and when it changes. It does not report asset loading or custom engine playback events.
Supply children for static custom content, or renderVisual for state, normalized size and intensity, and animated. A custom graphics renderer should honor animated and release its own resources.
CSS-only markup shows a static representative visual; the React component manages visibility and user preference changes.
Omit label for a decorative visual beside an already named response. Add label to expose the visual and state as an image.
Avoid
Mounting a separate graphics runtime for every historical message.
Using animation alone to communicate an error or progress that needs readable text.
Install
React package
npm install @noorddev/vlak-react
Load the stylesheet once at your app root, then import the components you use.
import "@noorddev/vlak-react/css";
import { Persona, type PersonaState, type PersonaVariant, type PersonaVisualContext } from "@noorddev/vlak-react";
Per-component imports are available at @noorddev/vlak-react/components/persona.
Copy the source
npx @noorddev/vlak-cli add persona
Adds the component to components/vlak/. Follow the StyleX setup to compile the source in your application.
shadcn registry
npx shadcn add https://vlak.dev/r/persona.json
Installs the same source through the shadcn CLI.
React
import { Persona, type PersonaState, type PersonaVariant, type PersonaVisualContext } from "@noorddev/vlak-react";
import type { ReactNode } from "react";
export function AssistantPersona({ state = "idle", variant = "orb", intensity, paused, renderVisual }: {
state?: PersonaState;
variant?: PersonaVariant;
intensity?: number;
paused?: boolean;
renderVisual?: (context: PersonaVisualContext) => ReactNode;
}) {
return <Persona state={state} variant={variant} intensity={intensity} paused={paused}
size={48} label="Assistant" renderVisual={renderVisual} />;
}
See the integration example to compose these components with your application's model and data.
Props
Persona
Three native monochrome visuals share five conversational states and an optional custom renderer.
Prop
Type
Default
Description
state
PersonaState
"idle"
variant
PersonaVariant
"waveform"
size
number
48
label
string
intensity
number
Input/output energy in the range 0–1. Asleep always settles to zero.
paused
boolean
false
Stop motion without changing the conversational state.
onMotionChange
(animated: boolean) => void
Called initially and whenever the effective motion policy changes.
children
ReactNode
A custom decorative visual. The application owns its rendering lifecycle.
renderVisual
(context: PersonaVisualContext) => ReactNode
Custom visuals should honor animated and release their own rendering resources.
Also accepts HTMLAttributes<HTMLDivElement>.
The ref reaches HTMLDivElement.
Accessibility
The default is decorative. A supplied label exposes a named image including the current conversational state.