import { Icon } from '../design/Icon'; import { CATEGORY_ICON_TOKENS, type CategoryIconToken } from '../design/icons.generated'; import styles from './CategoryIcon.module.css'; /** Colour tokens of SPEC §9.7 (14, `slate` and `amber` by D-054). */ export const COLOR_TOKENS = [ 'green', 'orange', 'brown', 'yellow', 'blue', 'teal', 'purple', 'red', 'pink', 'grey', 'indigo', 'lime', 'slate', 'amber', ] as const; export type ColorToken = (typeof COLOR_TOKENS)[number]; export function isColorToken(value: string): value is ColorToken { return (COLOR_TOKENS as readonly string[]).includes(value); } export function isCategoryIconToken(value: string): value is CategoryIconToken { return (CATEGORY_ICON_TOKENS as readonly string[]).includes(value); } interface Props { /** A §9.7 icon token; an unknown token shows `category`. */ icon: string; /** A §9.7 colour token; an unknown token shows `grey`. */ color: string; /** px; design-spec §3.4 sizes 32 to 64 (40 in ledger rows). */ size?: number; /** Solid: colour fill, on-cat icon. Container: tinted fill, coloured icon (unselected picker tiles, settings rows). */ variant?: 'solid' | 'container'; archived?: boolean; /** Announced name; decorative when omitted (the category name is printed beside it). */ label?: string; className?: string; } /** design-spec §3.4 `CategoryTile`: rounded tile (30 %), filled icon at 52 % of the tile. */ export function CategoryIcon({ icon, color, size = 40, variant = 'solid', archived = false, label, className }: Props) { const token: CategoryIconToken = isCategoryIconToken(icon) ? icon : 'category'; const colour: ColorToken = isColorToken(color) ? color : 'grey'; const style = variant === 'solid' ? { width: size, height: size, backgroundColor: `var(--cat-${colour})`, color: 'var(--on-cat)' } : { width: size, height: size, backgroundColor: `var(--cat-${colour}-container)`, color: `var(--cat-${colour})` }; return ( ); }