๐ข Avatar
Basic
NAvatar
- used to display a user's profile picture, initials, or icon.
Variants
variant="{variant}"
- change the variant of the avatar.
Variant | Description |
---|---|
solid | The default variant. |
soft | The soft variant. |
outline | The outline variant. |
~ | The unstyle or base variant |
Color
avatar="{variant}-{color}"
- change the color of the avatar.
primary
. You can also add your own colors to the palette through the Configuration section.Icon
icon="{icon}"
- set the icon of the avatar, instead of an image.
icon
prop with the src
prop.Skeleton mode
skeleton
- set skeleton mode while the image is loading.
skeleton
prop is only available when using the src
prop.With Indicator
Refer to the Indicator component for more details.
Size
size="{size}"
- change the size of the avatar.
๐ You can freely adjust the size of the avatar using any size imaginable. No limits exist, and you can use
breakpoints
such assm:sm, xs:lg
to change size based on screen size orstates
such ashover:lg, focus:3xl
to change size based on input state and more.
padding
and font-size
of the avatar scale depends on the size
. If you want to change the font-size
and padding
simultaneously, you can always customize it using utility classes.Fallbacks
fallback="{fallback}"
- set the fallback image url.
If there is an error loading the avatar image, the component falls back to an alternative in the following order:
- the provided
fallback
slot or prop - the provided
label
slot or prop - the first two letters of each word in the
alt
prop - a generic avatar icon
Lazy loading
Use the
Lazy
prefix provided by nuxt to lazy load the NAvatar component. For example:
<LazyNAvatar src="..." />
Customization
You can customize the
avatar
using theuna
prop and utility classes.
Slots
Slot | Description |
---|---|
default | The image, icon, or labels of the avatar. |
Example 1
default
slot, we usually recommend this if you want to have a component inside the avatar such as NIcon
or just a label. But if you want to have a fallback, you can see the example 2 below.Prop | Description |
---|---|
isLoading | The loading state of the avatar. |
error | The error state of the avatar. |
isReady | The ready state of the avatar. |
src | The source of the avatar. |
alt | The alt text of the avatar. |
Example 2
default
slot to have fallbacks in a custom way.Props
export interface NAvatarProps {
/**
* Allows you to add `UnaUI` avatar preset properties,
* Think of it as a shortcut for adding options or variants to the preset if available.
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/avatar.ts
* @example
* avatar="solid-green"
*/
avatar?: string
/**
* Add icon instead of image.
*
* @example
* icon="i-heroicons-information-circle"
*/
icon?: string
/**
* Add a label to the avatar.
*
* @example
* label="PR"
*/
label?: string
/**
* Set the size of the avatar.
*/
size?: string
/**
* Add src of the image.
*
* @example
* src="https://i.pravatar.cc/300"
*/
src?: string
/**
* Add alt of the image.
*
* @example
* alt="Profile"
*/
alt?: string
/**
* Add fallback of the image.
*
* @example
* fallback="https://i.pravatar.cc/300"
*/
fallback?: string
/**
* Add a delay before showing the avatar.
*
* @default 0
*/
delay?: number
/**
* Add a skeleton effect to the avatar.
*
* @default false
*/
skeleton?: boolean
/**
* `UnaUI` preset configuration
*
* @see https://github.com/una-ui/una-ui/blob/main/packages/preset/src/_shortcuts/avatar.ts
*/
una?: {
// base
avatar?: string
avatarLabel?: string
avatarSrc?: string
avatarFallback?: string
avatarIconBase?: string
// icons
avatarFallbackIcon?: string
}
}
Presets
type AvatarPrefix = 'avatar'
export const staticAvatar: Record<`${AvatarPrefix}-${string}` | AvatarPrefix, string> = {
// config
'avatar-default-variant': 'avatar-solid',
'avatar-fallback-icon': 'i-heroicons-user-20-solid',
// base
'avatar': 'relative font-medium leading-none h-2.5em w-2.5em inline-flex items-center justify-center rounded-full overflow-hidden',
'avatar-label': '',
'avatar-fallback': '',
'avatar-fallback-icon-base': 'text-1.5em',
'avatar-src': 'w-full h-full',
'avatar-icon-base': 'text-1.2em',
// variants
'avatar-solid-white': 'bg-base text-base ring-1 ring-base',
'avatar-solid-black': 'bg-inverted text-inverted',
}
export const dynamicAvatar: [RegExp, (params: RegExpExecArray) => string][] = [
// variants
[/^avatar-solid(-(\S+))?$/, ([, , c = 'gray']) => `bg-${c}-600 dark:bg-${c}-500 text-inverted`],
[/^avatar-soft(-(\S+))?$/, ([, , c = 'gray']) => `bg-${c}-50 text-${c}-700 dark:text-${c}-400 dark:bg-${c}-900`],
[/^avatar-outline(-(\S+))?$/, ([, , c = 'gray']) => `bg-transparent text-${c}-500 dark:text-${c}-400 ring-1 ring-${c}-500 dark:ring-${c}-400`],
]
export const avatar = [
...dynamicAvatar,
staticAvatar,
]
Component
<script setup lang="ts">
import type { NAvatarProps } from '../../types'
import { useImage } from '@vueuse/core'
import { computed } from 'vue'
import NIcon from './Icon.vue'
const props = withDefaults(defineProps<NAvatarProps>(), {
delay: 0,
})
const { isLoading, error, isReady } = useImage({ src: props?.src ?? '' }, { delay: props.delay })
// TODO: sync with NAvatarProps
const avatarVariants = ['solid', 'soft', 'outline'] as const
const hasVariant = computed(() => avatarVariants.some(avatarVariants => props.avatar?.includes(avatarVariants)))
const isBaseVariant = computed(() => props.avatar?.includes('~'))
const placeholder = computed(() => {
if (props.label)
return props.label
return props.alt?.split(' ').map(word => word[0]).join('').slice(0, 2)
})
</script>
<template>
<span
:avatar="avatar"
:size="size"
class="avatar"
:class="[
{ 'avatar-default-variant': !hasVariant && !isBaseVariant },
{ 'animate-pulse': isLoading && skeleton && src },
una?.avatar,
]"
>
<template v-if="!icon">
<slot
v-if="!skeleton"
v-bind="{ isLoading, error, isReady, ...props }"
>
<img
v-if="isReady && !error"
avatar="src"
:src="src"
:alt="alt"
:class="una?.avatarSrc"
>
<img
v-else-if="fallback"
avatar="src"
:src="fallback"
:alt="alt ?? 'avatar'"
:class="una?.avatarFallback"
>
<span
v-else-if="placeholder"
avatar="label"
:class="una?.avatarLabel"
>
{{ placeholder }}
</span>
<NIcon
v-else
avatar="fallback-icon-base"
:name="una?.avatarFallbackIcon ?? 'avatar-fallback-icon'"
:class="una?.avatarFallbackIcon"
/>
</slot>
</template>
<template v-else>
<NIcon
avatar="icon-base"
:class="una?.avatarIconBase"
:name="icon"
/>
</template>
</span>
</template>