Componentdata0.82 KB gzipZero dependencies
Spreadsheet Lite
Editable mini cell grid.
Preview
Live Preview
Installation
Tokens guide →Add to your project via CLI (zero dependencies, code you own):
npx bigbullui add spreadsheet-liteOr install the full npm package:
npm install bigbulluiUsage
Open in StackBlitzimport { SpreadsheetLite } from "@/components/ui/spreadsheet-lite";
<SpreadsheetLite />Usage guidance
Use Spreadsheet Lite when a ticket stub surface needs Editable mini cell grid. Keep props minimal and prefer composition with sibling stubs.
Avoid Spreadsheet Lite for long form flows or dense data grids where a dedicated layout block fits better.
Source code
spreadsheet-lite.tsxZero dependencies (only React + utils). Copy and paste directly into your project:
"use client";
import * as React from "react";
import { cn } from "./lib/utils";
export interface SpreadsheetLiteProps extends React.HTMLAttributes<HTMLDivElement> {
rows?: number;
cols?: number;
}
/** Spreadsheet lite: editable mini grid with active cell ring. */
export function SpreadsheetLite({ rows = 4, cols = 4, className, ...props }: SpreadsheetLiteProps) {
const [cells, setCells] = React.useState<string[][]>(() =>
Array.from({ length: rows }, (_, r) => Array.from({ length: cols }, (_, c) => (r === 0 ? `Seat ${c + 1}` : "")))
);
const [active, setActive] = React.useState<[number, number] | null>(null);
return (
<div className={cn("w-full max-w-md overflow-auto rounded-lg border-2 border-foreground bg-card p-2", className)} {...props}>
<table className="w-full border-collapse">
<tbody>
{cells.map((row, r) => (
<tr key={r}>
{row.map((val, c) => (
<td key={c} className="border border-dashed border-border p-0.5">
<input
value={val}
onChange={(e) =>
setCells((prev) => prev.map((pr, ri) => (ri === r ? pr.map((pc, ci) => (ci === c ? e.target.value : pc)) : pr)))
}
onFocus={() => setActive([r, c])}
onBlur={() => setActive(null)}
aria-label={`Cell row ${r + 1} column ${c + 1}`}
className={cn(
"w-full rounded-sm bg-transparent px-1.5 py-1 font-mono text-xs focus-visible:outline-none",
active?.[0] === r && active?.[1] === c && "bg-accent/10 ring-2 ring-inset ring-ring"
)}
/>
</td>
))}
</tr>
))}
</tbody>
</table>
</div>
);
}