cast-avatar
Version:
Dependency-free deterministic SVG avatar generator for browsers.
350 lines (313 loc) • 11.9 kB
TypeScript
// Type declarations for cast-avatar.
// The source is dependency-free ES module JavaScript (src/avatar.js); these
// declarations describe its public API for TypeScript consumers.
/** Avatar style. `'face'` is a legacy alias for `'cartoon'`. */
export type AvatarStyle =
| 'portrait'
| 'studio'
| 'cartoon'
| 'minimal'
| 'line'
| 'pixel'
| 'initials'
| 'bot'
| 'shapes'
| 'mesh'
| 'face';
/** Built-in background keywords (any CSS color is also accepted). */
export type BackgroundKeyword = 'auto' | 'transparent' | 'gradient' | 'dots' | 'rings' | 'grid';
/**
* Override any of the default color sets to theme avatars (e.g. to a brand
* palette). Tone maps (`skinTones`/`hairColors`) merge over the defaults;
* color lists replace the defaults when provided.
*/
export interface AvatarPalette {
skinTones?: Record<string, string>;
hairColors?: Record<string, string>;
backgrounds?: string[];
shapeColors?: string[];
clothingColors?: string[];
inks?: string[];
}
/** Names of the built-in palette presets resolvable by string. */
export type PalettePreset = 'accessible' | 'colorblind-safe';
/** Presence state shown by the status badge. */
export type Status = 'online' | 'busy' | 'away' | 'offline';
/**
* A shorthand that presets the expressive traits (eyes, mouth, eyebrows) while
* leaving identity traits seed-derived. Explicit `traits` still take precedence.
* Applies to the face styles. Great for reflecting agent/user state.
*/
export type Expression = 'neutral' | 'happy' | 'sad' | 'surprised' | 'thinking' | 'wink';
/**
* A subtle, deterministic CSS animation. Respects `prefers-reduced-motion`.
* `breathe` gently scales; `bounce` bobs; `blink` briefly closes the eyes
* (face styles only).
*/
export type Animate = 'breathe' | 'bounce' | 'blink';
/** Corner placement for a `dot` status badge. */
export type StatusPosition = 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right';
/** Full status badge configuration. */
export interface StatusBadge {
state: Status;
/** `dot` = corner badge (default); `ring` = colored border around the avatar. */
shape?: 'dot' | 'ring';
/** Corner for the `dot` shape; ignored for `ring`. Defaults to `bottom-right`. */
position?: StatusPosition;
/** Animate the badge with a pulse. */
pulse?: boolean;
/**
* Draw a colorblind-safe shape glyph on the `dot` so the state is
* distinguishable without relying on color alone. Defaults to `false`.
*/
icon?: boolean;
}
export type Gender = 'neutral' | 'feminine' | 'masculine';
export type SkinTone = 'light' | 'mediumLight' | 'medium' | 'mediumDark' | 'dark';
export type FaceShape = 'round' | 'oval' | 'soft';
export type HairStyle =
| 'none'
| 'stubble'
| 'short'
| 'long'
| 'curly'
| 'coily'
| 'bun'
| 'afro'
| 'mohawk'
| 'spiky'
| 'hijab';
export type HairColor = 'black' | 'brown' | 'blonde' | 'red' | 'gray' | 'white';
export type Eyes = 'round' | 'smile' | 'sleepy' | 'wink';
export type Mouth = 'smile' | 'neutral' | 'open';
export type FacialHair =
| 'none'
| 'stubble'
| 'mustache'
| 'goatee'
| 'beard'
| 'fullBeard'
| 'sideburns';
export type Headwear = 'none' | 'beanie' | 'cap' | 'turban' | 'bucket' | 'hijab';
export type Accessories = 'none' | 'glasses' | 'sunglasses';
export type Eyebrows = 'flat' | 'raised' | 'angled';
export type Nose = 'soft' | 'button' | 'wide';
export type Freckles = 'none' | 'light' | 'heavy';
export type Blush = 'none' | 'soft';
export type Earrings = 'none' | 'studs' | 'hoops';
/** Any trait may be set to `'auto'` to let the seed decide. */
export type Auto<T> = T | 'auto';
/** Trait inputs. Omitted or `'auto'` traits are derived deterministically from the seed. */
export interface AvatarTraits {
gender?: Auto<Gender>;
skinTone?: Auto<SkinTone>;
faceShape?: Auto<FaceShape>;
hairStyle?: Auto<HairStyle>;
hairColor?: Auto<HairColor>;
eyebrows?: Auto<Eyebrows>;
eyes?: Auto<Eyes>;
nose?: Auto<Nose>;
mouth?: Auto<Mouth>;
facialHair?: Auto<FacialHair>;
freckles?: Auto<Freckles>;
blush?: Auto<Blush>;
headwear?: Auto<Headwear>;
earrings?: Auto<Earrings>;
accessories?: Auto<Accessories>;
/** Clothing color — the one free-color trait. A CSS color or `'auto'`. */
clothing?: 'auto' | (string & {});
}
/** Fully resolved traits, as produced by {@link resolveAvatarOptions}. */
export interface ResolvedAvatarTraits {
gender: Gender;
skinTone: SkinTone;
faceShape: FaceShape;
hairStyle: HairStyle;
hairColor: HairColor;
eyebrows: Eyebrows;
eyes: Eyes;
nose: Nose;
mouth: Mouth;
facialHair: FacialHair;
freckles: Freckles;
blush: Blush;
headwear: Headwear;
earrings: Earrings;
accessories: Accessories;
clothing: string;
}
export interface AvatarOptions {
/** Stable identity input. `name` and `id` are accepted as aliases. */
seed?: string | number;
name?: string | number;
id?: string | number;
style?: Auto<AvatarStyle>;
/** Preset the expressive traits (eyes/mouth/eyebrows) to reflect a mood/state. */
expression?: Expression;
/** Rendered pixel size, clamped to 24–1024. Defaults to 128. */
size?: number;
traits?: AvatarTraits;
/**
* Background fill. A CSS color, `'transparent'`, a seeded `'gradient'`, a
* seeded pattern (`'dots'`, `'rings'`, `'grid'`), or `'auto'` / omitted to
* pick a color from the palette.
*/
background?: BackgroundKeyword | (string & {});
/** @deprecated Use `traits.clothing`. Top-level `clothing` is still accepted. */
clothing?: 'auto' | (string & {});
/** Presence badge. A state string (corner dot) or a full config object. Omitted = no badge. */
status?: Status | StatusBadge;
/** A subtle looping animation (`breathe` | `bounce`). Respects reduced-motion. */
animate?: Animate;
/**
* Override the default color sets (skin tones, hair, backgrounds, etc.), or
* name a built-in preset (`'accessible'` / `'colorblind-safe'`).
*/
palette?: AvatarPalette | PalettePreset;
/** Monogram font weight for the `initials` style (default `800`). */
fontWeight?: number | string;
/** Monogram font family for the `initials` style. */
fontFamily?: string;
/** Corner radius for the frame; number (px) or CSS length. Defaults to `'50%'`. */
radius?: number | string;
/** Accessible title / aria-label and native `<title>` tooltip. Defaults to `` `${seed} avatar` ``. */
title?: string;
/**
* Hide the avatar from assistive technology (`aria-hidden`, no role/label/title)
* instead of exposing it as a labelled image. Use when adjacent text already
* names the person. Defaults to `false`.
*/
decorative?: boolean;
/** Explicit initials for the `initials` style. */
initials?: string;
/** Legacy alias for `traits.hairStyle`. */
hair?: Auto<HairStyle>;
}
/** A resolved, serializable avatar configuration. */
export interface ResolvedAvatarConfig {
version: 1;
seed: string;
style: AvatarStyle;
size: number;
traits: ResolvedAvatarTraits;
background: string;
radius: number | string;
title: string;
initials?: string;
fontWeight?: number | string;
fontFamily?: string;
status?: Status | StatusBadge;
animate?: Animate;
palette?: AvatarPalette | PalettePreset;
decorative?: boolean;
}
/** The full set of allowed values for each option, keyed by trait name. */
export interface AvatarOptionSets {
style: AvatarStyle[];
gender: Gender[];
skinTone: SkinTone[];
faceShape: FaceShape[];
hairStyle: HairStyle[];
hairColor: HairColor[];
eyebrows: Eyebrows[];
eyes: Eyes[];
nose: Nose[];
mouth: Mouth[];
facialHair: FacialHair[];
freckles: Freckles[];
blush: Blush[];
headwear: Headwear[];
earrings: Earrings[];
accessories: Accessories[];
}
/** First argument of the public helpers: a bare seed or an options object. */
export type SeedOrOptions = string | number | AvatarOptions;
/** Resolve a seed/options pair into a complete, deterministic configuration. */
export function resolveAvatarOptions(
seedOrOptions?: SeedOrOptions,
maybeOptions?: AvatarOptions
): ResolvedAvatarConfig;
/** Short, stable hash of the resolved configuration (base-36). */
export function avatarHash(seedOrOptions?: SeedOrOptions, maybeOptions?: AvatarOptions): string;
/** Encode an avatar to a portable, hash-checked string (`ca1.<hash>.<payload>`). */
export function encodeAvatar(seedOrOptions?: SeedOrOptions, maybeOptions?: AvatarOptions): string;
/**
* Decode a string produced by {@link encodeAvatar}.
* @throws if the string is malformed or the embedded hash does not match.
*/
export function decodeAvatar(encoded: string): ResolvedAvatarConfig;
/** Render an avatar to an SVG string. Accepts a seed, options, or a resolved config. */
export function createAvatar(
seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
maybeOptions?: AvatarOptions
): string;
/** Render many avatars at once. Each item is a seed or options object; `sharedOptions` is merged under each. */
export function createAvatars(
items: Array<SeedOrOptions>,
sharedOptions?: AvatarOptions
): string[];
/** Options for {@link createAvatarSprite}: grid layout plus shared avatar options. */
export interface SpriteOptions extends AvatarOptions {
/** Avatars per row (default 8). */
columns?: number;
/** Pixel size of each avatar cell (default 64). */
cell?: number;
/** Gap in px between cells (default 8). */
gap?: number;
}
/** Render a roster of avatars into a single SVG sprite-sheet grid. */
export function createAvatarSprite(
items: Array<SeedOrOptions>,
options?: SpriteOptions
): string;
/**
* Combine seeds into a single deterministic, order-independent seed — for a
* stable "pair"/relationship avatar. `mergeSeeds('a','b') === mergeSeeds('b','a')`.
*/
export function mergeSeeds(
...seeds: Array<string | number | ReadonlyArray<string | number>>
): string;
/** Options for {@link createAvatarGroup}: shared avatar options plus the tile cap. */
export interface GroupOptions extends AvatarOptions {
/** Max member tiles (2–4, default 4); extra members collapse into a "+N" chip. */
max?: number;
}
/** A group member: a plain seed, or an object with per-member option overrides. */
export type GroupMember = string | number | (AvatarOptions & { seed: string | number });
/** Render several members into one cohesive group mark (a clipped mosaic). */
export function createAvatarGroup(
seeds: Array<GroupMember>,
options?: GroupOptions
): string;
/** Wrap an SVG string in a `data:image/svg+xml` URI. */
export function toDataUri(svg: string): string;
/** Render an avatar directly to a `data:image/svg+xml` URI. */
export function createAvatarDataUri(
seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
maybeOptions?: AvatarOptions
): string;
/**
* Render an avatar to a detached `SVGElement`.
* Requires a DOM environment; throws otherwise.
*/
export function createAvatarElement(
seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
maybeOptions?: AvatarOptions
): SVGElement | null;
/**
* Render an avatar and mount it into `target` (a selector or element).
* Requires a DOM environment; throws otherwise. Returns the SVG string.
*/
export function mountAvatar(
target: string | Element,
seedOrOptions?: SeedOrOptions | ResolvedAvatarConfig,
maybeOptions?: AvatarOptions
): string;
/** The allowed values for every trait (re-export of the internal option table). */
export const avatarOptions: AvatarOptionSets;
/** Resolve a palette override (object or preset name) into a full color set. */
export function resolvePalette(override?: AvatarPalette | PalettePreset): Required<AvatarPalette>;
/** A colorblind-safe palette preset (Okabe–Ito based). */
export const COLORBLIND_SAFE_PALETTE: AvatarPalette;
/** Built-in palette presets, keyed by preset name. */
export const PALETTE_PRESETS: Record<PalettePreset, AvatarPalette>;