import React from 'react'; import {createComponent} from '@workday/canvas-kit-react/common'; import {CSProps, createStencil, cssVar, handleCsProp, px2rem} from '@workday/canvas-kit-styling'; import {base, system} from '@workday/canvas-tokens-web'; import {AvatarImage} from './AvatarImage'; import {AvatarName} from './AvatarName'; export interface BaseAvatarProps extends CSProps { /** * Children of the BaseAvatar. */ children?: React.ReactNode; /** * The variant of the Avatar. * @default "blue" */ variant?: 'blue' | 'amber' | 'teal' | 'purple' | 'magenta' | 'green'; /** * The size of the Avatar. * `extraExtraSmall` is 24px x 24px * `extraSmall` is 32px x 32px * `small` is 40px x 40px * `medium` is 48px x 48px * `large` is 72px x 72px * `extraLarge` is 96px x 96px * `extraExtraLarge` is 120px x 120px * @default "medium" */ size?: | 'extraExtraSmall' | 'extraSmall' | 'small' | 'medium' | 'large' | 'extraLarge' | 'extraExtraLarge' | (string & {}); } export const baseAvatarStencil = createStencil({ vars: { backgroundColor: '', color: '', size: '', }, base: ({backgroundColor, color, size}) => ({ borderRadius: system.legacy.shape.full, // These are the fallbacks if "size" is not defined width: cssVar(size, system.legacy.size.lg), height: cssVar(size, system.legacy.size.lg), minWidth: cssVar(size, system.legacy.size.lg), minHeight: cssVar(size, system.legacy.size.lg), backgroundColor: cssVar(backgroundColor, base.legacy.blue600), color: cssVar(color, system.color.fg.inverse), display: 'flex', alignItems: 'center', justifyContent: 'center', overflow: 'hidden', border: 'none', // For Windows high contrast desktop themes outline: `${px2rem(1)} solid transparent`, // Remove outline when Avatar is or is inside a button/link — parent owns boundary and focus 'button &, a &, &:is(button, a)': { outline: 'none', }, // Focus-only ring when Avatar is the button/link — avoids clashing with a permanent boundary '&:is(button, a):focus-visible, &:is(button, a).focus': { outline: `${px2rem(2)} solid transparent`, outlineOffset: px2rem(2), }, fontFamily: system.fontFamily.default, fontWeight: system.fontWeight.normal, lineHeight: system.legacy.lineHeight.body.md, fontSize: system.legacy.fontSize.body.md, }), modifiers: { variant: { blue: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.blue600), color: cssVar(color, system.color.fg.inverse), }), amber: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.amber300), color: cssVar(color, base.legacy.amber800), }), teal: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.teal300), color: cssVar(color, base.legacy.teal800), }), purple: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.purple600), color: cssVar(color, system.color.fg.inverse), }), magenta: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.magenta600), color: cssVar(color, system.color.fg.inverse), }), green: ({backgroundColor, color}) => ({ backgroundColor: cssVar(backgroundColor, base.legacy.green600), color: cssVar(color, system.color.fg.inverse), }), }, size: { extraExtraSmall: ({size}) => ({ [size]: system.legacy.size.xs, lineHeight: system.legacy.lineHeight.subtext.sm, fontSize: system.legacy.fontSize.subtext.sm, letterSpacing: system.legacy.letterSpacing.subtext.sm, }), extraSmall: ({size}) => ({ [size]: system.legacy.size.sm, lineHeight: system.legacy.lineHeight.subtext.md, fontSize: system.legacy.fontSize.subtext.md, letterSpacing: system.legacy.letterSpacing.subtext.md, }), small: ({size}) => ({ [size]: system.legacy.size.md, lineHeight: system.legacy.lineHeight.body.sm, fontSize: system.legacy.fontSize.body.sm, letterSpacing: system.legacy.letterSpacing.body.sm, }), medium: ({size}) => ({ [size]: base.legacy.size600, lineHeight: system.legacy.lineHeight.body.md, fontSize: system.legacy.fontSize.body.md, }), large: ({size}) => ({ [size]: base.legacy.size900, fontWeight: system.fontWeight.bold, lineHeight: system.legacy.lineHeight.heading.md, fontSize: system.legacy.fontSize.heading.md, }), extraLarge: ({size}) => ({ [size]: base.legacy.size1200, fontWeight: system.fontWeight.bold, lineHeight: system.legacy.lineHeight.title.sm, fontSize: system.legacy.fontSize.title.sm, }), extraExtraLarge: ({size}) => ({ [size]: px2rem(120), fontWeight: system.fontWeight.bold, lineHeight: system.legacy.lineHeight.title.md, fontSize: system.legacy.fontSize.title.md, }), }, }, }); /** * JSDoc for Avatar. Will be part of the Component API docs */ export const BaseAvatar = createComponent('div')({ displayName: 'BaseAvatar', subComponents: { Image: AvatarImage, Name: AvatarName, }, Component: ({variant, size, ...elemProps}: BaseAvatarProps, ref, Element) => { return ; }, });