react-live-avatar
v0.1.0
Published
A floating, mood-driven, cursor-tracking animated robot mascot for React apps.
Maintainers
Readme
react-live-avatar
A floating, animated, mood-driven robot mascot for React apps — hand-rolled SVG + CSS + hooks, zero animation libraries, zero dependencies beyond React itself.
- SVG head (gradients, glow filters, ear light-strips) with CSS-driven eyes
that crossfade between 8 expressions:
idle,happy,curious,thinking,surprised,sad,sleepy,loading. - Eyes track the real cursor position via a self-parking
requestAnimationFrameloop that writes CSS custom properties directly to the DOM (no re-renders). - Idle animations: random blinking, occasional "glance around" when the cursor is quiet.
- Autonomous mood engine: drifts into a weighted-random mood every 9–18s, falls asleep after 45s of inactivity, wakes up "surprised" on the next input event.
- Hover speech bubble with a random phrase per mood (bundled in Indonesian and English — see Localization).
- Fully respects
prefers-reduced-motion(kills autonomous motion, keeps cursor tracking since that's user-driven). - Responsive: shrinks automatically below 640px viewport width.
Install
npm install react-live-avatarreact and react-dom >= 18 are peer dependencies.
Usage
import { RobotAvatar } from 'react-live-avatar'
import 'react-live-avatar/style.css'
function App() {
return <RobotAvatar size={150} autoExpression trackCursor />
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| expression | RobotExpression | 'idle' | Fixed expression; also the resting expression when autoExpression is on. |
| autoExpression | boolean | true when expression is unset | Let the robot drift into moods on its own. |
| size | number | 88 | Base size in px (desktop); shrinks automatically below 640px viewport width. |
| position | 'bottom-right' \| 'bottom-left' \| 'static' | 'bottom-right' | Fixed corner placement, or 'static' to lay out inline. |
| trackCursor | boolean | true | Whether the eyes follow the cursor. |
| lang | 'id' \| 'en' | 'en' | Language for the default aria-label and speech-bubble phrases. |
| onClick | () => void | — | Renders the root as a <button> instead of a <div role="img">. |
| className | string | — | Extra class applied to the root element. |
RobotExpression and RobotPosition types are exported for convenience.
Styling
Visual states are driven by CSS custom properties on the component root, with sane built-in fallbacks. If your app defines any of the following custom properties globally, the robot picks them up automatically instead of using its defaults:
| Custom property | Used for | Fallback |
|---|---|---|
| --color-primary | focus-visible outline | #3b82f6 |
| --color-surface | speech bubble background | #ffffff |
| --color-text-primary | speech bubble text | #1c2b38 |
| --color-border | speech bubble border | #e2e8f0 |
| --shadow-medium | speech bubble shadow | 0 8px 24px rgba(28, 43, 56, 0.08) |
| --font-body | speech bubble font | 'Inter', ui-sans-serif, system-ui, sans-serif |
| --fs-xs | speech bubble font-size | clamp(0.82rem, 0.74rem + 0.3vw, 0.9rem) |
| --weight-medium | speech bubble font-weight | 500 |
| --ease-out-expo | several transitions | cubic-bezier(0.16, 1, 0.3, 1) |
| --font-display | "Zzz" sleep text font | 'Poppins', ui-sans-serif, system-ui, sans-serif |
| --weight-bold | "Zzz" sleep text weight | 700 |
Localization
Built-in phrases and labels ship in Indonesian (id) and English (en); pass
lang="id" or lang="en" (default) to pick one. The mascot's default name in
the bundled English/Indonesian phrases is "Taku" — feel free to fork
src/phrases.ts if you want different copy or additional
languages.
License
MIT
