UNPKG

@dialpad/dialtone

Version:

Dialpad's Dialtone design system monorepo

348 lines (347 loc) 9.9 kB
import { getRandomElement as y, hasSlotContent as d, getUniqueString as g } from "../../common/utils/index.js"; import { AVATAR_GROUP_VALIDATOR as u, AVATAR_PRESENCE_STATES as m, AVATAR_SIZE_MODIFIERS as o, AVATAR_ICON_SIZES as _, AVATAR_PRESENCE_SIZE_MODIFIERS as S, AVATAR_KIND_MODIFIERS as I, AVATAR_RANDOM_COLORS as A } from "./avatar-constants.js"; import { ICON_SIZE_MODIFIERS as E } from "../icon/icon-constants.js"; import { extractInitialsFromName as C } from "./utils.js"; import { resolveComponent as p, createBlock as f, openBlock as r, resolveDynamicComponent as O, normalizeStyle as k, normalizeClass as l, withCtx as R, createElementVNode as b, createElementBlock as s, createCommentVNode as n, renderSlot as v, toDisplayString as c, mergeProps as T } from "vue"; import { _ as D } from "../../_plugin-vue_export-helper-CHgC5LLL.js"; import N from "../presence/presence.js"; const L = { compatConfig: { MODE: 3 }, name: "DtAvatar", components: { DtPresence: N }, inheritAttrs: !1, props: { /** * Id of the avatar content wrapper element */ id: { type: String, default() { return g(); } }, /** * 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: (e) => Object.keys(o).includes(e) }, /** * 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: m.NONE, validator: (e) => Object.values(m).includes(e) }, /** * 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: (e) => u(e) }, /** * 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: (e) => !e || Object.keys(E).includes(e) }, /** * 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: o, AVATAR_KIND_MODIFIERS: I, AVATAR_PRESENCE_SIZE_MODIFIERS: S, AVATAR_ICON_SIZES: _, imageLoadedSuccessfully: null, formattedInitials: "", initializing: !1, hasSlotContent: d }; }, computed: { hasOverlayIcon() { return d(this.$slots.overlayIcon); }, iconDataQa() { return "dt-avatar-icon"; }, avatarClasses() { return [ "d-avatar", this.$attrs.class, o[this.validatedSize], this.avatarClass, { "d-avatar--group": this.showGroup, [`d-avatar--color-${this.getColor()}`]: !this.isIconType(), "d-avatar--clickable": this.clickable } ]; }, overlayClasses() { return [ "d-avatar__overlay", this.overlayClass, { "d-avatar__overlay-icon": this.hasOverlayIcon } ]; }, showGroup() { return u(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(e) { this.imageLoadedSuccessfully = null, e && (this.validateProps(), this.setImageListeners()); } }, mounted() { this.validateProps(), this.setImageListeners(); }, methods: { isIconType() { return d(this.$slots.icon); }, async setImageListeners() { await this.$nextTick(); const e = this.$refs.avatarImage; e && (e.addEventListener("load", () => this._loadedImageEventHandler(e), { once: !0 }), e.addEventListener("error", () => this._erroredImageEventHandler(e), { once: !0 })); }, formatInitials() { const e = C(this.fullName); this.validatedSize === "xs" ? this.formattedInitials = "" : this.validatedSize === "sm" ? this.formattedInitials = e[0] : this.formattedInitials = e; }, getColor() { return this.color ?? y(A, this.seed); }, _loadedImageEventHandler(e) { this.imageLoadedSuccessfully = !0, e.classList.remove("d-d-none"); }, _erroredImageEventHandler(e) { this.imageLoadedSuccessfully = !1, e.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(e) { this.clickable && this.$emit("click", e); } } }, z = ["src", "alt"], V = ["aria-label", "data-qa", "role"], x = { key: 1, class: "d-avatar__overlay-text" }, P = { key: 1, class: "d-avatar__count", "data-qa": "dt-avatar-count" }; function w(e, M, a, j, i, t) { const h = p("dt-presence"); return r(), f(O(a.clickable ? "button" : "div"), { id: a.id, class: l(t.avatarClasses), style: k(e.$attrs.style), "data-qa": "dt-avatar", onClick: t.handleClick }, { default: R(() => [ b("div", { ref: "canvas", class: l([ a.canvasClass, "d-avatar__canvas", { "d-avatar--image-loaded": i.imageLoadedSuccessfully } ]) }, [ t.showImage ? (r(), s("img", { key: 0, ref: "avatarImage", class: "d-avatar__image", "data-qa": "dt-avatar-image", src: a.imageSrc, alt: a.imageAlt }, null, 8, z)) : t.isIconType() ? (r(), s("div", { key: 1, class: l([a.iconClass, i.AVATAR_KIND_MODIFIERS.icon]), "aria-label": a.clickable ? a.iconAriaLabel : "", "data-qa": t.iconDataQa, role: a.clickable ? "button" : "" }, [ v(e.$slots, "icon", { iconSize: a.iconSize || i.AVATAR_ICON_SIZES[a.size] }) ], 10, V)) : (r(), s("span", { key: 2, class: l([i.AVATAR_KIND_MODIFIERS.initials]) }, c(i.formattedInitials), 3)) ], 2), t.hasOverlayIcon || a.overlayText ? (r(), s("div", { key: 0, class: l(t.overlayClasses) }, [ t.hasOverlayIcon ? v(e.$slots, "overlayIcon", { key: 0 }) : a.overlayText ? (r(), s("p", x, c(a.overlayText), 1)) : n("", !0) ], 2)) : n("", !0), t.showGroup ? (r(), s("span", P, c(t.formattedGroup), 1)) : n("", !0), a.presence && !t.showGroup ? (r(), f(h, T({ key: 2, presence: a.presence, class: [ "d-avatar__presence", i.AVATAR_PRESENCE_SIZE_MODIFIERS[a.size] ] }, a.presenceProps, { "data-qa": "dt-presence" }), null, 16, ["presence", "class"])) : n("", !0) ]), _: 3 }, 8, ["id", "class", "style", "onClick"]); } const Q = /* @__PURE__ */ D(L, [["render", w]]); export { Q as default }; //# sourceMappingURL=avatar.js.map