Skip to content

Instantly share code, notes, and snippets.

@SilentImp
Created November 16, 2020 13:52
Show Gist options
  • Save SilentImp/4376e818b32390a92c754706b5aa2e3a to your computer and use it in GitHub Desktop.
Save SilentImp/4376e818b32390a92c754706b5aa2e3a to your computer and use it in GitHub Desktop.
import styled from "@emotion/styled";
import { AvatarProps, UserTypes } from "./Avatar";
interface StyledAvatarProps extends AvatarProps {
width: number;
height: number;
isComplete: boolean;
}
export default styled.img`
contain: strict;
${({ width, height }: StyledAvatarProps) => {
return `
width: ${width}px;
height: ${height}px;
`;
}}
aspect-ratio: 1 / 1;
aspect-ratio: attr(width) / attr(height);
box-sizing: border-box;
overflow: hidden;
display: block;
position: relative;
color: var(--ds-colors-white);
padding-left: 0;
border-radius: 100%;
-moz-force-broken-image-icon: 0;
background-image: url("data:image/svg+xml,%3Csvg width='42' height='48' viewBox='0 0 42 48' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21 25.5C17.5312 25.5 14.25 22.875 13.5938 19.5H9.09375C9.84375 25.5 14.8125 30 21 30C27.0938 30 32.0625 25.5 32.8125 19.5H28.3125C27.6562 22.875 24.375 25.5 21 25.5ZM29.3438 33C26.625 33 25.4062 34.5 21 34.5C16.5 34.5 15.2812 33 12.5625 33C5.625 33 0 38.7188 0 45.6562C0 46.9688 1.03125 48 2.34375 48H39.5625C40.875 48 42 46.9688 42 45.6562C42 38.7188 36.2812 33 29.3438 33ZM4.6875 43.5C5.625 40.2188 9.09375 37.5938 12.5625 37.5C13.875 37.5 16.125 39 21 39C25.7812 39 28.0312 37.5 29.3438 37.5C32.8125 37.5938 36.2812 40.2188 37.2188 43.5H4.6875ZM8.25 16.5H33.75C34.125 16.5 34.5 16.2188 34.5 15.75V12.75C34.5 12.375 34.125 12 33.75 12H33C33 7.6875 30.2812 4.03125 26.5312 2.4375L24 7.5V1.5C24 0.75 23.25 0 22.5 0H19.5C18.6562 0 18 0.75 18 1.5V7.5L15.375 2.4375C11.625 4.03125 9 7.6875 9 12H8.25C7.78125 12 7.5 12.375 7.5 12.75V15.75C7.5 16.2188 7.78125 16.5 8.25 16.5Z' fill='white'/%3E%3C/svg%3E");
${({ isComplete, width }: StyledAvatarProps) =>
!isComplete
? `
padding-left: ${width}px;
background-size: auto 50%;
`
: "background-size: cover;"}
background-color: ${({ type }: StyledAvatarProps) =>
type === UserTypes.CONSUMER
? "var(--ds-colors-violet60)"
: "var(--ds-colors-blue60)"};
background-repeat: no-repeat;
background-position: 50%;
`;
import React from "react";
import { render, act } from "@testing-library/react";
import * as suits from "../../helpers/tests/suits";
import Avatar from "./Avatar";
const img =
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAL0lEQVQImWP44mz2/4uz2f";
const renderComponent = (props = {}) => {
let dom;
act(() => {
dom = render(<Avatar {...props} />);
});
return {
...dom,
root: dom.container.firstChild as HTMLElement,
};
};
describe("Render", () => {
test("should show image when they loaded", () => {
const { root } = renderComponent({
src: img,
});
const styles = window.getComputedStyle(root);
const paddingLeft = styles.getPropertyValue("padding-left");
console.log("complete: ", root.complete); // false
expect(paddingLeft).toBe("0"); // 32px
});
});
import React, { useState, useCallback } from "react";
import StyledAvatar from "./Avatar.styled";
export enum UserTypes {
SERVICE_PRO = "SERVICE_PRO" as any,
CONSUMER = "CONSUMER" as any,
ADMIN = "ADMIN" as any,
SYSTEM = "SYSTEM" as any,
UNAUTHENTICATED = "UNAUTHENTICATED" as any,
}
export enum AvatarSizes {
s = "s" as any,
m = "m" as any,
l = "l" as any,
}
export const Sizes = {
s: 32,
m: 56,
l: 96,
} as Record<string, number>;
export interface AvatarProps {
alt: string;
type?: UserTypes;
size?: AvatarSizes;
src?: string;
srcSet?: string;
className?: string;
rest?: Record<string, unknown>;
}
const Avatar = React.forwardRef<HTMLImageElement, AvatarProps>(
(
{
size = AvatarSizes.s,
alt,
src,
srcSet,
type = UserTypes.SERVICE_PRO,
...rest
},
ref
): React.ReactElement => {
const [isComplete, setIsComplete] = useState(false);
const onLoad = useCallback(() => {
setIsComplete(true);
}, [setIsComplete]);
return (
<StyledAvatar
width={Sizes[size]}
height={Sizes[size]}
decoding="async"
loading="lazy"
alt={alt}
{...(src && { src })}
{...(srcSet && { srcSet })}
type={type}
onLoad={onLoad}
isComplete={isComplete}
ref={ref}
{...rest}
/>
);
}
);
Avatar.displayName = "Avatar";
export default Avatar;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment