UIPackage
Menu

Framework

Change language

Boilerplate repo

Avatar

avatarui

Round or rounded-square user image with a fallback that shows initials or an icon when the image is missing or fails to load. Sizes from xs to 2xl, optional status dot, and a group composition for stacked avatar lists.

Also available for React ->

Installation

$npx shadcn-vue@latest add https://uipkge.dev/r/vue/avatar.json
Named registry:npx shadcn-vue@latest add @uipkge/avatarInstalls to:app/components/ui/avatar/

Examples

Loading interactive previews…

Props

NameType / ValuesDefaultRequired
classHTMLAttributes['class']optional
size
'xs''sm''default''lg''xl''2xl'
optional
rounded
'none''sm''default''md''lg''xl''2xl''3xl''full'
optional
color
'default''primary''secondary''destructive''success''warning''info''error''muted'
optional
variant
'default''outlined''soft'
optional
tilebooleanfalseoptional
disabledbooleanfalseoptional
loadingbooleanfalseoptional

Schema

Type aliases from this item's source — use them to shape the data you pass in.

AvatarContext
interface AvatarContext {
  imageStatus: Ref<AvatarImageStatus>
  setImageStatus: (status: AvatarImageStatus) => void
}

npm dependencies

Used by

Files installed (7)

  • app/components/ui/avatar/Avatar.vue1.7 kB
    <script setup lang="ts">
    import type { HTMLAttributes } from 'vue'
    import { computed, provide, ref } from 'vue'
    import { cn } from '@/lib/utils'
    import { avatarVariants } from './avatar.variants'
    import { AVATAR_INJECTION_KEY, type AvatarImageStatus } from './context'
    
    // Inlined unions: SFC compiler can't extract runtime props from
    // `AvatarVariants['size']` etc. indexed-access types.
    const props = withDefaults(
      defineProps<{
        class?: HTMLAttributes['class']
        size?: 'xs' | 'sm' | 'default' | 'lg' | 'xl' | '2xl'
        rounded?: 'none' | 'sm' | 'default' | 'md' | 'lg' | 'xl' | '2xl' | '3xl' | 'full'
        color?: 'default' | 'primary' | 'secondary' | 'destructive' | 'success' | 'warning' | 'info' | 'error' | 'muted'
        variant?: 'default' | 'outlined' | 'soft'
        tile?: boolean
        disabled?: boolean
        loading?: boolean
      }>(),
      {
        tile: false,
        disabled: false,
        loading: false,
      },
    )
    
    const emit = defineEmits<{
      click: [event: MouseEvent]
    }>()
    
    function handleClick(event: MouseEvent) {
      if (!props.disabled) {
        emit('click', event)
      }
    }
    
    const imageStatus = ref<AvatarImageStatus>('idle')
    
    provide(AVATAR_INJECTION_KEY, {
      imageStatus,
      setImageStatus: (status) => {
        imageStatus.value = status
      },
    })
    
    const rootClasses = computed(() =>
      cn(
        avatarVariants({ size: props.size, rounded: props.rounded, color: props.color, variant: props.variant }),
        props.tile ? 'rounded-none' : '',
        props.disabled ? 'cursor-not-allowed opacity-50' : '',
        props.loading ? 'animate-pulse' : '',
        props.class,
      ),
    )
    </script>
    
    <template>
      <span :class="rootClasses" data-uipkge data-slot="avatar" @click="handleClick">
        <slot />
      </span>
    </template>
    
  • app/components/ui/avatar/AvatarFallback.vue1.3 kB
  • app/components/ui/avatar/AvatarGroup.vue2.8 kB
  • app/components/ui/avatar/AvatarImage.vue2.3 kB
  • app/components/ui/avatar/avatar.variants.ts3.3 kB
  • app/components/ui/avatar/context.ts0.3 kB
  • app/components/ui/avatar/index.ts0.5 kB

Raw manifest:https://uipkge.dev/r/vue/avatar.json