您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

functions.ts 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import GraphemeSplitter from 'grapheme-splitter';
  2. import _ from 'lodash';
  3. const AVATAR_COLORS = [
  4. '#6A50D3',
  5. '#FF9B42',
  6. '#DF486F',
  7. '#73348C',
  8. '#B23683',
  9. '#F96E57',
  10. '#4380E2',
  11. '#238561',
  12. '#00A8B3'
  13. ];
  14. const wordSplitRegex = (/\s+|\.+|_+|;+|-+|,+|\|+|\/+|\\+|"+|'+|\(+|\)+|#+|&+/);
  15. const splitter = new GraphemeSplitter();
  16. /**
  17. * Generates the background color of an initials based avatar.
  18. *
  19. * @param {string?} initials - The initials of the avatar.
  20. * @param {Array<string>} customAvatarBackgrounds - Custom avatar background values.
  21. * @returns {string}
  22. */
  23. export function getAvatarColor(initials: string | undefined, customAvatarBackgrounds: Array<string>) {
  24. const hasCustomAvatarBackgronds = customAvatarBackgrounds?.length;
  25. const colorsBase = hasCustomAvatarBackgronds ? customAvatarBackgrounds : AVATAR_COLORS;
  26. let colorIndex = 0;
  27. if (initials) {
  28. let nameHash = 0;
  29. for (const s of initials) {
  30. nameHash += Number(s.codePointAt(0));
  31. }
  32. colorIndex = nameHash % colorsBase.length;
  33. }
  34. return colorsBase[colorIndex];
  35. }
  36. /**
  37. * Returns the first grapheme from a word, uppercased.
  38. *
  39. * @param {string} word - The string to get grapheme from.
  40. * @returns {string}
  41. */
  42. function getFirstGraphemeUpper(word: string) {
  43. if (!word?.length) {
  44. return '';
  45. }
  46. return splitter.splitGraphemes(word)[0].toUpperCase();
  47. }
  48. /**
  49. * Generates initials for a simple string.
  50. *
  51. * @param {string?} s - The string to generate initials for.
  52. * @returns {string?}
  53. */
  54. export function getInitials(s?: string) {
  55. // We don't want to use the domain part of an email address, if it is one
  56. const initialsBasis = _.split(s, '@')[0];
  57. const [ firstWord, secondWord ] = initialsBasis.split(wordSplitRegex).filter(Boolean);
  58. return getFirstGraphemeUpper(firstWord) + getFirstGraphemeUpper(secondWord);
  59. }
  60. /**
  61. * Checks if the passed URL should be loaded with CORS.
  62. *
  63. * @param {string} url - The URL.
  64. * @param {Array<string>} corsURLs - The URL pattern that matches a URL that needs to be handled with CORS.
  65. * @returns {void}
  66. */
  67. export function isCORSAvatarURL(url: string, corsURLs: Array<string> = []): boolean {
  68. return corsURLs.some(pattern => url.startsWith(pattern));
  69. }
  70. /**
  71. * Checks if the passed prop is a loaded icon or not.
  72. *
  73. * @param {string? | Object?} iconProp - The prop to check.
  74. * @returns {boolean}
  75. */
  76. export function isIcon(iconProp?: string | Function): iconProp is Function {
  77. return Boolean(iconProp) && (typeof iconProp === 'object' || typeof iconProp === 'function');
  78. }