@nysds/nys-avatar
Version:
The Avatar component from the NYS Design System.
145 lines (144 loc) • 7.35 kB
JavaScript
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 =${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