UNPKG

@dialpad/dialtone-vue

Version:

Vue component library for Dialpad's design system Dialtone

296 lines (295 loc) 9.16 kB
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