Avatar
User avatar — initials, image, status indicator, and stacked group variants.
Overview
The Avatar component is a core building block of the Byteion design system, providing a robust, accessibility-compliant interface for its specific UI capabilities.
Why this exists
Avatars provide instant visual identity for users, teams, and entities. They appear in headers, comments, assignments, and notifications.
Mental model
An avatar is a circular element showing either a user's image or their initials as a fallback. It is a quick visual anchor in any interface.
When to use
When not to use
Basic example
The following example demonstrates standard usage, fully compliant with Byteion's token-first approach.
1. Sizes
Use sizes to establish hierarchy and fit different contexts.
2. With Image
Display user photos or any custom image.
3. With Initials
Use initials when an image is not available.
4. With Status
Show presence or availability with a status indicator.
5. Stacked
Display multiple avatars in a limited space.
6. Square
Use square avatars for a different visual style.
7. Variants
Different styles for different use cases.
8. Group / Stack Options
Control how avatars are stacked.
9. Usage Examples
Real-world component combinations.
Jane Cooper
jane.cooper@example.com
Brooklyn Simmons
2 hours agoThis looks great! 🎉
Robert Fox
1m agomentioned you in a comment
import { Avatar, AvatarGroup } from '@byteion/react';
export default function AvatarDemo() {
return (
<div className="space-y-6 p-6">
<div className="flex items-center gap-3">
<Avatar size="xs" initials="AB" />
<Avatar size="sm" initials="CD" />
<Avatar size="md" initials="EF" />
<Avatar size="lg" initials="GH" />
<Avatar size="xl" initials="JS" />
</div>
<div className="flex items-center gap-3">
<Avatar initials="JS" status="online" />
<Avatar initials="MM" status="busy" />
<Avatar initials="RV" status="away" />
<Avatar initials="TC" status="offline" />
</div>
<AvatarGroup max={4}>
<Avatar src="/avatars/01.png" alt="Ada" />
<Avatar src="/avatars/02.png" alt="Linus" />
<Avatar src="/avatars/03.png" alt="Grace" />
<Avatar initials="+5" />
</AvatarGroup>
</div>
);
}
<script setup lang="ts">
import { Avatar, AvatarGroup } from '@byteion/vue';
</script>
<template>
<div class="space-y-6 p-6">
<div class="flex items-center gap-3">
<Avatar size="xs" initials="AB" />
<Avatar size="sm" initials="CD" />
<Avatar size="md" initials="EF" />
<Avatar size="lg" initials="GH" />
<Avatar size="xl" initials="JS" />
</div>
<div class="flex items-center gap-3">
<Avatar initials="JS" status="online" />
<Avatar initials="MM" status="busy" />
<Avatar initials="RV" status="away" />
<Avatar initials="TC" status="offline" />
</div>
<AvatarGroup :max="4">
<Avatar src="/avatars/01.png" alt="Ada" />
<Avatar src="/avatars/02.png" alt="Linus" />
<Avatar src="/avatars/03.png" alt="Grace" />
<Avatar initials="+5" />
</AvatarGroup>
</div>
</template>
Variants
Each variant communicates a different meaning. Choose based on priority, not aesthetics.
Single default variant.
Sizes
Size should match the importance and context of the component.
- sm — sm size.
- md — md size.
- lg — lg size.
- xl — xl size.
States
This component reacts seamlessly to the following interaction and data states:
- online — online state.
- away — away state.
- busy — busy state.
- offline — offline state.
- default — Resting appearance before interaction.
- hover — Pointer is over the element — visual feedback via color or shadow.
- focus — Keyboard or tab focus — shows ring indicator for accessibility.
- active — Currently selected or in use.
- disabled — Non-interactive — grayed out, cursor not-allowed.
Anatomy
Usage guidelines
- Always pair with a name label.
- Use initials fallback consistently.
- Status dots should follow a standard color mapping.
Do and Don't
Do
- Pair with a name.
- Use initials fallback.
- Use status dots consistently.
Don't
- Do not use as the only identifier.
- Do not stretch non-square images.
- Do not omit the fallback.
Accessibility
Image has alt with user name. Initials fallback has aria-label.
Role:img (when image), none required for initials
Customization
Size and color follow avatar tokens.
Compose with React cva()
Use the exportedcva() +cn() utilities to compose your own variant on top of the Byteion tokens.
import { cva, cn, type VariantProps } from '@byteion/react';
const myAvatar = cva('base classes…', {
variants: {
accent: { soft:'border-primary-200', loud:'border-primary-500' },
},
defaultVariants: { accent:'soft' },
});
type Props = React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof myAvatar>;
Compose with Vue cva()
Use the exportedcva() +cn() utilities inside standard Vue setup blocks.
<script setup lang="ts">
import { computed, useAttrs } from 'vue';
import { cva, type VariantProps } from '@byteion/vue';
interface Props { accent?:'soft' |'loud' }
const props = withDefaults(defineProps<Props>(), { accent:'soft' });
const attrs = useAttrs();
const myAvatar = cva('base classes…', {
variants: { accent: { soft:'border-primary-200', loud:'border-primary-500' } },
});
const cls = computed(() => myAvatar({ accent: props.accent, class: attrs.class as string | undefined }));
</script>
Runtime events
Byteion keeps framework APIs idiomatic: HTML uses DOM custom events, React uses callback props, and Vue uses emitted events / v-model updates.
HTML / JS events
No HTML runtime events are declared by this adapter.
React callbacks
No React callback events are declared by this adapter.
Vue emits
No Vue emitted events are declared by this adapter.
Remote / AJAX
This component does not implement Byteion JS remote loading. Use normal HTML form submission, framework state, or your application data layer around it.
API Reference
Static HTML. Image src and initials set by consumer.
HTML Data Attributes
No custom data attributes required.
React Props · AvatarProps
Extracted directly fromreact/src/components/Avatar.tsx.
export interface AvatarProps
extends Omit<HTMLAttributes<HTMLSpanElement>, 'children'>,
VariantProps<typeof avatar> {
/** Image URL. Falls back to `initials` / `fallback` on error. */
src?: string;
alt?: string;
/** 1-2 letter fallback shown when no image / image fails. */
initials?: string;
/** Custom fallback node (overrides `initials`). */
fallback?: ReactNode;
/** Status indicator rendered as a colored dot in the bottom-right. */
status?: keyof typeof STATUS_BG;
/** Accessible label for the status dot (e.g. "Online"). */
statusLabel?: string;
}
React Variant Schema
Internal variant composition defined viacva().
cva(
'inline-flex items-center justify-center font-medium',
{
variants: {
size: {
xs: 'h-5 w-5 text-[10px]',
sm: 'h-8 w-8 text-xs',
md: 'h-10 w-10 text-sm',
lg: 'h-12 w-12 text-base',
xl: 'h-16 w-16 text-lg',
'2xl': 'h-20 w-20 text-2xl',
},
shape: {
circle: 'rounded-full',
square: 'rounded-md',
},
tone: {
neutral: 'bg-muted text-muted-foreground dark:bg-muted dark:text-muted-foreground',
primary: 'bg-primary-100 text-primary-700',
success: 'bg-success-100 text-success-700',
warning: 'bg-warning-100 text-warning-700',
danger: 'bg-danger-100 text-danger-700',
info: 'bg-info-100 text-info-700',
secondary: 'bg-secondary text-secondary-foreground',
},
variant: {
default: '',
bordered: 'ring-2 ring-border ring-offset-2 ring-offset-background',
soft: 'bg-muted/50 ring-1 ring-border/50',
outline: 'border-2 border-primary text-primary bg-transparent',
ghost: 'bg-muted text-foreground hover:bg-muted/80 transition-colors cursor-pointer',
},
},
defaultVariants: { size: 'md', shape: 'circle', tone: 'neutral', variant: 'default' },
},
)
Vue Props · AvatarProps
Extracted directly fromvue/src/components/Avatar.vue.
export interface AvatarProps {
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
shape?: 'circle' | 'square';
/** Image URL. Falls back to `initials` / `fallback` on error. */
src?: string;
alt?: string;
/** 1-2 letter fallback shown when no image / image fails. */
initials?: string;
/** Status indicator rendered as a colored dot in the bottom-right. */
status?: 'online' | 'away' | 'busy' | 'offline';
/** Accessible label for the status dot (e.g. "Online"). */
statusLabel?: string;
/** Background / text tone. */
tone?: 'neutral' | 'primary' | 'success' | 'warning' | 'danger' | 'info' | 'secondary';
/** Variant styling. */
variant?: 'default' | 'bordered' | 'soft' | 'outline' | 'ghost';
}
Developer tips
Common mistakes
- Missing fallback when image fails — always provide
initialsorfallback. - Missing accessible label when avatar stands alone.
- Duplicating screen-reader labels when avatar is next to visible name.
- Using avatar as the only identifier in tables.
- Relying only on status dot colour.
- Stretching non-square images.
- Using inconsistent sizes in the same list.
- Assigning random tones without rules.
- Making avatar clickable without a focusable element.
Production usage tips
- Test image load, broken image, missing image, initials fallback, and custom fallback.
- Test with long names, non-Latin names, single-word names, and missing names.
- Test status indicators in light mode, dark mode, and branded themes.
- Test avatar groups with 1, 2, 3, and overflow users.
- For Laravel or server-rendered apps, generate initials server-side when possible.
- For React or Vue SPAs, handle image error state and fallback rendering.
- In tables and lists, pair Avatar with name, role, email, or customer ID.
- In large lists, avoid loading full-size profile images.
Premium examples
Advanced patterns available in Byteion Pro:
Related components
- Badge — overlay labels and status badges
- Card — profile cards with avatar
- List — user and member lists
- Dropdown — user menu trigger
- Button — avatar as button trigger
- Tooltip — name tooltip on avatar
- Table — customer avatar cells
- Skeleton — avatar loading placeholder
Unlock Premium Patterns
Get access to copy-paste ready Pro blocks, SaaS templates, and advanced data-tables built with this component.
Explore Pro Components