- add the v1 AvatarDefinition schema, bounded parser, strict validation, semantic catalog, pure geometry, scene generation, and deterministic playback to @bible-strong/avatar-core - add the React 19 renderer with semantic controls, SSR-safe embedded/floating layouts, direct frame updates, pointer and keyboard movement, constraints, callbacks, and accessible controls - add real tarball packaging and a clean React/Vite consumer using the exported Strobi definition - add Studio semantic-key authoring, runtime readiness, JSON download/copy, bundled-key recovery, concise errors, targeted local-project clearing, npm guidance, syntax highlighting, and a runnable package preview - preserve the historical ZIP and Studio project exports, regenerate the standalone engine, and synchronize English, French, and Simplified Chinese copy - add focused contract, playback, renderer, interaction, persistence, export, and localization coverage - archive the completed runtime and semantic-curation specs, retain the Vite performance draft, and record the engineering session in TIMELOG.md Validation: - pnpm check: 19 test files, 162 tests, typecheck, engine freshness, package builds, and Studio production build passed - npm pack dry runs: 30 core files and 10 React files - package smoke: real tarballs installed, typechecked, and built outside the workspace - browser checks: semantic playback, embedded/floating render, drag, mobile overflow, runtime export recovery, formatted copy, syntax colors, and live package preview Publication remains disabled: both packages stay private and AGPL-3.0-only pending licensing and repository metadata approval. Vue and Angular adapters remain deferred. |
||
|---|---|---|
| .. | ||
| src | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| tsconfig.build.json | ||
| tsconfig.json | ||
| vite.config.ts | ||
@bible-strong/avatar-react
React 19 renderer for a validated Bible Strong AvatarDefinition. React and React DOM 19 are peer
dependencies; @bible-strong/avatar-core is installed as a normal dependency.
Install
pnpm add @bible-strong/avatar-react react react-dom
Import the package stylesheet once in the application entry point:
import { Avatar, type AvatarController } from '@bible-strong/avatar-react'
import type { AvatarDefinition } from '@bible-strong/avatar-core'
import '@bible-strong/avatar-react/styles.css'
import { useRef } from 'react'
export function Assistant({ definition }: { definition: AvatarDefinition }) {
const avatar = useRef<AvatarController>(null)
return (
<>
<Avatar ref={avatar} definition={definition} defaultAnimation="idle" />
<button onClick={() => avatar.current?.play('happy')}>Play happy</button>
<button onClick={() => avatar.current?.setExpression('neutral')}>Neutral</button>
</>
)
}
play and setExpression return { ok: true } or a typed error with one of
unknown_animation, unavailable_standard_animation, unknown_expression or
controlled_by_props. pause freezes the exact timeline position, calling play with the paused
key resumes it, and stop returns an uncontrolled avatar to neutral.
Playback props
animationandexpressionare mutually exclusive controlled targets. They take priority over defaults and imperative target changes.defaultAnimationanddefaultExpressioninitialize uncontrolled use. Animation autoplay is on by default whendefaultAnimationis present; setautoplay={false}to show its first expression statically.onAnimationEndfires once when aonceanimation completes naturally.onExpressionChangereports semantic expression changes.size,className,styleandariaLabelcustomize layout without changing the definition.
The definition is validated once per immutable object reference and revalidated/reinitialized when that reference changes.
Embedded and floating layout
Embedded mode is the default and stays in the caller's layout:
<div className="assistant-zone">
<Avatar definition={definition} animation="idle" />
</div>
Floating mode uses fixed positioning and portals to document.body after hydration. Supply
portalContainer for a dedicated overlay root. Server rendering emits a neutral fixed-size
placeholder before the portal handoff.
<Avatar
definition={definition}
mode="floating"
draggable
initialPosition={{ right: 24, bottom: 24 }}
constrainTo="viewport"
zIndex={1000}
/>
initialPosition accepts { x, y } or top/right/bottom/left anchors. A controlled position wins
over it. constrainTo accepts none, viewport or parent; floating defaults to viewport, while
embedded defaults to none. A constrained embedded parent needs a definite rendered size.
Dragging uses Pointer Events and direct transforms. onPositionPreview is limited to one callback
per animation frame and onPositionCommit reports the final clamped point. onDragStart and
onDragEnd bracket pointer movement. In controlled position mode callbacks report suggestions but
the supplied position remains authoritative. When resized bounds invalidate a controlled position,
onPositionChange reports the clamped suggestion. Resize re-clamping never emits a movement commit.
When draggable is enabled, arrow keys move by 10 px, Shift+Arrow by 1 px, and Escape cancels an
active pointer drag. Accessible directional and reset buttons provide the same movement without a
pointer.
Styling hooks
The stylesheet exposes .bs-avatar, .bs-avatar--embedded, .bs-avatar--floating,
.bs-avatar--draggable, .bs-avatar--dragging, .bs-avatar__svg and
.bs-avatar__move-controls. Consumer className and style are applied to the outer wrapper.
The public component never exposes Studio IDs or document types. This package is private while copyright ownership, Apache-2.0 relicensing and repository metadata are confirmed. Local tarballs are for verification only and must not be published.