Replace legacy hardcoded border-kodo-steel (RGB 59,69,84, theme-unaware) with semantic border-border token across 86 user-facing components. Covers UI primitives (checkbox, badge, modal, table, textarea, alert, radio-group, avatar), all modals, settings views, social features, playlist views, inventory, chat, commerce, and cloud file browser. Only story/test files retain the legacy token. Co-authored-by: Cursor <cursoragent@cursor.com>
173 lines
4.1 KiB
TypeScript
173 lines
4.1 KiB
TypeScript
import * as React from 'react';
|
|
import { cn } from '@/lib/utils';
|
|
|
|
/**
|
|
* BadgeProps - Propriétés du composant Badge
|
|
*
|
|
* @interface BadgeProps
|
|
* @extends React.HTMLAttributes<HTMLSpanElement>
|
|
*/
|
|
export interface BadgeProps extends React.HTMLAttributes<HTMLSpanElement> {
|
|
/**
|
|
* Texte du badge (alternative à children)
|
|
*/
|
|
label?: string;
|
|
|
|
/**
|
|
* Variant de couleur du badge
|
|
*
|
|
* - `cyan`: Cyan (par défaut)
|
|
* - `magenta`: Magenta
|
|
* - `lime`: Lime (vert)
|
|
* - `gold`: Or
|
|
* - `terminal`: Style terminal (monospace)
|
|
* - `default`, `primary`: Alias pour cyan
|
|
* - `success`: Alias pour lime
|
|
* - `warning`: Alias pour gold
|
|
* - `error`: Alias pour magenta
|
|
* - `secondary`: Alias pour magenta
|
|
*
|
|
* @default 'cyan'
|
|
*/
|
|
variant?:
|
|
| 'cyan'
|
|
| 'magenta'
|
|
| 'lime'
|
|
| 'gold'
|
|
| 'terminal'
|
|
| 'default'
|
|
| 'primary'
|
|
| 'success'
|
|
| 'warning'
|
|
| 'error'
|
|
| 'secondary';
|
|
|
|
/**
|
|
* Icône à afficher dans le badge
|
|
*/
|
|
icon?: React.ReactNode;
|
|
|
|
/**
|
|
* Taille du badge
|
|
*
|
|
* - `sm`: Petit (px-2 py-0.5 text-[10px])
|
|
* - `md`: Moyen (px-2.5 py-0.5 text-[10px]) - par défaut
|
|
* - `lg`: Grand (px-4 py-1 text-xs)
|
|
*
|
|
* @default 'md'
|
|
*/
|
|
size?: 'sm' | 'md' | 'lg';
|
|
|
|
/**
|
|
* Si `true`, affiche un point au lieu du texte
|
|
*
|
|
* @default false
|
|
*/
|
|
dot?: boolean;
|
|
|
|
/**
|
|
* Nombre à afficher dans le badge (pour notifications, etc.)
|
|
* Si fourni et > 0, affiche le nombre dans un badge secondaire
|
|
*/
|
|
count?: number;
|
|
|
|
/**
|
|
* Contenu du badge (alternative à label)
|
|
*/
|
|
children?: React.ReactNode;
|
|
}
|
|
|
|
/**
|
|
* Badge - Composant de badge avec design system Kodo
|
|
*
|
|
* Composant de badge pour afficher des labels, statuts ou compteurs.
|
|
* Supporte plusieurs variants de couleur, tailles et options d'affichage.
|
|
*
|
|
* @example
|
|
* ```tsx
|
|
* // Badge simple
|
|
* <Badge label="Nouveau" />
|
|
*
|
|
* // Badge avec variant
|
|
* <Badge variant="success">Actif</Badge>
|
|
*
|
|
* // Badge avec icône
|
|
* <Badge icon={<Star />} label="Premium" />
|
|
*
|
|
* // Badge avec compteur
|
|
* <Badge count={5}>Notifications</Badge>
|
|
* ```
|
|
*
|
|
* @component
|
|
* @param {BadgeProps} props - Propriétés du composant
|
|
* @returns {JSX.Element} Élément span stylisé comme un badge
|
|
*/
|
|
export const Badge = React.forwardRef<HTMLSpanElement, BadgeProps>(
|
|
(
|
|
{
|
|
label,
|
|
variant = 'cyan',
|
|
icon,
|
|
size = 'md',
|
|
dot,
|
|
count,
|
|
children,
|
|
className,
|
|
...props
|
|
},
|
|
ref,
|
|
) => {
|
|
// Map compatibility variants to Kodo variants
|
|
const variantMap: Record<string, string> = {
|
|
default: 'cyan',
|
|
primary: 'cyan',
|
|
success: 'lime',
|
|
warning: 'gold',
|
|
error: 'magenta',
|
|
secondary: 'magenta',
|
|
};
|
|
|
|
const actualVariant = variantMap[variant] || variant;
|
|
|
|
const styles: Record<string, string> = {
|
|
cyan: 'bg-kodo-steel/10 text-kodo-steel border-border/30',
|
|
magenta: 'bg-kodo-magenta/10 text-kodo-magenta border-kodo-magenta/30',
|
|
lime: 'bg-kodo-lime/10 text-kodo-lime border-kodo-lime/30',
|
|
gold: 'bg-kodo-gold/10 text-kodo-gold border-kodo-gold/30',
|
|
terminal:
|
|
'bg-kodo-terminal/10 text-kodo-terminal border-kodo-terminal/30 font-mono',
|
|
};
|
|
|
|
const sizeStyles = {
|
|
sm: 'px-2 py-0.5 text-xs',
|
|
md: 'px-2.5 py-0.5 text-xs',
|
|
lg: 'px-4 py-1 text-xs',
|
|
};
|
|
|
|
const displayText = label || children;
|
|
const badgeVariant = actualVariant as keyof typeof styles;
|
|
|
|
return (
|
|
<span
|
|
ref={ref}
|
|
className={cn(
|
|
'inline-flex items-center gap-1.5 rounded-full font-bold uppercase tracking-widest border',
|
|
styles[badgeVariant] || styles.cyan,
|
|
sizeStyles[size],
|
|
className,
|
|
)}
|
|
{...props}
|
|
>
|
|
{dot && <span className="w-3 h-3 rounded-full bg-current" />}
|
|
{icon && <span className="w-3 h-3">{icon}</span>}
|
|
{displayText}
|
|
{count !== undefined && count > 0 && (
|
|
<span className="ml-1 px-1.5 py-0.5 rounded-full bg-current/20 text-xs">
|
|
{count}
|
|
</span>
|
|
)}
|
|
</span>
|
|
);
|
|
},
|
|
);
|
|
Badge.displayName = 'Badge';
|