Agent avatar
A Lookout agent's character: a soft body, a colour and two eyes drawn from a seed, with a picker and a stack.
import { AgentAvatar, AgentAvatarPicker, AvatarStack, … } from "@arcadia/ui"A character is a body, a colour, a face and a small tilt, drawn from a seed. Store the picked fields, not the seed: a later change to the lists never re-skins an agent. characterFromId draws the same character for the same id every time; shuffledCharacter draws a fresh one, and both can avoid one colour so two agents made in a row never look alike.
At 20px and below the body is drawn flat with dot eyes, so the silhouette stays legible in a row. A photo shows circle-cropped at every size, with the character standing in while it loads and if it fails.
Examples
Expressions
Eyes only, no mouth: working reads along a line, waiting widens, sleepy closes and sad drops the inner corners.
rootStyle takes layout and the blink period. The stack takes the ring colour of the surface it sits on.
| Knob | Takes | Default | Sets |
|---|---|---|---|
`calc(${Ref<Duration>} * ${number})` | calc(${duration["--loop-watch"] | One blink cycle (seeded per agent from 1.25× to 2.2× the watch loop, about 4 to 7 seconds). |
| Knob | Takes | Default | Sets |
|---|---|---|---|
Paint | var(--bg-sidebar) | The ring around each avatar: the surface the stack sits on. |
AgentAvatar is an img role named by name; the drawing inside is decorative. Where the name is written beside it, as in the rows above, wrap it in an element with aria-hidden in dense lists.
AvatarStack is one image named by its label followed by every agent's name, the folded ones included. Each picker control is a toggle button with aria-pressed and a name ("Heart", "Blue", "Tilted eyes"), in labelled groups.
Blinking and the working glance stop under reduced motion.
AgentAvatar
avatarrequired- AgentAvatarValue
- The stored avatar: a character, or a photo with its character as the stand-in.
namerequired- string
- Accessible name: the agent's name.
size- AgentAvatarSizeDefault20
- Width and height in pixels. 20 and below draw flat with dot eyes, so the shape stays legible.
expression- AgentExpressionDefault"neutral"
- Eye-only mood for the agent's state:
working(a live turn),waiting(needs the user),sleepy(paused or archived),sad(failed). live- boolean
- Blinks now and then (live agents, and every avatar at 72px and up). Never under reduced motion.
photoSrc- string
- The photo's address when
avataris a photo; while it loads, and if it fails, the character shows. rootStyle- RootStyle<AgentAvatarKnobs>
- Typed StyleX override: layout and the blink knob.
Rest props go to HTMLAttributes<HTMLSpanElement>.
valuerequired- CharacterAvatar
- The character as it is now.
onChangerequired- void
- A shape, colour or face was picked: the whole next character (write it at once; the picker holds no state).
onShuffle- void
- Shuffle: a new random character. Omit to hide the button.
onReset- void
- Reset: back to the character the agent was created with. Omit to hide the button.
onUpload- void
- A picture was chosen (png, jpg or webp): the product crops and stores it. Omit to hide "Upload photo".
hasPhoto- boolean
- The agent shows a photo now: offers Remove photo (with
onRemovePhoto). onRemovePhoto- void
- Remove the photo: the character shows again.
namerequired- string
- The agent's name, for the controls' accessible names.
rootStyle- RootStyle
- Typed StyleX override: where the picker sits.
Rest props go to HTMLAttributes<HTMLDivElement>.
agentsrequired- AvatarStackItem[]
- The agents, in order; the first sits on top.
size- 16 | 20 | 24Default16
- Each avatar's size.
max- numberDefault3
- At most this many avatars; the rest fold into a
+ncount. label- string
- Accessible name for the whole stack ("Agents on lookout"); the names follow it.
rootStyle- RootStyle<AvatarStackKnobs>
- Typed StyleX override: layout and the ring knob.
Rest props go to HTMLAttributes<HTMLSpanElement>.
shaperequired- AgentShape
colorrequired- AgentColor
facerequired- AgentFace
tilt- numberDefault0
expression- AgentExpressionDefault"neutral"
simple- booleanDefaultfalse
- One flat fill, dot eyes: what stays legible at 20px and below.
gradientIdrequired- string
- Unique per instance: the body's gradient id.
eyes- SVGProps<SVGGElement>
- Attributes for the eye pair (AgentAvatar's motion class).
Rest props go to SVG element props.