CharacterPicker
Shape and ink chooser.
The selection ring follows the shape
The highlight is drawn in the selected shape's own outline, not as a generic circle — a hexagon gets a hexagonal ring. It is a CSS mask generated by the same function that draws the body, so a shape registered with defineShape gets a correct ring without any extra work.
Layouts
Face style and nose
Pass face to add a cute | eyes | line toggle. While the line face is selected a row of the six noses follows, and every shape preview is drawn in the chosen style so the reader sees what they will get.
Omit face and the picker stays a shape and ink chooser.
Restricting the options
Preview size
sizePx sets the size of each shape preview; face and nose previews scale with it. The default is PICKER_MARK_PX (36). lineWeight is passed to the previews so a picker matches the character it edits.
onSelectColor
The colour callback is onSelectColor, spelt like the color prop and the ColorId type it hands back.
Two more pickers
AgentCharacterPicker holds its edits until they are confirmed, for a dialog where a click is a proposal and Cancel has to mean something. CompactCharacterPicker is cut down to a handful of shapes and inks, for the space beside a sign-up form.
Keyboard and assistive technology
One radio group per row — shapes, inks, and when enabled face style and nose — each with an accessible name. Every option has role="radio" and aria-checked, and focus is visible. Tab moves between the groups and arrow keys move within one, which is what a radio group is expected to do.
API
| Prop | Type | Default | Description |
|---|---|---|---|
color* | "black" | "brown" | "red" | "orange" | "yellow" | "green" | "cyan" | "blue" | "violet" | "magenta" | "pink" | "gray" | — | — |
shape* | "mochi" | "circle" | "blob" | "pebble" | "egg" | "bun" | "tofu" | "pill" | "hex" | "onigiri" | "gem" | "cloud" | "drop" | "leaf" | "flower" | "clover" | "sprout" | "mushroom" | "acorn" | "cactus" | "pear" | "apple" | "strawberry" | "cherry" | "star" | "heart" | "flame" | "bell" | "ghost" | "bot" | "crescent" | "boba" | "fish" | "octopus" | "cat" | "bunny" | "bear" | "chick" | "penguin" | "pig" | "fox" | "bob" | "topknot" | "spiky" | "curly" | "twinbuns" | — | — |
className | string | — | — |
colors | readonly ("black" | "brown" | "red" | "orange" | "yellow" | "green" | "cyan" | "blue" | "violet" | "magenta" | "pink" | "gray")[] | — | Restrict the offered colours. |
face | "cute" | "eyes" | "line" | — | Face style. Passing this shows the face toggle; in line mode a row of noses follows. Omit it to keep the picker to shape and colour. |
layout | "grid" | "row" | 'grid' | `grid` stacks shapes over colours in fixed columns; `row` keeps both groups on one line. |
lineWeight | number | — | Line weight for the previews, so a picker matches the character it edits. |
nose | "slant" | "angular" | "hook" | "long" | "curve" | "bow" | null | — | Nose for the line face. Defaults to the first nose while `face` is `line`. `null` — the same "no nose" every other surface takes — also lands on the first nose, because the picker has to highlight one of the offered options and "none" is not one of them. |
onSelectColor | ((color: "black" | "brown" | "red" | "orange" | "yellow" | "green" | "cyan" | "blue" | "violet" | "magenta" | "pink" | "gray") => void) | — | — |
onSelectFace | ((face: "cute" | "eyes" | "line") => void) | — | — |
onSelectNose | ((nose: "slant" | "angular" | "hook" | "long" | "curve" | "bow") => void) | — | — |
onSelectShape | ((shape: "mochi" | "circle" | "blob" | "pebble" | "egg" | "bun" | "tofu" | "pill" | "hex" | "onigiri" | "gem" | "cloud" | "drop" | "leaf" | "flower" | "clover" | "sprout" | "mushroom" | "acorn" | "cactus" | "pear" | "apple" | "strawberry" | "cherry" | "star" | "heart" | "flame" | "bell" | "ghost" | "bot" | "crescent" | "boba" | "fish" | "octopus" | "cat" | "bunny" | "bear" | "chick" | "penguin" | "pig" | "fox" | "bob" | "topknot" | "spiky" | "curly" | "twinbuns") => void) | — | — |
shapes | readonly ("mochi" | "circle" | "blob" | "pebble" | "egg" | "bun" | "tofu" | "pill" | "hex" | "onigiri" | "gem" | "cloud" | "drop" | "leaf" | "flower" | "clover" | "sprout" | "mushroom" | "acorn" | "cactus" | "pear" | "apple" | "strawberry" | "cherry" | "star" | "heart" | "flame" | "bell" | "ghost" | "bot" | "crescent" | "boba" | "fish" | "octopus" | "cat" | "bunny" | "bear" | "chick" | "penguin" | "pig" | "fox" | "bob" | "topknot" | "spiky" | "curly" | "twinbuns")[] | SHAPE_IDS | Restrict the offered shapes. |
showSelection | boolean | true | Hide the selection ring, for read-only displays. The selection is still announced. |
sizePx | number | — | Size of each shape preview. Face and nose previews scale with it. Defaults to `PICKER_MARK_PX`. |
style | CSSProperties | — | — |
Next
- AgentCharacterPicker — edits held until they are confirmed
- AvatarEditor — character, generate and upload tabs
- Character setup — choosing what an agent looks like