Native web component
The native <orb-z> element is the foundation of Orbz. It works anywhere that
supports custom elements, whether the surrounding application uses plain
JavaScript or a framework.
Automatic registration
Import the browser entry once in code that runs for the application:
import "@neongate-ai/orbz/browser";The module calls defineOrbz() for you. Registration is guarded: it does
nothing on a server and returns an existing constructor when another part of
the page has already registered orb-z.
You can render the tag before or after the module loads. The browser upgrades existing tags when the custom element is defined.
<orb-z state="idle" preset="neongate" size="18rem"></orb-z>Explicit registration
Use the root entry when you want to choose exactly when registration happens:
import { defineOrbz } from "@neongate-ai/orbz";
const OrbzElementClass = defineOrbz();defineOrbz() returns the element constructor in a browser and undefined
when customElements or HTMLElement is unavailable. Calling it repeatedly is
safe.
Control it with attributes
<orb-z
state="thinking"
size="320px"
speed="1.15"
preset="periwinkle"
reduced-motion="system"
elevated
></orb-z>The element observes changes, so an attribute update immediately synchronizes its presentation:
const orb = document.querySelector("orb-z");
orb?.setAttribute("state", "speaking");
orb?.setAttribute("speed", "1.25");
orb?.toggleAttribute("elevated", true);Control it with properties
Properties are often clearer when state changes in JavaScript:
import type { OrbzElement } from "@neongate-ai/orbz";
const orb = document.querySelector<OrbzElement>("orb-z");
if (orb) {
orb.state = "listening";
orb.size = 300; // normalized to "300px"
orb.speed = 1.2;
orb.reducedMotion = "system";
orb.elevated = true;
}Every public property reflects through its matching attribute. size accepts a
number, which becomes pixels, or a CSS length string such as "20rem".
Boolean attributes
paused and elevated follow native HTML boolean-attribute semantics. The
presence of the attribute means true, regardless of the string assigned to it.
<!-- Elevated -->
<orb-z elevated></orb-z>
<!-- Also elevated: "false" is still a present attribute -->
<orb-z elevated="false"></orb-z>Remove the attribute or assign the property to false:
orb?.removeAttribute("elevated");
if (orb) {
orb.paused = false;
orb.elevated = false;
}Built-in preset or custom palette
Choose a built-in color preset with the preset attribute:
<orb-z preset="magenta"></orb-z>Available values are neongate, periwinkle, magenta, peach, mocha,
and ivory. The default colors are neongate.
For a custom palette, omit preset and set any of the five color attributes:
<orb-z
color-primary="#7C3AED"
color-secondary="#22D3EE"
color-accent="#F472B6"
color-highlight="#FDE68A"
color-background="#09090B"
></orb-z>Missing custom colors fall back to their NeonGate defaults. Do not combine an
explicit preset attribute with color-* attributes. If both modes are
present, the preset wins and Orbz reports the conflict to the console.
Drive it from an application state machine
Keep the application as the source of truth and make Orbz a projection of that state:
import type { OrbzElement, OrbzState } from "@neongate-ai/orbz";
const orb = document.querySelector<OrbzElement>("orb-z");
function presentAssistantState(state: OrbzState, message: string) {
if (orb) orb.state = state;
const status = document.querySelector<HTMLElement>("[data-assistant-status]");
if (status) status.textContent = message;
}
presentAssistantState("thinking", "Assistant is preparing a response");The five supported states are idle, listening, thinking, speaking, and
asleep. Unknown values normalize to idle.
Playback methods
The native element exposes three focused animation methods:
orb?.pause(); // freeze the current animation
orb?.play(); // resume it
orb?.restart(); // rebuild the current state's animationThe paused property and attribute remain the declarative choice. Use the
methods when an imperative browser integration is more convenient.
Motion preferences
reduced-motion="system" follows the user’s
prefers-reduced-motion setting and reacts when it changes. Use always to
force the reduced presentation or never to force the full motion profile.
<div role="status" aria-live="polite">
<orb-z state="thinking" reduced-motion="system"></orb-z>
<span data-assistant-status>Assistant is thinking</span>
</div>Keep meaningful text outside the orb. The component is a visual signal and should not be the sole way a user learns the assistant’s status.
Framework templates
Vue, Svelte, and Angular can bind their own reactive values directly to the
native tag after importing /browser once. There is no framework adapter or
shared runtime between the application and Orbz.
See the complete applications in the examples directory .