- 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>
47 lines
1.2 KiB
TypeScript
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>
|
|
);
|
|
}
|