@dialpad/dialtone-vue
Version:
Vue component library for Dialpad's design system Dialtone
296 lines (295 loc) • 9.16 kB
JavaScript
import { getRandomElement as l, getUniqueString as n } from "../../common/utils/index.js";
import { AVATAR_GROUP_VALIDATOR as r, AVATAR_PRESENCE_STATES as i, AVATAR_RANDOM_COLORS as o, AVATAR_SIZE_MODIFIERS as s, AVATAR_ICON_SIZES as d, AVATAR_PRESENCE_SIZE_MODIFIERS as c, AVATAR_KIND_MODIFIERS as u } from "./avatar-constants.js";
import { ICON_SIZE_MODIFIERS as m } from "../icon/icon-constants.js";
import { extractInitialsFromName as p } from "./utils.js";
import { n as v } from "../../_plugin-vue2_normalizer-DSLOjnn3.js";
import h from "../presence/presence.js";
const f = {
name: "DtAvatar",
components: { DtPresence: h },
inheritAttrs: !1,
props: {
/**
* Id of the avatar content wrapper element
*/
id: {
type: String,
default() {
return n();
}
},
/**
* Pass in a seed to get the random color generation based on that string. For example if you pass in a
* user ID as the string it will return the same randomly generated colors every time for that user.
*/
seed: {
type: String,
default: void 0
},
/**
* Set the avatar background to a specific color. If undefined will randomize the color which can be deterministic
* if the seed prop is set.
*/
color: {
type: String,
default: void 0
},
/**
* The size of the avatar
* @values xs, sm, md, lg, xl
*/
size: {
type: String,
default: "md",
validator: (a) => Object.keys(s).includes(a)
},
/**
* Used to customize the avatar container
*/
avatarClass: {
type: [String, Array, Object],
default: ""
},
/**
* Set classes on the avatar canvas. Wrapper around the core avatar image.
*/
canvasClass: {
type: [String, Array, Object],
default: ""
},
/**
* Pass through classes. Used to customize the avatar icon
*/
iconClass: {
type: [String, Array, Object],
default: ""
},
/**
* Determines whether to show the presence indicator for
* Avatar - accepts PRESENCE_STATES values: 'busy', 'away', 'offline',
* or 'active'. By default, it's null and nothing is shown.
* @values null, busy, away, offline, active
*/
presence: {
type: String,
default: i.NONE,
validator: (a) => Object.values(i).includes(a)
},
/**
* A set of props to be passed into the presence component.
*/
presenceProps: {
type: Object,
default: () => ({})
},
/**
* Determines whether to show a group avatar.
* Limit to 2 digits max, more than 99 will be rendered as “99+”.
* if the number is 1 or less it would just show the regular avatar as if group had not been set.
*/
group: {
type: Number,
default: void 0,
validator: (a) => r(a)
},
/**
* The text that overlays the avatar
*/
overlayText: {
type: String,
default: ""
},
/**
* Used to customize the avatar overlay
*/
overlayClass: {
type: [String, Array, Object],
default: ""
},
/**
* Source of the image
*/
imageSrc: {
type: String,
default: ""
},
/**
* Alt attribute of the image, required if imageSrc is provided.
* Can be set to '' (empty string) if the image is described
* in text nearby
*/
imageAlt: {
type: String,
default: void 0
},
/**
* Icon size to be displayed on the avatar
* @values 100, 200, 300, 400, 500, 600, 700, 800
*/
iconSize: {
type: String,
default: "",
validator: (a) => !a || Object.keys(m).includes(a)
},
/**
* Full name used to extract initials.
*/
fullName: {
type: String,
default: ""
},
/**
* Makes the avatar focusable and clickable,
* emits a click event when clicked.
*/
clickable: {
type: Boolean,
default: !1
},
/**
* Descriptive label for the icon.
* To avoid a11y issues, set this prop if clickable and iconName are set.
*/
iconAriaLabel: {
type: String,
default: void 0
}
},
emits: [
/**
* Avatar click event
*
* @event click
* @type {PointerEvent | KeyboardEvent}
*/
"click"
],
data() {
return {
AVATAR_SIZE_MODIFIERS: s,
AVATAR_KIND_MODIFIERS: u,
AVATAR_PRESENCE_SIZE_MODIFIERS: c,
AVATAR_ICON_SIZES: d,
imageLoadedSuccessfully: null,
formattedInitials: "",
initializing: !1
};
},
computed: {
hasOverlayIcon() {
return !!this.$slots.overlayIcon;
},
iconDataQa() {
return "dt-avatar-icon";
},
avatarClasses() {
return [
"d-avatar",
s[this.validatedSize],
this.avatarClass,
{
"d-avatar--group": this.showGroup,
"d-avatar--group-digits-2": this.showGroup && this.group > 9 && this.group < 100,
"d-avatar--group-digits-3": this.showGroup && this.group > 99,
[`d-avatar--color-${this.getColor()}`]: !this.isIconType(),
"d-avatar--clickable": this.clickable,
"d-avatar--presence": this.presence && !this.showGroup
}
];
},
overlayClasses() {
return [
"d-avatar__overlay",
this.overlayClass,
{ "d-avatar__overlay-icon": this.hasOverlayIcon }
];
},
showGroup() {
return r(this.group);
},
formattedGroup() {
return this.group > 99 ? "99+" : this.group;
},
validatedSize() {
return this.group ? "xs" : this.size;
},
showImage() {
return this.imageLoadedSuccessfully !== !1 && this.imageSrc;
}
},
watch: {
fullName: {
immediate: !0,
handler() {
this.formatInitials();
}
},
size: {
immediate: !0,
handler() {
this.formatInitials();
}
},
group: {
immediate: !0,
handler() {
this.formatInitials();
}
},
imageSrc(a) {
this.imageLoadedSuccessfully = null, a && (this.validateProps(), this.setImageListeners());
}
},
mounted() {
this.validateProps(), this.setImageListeners();
},
methods: {
isIconType() {
return this.$scopedSlots.icon && this.$scopedSlots.icon();
},
async setImageListeners() {
await this.$nextTick();
const a = this.$refs.avatarImage;
a && (a.addEventListener("load", () => this._loadedImageEventHandler(a), { once: !0 }), a.addEventListener("error", () => this._erroredImageEventHandler(a), { once: !0 }));
},
formatInitials() {
const a = p(this.fullName);
this.validatedSize === "xs" ? this.formattedInitials = "" : this.validatedSize === "sm" ? this.formattedInitials = a[0] : this.formattedInitials = a;
},
getColor() {
return this.color ?? l(o, this.seed);
},
_loadedImageEventHandler(a) {
this.imageLoadedSuccessfully = !0, a.classList.remove("d-d-none");
},
_erroredImageEventHandler(a) {
this.imageLoadedSuccessfully = !1, a.classList.add("d-d-none");
},
validateProps() {
this.imageSrc && this.imageAlt === void 0 && console.error('image-alt required if image-src is provided. Can be set to "" (empty string) if the image is described in text nearby');
},
handleClick(a) {
this.clickable && this.$emit("click", a);
}
}
};
var _ = function() {
var e = this, t = e._self._c;
return t(e.clickable ? "button" : "div", { tag: "component", class: e.avatarClasses, attrs: { id: e.id, "data-qa": "dt-avatar" }, on: { click: e.handleClick } }, [t("div", { ref: "canvas", class: [
e.canvasClass,
"d-avatar__canvas",
{ "d-avatar--image-loaded": e.imageLoadedSuccessfully }
] }, [e.showImage ? t("img", { ref: "avatarImage", staticClass: "d-avatar__image", attrs: { "data-qa": "dt-avatar-image", src: e.imageSrc, alt: e.imageAlt } }) : e.isIconType() ? t("div", { class: [e.iconClass, e.AVATAR_KIND_MODIFIERS.icon], attrs: { "aria-label": e.clickable ? e.iconAriaLabel : "", "data-qa": e.iconDataQa, role: e.clickable ? "button" : "" } }, [e._t("icon", null, { iconSize: e.iconSize || e.AVATAR_ICON_SIZES[e.size] })], 2) : t("span", { class: [e.AVATAR_KIND_MODIFIERS.initials] }, [e._v(" " + e._s(e.formattedInitials) + " ")])]), e.hasOverlayIcon || e.overlayText ? t("div", { class: e.overlayClasses }, [e.hasOverlayIcon ? e._t("overlayIcon") : e.overlayText ? t("p", { staticClass: "d-avatar__overlay-text" }, [e._v(" " + e._s(e.overlayText) + " ")]) : e._e()], 2) : e._e(), e.showGroup ? t("span", { staticClass: "d-avatar__count", attrs: { "data-qa": "dt-avatar-count" } }, [e._v(e._s(e.formattedGroup))]) : e._e(), e.presence && !e.showGroup ? t("dt-presence", e._b({ class: [
"d-avatar__presence",
e.AVATAR_PRESENCE_SIZE_MODIFIERS[e.size]
], attrs: { presence: e.presence, "data-qa": "dt-presence" } }, "dt-presence", e.presenceProps, !1)) : e._e()], 1);
}, g = [], I = /* @__PURE__ */ v(
f,
_,
g
);
const R = I.exports;
export {
R as default
};
//# sourceMappingURL=avatar.js.map