Bit Row

A row of equal-size bit cells (0 / 1) — the foundational primitive for any bitwise-operation visualization. Each cell shows a binary digit in a monospace font; per-bit tones model the four states most bit-manipulation algorithms touch (default, highlight, visited, dimmed); labels below each cell can show the bit index or the place value (2^k).

Customize
Value
172
8b
Display
place

Installation

npx shadcn@latest add https://craftbits.dev/r/bit-row.json

Usage

import { BitRow } from "@craft-bits/core";
 
<BitRow value={0b1010_1100} bits={8} labels="place" />

Highlight a single bit that "just flipped":

<BitRow
  value={0b0110_1001}
  bits={8}
  labels="index"
  tones={["default", "default", "default", "highlight", "default", "default", "default", "default"]}
/>

Understanding the component

  1. Three value shapes. value accepts a number (up to 32 bits via unsigned coercion), a bigint (arbitrary precision, low bits bits read), or a string of 0/1 digits with an optional 0b prefix. Strings preserve their literal width when bits is omitted.
  2. Width inference. When bits is omitted, the row sizes itself to the value's natural width — string length for strings, ⌊log₂(n)⌋ + 1 for non-zero numbers. Pass bits explicitly when you want a fixed-width display.
  3. Direction. direction="msb-first" (the default) reads the row left-to-right like a binary literal. direction="lsb-first" flips the row so the LSB sits on the left — useful when the visualization tracks bit indices that "grow" rightward.
  4. Tones are per display cell. tones[0] is the leftmost cell, regardless of direction. highlight paints an accent fill ("this bit matters here"), visited paints a success tint ("this bit just flipped"), dimmed drops the column to 30% opacity, and default lets 1-cells pick up a subtle accent border so the row reads as a binary value at a glance.
  5. Labels. labels="index" shows 0..n-1 beneath each cell (lowest index always = LSB regardless of direction). labels="place" shows the place value 2^k. labels="none" (the default) leaves the cells unlabelled.
  6. Responsive width. Cell width uses clamp(24px, …, 36px) so the row shrinks gracefully on narrow viewports and never breaks below the legibility floor.
  7. Reduced motion. When prefers-reduced-motion: reduce is set, the cell colour transition collapses to duration: 0 — tone changes snap instead of springing.

Props

PropTypeDefaultDescription
valuenumber | bigint | stringrequiredBinary value. number is read via unsigned 32-bit coercion; bigint is arbitrary precision; string is a 0/1 literal with optional "0b" prefix.
bitsnumberinferredNumber of cells to render. Defaults to the value's natural width.
direction"msb-first" | "lsb-first""msb-first"Bit order on the page.
tonesreadonly BitTone[][]Per-display-cell tone: default | highlight | visited | dimmed.
labels"index" | "place" | "none""none"What appears beneath each cell.
classNamestringMerged onto the outer <div>.

Accessibility

  • The outer element is role="group" with an aria-label announcing the binary value (Binary value: 0b10101100).
  • Each cell carries role="img" and an aria-label like "Bit 3: 0 (place value 2^3)" so a screen-reader user can read the row bit-by-bit.
  • Each cell exposes data-state (the tone) and data-bit (0/1) so consumer apps can hook custom styles or assistive tooling.
  • Colour is never the only signal — every cell renders its digit, and tones layer on a ring plus a fill so highlighted cells stay legible for colourblind users.
  • The tone-change colour transition respects prefers-reduced-motion: reduce and collapses to an instant swap when the user opts out.

Credits

  • Extracted from: algoflashcards (src/lessons/primitives/viz/BitRow.tsx). The library version drops the original's clickable rocker-switch interaction surface (consumers wire their own toggle behaviour around the read-only render), folds the multi-state palette into the four-tone semantic set used across DSA-viz siblings, and accepts bigint / binary-string inputs so visualisations beyond 32 bits work without a code change.