Avatar

A circular element that displays a user's profile image or initials as a fallback.

Loading...
<div class="flex flex-row flex-wrap items-center gap-6 md:gap-12">
    <twig:Avatar>
        <twig:Avatar:Image
            src="https://github.com/shadcn.png"
            alt="@shadcn"
            class="grayscale"
        />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
        <twig:Avatar:Fallback>ER</twig:Avatar:Fallback>
        <twig:Avatar:Badge class="bg-green-600 dark:bg-green-800" />
    </twig:Avatar>
    <twig:Avatar:Group class="grayscale">
        <twig:Avatar>
            <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
            <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
        </twig:Avatar>
        <twig:Avatar>
            <twig:Avatar:Image src="https://github.com/maxleiter.png" alt="@maxleiter" />
            <twig:Avatar:Fallback>LR</twig:Avatar:Fallback>
        </twig:Avatar>
        <twig:Avatar>
            <twig:Avatar:Image src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
            <twig:Avatar:Fallback>ER</twig:Avatar:Fallback>
        </twig:Avatar>
        <twig:Avatar:GroupCount>+3</twig:Avatar:GroupCount>
    </twig:Avatar:Group>
</div>

Installation

bin/console ux:install avatar --kit shadcn

That's it!

Install the following Composer dependencies:

composer require tales-from-a-dev/twig-tailwind-extra:^1.0.0

Copy the following file(s) into your Symfony app:

{# @prop size 'default'|'sm'|'lg' The size, default to `default` #}
{# @block content The default block #}
{%- props size = 'default' -%}

<span
    data-slot="avatar"
    data-size="{{ size }}"
    class="{{ 'size-8 rounded-full after:rounded-full data-[size=lg]:size-10 data-[size=sm]:size-6 after:border-border group/avatar relative flex shrink-0 select-none after:absolute after:inset-0 after:border after:mix-blend-darken dark:after:mix-blend-lighten ' ~ attributes.render('class')|tailwind_merge }}"
    {{ attributes }}
>
    {%- block content %}{% endblock -%}
</span>
{# @block content The default block #}
{%- set classes = html_classes(
    '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',
    attributes.render('class')|default(''),
) -%}

<span
    data-slot="avatar-badge"
    class="{{ classes|tailwind_merge }}"
    {{ attributes }}
>
    {%- block content %}{% endblock -%}
</span>
{# @block content The default block #}
<span
    data-slot="avatar-fallback"
    class="{{ 'bg-muted text-muted-foreground rounded-full flex size-full items-center justify-center text-sm group-data-[size=sm]/avatar:text-xs ' ~ attributes.render('class')|tailwind_merge }}"
    {{ attributes }}
>
    {%- block content %}{% endblock -%}
</span>
{# @block content The default block #}
<div
    data-slot="avatar-group"
    class="{{ '*:data-[slot=avatar]:ring-background group/avatar-group flex -space-x-2 *:data-[slot=avatar]:ring-2 ' ~ attributes.render('class')|tailwind_merge }}"
    {{ attributes }}
>
    {%- block content %}{% endblock -%}
</div>
{# @block content The default block #}
<div
    data-slot="avatar-group-count"
    class="{{ '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 ring-background relative flex shrink-0 items-center justify-center ring-2 ' ~ attributes.render('class')|tailwind_merge }}"
    {{ attributes }}
>
    {%- block content %}{% endblock -%}
</div>
<img
    data-slot="avatar-image"
    class="{{ 'hidden rounded-full aspect-square size-full object-cover ' ~ attributes.render('class')|tailwind_merge }}"
    onload="this.classList.remove('hidden'); this.closest('[data-slot=avatar]')?.querySelector('[data-slot=avatar-fallback]')?.classList.add('hidden');"
    {{ attributes.defaults({alt: ''}) }}
/>

Happy coding!

Usage

<twig:Avatar>
    <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
    <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
</twig:Avatar>

Examples

Basic

Loading...
<twig:Avatar>
    <twig:Avatar:Image
        src="https://github.com/shadcn.png"
        alt="@shadcn"
        class="grayscale"
    />
    <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
</twig:Avatar>

Badge

Loading...
<twig:Avatar>
    <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
    <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    <twig:Avatar:Badge class="bg-green-600 dark:bg-green-800" />
</twig:Avatar>

Badge with Icon

Loading...
<twig:Avatar>
    <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
    <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    <twig:Avatar:Badge>
        <twig:ux:icon name="lucide:plus" />
    </twig:Avatar:Badge>
</twig:Avatar>

Avatar Group

Loading...
<twig:Avatar:Group class="grayscale">
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/maxleiter.png" alt="@maxleiter" />
        <twig:Avatar:Fallback>LR</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
        <twig:Avatar:Fallback>ER</twig:Avatar:Fallback>
    </twig:Avatar>
</twig:Avatar:Group>

Avatar Group with Icon

Loading...
<twig:Avatar:Group class="grayscale">
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/maxleiter.png" alt="@maxleiter" />
        <twig:Avatar:Fallback>LR</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/evilrabbit.png" alt="@evilrabbit" />
        <twig:Avatar:Fallback>ER</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar:GroupCount>
        <twig:ux:icon name="lucide:plus" />
    </twig:Avatar:GroupCount>
</twig:Avatar:Group>

Sizes

Loading...
<div class="flex flex-wrap items-center gap-2 grayscale">
    <twig:Avatar size="sm">
        <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar>
        <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
    <twig:Avatar size="lg">
        <twig:Avatar:Image src="https://github.com/shadcn.png" alt="@shadcn" />
        <twig:Avatar:Fallback>CN</twig:Avatar:Fallback>
    </twig:Avatar>
</div>

API Reference

Avatar

Prop Type Description
size 'default'|'sm'|'lg' The size, default to default
Block Description
content The default block

Avatar:Badge

Block Description
content The default block

Avatar:Fallback

Block Description
content The default block

Avatar:Group

Block Description
content The default block

Avatar:GroupCount

Block Description
content The default block