import { Info, Alert, Cross, Check, ClockBorderless } from '@transferwise/icons'; import { clsx } from 'clsx'; import { useIntl } from 'react-intl'; import { SizeSmall, SizeMedium, SizeLarge, Sentiment, Size, Breakpoint, Status } from '../common'; import Circle, { CircleProps } from '../common/circle'; import { useMedia } from '../common/hooks/useMedia'; import messages from './StatusIcon.messages'; /** * @deprecated Use `16 | 24 | 32 | 40 | 48 | 56 | 72` instead. */ type LegacySizes = SizeSmall | SizeMedium | SizeLarge; export type StatusIconSentiment = Sentiment | Status.PENDING; export type StatusIconProps = { id?: string; /** @default 'neutral' */ sentiment?: `${StatusIconSentiment}`; /** @default 40 */ size?: LegacySizes | 16 | 24 | 32 | 40 | 48 | 56 | 72; /** * Override for the sentiment's-derived, default, accessible * name announced by the screen readers.
* Using `null` will render the icon purely presentational. * */ iconLabel?: string | null; }; const mapLegacySize = { [String(Size.SMALL)]: 16, [String(Size.MEDIUM)]: 40, [String(Size.LARGE)]: 48, } satisfies Record; const StatusIcon = ({ id, sentiment = 'neutral', size: sizeProp = 40, iconLabel, }: StatusIconProps) => { const intl = useIntl(); const iconMetaBySentiment: Record< `${Sentiment}` | Status.PENDING, { Icon: React.ElementType; defaultIconLabel: string; } > = { [Sentiment.NEGATIVE]: { Icon: Cross, defaultIconLabel: intl.formatMessage(messages.errorLabel), }, [Sentiment.POSITIVE]: { Icon: Check, defaultIconLabel: intl.formatMessage(messages.successLabel), }, [Sentiment.WARNING]: { Icon: Alert, defaultIconLabel: intl.formatMessage(messages.warningLabel), }, [Status.PENDING]: { Icon: ClockBorderless, defaultIconLabel: intl.formatMessage(messages.pendingLabel), }, [Sentiment.NEUTRAL]: { Icon: Info, defaultIconLabel: intl.formatMessage(messages.informationLabel), }, // deprecated [Sentiment.ERROR]: { Icon: Cross, defaultIconLabel: intl.formatMessage(messages.errorLabel), }, [Sentiment.INFO]: { Icon: Info, defaultIconLabel: intl.formatMessage(messages.informationLabel), }, [Sentiment.SUCCESS]: { Icon: Check, defaultIconLabel: intl.formatMessage(messages.successLabel), }, }; const { Icon, defaultIconLabel } = iconMetaBySentiment[sentiment]; const isTinyViewport = useMedia(`(max-width: ${Breakpoint.ZOOM_400}px)`); const size = mapLegacySize[sizeProp] ?? sizeProp; return ( ); }; export default StatusIcon;