/** * Copyright (c) OpenLens Authors. All rights reserved. * Licensed under MIT License. See LICENSE in root directory for more information. */ import styles from "./avatar.module.scss"; import React, { HTMLAttributes, ImgHTMLAttributes } from "react"; import randomColor from "randomcolor"; import GraphemeSplitter from "grapheme-splitter"; import { cssNames, iter } from "../../utils"; export interface AvatarProps extends HTMLAttributes { title: string; colorHash?: string; size?: number; src?: string; background?: string; variant?: "circle" | "rounded" | "square"; imgProps?: ImgHTMLAttributes; disabled?: boolean; } function getNameParts(name: string): string[] { const byWhitespace = name.split(/\s+/); if (byWhitespace.length > 1) { return byWhitespace; } const byDashes = name.split(/[-_]+/); if (byDashes.length > 1) { return byDashes; } return name.split(/@+/); } function getLabelFromTitle(title: string) { if (!title) { return "??"; } const [rawFirst, rawSecond, rawThird] = getNameParts(title); const splitter = new GraphemeSplitter(); const first = splitter.iterateGraphemes(rawFirst); const second = rawSecond ? splitter.iterateGraphemes(rawSecond): first; const third = rawThird ? splitter.iterateGraphemes(rawThird) : iter.newEmpty(); return [ ...iter.take(first, 1), ...iter.take(second, 1), ...iter.take(third, 1), ].filter(Boolean).join(""); } export function Avatar(props: AvatarProps) { const { title, variant = "rounded", size = 32, colorHash, children, background, imgProps, src, className, disabled, ...rest } = props; const colorFromHash = randomColor({ seed: colorHash, luminosity: "dark" }); const renderContents = () => { if (src) { return {title}/; } return children || getLabelFromTitle(title); }; return (
{renderContents()}
); }