@sioma/aurabot
v0.0.1
Published
Framework-agnostic AuraBot — an expressive assistant avatar with 18 states, animated SVG eyes, 3D mouse tracking, speech bubbles and responsive sizing. Zero-dependency vanilla core (`AuraBot.mount`) plus optional React adapter, `<aura-bot>` custom element
Maintainers
Readme
@sioma/aurabot
A framework-agnostic, expressive AI assistant bot component.
- 🧠 18 bot states (default, running, thinking, building, angry, evil, happy, hello, error, warning, info, success, recommending, sleeping, waking-up, unsure, blocked, incognito)
- 👀 10 eye emotions with mask-based SVG eyelid animation
- 🎯 3D mouse tracking with perspective transforms
- 💬 Cycling speech bubbles
- 📱 Responsive via CSS container queries
- 🪶 Zero runtime dependencies — the whole package, not just the core
- ⚛️ Optional React adapter at
@sioma/aurabot/react - 🧩 Custom element (
<aura-bot>) at@sioma/aurabot/element - 🎨 Brand logo + favicon — the bot's face as a standalone SVG (
auraBotLogoSvg,auraBotFaviconSvg,<AuraBotLogo />, shippedlogo.svg/favicon.svg)
Framework-agnostic is literal: the core is plain DOM + SVG + CSS, so the vanilla
entry and the custom element work under Preact, React, Vue, Svelte or no
framework at all. Nothing in the package reaches for a browser-only global at
mount time, so it also renders under jsdom (see __tests__/mount.spec.ts).
Install
Inside this monorepo:
{ "dependencies": { "@sioma/aurabot": "workspace:*" } }The package is set up to publish (@sioma/aurabot, publishConfig.access:
public) but has not been released to npm yet — pnpm changeset + pnpm
release is the path when you want it out there.
Vanilla JS
import "@sioma/aurabot/styles";
import { AuraBot } from "@sioma/aurabot";
const bot = AuraBot.mount(document.getElementById("bot")!, {
state: "running",
customMessages: ["Processing your request…"],
onToggle: () => bot.update({ isOpen: !bot.options.isOpen }),
});
// Later…
bot.update({ state: "happy" });
bot.destroy();React
import "@sioma/aurabot/styles";
import { AuraBot } from "@sioma/aurabot/react";
<AuraBot state="running" customMessages={["Processing…"]} />;Custom element
import "@sioma/aurabot/styles";
import { defineAuraBotElement } from "@sioma/aurabot/element";
defineAuraBotElement(); // registers <aura-bot><aura-bot state="happy" eye-shape="square"></aura-bot>Options / Props
| Name | Type | Default | Description |
| ------------------ | --------------------- | ----------- | --------------------------------------- |
| state | BotState | "default" | Current bot state |
| size | BotSize \| number | "xs" | Named preset (40px cube) or pixel width |
| emotionOverride | Emotion | — | Force an eye emotion |
| customMessages | string[] | — | Messages to cycle in the speech bubble |
| hideSpeechBubble | boolean | false | Hide the speech bubble |
| isOpen | boolean | false | Expanded/prompt mode |
| onToggle | () => void | — | Fired on bot tap |
| eyeShape | "round" \| "square" | "square" | Eye shape |
| className | string | — | Extra class name on root |
Brand logo & favicon
The bot's face doubles as the Sioma brand mark: a rounded square carrying the Sioma brand gradient as one smooth rotating sweep, with two eyes over it.
import { auraBotLogoSvg, auraBotFaviconSvg, createAuraBotLogo } from "@sioma/aurabot";
auraBotLogoSvg({ size: 50 }); // markup string (SSR, emails, files)
auraBotFaviconSvg(); // static + cropped + heavy stroke, for tab icons
createAuraBotLogo({ size: 50 }); // live SVGSVGElementimport { AuraBotLogo } from "@sioma/aurabot/react"; // SSR-safe (useId-stable ids)
<AuraBotLogo size={50} ariaLabel="Sioma" />;Changing the colours
Edit src/core/palette.ts, then rebuild. That is
the only file. It feeds the live component, the generated logo.svg and the
generated favicon.svg, so all three move together:
pnpm --filter @sioma/aurabot buildTo retheme ONE surface without moving the default, don't touch that file —
either pass options (auraBotLogoSvg({ gradientFrom: "…" })) or set the CSS
custom properties on an ancestor: --aura-gradient-from, --aura-gradient-to,
--aura-background (the glass sheen), --aura-primary (the outline). The
cascade is option → CSS var → AURA_PALETTE.
The mark is one smooth teal → orange sweep — the site's own brand gradient, with the sweep itself rotating. Four discrete colour balls were tried first and banded wherever two hues met, however wide the blur.
The generated files are exported as @sioma/aurabot/logo.svg and
@sioma/aurabot/favicon.svg, with the colours baked in — a standalone .svg
has no theme around it to resolve a var against.
The marketing site's social card imports auraBotLogoSvg from here rather than
inlining a copy (apps/site/build/og/generate-og.mjs), so there is no second
copy of the mark anywhere.
See it render
A static harness mounts every state plus both custom-element eye shapes against
the built dist/, which is also how the CSS bundle gets checked:
pnpm --filter @sioma/aurabot buildThen serve the package directory and open /.harness/index.html (the
aurabot-harness entry in .claude/launch.json does exactly this on port 8492).
Provenance
Ported from OnUI's @onui/aurabot, which is where this component was originally
built. This copy is the source of truth now: @onui/svg-utils (the
setAnimation helper, the SvgAnimation types and svg-animations.css) is
inlined here, so the package stands alone with no workspace dependencies.
License
FSL-1.1-Apache-2.0 — see LICENSE. Source-available: free for any purpose except building a competing product, and it converts to Apache 2.0 two years after each release.
