diff --git a/src/renderer/components/+catalog/catalog.module.css b/src/renderer/components/+catalog/catalog.module.css index 2e6c7c7004..f0090dec76 100644 --- a/src/renderer/components/+catalog/catalog.module.css +++ b/src/renderer/components/+catalog/catalog.module.css @@ -140,3 +140,8 @@ background-color: var(--blue); --color-active: white; } + +.catalogAvatar { + font-size: 1.45ch; + border-radius: 2px; +} \ No newline at end of file diff --git a/src/renderer/components/+catalog/catalog.tsx b/src/renderer/components/+catalog/catalog.tsx index fff6fd045e..86977923fc 100644 --- a/src/renderer/components/+catalog/catalog.tsx +++ b/src/renderer/components/+catalog/catalog.tsx @@ -41,10 +41,10 @@ import { createStorage, prevDefault } from "../../utils"; import { CatalogEntityDetails } from "./catalog-entity-details"; import { browseCatalogTab, catalogURL, CatalogViewRouteParam } from "../../../common/routes"; import { CatalogMenu } from "./catalog-menu"; -import { HotbarIcon } from "../hotbar/hotbar-icon"; import { RenderDelay } from "../render-delay/render-delay"; import { Icon } from "../icon"; import { HotbarToggleMenuItem } from "./hotbar-toggle-menu-item"; +import { Avatar } from "../avatar/avatar"; export const previousActiveTab = createStorage("catalog-previous-active-tab", browseCatalogTab); @@ -213,15 +213,17 @@ export class Catalog extends React.Component { return ( <> - + className={styles.catalogAvatar} + width={24} + height={24} + > + {item.entity.spec.icon?.material && } + {item.name} ", () => { + test("renders w/o errors", () => { + const { container } = render(); + + expect(container).toBeInstanceOf(HTMLElement); + }); + + test("shows capital letters from title", () => { + const { getByText } = render(); + + expect(getByText("JF")).toBeInTheDocument(); + }); + + test("shows custom icon passed as children", () => { + const { getByTestId } = render(); + + expect(getByTestId("alarm-icon")).toBeInTheDocument(); + }); + + test("shows element if src prop passed", () => { + const { getByAltText } = render(); + + expect(getByAltText("John Ferguson")).toBeInTheDocument(); + }); +}); diff --git a/src/renderer/components/avatar/avatar.module.css b/src/renderer/components/avatar/avatar.module.css new file mode 100644 index 0000000000..96a6b1866b --- /dev/null +++ b/src/renderer/components/avatar/avatar.module.css @@ -0,0 +1,45 @@ +/** + * Copyright (c) 2021 OpenLens Authors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +.Avatar { + background-color: hsl(0deg, 0%, 45%); + text-transform: uppercase; + color: white; + font-size: 1.6ch; + overflow: hidden; + display: flex; + align-items: center; + justify-content: center; + + img { + width: 100%; + height: 100%; + object-fit: cover; + } +} + +.circle { + border-radius: 50%; +} + +.rounded { + border-radius: var(--border-radius); +} \ No newline at end of file diff --git a/src/renderer/components/avatar/avatar.tsx b/src/renderer/components/avatar/avatar.tsx index 3de76af7ab..828feb05cc 100644 --- a/src/renderer/components/avatar/avatar.tsx +++ b/src/renderer/components/avatar/avatar.tsx @@ -19,13 +19,14 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +import styles from "./avatar.module.css"; + import React, { DOMAttributes } from "react"; import randomColor from "randomcolor"; import GraphemeSplitter from "grapheme-splitter"; -import { Avatar as MaterialAvatar, AvatarTypeMap } from "@material-ui/core"; -import { iter } from "../../utils"; +import { cssNames, iter } from "../../utils"; -interface Props extends DOMAttributes, Partial { +interface Props extends DOMAttributes { title: string; colorHash?: string; width?: number; @@ -33,6 +34,8 @@ interface Props extends DOMAttributes, Partial { src?: string; className?: string; background?: string; + variant?: "circle" | "rounded" | "square"; + imgProps?: React.ImgHTMLAttributes; } function getNameParts(name: string): string[] { @@ -51,7 +54,7 @@ function getNameParts(name: string): string[] { return name.split(/@+/); } -function getIconString(title: string) { +function getLabelFromTitle(title: string) { if (!title) { return "??"; } @@ -70,36 +73,30 @@ function getIconString(title: string) { } export function Avatar(props: Props) { - const { title, width = 32, height = 32, colorHash, children, background, ...settings } = props; + const { title, width = 32, height = 32, variant = "rounded", colorHash, children, background, imgProps, src, className, ...rest } = props; const getBackgroundColor = () => { - if (background) { - return background; - } - - if (settings.src) { - return "transparent"; - } - - return randomColor({ seed: colorHash, luminosity: "dark" }); + return background || randomColor({ seed: colorHash, luminosity: "dark" }); }; - const generateAvatarStyle = (): React.CSSProperties => { - return { - backgroundColor: getBackgroundColor(), - width, - height, - textTransform: "uppercase", - }; + const renderContents = () => { + if (src) { + return {title}/; + } + + return children || getLabelFromTitle(title); }; return ( - - {children || getIconString(title)} - + {renderContents()} + ); }