11<template >
22 <component
3- :is =" tag "
3+ :is =" computedTag "
44 class =" b-avatar"
5- :class =" classes "
6- :style =" tagStyle "
7- v-bind =" attrs "
5+ :class =" computedClasses "
6+ :style =" computedStyle "
7+ v-bind =" computedAttrs "
88 @click =" clicked"
99 >
1010 <span v-if =" hasDefaultSlot" class =" b-avatar-custom" >
1111 <slot />
1212 </span >
13- <span v-else-if =" src" class =" b-avatar-img" >
13+ <span v-else-if =" !! src" class =" b-avatar-img" >
1414 <img :src =" src" :alt =" alt" @error =" onImgError" />
1515 </span >
16- <span v-else-if =" text" class =" b-avatar-text" :class =" textClasses" :style =" fontStyle " >
16+ <span v-else-if =" !! text" class =" b-avatar-text" :class =" textClasses" :style =" textFontStyle " >
1717 {{ text }}
1818 </span >
19-
2019 <span v-if =" showBadge" class =" b-avatar-badge" :class =" badgeClasses" :style =" badgeStyle" >
2120 <slot v-if =" hasBadgeSlot" name =" badge" />
2221 <span v-else :class =" badgeTextClasses" >{{ badgeText }}</span >
@@ -31,7 +30,7 @@ import type {BAvatarGroupParentData} from '../../types/components'
3130import {computed , inject , StyleValue , toRef , useSlots } from ' vue'
3231import type {Booleanish , ButtonType , ColorVariant , TextColorVariant } from ' ../../types'
3332import {injectionKey } from ' ./BAvatarGroup.vue'
34- import {useBooleanish } from ' ../../composables'
33+ import {eagerComputed , useBooleanish } from ' ../../composables'
3534
3635interface BAvatarProps {
3736 alt? : string
@@ -62,19 +61,12 @@ const props = withDefaults(defineProps<BAvatarProps>(), {
6261 badgeVariant: ' primary' ,
6362 button: false ,
6463 buttonType: ' button' ,
65- textVariant: undefined ,
6664 disabled: false ,
6765 rounded: ' circle' ,
6866 square: false ,
6967 variant: ' secondary' ,
7068})
7169
72- const badgeLeftBoolean = useBooleanish (toRef (props , ' badgeLeft' ))
73- const badgeTopBoolean = useBooleanish (toRef (props , ' badgeTop' ))
74- const buttonBoolean = useBooleanish (toRef (props , ' button' ))
75- const disabledBoolean = useBooleanish (toRef (props , ' disabled' ))
76- const squareBoolean = useBooleanish (toRef (props , ' square' ))
77-
7870interface BAvatarEmits {
7971 (e : ' click' , value : MouseEvent ): void
8072 (e : ' img-error' , value : Event ): void
@@ -84,55 +76,49 @@ const emit = defineEmits<BAvatarEmits>()
8476
8577const slots = useSlots ()
8678
79+ const parentData = inject <BAvatarGroupParentData | null >(injectionKey , null )
80+
8781const SIZES = [' sm' , null , ' lg' ]
8882const FONT_SIZE_SCALE = 0.4
8983const BADGE_FONT_SIZE_SCALE = FONT_SIZE_SCALE * 0.7
9084
91- const parentData = inject <BAvatarGroupParentData | null >(injectionKey , null )
92-
93- const computeContrastVariant = (colorVariant : ColorVariant ): ColorVariant => {
94- const variant = colorVariant
95-
96- if (variant === ' light' ) return ' dark'
97- if (variant === ' warning' ) return ' dark'
98- return ' light'
99- }
85+ const badgeLeftBoolean = useBooleanish (toRef (props , ' badgeLeft' ))
86+ const badgeTopBoolean = useBooleanish (toRef (props , ' badgeTop' ))
87+ const buttonBoolean = useBooleanish (toRef (props , ' button' ))
88+ const disabledBoolean = useBooleanish (toRef (props , ' disabled' ))
89+ const squareBoolean = useBooleanish (toRef (props , ' square' ))
10090
10191const hasDefaultSlot = computed <boolean >(() => ! isEmptySlot (slots .default ))
92+
10293const hasBadgeSlot = computed <boolean >(() => ! isEmptySlot (slots .badge ))
103- const showBadge = computed <string | boolean >(
104- () => props .badge || props .badge === ' ' || hasBadgeSlot .value
105- )
10694
107- const computedSize = computed <string | null >(() =>
95+ const showBadge = computed <boolean >(() => !! props .badge || props .badge === ' ' || hasBadgeSlot .value )
96+
97+ const computedSize = eagerComputed <string | null >(() =>
10898 parentData ?.size ? parentData .size : computeSize (props .size )
10999)
110100
111- const computedVariant = computed <ColorVariant >(() =>
101+ const computedVariant = eagerComputed <ColorVariant >(() =>
112102 parentData ?.variant ? parentData .variant : props .variant
113103)
114104
115- const computedRounded = computed <string | boolean >(() =>
105+ const computedRounded = eagerComputed <string | boolean >(() =>
116106 parentData ?.rounded ? parentData .rounded : props .rounded
117107)
118108
119- const attrs = computed (() => ({
109+ const computedAttrs = computed (() => ({
120110 ' type' : buttonBoolean .value ? props .buttonType : undefined ,
121111 ' aria-label' : props .ariaLabel || null ,
122112 ' disabled' : disabledBoolean .value || null ,
123113}))
124114
125- const badgeClasses = computed (() => ({
126- [` bg-${props .badgeVariant } ` ]: !! props .badgeVariant ,
127- }))
115+ const badgeClasses = computed (() => [` bg-${props .badgeVariant } ` ])
128116
129117const badgeText = computed <string | false >(() => (props .badge === true ? ' ' : props .badge ))
130- const badgeTextClasses = computed <string >(() => {
131- const textVariant = computeContrastVariant (props .badgeVariant )
132- return ` text-${textVariant } `
133- })
134118
135- const classes = computed (() => ({
119+ const badgeTextClasses = computed (() => [[` text-${computeContrastVariant (props .badgeVariant )} ` ]])
120+
121+ const computedClasses = computed (() => ({
136122 [` b-avatar-${props .size } ` ]: !! props .size && SIZES .indexOf (computeSize (props .size )) !== - 1 ,
137123 [` bg-${computedVariant .value } ` ]: !! computedVariant .value ,
138124 [` badge ` ]: ! buttonBoolean .value && computedVariant .value && hasDefaultSlot .value ,
@@ -149,10 +135,9 @@ const classes = computed(() => ({
149135 [` btn-${computedVariant .value } ` ]: buttonBoolean .value ? !! computedVariant .value : false ,
150136}))
151137
152- const textClasses = computed <string >(() => {
153- const textVariant = props .textVariant || computeContrastVariant (computedVariant .value )
154- return ` text-${textVariant } `
155- })
138+ const textClasses = computed (() => [
139+ [` text-${props .textVariant || computeContrastVariant (computedVariant .value )} ` ],
140+ ])
156141
157142const badgeStyle = computed <StyleValue >(() => {
158143 const offset = props .badgeOffset || ' 0px'
@@ -169,7 +154,7 @@ const badgeStyle = computed<StyleValue>(() => {
169154 }
170155})
171156
172- const fontStyle = computed <StyleValue >(() => {
157+ const textFontStyle = computed <StyleValue >(() => {
173158 const fontSize =
174159 SIZES .indexOf (computedSize .value || null ) === - 1
175160 ? ` calc(${computedSize .value } * ${FONT_SIZE_SCALE }) `
@@ -185,16 +170,21 @@ const marginStyle = computed(() => {
185170 return value ? {marginLeft: value , marginRight: value } : {}
186171})
187172
188- const tag = computed <' button' | ' span' >(() => (buttonBoolean .value ? ' button' : ' span' ))
189- const tagStyle = computed (() => ({
173+ const computedTag = computed <' button' | ' span' >(() => (buttonBoolean .value ? ' button' : ' span' ))
174+
175+ const computedStyle = computed (() => ({
190176 ... marginStyle .value ,
191177 width: computedSize .value ,
192178 height: computedSize .value ,
193179}))
194180
181+ const computeContrastVariant = (colorVariant : ColorVariant ): ' dark' | ' light' =>
182+ colorVariant === ' light' || colorVariant === ' warning' ? ' dark' : ' light'
183+
195184const clicked = (e : MouseEvent ): void => {
196185 if (! disabledBoolean .value && buttonBoolean .value ) emit (' click' , e )
197186}
187+
198188const onImgError = (e : Event ): void => emit (' img-error' , e )
199189 </script >
200190
0 commit comments