import { forwardRef, type ButtonHTMLAttributes, type HTMLAttributes, type ReactNode } from 'react' type ChipTone = 'neutral' | 'accent' | 'cool' | 'success' | 'warning' | 'error' | 'glow' | 'outline' type ChipSize = 'xs' | 'sm' | 'md' const toneClass: Record = { neutral: 'bg-white/8 text-text-1 border-white/8 hover:bg-white/12', accent: 'bg-accent/15 text-accent border-accent/25 hover:bg-accent/20', cool: 'bg-cool/12 text-cool border-cool/25', success: 'bg-success/12 text-success border-success/25', warning: 'bg-warning/12 text-warning border-warning/25', error: 'bg-error/12 text-error border-error/25', glow: 'bg-gradient-to-r from-accent/20 to-cool/15 text-text-1 border-accent/30 shadow-[0_0_12px_rgba(245,182,66,0.25)]', outline: 'bg-transparent text-text-2 border-border hover:border-border-hover hover:text-text-1', } const sizeClass: Record = { xs: 'h-5 px-1.5 text-[10px] gap-1 rounded', sm: 'h-6 px-2 text-[11px] gap-1.5 rounded-md', md: 'h-7 px-2.5 text-[12px] gap-1.5 rounded-md', } interface ChipBase { tone?: ChipTone size?: ChipSize icon?: ReactNode trailing?: ReactNode active?: boolean } export type ChipProps = ChipBase & HTMLAttributes & { as?: 'span' } export type ChipButtonProps = ChipBase & ButtonHTMLAttributes & { as: 'button' } export const Chip = forwardRef( function Chip(props, ref) { const { tone = 'neutral', size = 'sm', icon, trailing, active, className = '', children, as = 'span', ...rest } = props as ChipBase & { as?: 'span' | 'button' } & Record const baseCls = `inline-flex items-center font-medium tracking-tight border whitespace-nowrap select-none transition-colors duration-150 ${ sizeClass[size] } ${toneClass[active ? 'accent' : tone]} ${className}` if (as === 'button') { return ( ) } return ( )} ref={ref as React.Ref} className={baseCls} > {icon} {children} {trailing} ) }, )