@esri/calcite-components
Version:
Web Components for Esri's Calcite Design System.
113 lines (112 loc) • 4.81 kB
JavaScript
/*! 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
};