Installation
Install the dependencies
pnpm add cn class-variance-authority github:sveltery/baseCopy the component
Copy the following files into src/lib/components/ui/avatar.
<script lang="ts">
import { Avatar as AvatarPrimitive } from '@sveltery/base/avatar';
import { cn } from 'cn';
import type { AvatarProps } from './types.js';
let { children, class: classProp, size = 'default', ...props }: AvatarProps = $props();
</script>
<AvatarPrimitive.Root
data-slot="avatar"
data-size={size}
class={cn('size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:border-border after:mix-blend-darken dark:after:mix-blend-lighten', classProp)}
{...props}
{children}
/><script lang="ts">
import { cn } from 'cn';
import type { AvatarBadgeProps } from './types.js';
let { children, class: classProp, ...props }: AvatarBadgeProps = $props();
</script>
<span
data-slot="avatar-badge"
class={cn(
'bg-primary text-primary-foreground ring-background absolute right-0 bottom-0 z-10 inline-flex items-center justify-center rounded-full bg-blend-color ring-2 select-none',
'group-data-[size=sm]/avatar:size-2 group-data-[size=sm]/avatar:[&>svg]:hidden',
'group-data-[size=default]/avatar:size-2.5 group-data-[size=default]/avatar:[&>svg]:size-2',
'group-data-[size=lg]/avatar:size-3 group-data-[size=lg]/avatar:[&>svg]:size-2',
classProp,
)}
{...props}
>
{@render children?.()}
</span><script lang="ts">
import { Avatar as AvatarPrimitive } from '@sveltery/base/avatar';
import { cn } from 'cn';
import type { AvatarFallbackProps } from './types.js';
let { children, class: classProp, ...props }: AvatarFallbackProps = $props();
</script>
<AvatarPrimitive.Fallback
data-slot="avatar-fallback"
class={cn('bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs', classProp)}
{...props}
{children}
/><script lang="ts">
import { cn } from 'cn';
import type { AvatarGroupProps } from './types.js';
let { children, class: classProp, ...props }: AvatarGroupProps = $props();
</script>
<div
data-slot="avatar-group"
class={cn('group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background', classProp)}
{...props}
>
{@render children?.()}
</div><script lang="ts">
import { cn } from 'cn';
import type { AvatarGroupCountProps } from './types.js';
let { children, class: classProp, ...props }: AvatarGroupCountProps = $props();
</script>
<div data-slot="avatar-group-count" class={cn('bg-muted text-muted-foreground size-8 rounded-full text-sm group-has-data-[size=lg]/avatar-group:size-10 group-has-data-[size=sm]/avatar-group:size-6 [&>svg]:size-4 group-has-data-[size=lg]/avatar-group:[&>svg]:size-5 group-has-data-[size=sm]/avatar-group:[&>svg]:size-3 relative flex shrink-0 items-center justify-center ring-2 ring-background', '', classProp)} {...props}>
{@render children?.()}
</div><script lang="ts">
import { Avatar as AvatarPrimitive } from '@sveltery/base/avatar';
import { cn } from 'cn';
import type { AvatarImageProps } from './types.js';
let { children, class: classProp, ...props }: AvatarImageProps = $props();
</script>
<AvatarPrimitive.Image data-slot="avatar-image" class={cn('rounded-full aspect-square size-full object-cover', classProp)} {...props} {children} />import type { HTMLAttributes } from 'svelte/elements';
import type { AvatarRootProps } from '@sveltery/base/avatar';
export type { AvatarImageProps, AvatarFallbackProps, AvatarRootState, AvatarImageState, AvatarFallbackState, ImageLoadingStatus } from '@sveltery/base/avatar';
export type AvatarProps = AvatarRootProps & { size?: 'default' | 'sm' | 'lg' };
export type AvatarBadgeProps = HTMLAttributes<HTMLSpanElement>;
export type AvatarGroupProps = HTMLAttributes<HTMLDivElement>;
export type AvatarGroupCountProps = HTMLAttributes<HTMLDivElement>;export { default as Avatar } from './Avatar.svelte';
export { default as AvatarImage } from './AvatarImage.svelte';
export { default as AvatarFallback } from './AvatarFallback.svelte';
export { default as AvatarBadge } from './AvatarBadge.svelte';
export { default as AvatarGroup } from './AvatarGroup.svelte';
export { default as AvatarGroupCount } from './AvatarGroupCount.svelte';
export type { AvatarProps, AvatarImageProps, AvatarFallbackProps, AvatarBadgeProps, AvatarGroupProps, AvatarGroupCountProps, AvatarRootState, AvatarImageState, AvatarFallbackState, ImageLoadingStatus } from './types.js';Update the import paths
Change the imports to match your project setup.
Usage
<script lang="ts">
import { Avatar, AvatarFallback, AvatarImage } from '$lib/components/ui/avatar';
</script><Avatar>
<AvatarImage src="https://github.com/sveltejs.png" alt="@sveltejs" />
<AvatarFallback>SV</AvatarFallback>
</Avatar>API reference
Avatar is styled on top of the Sveltery Base Avatar primitive, which owns its behavior, focus handling and accessibility. See the Base UI Avatar documentation for the behavior it ports.