feat(viz): bit display primitive
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
'use client';
|
||||
|
||||
import { motion } from 'framer-motion';
|
||||
import { cn } from '@/lib/utils';
|
||||
import type { BitState } from '@/lib/visualizations/types';
|
||||
|
||||
interface BitDisplayProps {
|
||||
bit: BitState;
|
||||
bitWidth?: number;
|
||||
showLabel?: boolean;
|
||||
showDecimal?: boolean;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const STATE_CLASSES = {
|
||||
normal: 'bg-[var(--muted)] border-[var(--border)] text-[var(--foreground)]',
|
||||
highlighted: 'bg-[var(--primary)]/20 border-[var(--primary)] text-[var(--primary)]',
|
||||
comparing: 'bg-amber-500/20 border-amber-500 text-amber-500 shadow-[0_0_8px_rgba(245,158,11,0.4)]',
|
||||
result: 'bg-green-500/20 border-green-500 text-green-500',
|
||||
cancelled: 'bg-[var(--muted)]/30 border-[var(--border)]/50 text-[var(--muted-foreground)] opacity-40',
|
||||
} as const;
|
||||
|
||||
export function BitDisplay({
|
||||
bit,
|
||||
bitWidth = 8,
|
||||
showLabel = true,
|
||||
showDecimal = true,
|
||||
className,
|
||||
}: BitDisplayProps) {
|
||||
// Pad the bits string to the desired width
|
||||
const paddedBits = bit.bits.padStart(bitWidth, '0');
|
||||
|
||||
return (
|
||||
<div className={cn('flex flex-col items-center gap-1', className)}>
|
||||
{/* Label (e.g., "result", "num") */}
|
||||
{showLabel && bit.label && (
|
||||
<span className="text-xs font-medium text-[var(--muted-foreground)]">
|
||||
{bit.label}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Decimal value display */}
|
||||
{showDecimal && (
|
||||
<span
|
||||
className={cn(
|
||||
'text-sm font-mono font-medium mb-1',
|
||||
bit.state === 'cancelled'
|
||||
? 'text-[var(--muted-foreground)] line-through opacity-50'
|
||||
: 'text-[var(--foreground)]'
|
||||
)}
|
||||
>
|
||||
{bit.value}
|
||||
</span>
|
||||
)}
|
||||
|
||||
{/* Binary representation - individual bit cells */}
|
||||
<motion.div
|
||||
layout
|
||||
initial={false}
|
||||
animate={{
|
||||
scale: bit.state === 'highlighted' || bit.state === 'comparing' ? 1.02 : 1,
|
||||
}}
|
||||
transition={{ duration: 0.2 }}
|
||||
className={cn(
|
||||
'flex items-center rounded-lg border-2 overflow-hidden',
|
||||
STATE_CLASSES[bit.state]
|
||||
)}
|
||||
>
|
||||
{paddedBits.split('').map((bitChar, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={cn(
|
||||
'w-6 h-8 flex items-center justify-center font-mono text-sm font-medium',
|
||||
index > 0 && 'border-l border-[var(--border)]/30',
|
||||
bit.state === 'cancelled' && 'line-through'
|
||||
)}
|
||||
>
|
||||
{bitChar}
|
||||
</div>
|
||||
))}
|
||||
</motion.div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user