UNPKG

@esri/calcite-components

Version:

Web Components for Esri's Calcite Design System.

113 lines (112 loc) 4.81 kB
/*! All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://github.com/Esri/calcite-design-system/blob/dev/LICENSE.md for details. v3.2.1 */ import { c as customElement } from "../../chunks/runtime.js"; import { html } from "lit-html"; import { LitElement, nothing, safeClassMap, safeStyleMap } from "@arcgis/lumina"; import { C as getModeName } from "../../chunks/dom.js"; import { w as hexToRGB, i as isValidHex } from "../../chunks/utils4.js"; import { css } from "@lit/reactive-element/css-tag.js"; const CSS = { thumbnail: "thumbnail", background: "background", initials: "initials", icon: "icon" }; function stringToHex(string) { string = mixStringDeterministically(string); let hash = 0; for (let i = 0; i < string.length; i++) { hash = string.charCodeAt(i) + ((hash << 5) - hash); } let hex = "#"; for (let j = 0; j < 3; j++) { const value = hash >> j * 8 & 255; hex += ("00" + value.toString(16)).substr(-2); } return hex; } function mixStringDeterministically(string) { const midPoint = Math.floor(string.length / 2); const reversed = string.split("").reverse().join(""); return reversed.substring(midPoint) + reversed.slice(0, midPoint); } function rgbToHue(rgb) { let { r, g, b } = rgb; r /= 255; g /= 255; b /= 255; const max = Math.max(r, g, b); const min = Math.min(r, g, b); const delta = max - min; if (max === min) { return 0; } let hue = (max + min) / 2; switch (max) { case r: hue = (g - b) / delta + (g < b ? 6 : 0); break; case g: hue = (b - r) / delta + 2; break; case b: hue = (r - g) / delta + 4; break; } return Math.round(hue * 60); } function hexToHue(hex) { return rgbToHue(hexToRGB(hex)); } const styles = css`:host{display:inline-block;overflow:hidden;border-radius:var(--calcite-avatar-corner-radius, 50%);color:var(--calcite-avatar-color, var(--calcite-color-text-2))}:host([scale=s]){block-size:1.5rem;inline-size:1.5rem;font-size:var(--calcite-font-size--3)}:host([scale=m]){block-size:2rem;inline-size:2rem;font-size:var(--calcite-font-size--2)}:host([scale=l]){block-size:2.75rem;inline-size:2.75rem;font-size:var(--calcite-font-size-0)}.icon{display:flex}.background{display:flex;block-size:100%;inline-size:100%;align-items:center;justify-content:center;border-radius:var(--calcite-avatar-corner-radius, 50%)}.initials{font-weight:var(--calcite-font-weight-bold);text-transform:uppercase}.thumbnail{block-size:100%;inline-size:100%;border-radius:var(--calcite-avatar-corner-radius, 50%)}:host([hidden]){display:none}[hidden]{display:none}`; class Avatar extends LitElement { constructor() { super(...arguments); this.thumbnailFailedToLoad = false; this.scale = "m"; } static { this.properties = { thumbnailFailedToLoad: [16, {}, { state: true }], fullName: [3, {}, { reflect: true }], label: 1, scale: [3, {}, { reflect: true }], thumbnail: [3, {}, { reflect: true }], userId: [3, {}, { reflect: true }], username: [3, {}, { reflect: true }] }; } static { this.styles = styles; } determineContent() { if (this.thumbnail && !this.thumbnailFailedToLoad) { return html`<img alt=${(this.label || "") ?? nothing} class=${safeClassMap(CSS.thumbnail)} @error=${() => this.thumbnailFailedToLoad = true} src=${this.thumbnail ?? nothing}>`; } const initials = this.generateInitials(); const backgroundColor = this.generateFillColor(); return html`<span .ariaLabel=${this.label || this.fullName} class=${safeClassMap(CSS.background)} role=figure style=${safeStyleMap({ backgroundColor })}>${initials ? html`<span aria-hidden=true class=${safeClassMap(CSS.initials)}>${initials}</span>` : html`<calcite-icon class=${safeClassMap(CSS.icon)} icon=user .scale=${this.scale}></calcite-icon>`}</span>`; } generateFillColor() { const { userId, username, fullName, el } = this; const theme = getModeName(el); const id = userId && `#${userId.substr(userId.length - 6)}`; const name = username || fullName || ""; const hex = id && isValidHex(id) ? id : stringToHex(name); if (!userId && !name || !isValidHex(hex)) { return `var(--calcite-avatar-background-color, var(--calcite-color-foreground-2))`; } const hue = hexToHue(hex); const l = theme === "dark" ? 20 : 90; return `var(--calcite-avatar-background-color, hsl(${hue}, 60%, ${l}%))`; } generateInitials() { const { fullName, username } = this; if (fullName) { return fullName.trim().split(" ").map((name) => name.substring(0, 1)).join(""); } else if (username) { return username.substring(0, 2); } return false; } render() { return this.determineContent(); } } customElement("calcite-avatar", Avatar); export { Avatar };