import {Property} from 'csstype'; import React from 'react'; import {createComponent} from '@workday/canvas-kit-react/common'; import {createStencil, handleCsProp} from '@workday/canvas-kit-styling'; import {system} from '@workday/canvas-tokens-web'; import {AvatarNameProps} from './AvatarName'; import {BaseAvatar, BaseAvatarProps, baseAvatarStencil} from './BaseAvatar'; export interface AvatarProps extends BaseAvatarProps, AvatarNameProps { /** * The URL of the user's photo. For best fit, use square images. */ url?: string; /** * An objectFit property that can customize how to resize your image to fit its container. * @default "contain" */ objectFit?: Property.ObjectFit; /** * If true, hides the image and fallback initials from assistive technology. This is useful when * the Avatar is purely decorative and is rendered next to a name or text. * @default false */ isDecorative?: boolean; } export const avatarStencil = createStencil({ extends: baseAvatarStencil, parts: { avatarImage: 'avatar-image', avatarName: 'avatar-name', }, base: {}, modifiers: { imageLoaded: { false: ({avatarImagePart}) => ({ [avatarImagePart]: { display: 'none', }, }), true: { backgroundColor: system.color.bg.default, }, }, objectFit: { contain: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'contain', }, }), cover: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'cover', }, }), fill: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'fill', }, }), none: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'none', }, }), ['scale-down']: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'scale-down', }, }), initial: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'initial', }, }), inherit: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'inherit', }, }), unset: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'unset', }, }), ['-moz-initial']: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: '-moz-initial', }, }), ['revert']: ({avatarImagePart}) => ({ [avatarImagePart]: { objectFit: 'revert', }, }), }, }, }); /** * JSDoc for Avatar. Will be part of the Component API docs */ export const Avatar = createComponent('div')({ displayName: 'Avatar', Component: ( { url, name, variant, objectFit = 'contain', preferredInitials, isDecorative, size, ...elemProps }: AvatarProps, ref, Element ) => { const [imageLoaded, setImageLoaded] = React.useState(false); const handleImageLoad = () => { if (!imageLoaded) { setImageLoaded(true); } }; return ( {url && ( <> )} {name && (!url || !imageLoaded) && ( )} ); }, });