import React from 'react'; import classNames from 'classnames'; import { StatusIndicator as CoreStatusIndicator, type StatusIndicatorEmphasis, type StatusIndicatorSize, type StatusIndicatorStateName, type StatusIndicatorVariant, } from '@shoptet/ui-core-web'; import type { SafeOmit } from '@shoptet/utils'; import { iconGlyphChar } from '../Icon/iconGlyphChar'; import { IconName } from '../Icon/IconName'; import { Tooltip } from '../Tooltip/Tooltip'; import { StatusIndicatorShape } from './StatusIndicatorShape'; export type StatusIndicatorState = StatusIndicatorStateName; const STATE_CLASS: Record = { critical: 'status-indicator--critical', warning: 'status-indicator--warning', positive: 'status-indicator--positive', informative: 'status-indicator--informative', notice: 'status-indicator--notice', neutral: 'status-indicator--neutral', }; const SIZE_CLASS: Record = { small: 'status-indicator--small', medium: 'status-indicator--medium', }; const VARIANT_CLASS: Record = { full: 'status-indicator--full', outlined: 'status-indicator--outlined', }; /** Default glyph per intent when `symbol` is `true`. Exported for the PHP-renderer contract test. */ export const DEFAULT_SYMBOL: Record = { critical: IconName.SHP_CRITICAL_STATUS_SYMBOL, warning: IconName.SHP_CRITICAL_STATUS_SYMBOL, positive: IconName.SHP_SUCCESS_STATUS_SYMBOL, informative: IconName.SHP_INFORMATIVE_STATUS_SYMBOL, notice: IconName.SHP_INFORMATIVE_STATUS_SYMBOL, neutral: IconName.SHP_INFORMATIVE_STATUS_SYMBOL, }; export interface StatusIndicatorProps extends SafeOmit< React.ComponentProps<'span'>, 'children' | 'className' | 'style' | 'aria-label' | 'aria-hidden' | 'role' > { /** Semantic intent. Drives shape, colour, and default symbol. */ state: StatusIndicatorStateName; /** @default 'small' */ size?: StatusIndicatorSize; /** * `medium` fills the shape with the intent colour; `low` draws it as an outline over a white fill. * @default 'medium' */ emphasis?: StatusIndicatorEmphasis; /** * `true` (default) shows the intent's default glyph; `false` shows the shape only; * an `IconName` shows a custom glyph. * @default true */ symbol?: boolean | IconName; /** Text label naming the status. Rendered after the shape unless `labelHidden`. */ label: React.ReactNode; /** * Hide the label visually while keeping it readable by assistive tech. * @default false */ labelHidden?: boolean; /** Optional tooltip content. Makes the whole indicator the trigger, read as its description. */ tooltip?: React.ReactNode; } export const StatusIndicator: React.FC = ({ state, size = 'small', emphasis = 'medium', symbol = true, label, labelHidden = false, tooltip, ...rest }) => { const iconName: IconName | undefined = symbol === false ? undefined : symbol === true ? DEFAULT_SYMBOL[state] : symbol; const symbolChar = iconName === undefined ? undefined : iconGlyphChar(iconName); const variant = emphasis === 'low' ? 'outlined' : 'full'; const indicator = ( {label} ); return tooltip === undefined ? indicator : {indicator}; };