Tessera UI

Components

Avatar

A person or a thing as a picture, or as initials when there is no picture or it does not load.

The preview needs JavaScript. The code is in the Code tab.

Avatar-0.tess
<template>
  <div>
    <Avatar name="Ada Lovelace" size="sm" />
    <Avatar name="Grace Hopper" />
    <Avatar name="Alan Turing" size="lg" />
  </div>
</template>

Installation

npx @pixelscriptio/tessera add Avatar
pnpm exec tessera add Avatar
yarn tessera add Avatar
bunx @pixelscriptio/tessera add Avatar
  • Works with Tessera 0.9.0 or newer.
  1. Copy and paste the code into your project

    Put it in system/components.

    system/components/Avatar.tess
    <contract>
    {
      "name": "Avatar",
      "role": "img",
      "description": "A person or a thing as a picture, or as initials when there is no picture or it does not load.",
      "since": "0.8.0",
      "parts": ["root", "image", "initials"],
      "variants": {
        "size": ["md", "sm", "lg"] // first value is the default
      },
      "preview": {
        "props": {
          "name": "Ada Lovelace"
        }
      }
    }
    </contract>
    
    <script>
    const { src, name } = props({ src: '', name: '' })
    
    // A picture that fails to load falls back to the initials.
    const failed = state(false)
    effect(() => {
      src.value
      failed.value = false
    })
    
    function broke() {
      failed.value = true
    }
    
    const initials = derived(() =>
      name.value
        .trim()
        .split(/\s+/)
        .filter(Boolean)
        .slice(0, 2)
        .map((part) => part[0].toUpperCase())
        .join(''),
    )
    </script>
    
    <template>
      <span class="root" role="img" :aria-label="name || 'Avatar'">
        <img
          class="image"
          if="src && !failed"
          :src="src"
          alt=""
          @error="broke()"
          />
        <span class="initials" else aria-hidden="true">{initials}</span>
      </span>
    </template>
    
    <style>
    .root {
      display: inline-flex;
      align-items: center;
      justify-content: center;
      width: $space.8;
      height: $space.8;
      overflow: hidden;
      border-radius: $radius.full;
      background: $color.surface.hover;
      color: $color.text.default;
      font-size: $font.size.sm;
      font-weight: $font.weight.bold;
    
      &[data-size='sm'] {
        width: $space.6;
        height: $space.6;
        font-size: $font.size.xs;
      }
    
      &[data-size='lg'] {
        width: $space.12;
        height: $space.12;
        font-size: $font.size.lg;
      }
    }
    
    .image {
      width: 100%;
      height: 100%;
      object-fit: cover;
    }
    </style>
    
  2. Check your design tokens

    Your design system needs these. tessera add reports the ones that are missing; by hand, run npx @pixelscriptio/tessera check.

    color.surface.hover color.text.default font.size.lg font.size.sm font.size.xs font.weight.bold radius.full space.12 space.6 space.8

Usage

Using Avatar

A person or a thing as a picture, or as initials.

  • Give it a name. It is the accessible name, and the initials come from it (the first letters of the first two words).
  • Give it a src for a picture. If the picture does not load, the initials are shown instead, so there is never a broken image.
  • The picture is described by the name once, on the avatar. Do not repeat the name in text beside it for people who use a screen reader unless it adds something.
  • size is sm, md or lg.

The preview needs JavaScript. The code is in the Code tab.

Avatar-0.tess
<template>
  <div>
    <Avatar name="Ada Lovelace" size="sm" />
    <Avatar name="Grace Hopper" />
    <Avatar name="Alan Turing" size="lg" />
  </div>
</template>

API reference

Variants

VariantValues
sizemd default sm lg

Anatomy

Roleimg
Partsroot image initials
Since0.8.0

Design tokens it uses

Your design system needs these. tessera add checks that it has them, and can add the ones it lacks.

color.surface.hover color.text.default font.size.lg font.size.sm font.size.xs font.weight.bold radius.full space.12 space.6 space.8

Checksum

75fa071cce6df7483b4751469a9f4602317976f66b30a18c8c7f0864a6298f6a