import { ComponentPropsWithoutRef, ReactNode } from 'react';
import { IconSize } from '@pantheon-systems/pds-toolkit-react';
import { Icon, IconProps } from '../Icon/Icon';
import './badge.css';
// Stand-in for the v2 `mergeClasses` util, which the published package does
// not export. The port uses the real one.
const mergeClasses = (classes: Array<string | null | undefined>) =>
classes.filter(Boolean).join(' ');
export type BadgeColor =
| 'agentic-filled'
| 'ai-active'
| 'brand'
| 'brand-muted'
| 'critical'
| 'critical-muted'
| 'discovery'
| 'discovery-muted'
| 'gold'
| 'gold-muted'
| 'indigo'
| 'indigo-muted'
| 'info'
| 'info-muted'
| 'ink'
| 'ink-muted'
| 'lime'
| 'lime-muted'
| 'orange'
| 'orange-muted'
| 'rose'
| 'rose-muted'
| 'silver'
| 'silver-muted'
| 'sky'
| 'sky-muted'
| 'slate'
| 'slate-muted'
| 'stone'
| 'stone-muted'
| 'success'
| 'success-muted'
| 'warning'
| 'warning-muted';
export type BadgeSize = 'xs' | 's' | 'm';
/**
* Maps each badge size to the closest-fitting Icon size, so a badge's icon
* never has to be requested directly by consumers.
*/
const iconSizes: Record<BadgeSize, IconSize> = {
xs: 'xs',
s: 'xs',
m: 'm',
};
/**
* Badge component props
*/
export interface BadgeProps extends ComponentPropsWithoutRef<'span'> {
/**
* Additional class names
*/
className?: string;
/**
* Badge color
*/
color: BadgeColor;
/**
* Optional leading icon. Sized to fit the badge's `size` and always
* colored to match the badge's foreground color.
*/
iconName?: IconProps['iconName'];
/**
* Badge text or content.
*/
label: ReactNode;
/**
* Badge size
*/
size?: BadgeSize;
}
/**
* Badge UI component
*/
export const Badge = ({
className,
color = 'brand-muted',
iconName,
label,
size = 's',
...props
}: BadgeProps) => {
const baseClass = 'pds-badge';
const colorClass = `${baseClass}--${color}`;
const sizeClass = `${baseClass}--${size}`;
return (
<span
className={mergeClasses([
baseClass,
colorClass,
sizeClass,
className ?? '',
])}
{...props}
>
{iconName && (
<Icon
className={`${baseClass}__icon`}
iconName={iconName}
size={iconSizes[size]}
/>
)}
<span className={`${baseClass}__label`}>{label}</span>
</span>
);
};
Badge
A copy of the PDS v2 Badge (pds-badge, same class names, props and CSS) with one addition: color='agentic-filled', the AI gradient as the fill, for denoting an agentic category.
Extends a PDS componentOpen in Storybook