@dialpad/dialtone 9.70.0-beta.2 → 9.70.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/tokens/doc.json +14954 -14954
- package/dist/vue3/component-documentation.json +1 -1
- package/dist/vue3/dialtone-vue.cjs +1 -1
- package/dist/vue3/dialtone-vue.js +1 -1
- package/dist/vue3/lib/avatar.cjs +45 -31
- package/dist/vue3/lib/avatar.cjs.map +1 -1
- package/dist/vue3/lib/avatar.js +47 -33
- package/dist/vue3/lib/avatar.js.map +1 -1
- package/dist/vue3/lib/callbox.cjs +6 -14
- package/dist/vue3/lib/callbox.cjs.map +1 -1
- package/dist/vue3/lib/callbox.js +7 -15
- package/dist/vue3/lib/callbox.js.map +1 -1
- package/dist/vue3/lib/contact-info.cjs +10 -28
- package/dist/vue3/lib/contact-info.cjs.map +1 -1
- package/dist/vue3/lib/contact-info.js +11 -29
- package/dist/vue3/lib/contact-info.js.map +1 -1
- package/dist/vue3/lib/contact-row.cjs +9 -14
- package/dist/vue3/lib/contact-row.cjs.map +1 -1
- package/dist/vue3/lib/contact-row.js +10 -15
- package/dist/vue3/lib/contact-row.js.map +1 -1
- package/dist/vue3/lib/feed-item-row.cjs +10 -16
- package/dist/vue3/lib/feed-item-row.cjs.map +1 -1
- package/dist/vue3/lib/feed-item-row.js +11 -17
- package/dist/vue3/lib/feed-item-row.js.map +1 -1
- package/dist/vue3/style.css +49 -49
- package/dist/vue3/types/common/storybook_utils.d.ts +25 -0
- package/dist/vue3/types/common/storybook_utils.d.ts.map +1 -0
- package/dist/vue3/types/components/avatar/avatar.vue.d.ts +34 -6
- package/dist/vue3/types/components/avatar/avatar.vue.d.ts.map +1 -1
- package/dist/vue3/types/components/chip/chip.vue.d.ts +1 -1
- package/dist/vue3/types/components/collapsible/collapsible.vue.d.ts +1 -1
- package/dist/vue3/types/components/split_button/split_button-omega.vue.d.ts +1 -1
- package/dist/vue3/types/recipes/buttons/callbar_button/callbar_button.vue.d.ts +1 -1
- package/dist/vue3/types/recipes/buttons/callbar_button_with_popover/callbar_button_with_popover.vue.d.ts +1 -1
- package/dist/vue3/types/recipes/conversation_view/feed_item_row/feed_item_row.vue.d.ts +1 -0
- package/dist/vue3/types/recipes/conversation_view/feed_item_row/feed_item_row.vue.d.ts.map +1 -1
- package/dist/vue3/types/recipes/item_layout/contact_info/contact_info.vue.d.ts +3 -3
- package/dist/vue3/types/recipes/leftbar/callbox/callbox.vue.d.ts.map +1 -1
- package/dist/vue3/types/recipes/leftbar/contact_row/contact_row.vue.d.ts +1 -0
- package/dist/vue3/types/recipes/leftbar/contact_row/contact_row.vue.d.ts.map +1 -1
- package/dist/vue3/types/recipes/leftbar/general_row/general_row.vue.d.ts +1 -1
- package/package.json +1 -1
|
@@ -96,11 +96,11 @@ const lib_topBannerInfo = require("./lib/top-banner-info.cjs");
|
|
|
96
96
|
require("vue");
|
|
97
97
|
require("date-fns");
|
|
98
98
|
require("@dialpad/dialtone-emojis");
|
|
99
|
+
require("@dialpad/dialtone-icons/icons.js");
|
|
99
100
|
require("./chunks/_plugin-vue_export-helper-fhnQq0tA.js");
|
|
100
101
|
require("./chunks/modal-VgxXAQFP.js");
|
|
101
102
|
require("./chunks/sr_only_close_button-xGrHFjwA.js");
|
|
102
103
|
require("@dialpad/dialtone-icons/vue3");
|
|
103
|
-
require("@dialpad/dialtone-icons/icons.js");
|
|
104
104
|
require("@dialpad/dialtone-icons/illustrations.js");
|
|
105
105
|
require("tippy.js");
|
|
106
106
|
require("@tiptap/vue-3");
|
|
@@ -94,11 +94,11 @@ import { COLOR_CODES, DtRecipeTopBannerInfo } from "./lib/top-banner-info.js";
|
|
|
94
94
|
import "vue";
|
|
95
95
|
import "date-fns";
|
|
96
96
|
import "@dialpad/dialtone-emojis";
|
|
97
|
+
import "@dialpad/dialtone-icons/icons.js";
|
|
97
98
|
import "./chunks/_plugin-vue_export-helper-caHeSgYY.js";
|
|
98
99
|
import "./chunks/modal-XOr4kiNZ.js";
|
|
99
100
|
import "./chunks/sr_only_close_button-3EdsV-dH.js";
|
|
100
101
|
import "@dialpad/dialtone-icons/vue3";
|
|
101
|
-
import "@dialpad/dialtone-icons/icons.js";
|
|
102
102
|
import "@dialpad/dialtone-icons/illustrations.js";
|
|
103
103
|
import "tippy.js";
|
|
104
104
|
import "@tiptap/vue-3";
|
package/dist/vue3/lib/avatar.cjs
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
3
|
const common_utils = require("../common/utils.cjs");
|
|
4
|
+
const iconNames = require("@dialpad/dialtone-icons/icons.js");
|
|
4
5
|
const icon_constants = require("../chunks/icon_constants-da57m7BZ.js");
|
|
5
6
|
const vue = require("vue");
|
|
6
7
|
const _pluginVue_exportHelper = require("../chunks/_plugin-vue_export-helper-fhnQq0tA.js");
|
|
7
8
|
const lib_presence = require("./presence.cjs");
|
|
9
|
+
const lib_icon = require("./icon.cjs");
|
|
8
10
|
require("../common/constants.cjs");
|
|
9
|
-
require("@dialpad/dialtone-icons/
|
|
11
|
+
require("@dialpad/dialtone-icons/vue3");
|
|
10
12
|
const AVATAR_SIZE_MODIFIERS = {
|
|
11
13
|
xs: "d-avatar--xs",
|
|
12
14
|
sm: "d-avatar--sm",
|
|
@@ -60,15 +62,19 @@ const AVATAR_COLORS = [
|
|
|
60
62
|
];
|
|
61
63
|
const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);
|
|
62
64
|
const AVATAR_GROUP_VALIDATOR = (group) => group > 1;
|
|
65
|
+
function getIconNames() {
|
|
66
|
+
return [void 0, ...iconNames];
|
|
67
|
+
}
|
|
63
68
|
const extractInitialsFromName = (fullName) => {
|
|
64
69
|
if (typeof fullName !== "string" || !fullName.trim())
|
|
65
70
|
return "";
|
|
66
71
|
const names = fullName.trim().split(/\s+/g);
|
|
67
72
|
return names.length === 1 ? names.join("").substring(0, 2) : names.filter((_, index) => index === 0 || index === names.length - 1).map((name) => name.slice(0, 1).toUpperCase()).join("");
|
|
68
73
|
};
|
|
74
|
+
const ICONS_LIST = getIconNames();
|
|
69
75
|
const _sfc_main = {
|
|
70
76
|
name: "DtAvatar",
|
|
71
|
-
components: { DtPresence: lib_presence.DtPresence },
|
|
77
|
+
components: { DtPresence: lib_presence.DtPresence, DtIcon: lib_icon.DtIcon },
|
|
72
78
|
inheritAttrs: false,
|
|
73
79
|
props: {
|
|
74
80
|
/**
|
|
@@ -156,6 +162,13 @@ const _sfc_main = {
|
|
|
156
162
|
default: void 0,
|
|
157
163
|
validator: (group) => AVATAR_GROUP_VALIDATOR(group)
|
|
158
164
|
},
|
|
165
|
+
/**
|
|
166
|
+
* The icon that overlays the avatar
|
|
167
|
+
*/
|
|
168
|
+
overlayIcon: {
|
|
169
|
+
type: String,
|
|
170
|
+
default: ""
|
|
171
|
+
},
|
|
159
172
|
/**
|
|
160
173
|
* The text that overlays the avatar
|
|
161
174
|
*/
|
|
@@ -186,6 +199,14 @@ const _sfc_main = {
|
|
|
186
199
|
type: String,
|
|
187
200
|
default: void 0
|
|
188
201
|
},
|
|
202
|
+
/**
|
|
203
|
+
* Icon name to be displayed on the avatar
|
|
204
|
+
*/
|
|
205
|
+
iconName: {
|
|
206
|
+
type: String,
|
|
207
|
+
default: void 0,
|
|
208
|
+
validator: (name) => ICONS_LIST.includes(name)
|
|
209
|
+
},
|
|
189
210
|
/**
|
|
190
211
|
* Icon size to be displayed on the avatar
|
|
191
212
|
* @values 100, 200, 300, 400, 500, 600, 700, 800
|
|
@@ -236,19 +257,12 @@ const _sfc_main = {
|
|
|
236
257
|
AVATAR_ICON_SIZES,
|
|
237
258
|
imageLoadedSuccessfully: null,
|
|
238
259
|
formattedInitials: "",
|
|
239
|
-
initializing: false
|
|
240
|
-
hasSlotContent: common_utils.hasSlotContent
|
|
260
|
+
initializing: false
|
|
241
261
|
};
|
|
242
262
|
},
|
|
243
263
|
computed: {
|
|
244
|
-
|
|
245
|
-
return
|
|
246
|
-
},
|
|
247
|
-
hasOverlayIcon() {
|
|
248
|
-
return common_utils.hasSlotContent(this.$slots.overlayIcon);
|
|
249
|
-
},
|
|
250
|
-
iconDataQa() {
|
|
251
|
-
return "dt-avatar-icon";
|
|
264
|
+
isNotIconType() {
|
|
265
|
+
return !this.iconName;
|
|
252
266
|
},
|
|
253
267
|
avatarClasses() {
|
|
254
268
|
return [
|
|
@@ -257,7 +271,7 @@ const _sfc_main = {
|
|
|
257
271
|
this.avatarClass,
|
|
258
272
|
{
|
|
259
273
|
"d-avatar--group": this.showGroup,
|
|
260
|
-
[`d-avatar--color-${this.getColor()}`]:
|
|
274
|
+
[`d-avatar--color-${this.getColor()}`]: this.isNotIconType,
|
|
261
275
|
"d-avatar--clickable": this.clickable
|
|
262
276
|
}
|
|
263
277
|
];
|
|
@@ -265,8 +279,7 @@ const _sfc_main = {
|
|
|
265
279
|
overlayClasses() {
|
|
266
280
|
return [
|
|
267
281
|
"d-avatar__overlay",
|
|
268
|
-
this.overlayClass
|
|
269
|
-
{ "d-avatar__overlay-icon": this.hasOverlayIcon }
|
|
282
|
+
this.overlayClass
|
|
270
283
|
];
|
|
271
284
|
},
|
|
272
285
|
showGroup() {
|
|
@@ -356,17 +369,17 @@ const _sfc_main = {
|
|
|
356
369
|
}
|
|
357
370
|
};
|
|
358
371
|
const _hoisted_1 = ["src", "alt"];
|
|
359
|
-
const _hoisted_2 =
|
|
360
|
-
const _hoisted_3 = {
|
|
372
|
+
const _hoisted_2 = {
|
|
361
373
|
key: 1,
|
|
362
374
|
class: "d-avatar__overlay-text"
|
|
363
375
|
};
|
|
364
|
-
const
|
|
376
|
+
const _hoisted_3 = {
|
|
365
377
|
key: 1,
|
|
366
378
|
class: "d-avatar__count",
|
|
367
379
|
"data-qa": "dt-avatar-count"
|
|
368
380
|
};
|
|
369
381
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
382
|
+
const _component_dt_icon = vue.resolveComponent("dt-icon");
|
|
370
383
|
const _component_dt_presence = vue.resolveComponent("dt-presence");
|
|
371
384
|
return vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent($props.clickable ? "button" : "div"), {
|
|
372
385
|
id: $props.id,
|
|
@@ -390,28 +403,29 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
390
403
|
"data-qa": "dt-avatar-image",
|
|
391
404
|
src: $props.imageSrc,
|
|
392
405
|
alt: $props.imageAlt
|
|
393
|
-
}, null, 8, _hoisted_1)) : $
|
|
406
|
+
}, null, 8, _hoisted_1)) : $props.iconName ? (vue.openBlock(), vue.createBlock(_component_dt_icon, {
|
|
394
407
|
key: 1,
|
|
408
|
+
name: $props.iconName,
|
|
409
|
+
"aria-label": $props.iconAriaLabel,
|
|
410
|
+
size: $props.iconSize || $data.AVATAR_ICON_SIZES[$props.size],
|
|
395
411
|
class: vue.normalizeClass([$props.iconClass, $data.AVATAR_KIND_MODIFIERS.icon]),
|
|
396
|
-
"
|
|
397
|
-
|
|
398
|
-
role: $props.clickable ? "button" : ""
|
|
399
|
-
}, [
|
|
400
|
-
vue.renderSlot(_ctx.$slots, "icon", {
|
|
401
|
-
iconSize: $props.iconSize || $data.AVATAR_ICON_SIZES[$props.size]
|
|
402
|
-
})
|
|
403
|
-
], 10, _hoisted_2)) : (vue.openBlock(), vue.createElementBlock("span", {
|
|
412
|
+
"data-qa": "dt-avatar-icon"
|
|
413
|
+
}, null, 8, ["name", "aria-label", "size", "class"])) : (vue.openBlock(), vue.createElementBlock("span", {
|
|
404
414
|
key: 2,
|
|
405
415
|
class: vue.normalizeClass([$data.AVATAR_KIND_MODIFIERS.initials])
|
|
406
416
|
}, vue.toDisplayString($data.formattedInitials), 3))
|
|
407
417
|
], 2),
|
|
408
|
-
$
|
|
418
|
+
$props.overlayIcon || $props.overlayText ? (vue.openBlock(), vue.createElementBlock("div", {
|
|
409
419
|
key: 0,
|
|
410
420
|
class: vue.normalizeClass($options.overlayClasses)
|
|
411
421
|
}, [
|
|
412
|
-
$
|
|
422
|
+
$props.overlayIcon ? (vue.openBlock(), vue.createBlock(_component_dt_icon, {
|
|
423
|
+
key: 0,
|
|
424
|
+
class: "d-avatar__overlay-icon",
|
|
425
|
+
name: $props.overlayIcon
|
|
426
|
+
}, null, 8, ["name"])) : $props.overlayText ? (vue.openBlock(), vue.createElementBlock("p", _hoisted_2, vue.toDisplayString($props.overlayText), 1)) : vue.createCommentVNode("", true)
|
|
413
427
|
], 2)) : vue.createCommentVNode("", true),
|
|
414
|
-
$options.showGroup ? (vue.openBlock(), vue.createElementBlock("span",
|
|
428
|
+
$options.showGroup ? (vue.openBlock(), vue.createElementBlock("span", _hoisted_3, vue.toDisplayString($options.formattedGroup), 1)) : vue.createCommentVNode("", true),
|
|
415
429
|
$props.presence && !$options.showGroup ? (vue.openBlock(), vue.createBlock(_component_dt_presence, vue.mergeProps({
|
|
416
430
|
key: 2,
|
|
417
431
|
presence: $props.presence,
|
|
@@ -421,7 +435,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
421
435
|
]
|
|
422
436
|
}, $props.presenceProps, { "data-qa": "dt-presence" }), null, 16, ["presence", "class"])) : vue.createCommentVNode("", true)
|
|
423
437
|
]),
|
|
424
|
-
_:
|
|
438
|
+
_: 1
|
|
425
439
|
}, 8, ["id", "class", "onClick"]);
|
|
426
440
|
}
|
|
427
441
|
const DtAvatar = /* @__PURE__ */ _pluginVue_exportHelper._export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.cjs","sources":["../../components/avatar/avatar_constants.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <div\n v-else-if=\"isIconType\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n :aria-label=\"clickable ? iconAriaLabel : ''\"\n :data-qa=\"iconDataQa\"\n :role=\"clickable ? 'button' : ''\"\n >\n <!-- @slot Slot for avatar icon. It will display if no imageSrc is provided -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n />\n </div>\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"hasOverlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <!-- @slot Slot for overlay icon. -->\n <slot\n v-if=\"hasOverlayIcon\"\n name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement, hasSlotContent } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n hasSlotContent,\n };\n },\n\n computed: {\n isIconType () {\n return hasSlotContent(this.$slots.icon);\n },\n\n hasOverlayIcon () {\n return hasSlotContent(this.$slots.overlayIcon);\n },\n\n iconDataQa () {\n return 'dt-avatar-icon';\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: !this.isIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n { 'd-avatar__overlay-icon': this.hasOverlayIcon },\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["DtPresence","getUniqueString","ICON_SIZE_MODIFIERS","hasSlotContent","getRandomElement","_openBlock","_createBlock","_resolveDynamicComponent","_createElementVNode","_normalizeClass","_createElementBlock","_renderSlot","_toDisplayString","_mergeProps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"avatar.cjs","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.js';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.js';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component so it is able to be live edited with storybook controls addon.\n * @param {object} args storybook control args\n * @param {component} templateComponent vue component template for rendering to storybook.\n * Note this should not be the component itself,\n * but rather the usage of that component.\n * @returns {component} the template component with props and args added.\n */\nexport const createTemplateFromVueFile = (args, argTypes, templateComponent) => ({\n components: { templateComponent },\n setup () {\n return { args };\n },\n template: '<template-component v-bind=\"args\"></template-component>',\n});\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n createTemplateFromVueFile,\n getIllustrationNames,\n getIconNames,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["DtPresence","DtIcon","getUniqueString","ICON_SIZE_MODIFIERS","getRandomElement","_openBlock","_createBlock","_resolveDynamicComponent","_createElementVNode","_normalizeClass","_createElementBlock","_toDisplayString","_mergeProps"],"mappings":"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"}
|
package/dist/vue3/lib/avatar.js
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
|
-
import { getUniqueString,
|
|
1
|
+
import { getUniqueString, getRandomElement } from "../common/utils.js";
|
|
2
|
+
import iconNames from "@dialpad/dialtone-icons/icons.js";
|
|
2
3
|
import { ICON_SIZE_MODIFIERS } from "../chunks/icon_constants-H9ahUVCG.js";
|
|
3
|
-
import { resolveComponent, openBlock, createBlock, resolveDynamicComponent, normalizeClass, withCtx, createElementVNode, createElementBlock,
|
|
4
|
+
import { resolveComponent, openBlock, createBlock, resolveDynamicComponent, normalizeClass, withCtx, createElementVNode, createElementBlock, toDisplayString, createCommentVNode, mergeProps } from "vue";
|
|
4
5
|
import { _export_sfc } from "../chunks/_plugin-vue_export-helper-caHeSgYY.js";
|
|
5
6
|
import { DtPresence } from "./presence.js";
|
|
7
|
+
import { DtIcon } from "./icon.js";
|
|
6
8
|
import "../common/constants.js";
|
|
7
|
-
import "@dialpad/dialtone-icons/
|
|
9
|
+
import "@dialpad/dialtone-icons/vue3";
|
|
8
10
|
const AVATAR_SIZE_MODIFIERS = {
|
|
9
11
|
xs: "d-avatar--xs",
|
|
10
12
|
sm: "d-avatar--sm",
|
|
@@ -58,15 +60,19 @@ const AVATAR_COLORS = [
|
|
|
58
60
|
];
|
|
59
61
|
const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);
|
|
60
62
|
const AVATAR_GROUP_VALIDATOR = (group) => group > 1;
|
|
63
|
+
function getIconNames() {
|
|
64
|
+
return [void 0, ...iconNames];
|
|
65
|
+
}
|
|
61
66
|
const extractInitialsFromName = (fullName) => {
|
|
62
67
|
if (typeof fullName !== "string" || !fullName.trim())
|
|
63
68
|
return "";
|
|
64
69
|
const names = fullName.trim().split(/\s+/g);
|
|
65
70
|
return names.length === 1 ? names.join("").substring(0, 2) : names.filter((_, index) => index === 0 || index === names.length - 1).map((name) => name.slice(0, 1).toUpperCase()).join("");
|
|
66
71
|
};
|
|
72
|
+
const ICONS_LIST = getIconNames();
|
|
67
73
|
const _sfc_main = {
|
|
68
74
|
name: "DtAvatar",
|
|
69
|
-
components: { DtPresence },
|
|
75
|
+
components: { DtPresence, DtIcon },
|
|
70
76
|
inheritAttrs: false,
|
|
71
77
|
props: {
|
|
72
78
|
/**
|
|
@@ -154,6 +160,13 @@ const _sfc_main = {
|
|
|
154
160
|
default: void 0,
|
|
155
161
|
validator: (group) => AVATAR_GROUP_VALIDATOR(group)
|
|
156
162
|
},
|
|
163
|
+
/**
|
|
164
|
+
* The icon that overlays the avatar
|
|
165
|
+
*/
|
|
166
|
+
overlayIcon: {
|
|
167
|
+
type: String,
|
|
168
|
+
default: ""
|
|
169
|
+
},
|
|
157
170
|
/**
|
|
158
171
|
* The text that overlays the avatar
|
|
159
172
|
*/
|
|
@@ -184,6 +197,14 @@ const _sfc_main = {
|
|
|
184
197
|
type: String,
|
|
185
198
|
default: void 0
|
|
186
199
|
},
|
|
200
|
+
/**
|
|
201
|
+
* Icon name to be displayed on the avatar
|
|
202
|
+
*/
|
|
203
|
+
iconName: {
|
|
204
|
+
type: String,
|
|
205
|
+
default: void 0,
|
|
206
|
+
validator: (name) => ICONS_LIST.includes(name)
|
|
207
|
+
},
|
|
187
208
|
/**
|
|
188
209
|
* Icon size to be displayed on the avatar
|
|
189
210
|
* @values 100, 200, 300, 400, 500, 600, 700, 800
|
|
@@ -234,19 +255,12 @@ const _sfc_main = {
|
|
|
234
255
|
AVATAR_ICON_SIZES,
|
|
235
256
|
imageLoadedSuccessfully: null,
|
|
236
257
|
formattedInitials: "",
|
|
237
|
-
initializing: false
|
|
238
|
-
hasSlotContent
|
|
258
|
+
initializing: false
|
|
239
259
|
};
|
|
240
260
|
},
|
|
241
261
|
computed: {
|
|
242
|
-
|
|
243
|
-
return
|
|
244
|
-
},
|
|
245
|
-
hasOverlayIcon() {
|
|
246
|
-
return hasSlotContent(this.$slots.overlayIcon);
|
|
247
|
-
},
|
|
248
|
-
iconDataQa() {
|
|
249
|
-
return "dt-avatar-icon";
|
|
262
|
+
isNotIconType() {
|
|
263
|
+
return !this.iconName;
|
|
250
264
|
},
|
|
251
265
|
avatarClasses() {
|
|
252
266
|
return [
|
|
@@ -255,7 +269,7 @@ const _sfc_main = {
|
|
|
255
269
|
this.avatarClass,
|
|
256
270
|
{
|
|
257
271
|
"d-avatar--group": this.showGroup,
|
|
258
|
-
[`d-avatar--color-${this.getColor()}`]:
|
|
272
|
+
[`d-avatar--color-${this.getColor()}`]: this.isNotIconType,
|
|
259
273
|
"d-avatar--clickable": this.clickable
|
|
260
274
|
}
|
|
261
275
|
];
|
|
@@ -263,8 +277,7 @@ const _sfc_main = {
|
|
|
263
277
|
overlayClasses() {
|
|
264
278
|
return [
|
|
265
279
|
"d-avatar__overlay",
|
|
266
|
-
this.overlayClass
|
|
267
|
-
{ "d-avatar__overlay-icon": this.hasOverlayIcon }
|
|
280
|
+
this.overlayClass
|
|
268
281
|
];
|
|
269
282
|
},
|
|
270
283
|
showGroup() {
|
|
@@ -354,17 +367,17 @@ const _sfc_main = {
|
|
|
354
367
|
}
|
|
355
368
|
};
|
|
356
369
|
const _hoisted_1 = ["src", "alt"];
|
|
357
|
-
const _hoisted_2 =
|
|
358
|
-
const _hoisted_3 = {
|
|
370
|
+
const _hoisted_2 = {
|
|
359
371
|
key: 1,
|
|
360
372
|
class: "d-avatar__overlay-text"
|
|
361
373
|
};
|
|
362
|
-
const
|
|
374
|
+
const _hoisted_3 = {
|
|
363
375
|
key: 1,
|
|
364
376
|
class: "d-avatar__count",
|
|
365
377
|
"data-qa": "dt-avatar-count"
|
|
366
378
|
};
|
|
367
379
|
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
380
|
+
const _component_dt_icon = resolveComponent("dt-icon");
|
|
368
381
|
const _component_dt_presence = resolveComponent("dt-presence");
|
|
369
382
|
return openBlock(), createBlock(resolveDynamicComponent($props.clickable ? "button" : "div"), {
|
|
370
383
|
id: $props.id,
|
|
@@ -388,28 +401,29 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
388
401
|
"data-qa": "dt-avatar-image",
|
|
389
402
|
src: $props.imageSrc,
|
|
390
403
|
alt: $props.imageAlt
|
|
391
|
-
}, null, 8, _hoisted_1)) : $
|
|
404
|
+
}, null, 8, _hoisted_1)) : $props.iconName ? (openBlock(), createBlock(_component_dt_icon, {
|
|
392
405
|
key: 1,
|
|
406
|
+
name: $props.iconName,
|
|
407
|
+
"aria-label": $props.iconAriaLabel,
|
|
408
|
+
size: $props.iconSize || $data.AVATAR_ICON_SIZES[$props.size],
|
|
393
409
|
class: normalizeClass([$props.iconClass, $data.AVATAR_KIND_MODIFIERS.icon]),
|
|
394
|
-
"
|
|
395
|
-
|
|
396
|
-
role: $props.clickable ? "button" : ""
|
|
397
|
-
}, [
|
|
398
|
-
renderSlot(_ctx.$slots, "icon", {
|
|
399
|
-
iconSize: $props.iconSize || $data.AVATAR_ICON_SIZES[$props.size]
|
|
400
|
-
})
|
|
401
|
-
], 10, _hoisted_2)) : (openBlock(), createElementBlock("span", {
|
|
410
|
+
"data-qa": "dt-avatar-icon"
|
|
411
|
+
}, null, 8, ["name", "aria-label", "size", "class"])) : (openBlock(), createElementBlock("span", {
|
|
402
412
|
key: 2,
|
|
403
413
|
class: normalizeClass([$data.AVATAR_KIND_MODIFIERS.initials])
|
|
404
414
|
}, toDisplayString($data.formattedInitials), 3))
|
|
405
415
|
], 2),
|
|
406
|
-
$
|
|
416
|
+
$props.overlayIcon || $props.overlayText ? (openBlock(), createElementBlock("div", {
|
|
407
417
|
key: 0,
|
|
408
418
|
class: normalizeClass($options.overlayClasses)
|
|
409
419
|
}, [
|
|
410
|
-
$
|
|
420
|
+
$props.overlayIcon ? (openBlock(), createBlock(_component_dt_icon, {
|
|
421
|
+
key: 0,
|
|
422
|
+
class: "d-avatar__overlay-icon",
|
|
423
|
+
name: $props.overlayIcon
|
|
424
|
+
}, null, 8, ["name"])) : $props.overlayText ? (openBlock(), createElementBlock("p", _hoisted_2, toDisplayString($props.overlayText), 1)) : createCommentVNode("", true)
|
|
411
425
|
], 2)) : createCommentVNode("", true),
|
|
412
|
-
$options.showGroup ? (openBlock(), createElementBlock("span",
|
|
426
|
+
$options.showGroup ? (openBlock(), createElementBlock("span", _hoisted_3, toDisplayString($options.formattedGroup), 1)) : createCommentVNode("", true),
|
|
413
427
|
$props.presence && !$options.showGroup ? (openBlock(), createBlock(_component_dt_presence, mergeProps({
|
|
414
428
|
key: 2,
|
|
415
429
|
presence: $props.presence,
|
|
@@ -419,7 +433,7 @@ function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
|
|
|
419
433
|
]
|
|
420
434
|
}, $props.presenceProps, { "data-qa": "dt-presence" }), null, 16, ["presence", "class"])) : createCommentVNode("", true)
|
|
421
435
|
]),
|
|
422
|
-
_:
|
|
436
|
+
_: 1
|
|
423
437
|
}, 8, ["id", "class", "onClick"]);
|
|
424
438
|
}
|
|
425
439
|
const DtAvatar = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"avatar.js","sources":["../../components/avatar/avatar_constants.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <div\n v-else-if=\"isIconType\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n :aria-label=\"clickable ? iconAriaLabel : ''\"\n :data-qa=\"iconDataQa\"\n :role=\"clickable ? 'button' : ''\"\n >\n <!-- @slot Slot for avatar icon. It will display if no imageSrc is provided -->\n <slot\n name=\"icon\"\n :icon-size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n />\n </div>\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"hasOverlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <!-- @slot Slot for overlay icon. -->\n <slot\n v-if=\"hasOverlayIcon\"\n name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement, hasSlotContent } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n hasSlotContent,\n };\n },\n\n computed: {\n isIconType () {\n return hasSlotContent(this.$slots.icon);\n },\n\n hasOverlayIcon () {\n return hasSlotContent(this.$slots.overlayIcon);\n },\n\n iconDataQa () {\n return 'dt-avatar-icon';\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: !this.isIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n { 'd-avatar__overlay-icon': this.hasOverlayIcon },\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["_openBlock","_createBlock","_resolveDynamicComponent","_createElementVNode","_normalizeClass","_createElementBlock","_renderSlot","_toDisplayString","_mergeProps"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"avatar.js","sources":["../../components/avatar/avatar_constants.js","../../common/storybook_utils.js","../../components/avatar/utils.js","../../components/avatar/avatar.vue"],"sourcesContent":["export const AVATAR_SIZE_MODIFIERS = {\n xs: 'd-avatar--xs',\n sm: 'd-avatar--sm',\n md: 'd-avatar--md',\n lg: 'd-avatar--lg',\n xl: 'd-avatar--xl',\n};\n\nexport const AVATAR_KIND_MODIFIERS = {\n default: '',\n icon: 'd-avatar__icon',\n initials: 'd-avatar__initials',\n};\n\nexport const AVATAR_PRESENCE_SIZE_MODIFIERS = {\n md: 'd-avatar__presence--md',\n lg: 'd-avatar__presence--lg',\n};\n\nexport const AVATAR_PRESENCE_STATES = {\n NONE: '',\n BUSY: 'busy',\n AWAY: 'away',\n OFFLINE: 'offline',\n ACTIVE: 'active',\n};\n\nexport const AVATAR_ICON_SIZES = {\n xs: '100',\n sm: '200',\n md: '300',\n lg: '500',\n xl: '600',\n};\n\nexport const AVATAR_COLORS = [\n '000',\n '100',\n '200',\n '300',\n '400',\n '500',\n '600',\n '700',\n '800',\n '900',\n '1000',\n '1100',\n '1200',\n '1300',\n '1400',\n '1500',\n '1600',\n '1700',\n '1800',\n];\n\n// We do not use the color '000' (grey) in the randomized avatar colors, but it can still be set manually.\nexport const AVATAR_RANDOM_COLORS = AVATAR_COLORS.slice(1);\n\nexport const AVATAR_GROUP_VALIDATOR = (group) => group > 1;\n\nexport default {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_ICON_SIZES,\n AVATAR_COLORS,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n};\n","import iconNames from '@dialpad/dialtone-icons/icons.js';\nimport illustrationNames from '@dialpad/dialtone-icons/illustrations.js';\n\n/**\n * Will use a Vue SFC to render the template rather than a template string.\n * This is useful for more complex components that are hard to work with and\n * get messy when rendered via a template string. Will pass args and argTypes\n * into the component so it is able to be live edited with storybook controls addon.\n * @param {object} args storybook control args\n * @param {component} templateComponent vue component template for rendering to storybook.\n * Note this should not be the component itself,\n * but rather the usage of that component.\n * @returns {component} the template component with props and args added.\n */\nexport const createTemplateFromVueFile = (args, argTypes, templateComponent) => ({\n components: { templateComponent },\n setup () {\n return { args };\n },\n template: '<template-component v-bind=\"args\"></template-component>',\n});\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIconNames () {\n return [undefined, ...iconNames];\n}\n\n/**\n * Gets the full list of icon component names from the dialtone package\n * @returns {string[]} icon component names\n */\nexport function getIllustrationNames () {\n return [undefined, ...illustrationNames];\n}\n\nexport const generateTemplate = (component,\n { props = [], excludeProps = [], customProps = [], childTemplate } = {}) => {\n if (!component) {\n console.warn('Generate template: Please provide a component');\n return '';\n }\n\n const { name, props: componentProps } = component;\n const finalProps = props.length ? props : Object.keys(componentProps);\n const normalizedName = name.split(/(?=[A-Z])/).join('-').toLowerCase();\n\n const startFragment = `<${normalizedName}`;\n\n const propFragments = finalProps\n .filter(prop => !excludeProps.includes(prop))\n .map(prop => `:${prop}=\"${prop}\"`);\n\n const endFragment = childTemplate ? `>${childTemplate}</${normalizedName}>` : ' />';\n\n return [startFragment, ...propFragments, ...customProps, endFragment].join(' ');\n};\n\nexport default {\n generateTemplate,\n createTemplateFromVueFile,\n getIllustrationNames,\n getIconNames,\n};\n","export const extractInitialsFromName = (fullName) => {\n if (typeof fullName !== 'string' || !fullName.trim()) return '';\n\n const names = fullName.trim().split(/\\s+/g);\n\n return names.length === 1\n ? names.join('').substring(0, 2)\n : names.filter((_, index) => (index === 0 || index === names.length - 1))\n .map(name => name.slice(0, 1).toUpperCase())\n .join('');\n};\n","<template>\n <component\n :is=\"clickable ? 'button' : 'div'\"\n :id=\"id\"\n :class=\"avatarClasses\"\n data-qa=\"dt-avatar\"\n @click=\"handleClick\"\n >\n <div\n ref=\"canvas\"\n :class=\"[\n canvasClass,\n 'd-avatar__canvas',\n { 'd-avatar--image-loaded': imageLoadedSuccessfully },\n ]\"\n >\n <img\n v-if=\"showImage\"\n ref=\"avatarImage\"\n class=\"d-avatar__image\"\n data-qa=\"dt-avatar-image\"\n :src=\"imageSrc\"\n :alt=\"imageAlt\"\n >\n <dt-icon\n v-else-if=\"iconName\"\n :name=\"iconName\"\n :aria-label=\"iconAriaLabel\"\n :size=\"iconSize || AVATAR_ICON_SIZES[size]\"\n :class=\"[iconClass, AVATAR_KIND_MODIFIERS.icon]\"\n data-qa=\"dt-avatar-icon\"\n />\n <span\n v-else\n :class=\"[AVATAR_KIND_MODIFIERS.initials]\"\n >\n {{ formattedInitials }}\n </span>\n </div>\n <div\n v-if=\"overlayIcon || overlayText\"\n :class=\"overlayClasses\"\n >\n <dt-icon\n v-if=\"overlayIcon\"\n class=\"d-avatar__overlay-icon\"\n :name=\"overlayIcon\"\n />\n <p\n v-else-if=\"overlayText\"\n class=\"d-avatar__overlay-text\"\n >\n {{ overlayText }}\n </p>\n </div>\n <span\n v-if=\"showGroup\"\n class=\"d-avatar__count\"\n data-qa=\"dt-avatar-count\"\n >{{ formattedGroup }}</span>\n <dt-presence\n v-if=\"presence && !showGroup\"\n :presence=\"presence\"\n :class=\"[\n 'd-avatar__presence',\n AVATAR_PRESENCE_SIZE_MODIFIERS[size],\n ]\"\n v-bind=\"presenceProps\"\n data-qa=\"dt-presence\"\n />\n </component>\n</template>\n\n<script>\nimport { getUniqueString, getRandomElement } from '@/common/utils';\nimport { DtPresence } from '../presence';\nimport { DtIcon } from '@/components/icon';\nimport {\n AVATAR_KIND_MODIFIERS,\n AVATAR_SIZE_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_PRESENCE_STATES,\n AVATAR_RANDOM_COLORS,\n AVATAR_GROUP_VALIDATOR,\n AVATAR_ICON_SIZES,\n} from './avatar_constants';\nimport { getIconNames } from '@/common/storybook_utils.js';\nimport { ICON_SIZE_MODIFIERS } from '@/components/icon/icon_constants.js';\nimport { extractInitialsFromName } from './utils';\n\nconst ICONS_LIST = getIconNames();\n\n/**\n * An avatar is a visual representation of a user or object.\n * @see https://dialtone.dialpad.com/components/avatar.html\n */\nexport default {\n name: 'DtAvatar',\n components: { DtPresence, DtIcon },\n\n inheritAttrs: false,\n\n props: {\n /**\n * Id of the avatar content wrapper element\n */\n id: {\n type: String,\n default () { return getUniqueString(); },\n },\n\n /**\n * Pass in a seed to get the random color generation based on that string. For example if you pass in a\n * user ID as the string it will return the same randomly generated colors every time for that user.\n */\n seed: {\n type: String,\n default: undefined,\n },\n\n /**\n * Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic\n * if the seed prop is set.\n */\n color: {\n type: String,\n default: undefined,\n },\n\n /**\n * The size of the avatar\n * @values xs, sm, md, lg, xl\n */\n size: {\n type: String,\n default: 'md',\n validator: (size) => Object.keys(AVATAR_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Used to customize the avatar container\n */\n avatarClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Set classes on the avatar canvas. Wrapper around the core avatar image.\n */\n canvasClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Pass through classes. Used to customize the avatar icon\n */\n iconClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Determines whether to show the presence indicator for\n * Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',\n * or 'active'. By default, it's null and nothing is shown.\n * @values null, busy, away, offline, active\n */\n presence: {\n type: String,\n default: AVATAR_PRESENCE_STATES.NONE,\n validator: (state) => {\n return Object.values(AVATAR_PRESENCE_STATES).includes(state);\n },\n },\n\n /**\n * A set of props to be passed into the presence component.\n */\n presenceProps: {\n type: Object,\n default: () => ({}),\n },\n\n /**\n * Determines whether to show a group avatar.\n * Limit to 2 digits max, more than 99 will be rendered as “99+”.\n * if the number is 1 or less it would just show the regular avatar as if group had not been set.\n */\n group: {\n type: Number,\n default: undefined,\n validator: (group) => AVATAR_GROUP_VALIDATOR(group),\n },\n\n /**\n * The icon that overlays the avatar\n */\n overlayIcon: {\n type: String,\n default: '',\n },\n\n /**\n * The text that overlays the avatar\n */\n overlayText: {\n type: String,\n default: '',\n },\n\n /**\n * Used to customize the avatar overlay\n */\n overlayClass: {\n type: [String, Array, Object],\n default: '',\n },\n\n /**\n * Source of the image\n */\n imageSrc: {\n type: String,\n default: '',\n },\n\n /**\n * Alt attribute of the image, required if imageSrc is provided.\n * Can be set to '' (empty string) if the image is described\n * in text nearby\n */\n imageAlt: {\n type: String,\n default: undefined,\n },\n\n /**\n * Icon name to be displayed on the avatar\n */\n iconName: {\n type: String,\n default: undefined,\n validator: (name) => ICONS_LIST.includes(name),\n },\n\n /**\n * Icon size to be displayed on the avatar\n * @values 100, 200, 300, 400, 500, 600, 700, 800\n */\n iconSize: {\n type: String,\n default: '',\n validator: (size) => !size || Object.keys(ICON_SIZE_MODIFIERS).includes(size),\n },\n\n /**\n * Full name used to extract initials.\n */\n fullName: {\n type: String,\n default: '',\n },\n\n /**\n * Makes the avatar focusable and clickable,\n * emits a click event when clicked.\n */\n clickable: {\n type: Boolean,\n default: false,\n },\n\n /**\n * Descriptive label for the icon.\n * To avoid a11y issues, set this prop if clickable and iconName are set.\n */\n iconAriaLabel: {\n type: String,\n default: undefined,\n },\n },\n\n emits: [\n /**\n * Avatar click event\n *\n * @event click\n * @type {PointerEvent | KeyboardEvent}\n */\n 'click',\n ],\n\n data () {\n return {\n AVATAR_SIZE_MODIFIERS,\n AVATAR_KIND_MODIFIERS,\n AVATAR_PRESENCE_SIZE_MODIFIERS,\n AVATAR_ICON_SIZES,\n imageLoadedSuccessfully: null,\n formattedInitials: '',\n initializing: false,\n };\n },\n\n computed: {\n isNotIconType () {\n return !this.iconName;\n },\n\n avatarClasses () {\n return [\n 'd-avatar',\n AVATAR_SIZE_MODIFIERS[this.validatedSize],\n this.avatarClass,\n {\n 'd-avatar--group': this.showGroup,\n [`d-avatar--color-${this.getColor()}`]: this.isNotIconType,\n 'd-avatar--clickable': this.clickable,\n },\n ];\n },\n\n overlayClasses () {\n return [\n 'd-avatar__overlay',\n this.overlayClass,\n ];\n },\n\n showGroup () {\n return AVATAR_GROUP_VALIDATOR(this.group);\n },\n\n formattedGroup () {\n return this.group > 99 ? '99+' : this.group;\n },\n\n validatedSize () {\n // TODO: Group only supports xs size for now. Remove this when we support other sizes.\n return this.group ? 'xs' : this.size;\n },\n\n showImage () {\n return this.imageLoadedSuccessfully !== false && this.imageSrc;\n },\n },\n\n watch: {\n fullName: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n size: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n group: {\n immediate: true,\n handler () {\n this.formatInitials();\n },\n },\n\n imageSrc (newSrc) {\n this.imageLoadedSuccessfully = null;\n if (!newSrc) return;\n\n this.validateProps();\n this.setImageListeners();\n },\n },\n\n mounted () {\n this.validateProps();\n this.setImageListeners();\n },\n\n methods: {\n async setImageListeners () {\n await this.$nextTick();\n const el = this.$refs.avatarImage;\n if (!el) return;\n\n el.addEventListener('load', () => this._loadedImageEventHandler(el), { once: true });\n el.addEventListener('error', () => this._erroredImageEventHandler(el), { once: true });\n },\n\n formatInitials () {\n const initials = extractInitialsFromName(this.fullName);\n\n if (this.validatedSize === 'xs') {\n this.formattedInitials = '';\n } else if (this.validatedSize === 'sm') {\n this.formattedInitials = initials[0];\n } else {\n this.formattedInitials = initials;\n }\n },\n\n getColor () {\n return this.color ?? getRandomElement(AVATAR_RANDOM_COLORS, this.seed);\n },\n\n _loadedImageEventHandler (el) {\n this.imageLoadedSuccessfully = true;\n el.classList.remove('d-d-none');\n },\n\n _erroredImageEventHandler (el) {\n this.imageLoadedSuccessfully = false;\n el.classList.add('d-d-none');\n },\n\n validateProps () {\n if (this.imageSrc && this.imageAlt === undefined) {\n console.error('image-alt required if image-src is provided. Can be set to \"\" (empty string) if the image is described in text nearby');\n }\n },\n\n handleClick (e) {\n if (!this.clickable) return;\n this.$emit('click', e);\n },\n },\n};\n</script>\n\n<style lang=\"less\">\n//TODO: Move these classes to dialtone and document.\n.d-avatar--image-loaded {\n background-color: transparent;\n background-image: unset;\n}\n\n.d-avatar__count {\n z-index: var(--zi-base);\n}\n\n.d-avatar__presence {\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay {\n background-color: var(--dt-color-surface-contrast-opaque);\n opacity: var(--dt-opacity-900);\n position: absolute;\n width: 100%;\n height: 100%;\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--dt-size-radius-circle);\n z-index: var(--zi-base);\n}\n\n.d-avatar__overlay-icon {\n color: var(--dt-color-foreground-primary-inverted);\n width: 100%;\n}\n\n.d-avatar__overlay-text {\n color: var(--dt-color-foreground-primary-inverted);\n font-weight: var(--dt-font-weight-bold);\n font-size: var(--dt-font-size-200);\n width: 100%;\n text-align: center;\n}\n\n.d-avatar--clickable {\n --avatar-color-border: transparent;\n\n cursor: pointer;\n padding: 0;\n background-color: transparent;\n\n border-radius: var(--dt-size-radius-circle);\n border: var(--dt-size-border-100) solid var(--avatar-color-border);\n\n &:focus-visible {\n outline: none;\n box-shadow: var(--dt-shadow-focus);\n }\n\n &:hover {\n --avatar-color-border: var(--dt-color-border-default);\n }\n\n &:active {\n --avatar-color-border: var(--dt-color-border-moderate);\n\n transform: scale(0.98);\n }\n}\n</style>\n"],"names":["_openBlock","_createBlock","_resolveDynamicComponent","_createElementVNode","_normalizeClass","_createElementBlock","_toDisplayString","_mergeProps"],"mappings":"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"}
|