UNPKG

@nysds/nys-avatar

Version:

The Avatar component from the NYS Design System.

145 lines (144 loc) 7.35 kB
import { LitElement as g, unsafeCSS as m, html as l } from "lit"; import { property as e, state as b } from "lit/decorators.js"; import { ifDefined as y } from "lit/directives/if-defined.js"; /*! * █▄ █ █ █ █▀▀▀█ █▀▀▄ █▀▀▀█ * █ █ █ █▄▄▄█ ▀▀▀▄▄ █ █ ▀▀▀▄▄ * █ ▀█ █ █▄▄▄█ █▄▄▀ █▄▄▄█ * * Avatar Component v1.16.0 * Part of the New York State Design System * Repository: https://github.com/its-hcd/nysds * License: MIT */ const x = ":host{--_nys-avatar-border-radius: var(--nys-radius-round, 1776px);--_nys-avatar-size: var(--nys-avatar-size, var(--nys-font-size-6xl, 36px));--_nys-avatar-shape: var(--nys-radius-round, 1776px);--_nys-avatar-border-color: var(--nys-color-ink-reverse, #ffffff);--_nys-avatar-border-size: var(--nys-border-width-sm, 1px);--_nys-avatar-width: var(--nys-font-size-6xl, 36px);--_nys-avatar-color: var(--nys-color-theme, #154973);--_nys-avatar-background-color: var(--nys-color-theme-weaker, #eff6fb);--_nys-avatar-outline-color: var(--nys-color-focus, #004dd1);--_nys-avatar-outline-width: var(--nys-border-width-md, 2px);--_nys-avatar-outline-offset: var(--nys-space-2px, 2px)}.nys-avatar{display:inline-block}.nys-avatar__component{display:flex;justify-content:center;align-items:center;border-radius:var(--_nys-avatar-border-radius);width:var(--_nys-avatar-size);height:var(--_nys-avatar-size);font-size:var(--_nys-avatar-size);overflow:hidden;box-sizing:border-box;color:var(--_nys-avatar-color);background-color:var(--_nys-avatar-background-color);border:var(--_nys-avatar-border-size) solid var(--_nys-avatar-border-color);outline-offset:var(--_nys-avatar-outline-offset);transition:all .15s ease-in-out;-webkit-user-select:none;user-select:none}:host([interactive]) .nys-avatar__component:hover,:host([interactive]) .nys-avatar__component:active{--_nys-avatar-color: var( --nys-color-text-reverse, --nys-color-ink-reverse, #ffffff );cursor:pointer}:host([interactive]) .nys-avatar__component:hover{--_nys-avatar-background-color: var(--nys-color-theme-mid, #457aa5)}:host([interactive]) .nys-avatar__component:active{--_nys-avatar-background-color: var(--nys-color-theme-strong, #0e324f)}:host([disabled]) .nys-avatar__component{--_nys-avatar-color: var(--nys-color-text-disabled, #bec0c1);--_nys-avatar-background-color: var(--nys-color-neutral-10, #f6f6f6);cursor:not-allowed}:host([disabled]) .nys-avatar__component:focus-within{outline:solid var(--_nys-avatar-outline-width) var(--_nys-avatar-outline-color)}div[part=nys-avatar__icon]{display:flex;align-items:center;justify-content:center}.nys-avatar__initials{display:flex;align-items:center;justify-content:center;width:100%;height:100%;font-size:calc(var(--_nys-avatar-width) * .5);font-weight:700;text-transform:uppercase}.nys-avatar__image{width:100%;height:100%;object-fit:cover}.nys-avatar__icon{width:100%;height:100%;fill:currentcolor}"; var k = Object.defineProperty, a = (h, n, s, i) => { for (var r = void 0, o = h.length - 1, c; o >= 0; o--) (c = h[o]) && (r = c(n, s, r) || r); return r && k(n, s, r), r; }; let w = 0; const d = class d extends g { constructor() { super(...arguments), this.id = "", this.ariaLabel = "", this.image = "", this.initials = "", this.icon = "", this.color = "", this.interactive = !1, this.disabled = !1, this.lazy = !1, this._slotHasContent = !1; } /** * Lifecycle methods * -------------------------------------------------------------------------- */ connectedCallback() { super.connectedCallback(), this.id || (this.id = `nys-avatar-${Date.now()}-${w++}`); } async _handleSlotChange() { const n = this.shadowRoot?.querySelector("slot"); if (!n) { this._slotHasContent = !1; return; } await Promise.resolve(); const s = n.assignedNodes({ flatten: !0 }).filter( (i) => i.nodeType === Node.ELEMENT_NODE || i.nodeType === Node.TEXT_NODE && i.textContent?.trim() ); this._slotHasContent = s.length > 0; } /** * Functions * -------------------------------------------------------------------------- */ /** * Computes the appropriate foreground color (icon or initials) * based on the avatar's background color for sufficient contrast. * * @returns CSS color string for foreground */ getContrastForeground() { const n = "var(--nys-color-ink, #000)", s = "var(--nys-color-ink-reverse, #fff)", i = "var(--nys-color-text, #000)", r = "var(--nys-color-text-reverse, #fff)"; if (!this.color) return; const o = document.createElement("div"); o.style.color = this.color, document.body.appendChild(o); const c = getComputedStyle(o).color; document.body.removeChild(o); const v = c.match(/\d+/g); if (!v) return; const _ = Number(v[0]), p = Number(v[1]), u = Number(v[2]), f = (0.299 * _ + 0.587 * p + 0.114 * u) / 255 < 0.5; return this.initials?.length > 0 ? f ? r : i : f ? s : n; } render() { return l` <div class="nys-avatar"> <div class="nys-avatar__content"> <div part="nys-avatar" class="nys-avatar__component" style=${this.color ? `--_nys-avatar-background-color: ${this.color}; color: ${this.getContrastForeground()}` : ""} role=${y( this.interactive ? "button" : this.image ? void 0 : "img" )} aria-label=${y( this.image ? void 0 : this.ariaLabel ? this.ariaLabel : "avatar" )} tabindex=${y( this.interactive && !this.disabled ? 0 : void 0 )} > ${this.image?.length > 0 ? l`<img part="nys-avatar__image" class="nys-avatar__image" src=${this.image} alt=${this.ariaLabel || "avatar"} loading=${this.lazy ? "lazy" : "eager"} />` : this.initials?.length > 0 ? l`<span part="nys-avatar__initials" class="nys-avatar__initials" aria-hidden="true" >${this.initials}</span >` : l`<div part="nys-avatar__icon"> <slot @slotchange=${this._handleSlotChange}></slot> ${this._slotHasContent ? null : l`<nys-icon label="nys-avatar__icon" name=${this.icon?.length > 0 ? this.icon : "account_circle"} ></nys-icon>`} </div>`} </div> </div> </div> `; } }; d.styles = m(x); let t = d; a([ e({ type: String, reflect: !0 }) ], t.prototype, "id"); a([ e({ type: String }) ], t.prototype, "ariaLabel"); a([ e({ type: String }) ], t.prototype, "image"); a([ e({ type: String }) ], t.prototype, "initials"); a([ e({ type: String }) ], t.prototype, "icon"); a([ e({ type: String }) ], t.prototype, "color"); a([ e({ type: Boolean, reflect: !0 }) ], t.prototype, "interactive"); a([ e({ type: Boolean, reflect: !0 }) ], t.prototype, "disabled"); a([ e({ type: Boolean, reflect: !0 }) ], t.prototype, "lazy"); a([ b() ], t.prototype, "_slotHasContent"); customElements.get("nys-avatar") || customElements.define("nys-avatar", t); export { t as NysAvatar }; //# sourceMappingURL=nys-avatar.js.map