11<script setup lang='ts'>
22import type { PropType } from ' vue'
3- import { computed , defineComponent } from ' vue'
3+ import { omit } from ' lodash-es'
4+ import { computed , defineComponent , ref , useAttrs , watch } from ' vue'
45import classNames from ' classnames'
56import { Icon } from ' @iconify/vue'
67import type { VariantJSWithClassesListProps } from ' ../../../utils/getVariantProps'
@@ -21,7 +22,11 @@ const props = defineProps({
2122 },
2223 src: {
2324 type: String ,
24- default: ' ' ,
25+ default: null ,
26+ },
27+ text: {
28+ type: String ,
29+ default: null ,
2530 },
2631 size: {
2732 type: String as PropType <AvatarSize >,
@@ -40,7 +45,7 @@ const props = defineProps({
4045
4146 chipColor: {
4247 type: String ,
43- default: ' ' ,
48+ default: null ,
4449 },
4550
4651 chipSize: {
@@ -55,11 +60,29 @@ const props = defineProps({
5560
5661 chipText: {
5762 type: String ,
58- default: ' ' ,
63+ default: null ,
5964 },
6065
6166})
6267
68+ const url = computed (() => {
69+ if (typeof props .src === ' boolean' )
70+ return null
71+
72+ return props .src
73+ })
74+
75+ const error = ref (false )
76+
77+ watch (() => props .src , () => {
78+ if (error .value )
79+ error .value = false
80+ })
81+
82+ function onError() {
83+ error .value = true
84+ }
85+
6386const placeholder = computed (() => {
6487 return (props .alt || ' ' ).split (' ' ).map (word => word .charAt (0 )).join (' ' ).substring (0 , 2 )
6588})
@@ -78,6 +101,7 @@ const variant = computed(() => {
78101const avatarWrapperClasses = computed <string >(() => {
79102 return classNames (
80103 variant .value .root ,
104+ (error .value || ! url .value ) && variant .value .avatarBackground ,
81105 variant .value .avatarSize && variant .value [props .size ],
82106 )
83107})
@@ -121,6 +145,8 @@ const avatarIconSize = computed(() => {
121145const avatarChipColorStyles = computed (() => ({
122146 ' background-color' : props .chipColor || ' ' ,
123147}))
148+ const attrs = useAttrs ()
149+ const attrsOmitted = omit (attrs , [' class' ])
124150 </script >
125151
126152<script lang="ts">
@@ -132,9 +158,10 @@ export default defineComponent({
132158
133159<template >
134160 <span :class =" [avatarWrapperClasses, avatarClasses]" :title =" props.name" >
135- <img v-if =" props.src" :class =" avatarClasses" :src =" props.src" :alt =" props.name" >
136- <span v-else-if =" !props.src" :class =" variant.avatarPlaceholderClass" >{{ placeholder }}</span >
137- <Icon v-if =" !props.src && !placeholder" :icon =" props.icon" :class =" [avatarIconSize, variant.avatarIconColor]" />
161+ <img v-if =" url && !error" v-bind =" attrsOmitted" :class =" avatarClasses" :src =" url" :alt =" props.name" @error =" onError" >
162+ <span v-else-if =" text" :class =" variant.avatarText" >{{ props.text }}</span >
163+ <span v-else-if =" placeholder" :class =" variant.avatarPlaceholderClass" >{{ placeholder }}</span >
164+ <Icon v-else-if =" props.icon" :icon =" props.icon" :class =" [avatarIconSize, variant.avatarIconColor]" />
138165 <span v-if =" props.chipColor" :style =" avatarChipColorStyles" :class =" [avatarChipClass, avatarChipSize]" >
139166 {{ chipText }}
140167 </span >
0 commit comments