@@ -16,6 +16,7 @@ const CLASS_NAME = 'b-avatar'
16
16
const RX_NUMBER = /^[0-9]*\.?[0-9]+$/
17
17
18
18
const FONT_SIZE_SCALE = 0.4
19
+
const BADGE_FONT_SIZE_SCALE = FONT_SIZE_SCALE * 0.7
19
20
20
21
const DEFAULT_SIZES = {
21
22
sm: '1.5em',
@@ -112,6 +113,26 @@ const props = {
112
113
type: String,
113
114
default: 'button'
114
115
},
116
+
badge: {
117
+
type: [Boolean, String],
118
+
default: false
119
+
},
120
+
badgeVariant: {
121
+
type: String,
122
+
default: () => getComponentConfig(NAME, 'badgeVariant')
123
+
},
124
+
badgeTop: {
125
+
type: Boolean,
126
+
default: false
127
+
},
128
+
badgeLeft: {
129
+
type: Boolean,
130
+
default: false
131
+
},
132
+
badgeOffset: {
133
+
type: String,
134
+
default: '0px'
135
+
},
115
136
...linkProps,
116
137
ariaLabel: {
117
138
type: String
@@ -149,6 +170,17 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({
149
170
fontSize() {
150
171
const size = this.computedSize
151
172
return size ? `calc(${size} * ${FONT_SIZE_SCALE})` : null
173
+
},
174
+
badgeStyle() {
175
+
const { computedSize: size, badgeTop, badgeLeft, badgeOffset } = this
176
+
const offset = badgeOffset || '0px'
177
+
return {
178
+
fontSize: size ? `calc(${size} * ${BADGE_FONT_SIZE_SCALE} )` : null,
179
+
top: badgeTop ? offset : null,
180
+
bottom: badgeTop ? null : offset,
181
+
left: badgeLeft ? offset : null,
182
+
right: badgeLeft ? null : offset
183
+
}
152
184
}
153
185
},
154
186
watch: {
@@ -178,7 +210,10 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({
178
210
fontSize,
179
211
computedSize: size,
180
212
button: isButton,
181
-
buttonType: type
213
+
buttonType: type,
214
+
badge,
215
+
badgeVariant,
216
+
badgeStyle
182
217
} = this
183
218
const isBLink = !isButton && (this.href || this.to)
184
219
const tag = isButton ? BButton : isBLink ? BLink : 'span'
@@ -189,7 +224,7 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({
189
224
let $content = null
190
225
if (this.hasNormalizedSlot('default')) {
191
226
// Default slot overrides props
192
-
$content = this.normalizeSlot('default')
227
+
$content = h('span', { staticClass: 'b-avatar-custom' }, [this.normalizeSlot('default')])
193
228
} else if (src) {
194
229
$content = h('img', { attrs: { src, alt }, on: { error: this.onImgError } })
195
230
} else if (icon) {
@@ -198,12 +233,27 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({
198
233
attrs: { 'aria-hidden': 'true', alt }
199
234
})
200
235
} else if (text) {
201
-
$content = h('span', { style: { fontSize } }, text)
236
+
$content = h('span', { staticClass: 'b-avatar-text', style: { fontSize } }, [h('span', text)])
202
237
} else {
203
238
// Fallback default avatar content
204
239
$content = h(BIconPersonFill, { attrs: { 'aria-hidden': 'true', alt } })
205
240
}
206
241
242
+
let $badge = h()
243
+
const hasBadgeSlot = this.hasNormalizedSlot('badge')
244
+
if (badge || badge === '' || hasBadgeSlot) {
245
+
const badgeText = badge === true ? '' : badge
246
+
$badge = h(
247
+
'span',
248
+
{
249
+
staticClass: 'b-avatar-badge',
250
+
class: { [`badge-${badgeVariant}`]: !!badgeVariant },
251
+
style: badgeStyle
252
+
},
253
+
[hasBadgeSlot ? this.normalizeSlot('badge') : badgeText]
254
+
)
255
+
}
256
+
207
257
const componentData = {
208
258
staticClass: CLASS_NAME,
209
259
class: {
@@ -217,11 +267,11 @@ export const BAvatar = /*#__PURE__*/ Vue.extend({
217
267
disabled
218
268
},
219
269
style: { width: size, height: size },
220
-
attrs: { 'aria-label': ariaLabel },
270
+
attrs: { 'aria-label': ariaLabel || null },
221
271
props: isButton ? { variant, disabled, type } : isBLink ? pluckProps(linkProps, this) : {},
222
272
on: isBLink || isButton ? { click: this.onClick } : {}
223
273
}
224
274
225
-
return h(tag, componentData, [$content])
275
+
return h(tag, componentData, [$content, $badge])
226
276
}
227
277
})
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4