Skip to content
Get started

Components

VoiceOrb

Unstable: voice mode, an orb, a written state (Tap to talk, Listening…, Speaking…) and one big control that starts and stops. Import it from @nizivo/react/unstable/voice-orb.

Server component, no client JSUnstable

Examples

Basic

Three states: idle, listening with what was heard so far, and speaking.

Tap to talk
Listening…
“Which products sold out last week?”
Speaking…
import type { JSX } from 'react';
import { VoiceOrb } from '@nizivo/react/unstable/voice-orb';

export function VoiceOrbExample(): JSX.Element {
  return (
    <div style={{ display: 'flex', flexWrap: 'wrap', alignItems: 'flex-start', gap: 24 }}>
      <VoiceOrb state="idle" />
      <VoiceOrb state="listening">“Which products sold out last week?”</VoiceOrb>
      <VoiceOrb state="speaking" />
    </div>
  );
}

Import

import { VoiceOrb } from '@nizivo/react/unstable/voice-orb';

// Once per app (Getting started), after
// @nizivo/tokens/tokens.css and @nizivo/react/css/base.css and @nizivo/react/css/icon-button.css
import '@nizivo/react/css/voice-orb.css';

Static or interactive

Server. No client JavaScript: the control is an IconButtonStatic (IconButton without its tooltip) that calls onToggle. How to choose.

State

state is idle, listening or speaking. The label carries it, in a polite live region, and the button changes from Start talking (the mic) to Stop. The orb and the waveform are decoration; both stand still under Reduced motion.

Captions

Put what was heard, and what the assistant says, in the children: voice needs a text twin.

The orb

The design's orb is a shader: pass GlowOrb as orb (orb={<GlowOrb state={state} level={level} />}) and it grows with the voice. Without it the orb is drawn with CSS gradients; orb takes any picture in its place, hidden from assistive technology.

Props

Server component Renders data-slot="voice-orb" with the class nz-voice-orb. Props: VoiceOrbProps. Source: src/unstable/voice-orb/voice-orb.tsx.

NameTypeDefaultDescription
labelsPartial<VoiceOrbLabels>–
onToggle() => void–

The button calls it: start while idle, stop while listening or speaking.

orbReactNode–

Replaces the CSS orb, for example <GlowOrb state={state} />. Decorative: it is hidden from assistive technology.

renderRenderProp<Record<string, never>>–

Must render a <div>.

staterequiredVoiceState
"idle""listening""speaking"
–
  • Also takes every attribute of <div> except onToggle. (Omit<ComponentPropsWithRef<"div">, "onToggle">)

render takes an element, or, in client code, a function of the props and no state.

Other exports

VoiceOrbLabels type

import type { VoiceOrbLabels } from '@nizivo/react/unstable/voice-orb'

VoiceOrb's own strings (§16.4): serialisable, English defaults.

NameTypeDefaultDescription
idlerequiredstring'Tap to talk'
listeningrequiredstring'Listening…'
speakingrequiredstring'Speaking…'
startrequiredstring'Start talking'

The button's name while idle.

stoprequiredstring'Stop'

The button's name while listening or speaking.

VoiceOrbProps type

import type { VoiceOrbProps } from '@nizivo/react/unstable/voice-orb'

The props of VoiceOrb, listed above.

VoiceState type

import type { VoiceState } from '@nizivo/react/unstable/voice-orb'

What the voice assistant is doing: idle, listening or speaking.

type VoiceState = "idle" | "listening" | "speaking"

Data attributes and slots

Style parts by class (.nz-<slot>) and state by data attribute. Attribute meanings come from contracts/vocabulary.json.

SlotRendered byData attributes
voice-orb
.nz-voice-orb
VoiceOrb
root (takes render)
  • data-tone: "idle""listening""speaking"
    The tone prop; values in each component manifest
voice-orb-button
.nz-voice-orb-button
VoiceOrb
inner element (CSS only); interactive, focus: self
none
voice-orb-captions
.nz-voice-orb-captions
VoiceOrb
inner element (CSS only)
none
voice-orb-label
.nz-voice-orb-label
VoiceOrb
inner element (CSS only)
none
voice-orb-orb
.nz-voice-orb-orb
VoiceOrb
inner element (CSS only)
none

CSS hooks

Set a hook on the component's class or any ancestor to restyle it without specificity games; leave it unset for the default shown.

This stylesheet reads no public hook.

Layers: nz.components. Classes: .nz-glow-orb, .nz-voice-orb, .nz-voice-orb-bar, .nz-voice-orb-button, .nz-voice-orb-captions, .nz-voice-orb-label, .nz-voice-orb-orb, .nz-voice-orb-sphere, .nz-voice-orb-wave.

Tokens this stylesheet reads (16)

--nz-bg-accent, --nz-bg-brand, --nz-bg-canvas, --nz-duration-pulse, --nz-font-body-s, --nz-font-label-m, --nz-icon-secondary, --nz-radius-full, --nz-space-0-5, --nz-space-1, --nz-space-10, --nz-space-4, --nz-space-6, --nz-space-8, --nz-text-primary, --nz-text-secondary

Accessibility

These parts are interactive. Each gets the focus outline and touch-action rule from @nizivo/react/css/base.css (the nz.base layer), so the floor survives a restyle:

  • voice-orb-button: draws the focus outline itself on keyboard focus.

Keyboard

To be written.

On this page