avatar.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. /*!
  2. * All material copyright ESRI, All Rights Reserved, unless otherwise specified.
  3. * See https://github.com/Esri/calcite-components/blob/master/LICENSE.md for details.
  4. * v1.0.0-beta.82
  5. */
  6. import { Component, Element, h, Prop, State } from "@stencil/core";
  7. import { isValidHex } from "../color-picker/utils";
  8. import { hexToHue, stringToHex } from "./utils";
  9. import { getThemeName } from "../../utils/dom";
  10. export class Avatar {
  11. constructor() {
  12. //--------------------------------------------------------------------------
  13. //
  14. // Properties
  15. //
  16. //--------------------------------------------------------------------------
  17. /** specify the scale of the avatar, defaults to m */
  18. this.scale = "m";
  19. //--------------------------------------------------------------------------
  20. //
  21. // Private State/Props
  22. //
  23. //--------------------------------------------------------------------------
  24. /** True if thumnail fails to load */
  25. this.error = false;
  26. }
  27. //--------------------------------------------------------------------------
  28. //
  29. // Lifecycle
  30. //
  31. //--------------------------------------------------------------------------
  32. render() {
  33. return this.determineContent();
  34. }
  35. //--------------------------------------------------------------------------
  36. //
  37. // Private Methods
  38. //
  39. //--------------------------------------------------------------------------
  40. determineContent() {
  41. if (this.thumbnail && !this.error) {
  42. return (h("img", { alt: "", class: "thumbnail", onError: () => (this.error = true), src: this.thumbnail }));
  43. }
  44. const initials = this.generateInitials();
  45. const backgroundColor = this.generateFillColor();
  46. return (h("span", { class: "background", style: { backgroundColor } }, initials ? (h("span", { "aria-hidden": "true", class: "initials" }, initials)) : (h("calcite-icon", { class: "icon", icon: "user", scale: this.scale }))));
  47. }
  48. /**
  49. * Generate a valid background color that is consistent and unique to this user
  50. */
  51. generateFillColor() {
  52. const { userId, username, fullName, el } = this;
  53. const theme = getThemeName(el);
  54. const id = userId && `#${userId.substr(userId.length - 6)}`;
  55. const name = username || fullName || "";
  56. const hex = id && isValidHex(id) ? id : stringToHex(name);
  57. // if there is not unique information, or an invalid hex is produced, return a default
  58. if ((!userId && !name) || !isValidHex(hex)) {
  59. return `var(--calcite-ui-foreground-2)`;
  60. }
  61. const hue = hexToHue(hex);
  62. const l = theme === "dark" ? 20 : 90;
  63. return `hsl(${hue}, 60%, ${l}%)`;
  64. }
  65. /**
  66. * Use fullname or username to generate initials
  67. */
  68. generateInitials() {
  69. const { fullName, username } = this;
  70. if (fullName) {
  71. return fullName
  72. .trim()
  73. .split(" ")
  74. .map((name) => name.substring(0, 1))
  75. .join("");
  76. }
  77. else if (username) {
  78. return username.substring(0, 2);
  79. }
  80. return false;
  81. }
  82. static get is() { return "calcite-avatar"; }
  83. static get encapsulation() { return "shadow"; }
  84. static get originalStyleUrls() { return {
  85. "$": ["avatar.scss"]
  86. }; }
  87. static get styleUrls() { return {
  88. "$": ["avatar.css"]
  89. }; }
  90. static get properties() { return {
  91. "scale": {
  92. "type": "string",
  93. "mutable": false,
  94. "complexType": {
  95. "original": "Scale",
  96. "resolved": "\"l\" | \"m\" | \"s\"",
  97. "references": {
  98. "Scale": {
  99. "location": "import",
  100. "path": "../interfaces"
  101. }
  102. }
  103. },
  104. "required": false,
  105. "optional": false,
  106. "docs": {
  107. "tags": [],
  108. "text": "specify the scale of the avatar, defaults to m"
  109. },
  110. "attribute": "scale",
  111. "reflect": true,
  112. "defaultValue": "\"m\""
  113. },
  114. "thumbnail": {
  115. "type": "string",
  116. "mutable": false,
  117. "complexType": {
  118. "original": "string",
  119. "resolved": "string",
  120. "references": {}
  121. },
  122. "required": false,
  123. "optional": false,
  124. "docs": {
  125. "tags": [],
  126. "text": "src to an image (remember to add a token if the user is private)"
  127. },
  128. "attribute": "thumbnail",
  129. "reflect": false
  130. },
  131. "fullName": {
  132. "type": "string",
  133. "mutable": false,
  134. "complexType": {
  135. "original": "string",
  136. "resolved": "string",
  137. "references": {}
  138. },
  139. "required": false,
  140. "optional": false,
  141. "docs": {
  142. "tags": [],
  143. "text": "full name of the user"
  144. },
  145. "attribute": "full-name",
  146. "reflect": false
  147. },
  148. "username": {
  149. "type": "string",
  150. "mutable": false,
  151. "complexType": {
  152. "original": "string",
  153. "resolved": "string",
  154. "references": {}
  155. },
  156. "required": false,
  157. "optional": false,
  158. "docs": {
  159. "tags": [],
  160. "text": "user name"
  161. },
  162. "attribute": "username",
  163. "reflect": false
  164. },
  165. "userId": {
  166. "type": "string",
  167. "mutable": false,
  168. "complexType": {
  169. "original": "string",
  170. "resolved": "string",
  171. "references": {}
  172. },
  173. "required": false,
  174. "optional": false,
  175. "docs": {
  176. "tags": [],
  177. "text": "unique id for user"
  178. },
  179. "attribute": "user-id",
  180. "reflect": false
  181. }
  182. }; }
  183. static get states() { return {
  184. "error": {}
  185. }; }
  186. static get elementRef() { return "el"; }
  187. }