From 242bec1a8315e6922ce337d3aa12eda9ccc44a31 Mon Sep 17 00:00:00 2001 From: Alexander Chen Date: Mon, 21 Sep 2026 09:01:25 -0400 Subject: [PATCH] docs: improve voice orb discovery and interactive guides --- .changeset/voice-orb-guides.md | 5 + ROADMAP.md | 5 + demo/demos/voice-orb/index.html | 14 +++ demo/index.html | 12 +-- demo/src/App.tsx | 8 +- demo/src/voice-orb-preview.css | 141 +++++++++++++++++++++++++++++ demo/src/voice-orb-preview.tsx | 128 ++++++++++++++++++++++++++ demo/vercel.json | 8 ++ demo/vite.config.ts | 5 + docs/adapters/elevenlabs.mdx | 156 +++++++++++++++++++++++++------- docs/examples/voice-orb-ui.mdx | 99 ++++++++++++++++++-- docs/themes/voice-states.mdx | 3 + 12 files changed, 535 insertions(+), 49 deletions(-) create mode 100644 .changeset/voice-orb-guides.md create mode 100644 demo/demos/voice-orb/index.html create mode 100644 demo/src/voice-orb-preview.css create mode 100644 demo/src/voice-orb-preview.tsx diff --git a/.changeset/voice-orb-guides.md b/.changeset/voice-orb-guides.md new file mode 100644 index 0000000..48bdd89 --- /dev/null +++ b/.changeset/voice-orb-guides.md @@ -0,0 +1,5 @@ +--- +--- + +Clarify voice orb discovery on the homepage and expand the ElevenLabs and React animation guides +with an interactive theme preview, customization examples, and session lifecycle guidance. diff --git a/ROADMAP.md b/ROADMAP.md index dff180d..f77c600 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -86,6 +86,11 @@ HTML routes to their maintained equivalents, and links directly from the homepag use-case guides. Documentation pages use one descriptive page heading and implementation-focused content that stays aligned with the public API. +Voice-orb discovery now builds on those routes: the homepage introduces the React voice orb while +retaining its broader voice agent UI positioning, the ElevenLabs guide explains visual choices +and includes a complete integration, and both provider and animation guides embed an interactive +theme/state preview. The animation example remains a secondary homepage documentation link. + ## Experience ### More impressive themes diff --git a/demo/demos/voice-orb/index.html b/demo/demos/voice-orb/index.html new file mode 100644 index 0000000..0d51f9c --- /dev/null +++ b/demo/demos/voice-orb/index.html @@ -0,0 +1,14 @@ + + + + + + + + Voice orb animation preview — orb-ui + + +
+ + + diff --git a/demo/index.html b/demo/index.html index 4916034..2d393cd 100644 --- a/demo/index.html +++ b/demo/index.html @@ -3,10 +3,10 @@ - orb-ui: React Voice Agent UI Components + orb-ui — React Voice Orb & Voice Agent UI Components @@ -19,10 +19,10 @@ - + @@ -35,10 +35,10 @@ - + alive.

- Give realtime voice agents a visible presence with expressive themes, clear session - states, and provider adapters that all end at one React component. + Give your voice agent a voice orb that feels like your product. One React component, + expressive audio-reactive themes, and adapters for ElevenLabs, Vapi, and more.

diff --git a/demo/src/voice-orb-preview.css b/demo/src/voice-orb-preview.css new file mode 100644 index 0000000..a76aaa3 --- /dev/null +++ b/demo/src/voice-orb-preview.css @@ -0,0 +1,141 @@ +:root { + color-scheme: dark; + font-family: system-ui, sans-serif; + color: #edf2ff; + background: #10131b; +} +* { + box-sizing: border-box; +} +body { + margin: 0; +} +.orb-preview { + max-width: 760px; + margin: auto; + padding: 24px; +} +h1 { + font-size: 20px; + letter-spacing: -0.025em; + margin: 0 0 6px; +} +p { + margin: 0; + color: #a9b5cb; + font-size: 13px; +} +.orb-preview__surface { + min-height: 260px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + text-align: center; +} +.orb-preview__surface p { + min-height: 36px; +} +.orb-preview__choices, +.orb-preview__levels { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 18px; +} +label, +legend { + font-size: 12px; + color: #b9c6dd; +} +label { + display: block; + min-width: 0; +} +select { + display: block; + width: 100%; + margin-top: 7px; +} +select, +button { + background: #1b2230; + color: #edf2ff; + border: 1px solid #364156; + border-radius: 7px; + padding: 9px 10px; + font: inherit; + text-transform: capitalize; + cursor: pointer; +} +fieldset { + border: 0; + padding: 0; + margin: 20px 0; + min-width: 0; +} +legend { + padding: 0 0 8px; +} +.orb-preview__states { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 6px; +} +.orb-preview__states button { + font-size: 12px; +} +button[aria-pressed='true'] { + background: #243d64; + border-color: #91baff; + color: #fff; +} +button:hover { + border-color: #91baff; +} +:focus-visible { + outline: 2px solid #91baff; + outline-offset: 3px; +} +input[type='range'] { + display: block; + accent-color: #91baff; + width: 100%; + margin: 12px 0 0; +} +label span { + float: right; + font-variant-numeric: tabular-nums; +} +details { + margin-top: 22px; + border-top: 1px solid #2d3547; + padding-top: 16px; +} +summary { + cursor: pointer; + font-size: 12px; + color: #b9c6dd; +} +pre { + overflow: auto; + font-size: 11px; + line-height: 1.6; + padding: 12px; + background: #0a0d14; + border-radius: 8px; +} +@media (min-width: 600px) { + .orb-preview__states { + grid-template-columns: repeat(6, 1fr); + } +} +@media (max-width: 360px) { + .orb-preview { + padding: 16px; + } + .orb-preview__choices, + .orb-preview__levels { + gap: 12px; + } +} diff --git a/demo/src/voice-orb-preview.tsx b/demo/src/voice-orb-preview.tsx new file mode 100644 index 0000000..65b2fdd --- /dev/null +++ b/demo/src/voice-orb-preview.tsx @@ -0,0 +1,128 @@ +import { StrictMode, useState } from 'react' +import { createRoot } from 'react-dom/client' +import { Orb } from 'orb-ui' +import type { OrbSignal, OrbState, OrbThemeName, OrbThemePreset } from 'orb-ui' +import './voice-orb-preview.css' + +const themes: OrbThemeName[] = ['circle', 'cloud', 'radial', 'bars'] +const presets: OrbThemePreset[] = ['balanced', 'calm', 'expressive'] +const states: OrbState[] = ['idle', 'connecting', 'listening', 'thinking', 'speaking', 'error'] +const descriptions: Record = { + idle: 'Ready to start', + connecting: 'Connecting to the agent', + listening: 'Listening to you · input level drives the motion', + thinking: 'Preparing a response', + speaking: 'Agent speaking · output level drives the motion', + error: 'Connection failed', +} + +function VoiceOrbPreview() { + const [theme, setTheme] = useState('circle') + const [preset, setPreset] = useState('balanced') + const [state, setState] = useState('listening') + const [inputVolume, setInputVolume] = useState(0.45) + const [outputVolume, setOutputVolume] = useState(0.7) + const signal: OrbSignal = { state, inputVolume, outputVolume } + const code = `` + + return ( +
+
+

Make the voice orb your own.

+

Preview only. No microphone or live call.

+
+
+ +

{descriptions[state]}

+
+
+ + +
+
+ Voice state +
+ {states.map((name) => ( + + ))} +
+
+
+ + +
+
+ React code for this preview +
+          {code}
+        
+
+
+ ) +} + +createRoot(document.getElementById('root')!).render( + + + , +) diff --git a/demo/vercel.json b/demo/vercel.json index 3ff9e76..3b255e8 100644 --- a/demo/vercel.json +++ b/demo/vercel.json @@ -251,6 +251,14 @@ } ], "rewrites": [ + { + "source": "/demos/voice-orb", + "destination": "/demos/voice-orb/index.html" + }, + { + "source": "/demos/voice-orb/", + "destination": "/demos/voice-orb/index.html" + }, { "source": "/playground", "destination": "/playground/index.html" diff --git a/demo/vite.config.ts b/demo/vite.config.ts index b740b8c..b7d068a 100644 --- a/demo/vite.config.ts +++ b/demo/vite.config.ts @@ -14,6 +14,10 @@ function playgroundRoutePlugin(): Plugin { const url = request.url ?? '' const [pathname, query] = url.split('?') + if (pathname === '/demos/voice-orb') { + request.url = `/demos/voice-orb/${query ? `?${query}` : ''}` + } + if ( pathname === '/playground' || pathname === '/provider-playground' || @@ -36,6 +40,7 @@ export default defineConfig({ input: { main: resolveInput('./index.html'), playground: resolveInput('./playground/index.html'), + voiceOrb: resolveInput('./demos/voice-orb/index.html'), }, }, }, diff --git a/docs/adapters/elevenlabs.mdx b/docs/adapters/elevenlabs.mdx index 944babf..a3f6de5 100644 --- a/docs/adapters/elevenlabs.mdx +++ b/docs/adapters/elevenlabs.mdx @@ -1,11 +1,53 @@ --- -title: ElevenLabs Voice Orb UI for React -description: Build an ElevenLabs Conversational AI voice orb UI in React with provider state mapping, audio-reactive themes, and accessible controls. +title: ElevenLabs Orb for React with Custom Themes +description: Connect your ElevenLabs agent to orb-ui's circle, cloud, radial, or bars themes. Build a custom React voice orb with audio response, presets, and accessible controls. --- -ElevenLabs Conversational AI can power realtime voice experiences. orb-ui turns those sessions into -a React voice orb UI with visible listening and speaking states, audio-reactive feedback, and -accessible call controls. +Keep your ElevenLabs agent and give it a voice orb that fits your product. orb-ui connects to +ElevenLabs Conversational AI through `@elevenlabs/client`, with a choice of circle, cloud, radial, +and bars themes, motion presets, and audio-reactive listening and speaking states. + +## Preview your ElevenLabs orb UI + +Try the visual themes before connecting an agent. Select listening to preview input response or +speaking to preview output response. These are simulated signals: no microphone, account, or live +ElevenLabs session is needed. + +