Files
goodgo-platform/apps/web/components/design-system/signal.tsx
Ho Ngoc Hai 7d6fcb4d8d feat(web): design tokens, Tailwind config, base components (TEC-3057)
- Add chart palette, motion, and z-index CSS vars to globals.css
- Replace custom theme-provider with next-themes (dark default)
- Extend tailwind.config.ts with heading fonts, spacing (row-compact,
  row-roomy, sidebar), chart colors, elevation shadows, glow shadows,
  transition timing, pill border-radius, z-index scale
- Update tick-flash animations to match design token spec (480ms)
- Add prefers-reduced-motion support for all animations
- Create base design-system components:
  Surface, SurfaceElevated, Divider, DensityProvider/useDensity,
  Numeric (VND/percent/compact formatting), Signal (up/down/neutral pill)
- Add dev-only /dev/tokens showcase route (404 in production)
- Update theme-provider tests to match next-themes integration

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-04-21 03:19:40 +07:00

47 lines
1.2 KiB
TypeScript

import { ArrowDown, ArrowUp, Minus } from 'lucide-react';
import { cn } from '@/lib/utils';
export type SignalDirection = 'up' | 'down' | 'neutral';
export interface SignalProps {
/** Direction of the signal. */
direction: SignalDirection;
/** Text label shown inside the pill. */
label?: string;
/** Additional class names. */
className?: string;
}
const directionStyles: Record<SignalDirection, string> = {
up: 'bg-signal-up/10 text-signal-up',
down: 'bg-signal-down/10 text-signal-down',
neutral: 'bg-signal-neutral/10 text-signal-neutral',
};
const icons: Record<SignalDirection, React.ElementType> = {
up: ArrowUp,
down: ArrowDown,
neutral: Minus,
};
/**
* Signal pill — shows direction (up/down/neutral) with arrow icon and optional label.
* Uses `--signal-*` design tokens.
*/
export function Signal({ direction, label, className }: SignalProps) {
const Icon = icons[direction];
return (
<span
className={cn(
'inline-flex items-center gap-1 rounded-pill px-2 py-0.5 text-xs font-medium',
directionStyles[direction],
className,
)}
>
<Icon className="h-3 w-3" aria-hidden="true" />
{label && <span>{label}</span>}
</span>
);
}