gridcn
exampledata-grid-cell-types-demosource: ok · hit
Data Grid Cell Types Demo
Every built-in cell type in one grid, plus a read-only column, a validate rule, and a custom renderCell override.
npx shadcn add "https://gridcn.vercel.app/r/data-grid-cell-types-demo.json"free
No selection tags yet — empty means no evidence, not lack of support.
Dependencies
Bundle weight · lightRegistry dependencies
DammersCode/gridcn/data-grid
Files2 · source cached 10/14/2026, 8:01:59 AM
registry/default/examples/data-grid-cell-types-demo.tsx
"use client";
import { useMemo, type ReactNode } from "react";
import {
DataGrid,
defineColumns,
type CellRenderProps,
} from "@/registry/default/components/data-grid/data-grid";
import { generateDemoRows, type DemoRow } from "./demo-data";
const columns = defineColumns<DemoRow>()([
{ id: "name", header: "Text", accessorKey: "name", type: "text", width: 55, flex: 1 },
{
id: "email",
header: "Read-only",
accessorKey: "email",
type: "text",
readOnly: true,
width: 60,
flex: 1,
},
{
id: "age",
header: "Validated",
accessorKey: "age",
type: "number",
options: { min: 18, max: 100 },
validate: (value: unknown) => (typeof value === "number" && value < 18 ? "Must be 18 or older" : null),
width: 55,
flex: 1,
},
{ id: "active", header: "Checkbox", accessorKey: "active", type: "checkbox", width: 50, flex: 1 },
{
id: "role",
header: "Select",
accessorKey: "role",
type: "select",
options: {
choices: [
{ value: "Admin", label: "Admin" },
{ value: "User", label: "User" },
{ value: "Editor", label: "Editor" },
{ value: "Viewer", label: "Viewer" },
{ value: "Manager", label: "Manager" },
],
},
width: 55,
flex: 1,
},
{
id: "joined",
header: "Date",
accessorKey: "joined",
type: "date",
options: { displayFormat: { year: "numeric", month: "short", day: "numeric" } },
width: 55,
flex: 1,
},
{
id: "score",
header: "renderCell",
accessorKey: "score",
type: "number",
options: { min: 0, max: 100 },
// Display override: same number type/pipeline (edit/paste/sort unchanged), custom rendering only.
renderCell: ({ value }: CellRenderProps<DemoRow, number | null>) => (
<div className="flex h-full items-center gap-2 px-2 tabular-nums">
<div className="h-1.5 flex-1 overflow-hidden bg-muted">
<div className="h-full bg-primary" style={{ width: `${value ?? 0}%` }} />
</div>
<span className="text-xs text-muted-foreground">{value}</span>
</div>
),
width: 60,
flex: 1,
},
] as const);
/**
* Every built-in cell type in one grid, plus a read-only column, a `validate` rule (Age rejects
* under-18 edits), and a `renderCell` override on Score that keeps the number type's edit/sort/
* clipboard pipeline but renders a progress bar instead of plain text.
*/
export default function DataGridCellTypesDemo(): ReactNode {
const rows = useMemo(() => generateDemoRows(8), []);
return (
<div className="w-full flex flex-col gap-3">
<p className="text-sm text-muted-foreground">
Try each column's editor: Text is plain, Read-only refuses edits, Validated rejects an age
under 18 and keeps the editor open with a message under the cell, and renderCell shows a
progress bar over the same number type.
</p>
<div className="h-[360px] overflow-hidden rounded-md border border-border">
<DataGrid
defaultData={rows}
columns={columns}
getRowId={(row) => row.id}
className="h-full rounded-none border-none"
/>
</div>
</div>
);
}
registry/default/examples/demo-data.ts
/** Deterministic LCG so SSR/CSR markup match without Math.random(); shared across example rows. */
function createSeededLcg(seed: number) {
let state = seed;
return () => {
state = (state * 1103515245 + 12345) & 0x7fffffff;
return state / 0x7fffffff;
};
}
export type DemoRow = {
id: string;
name: string;
email: string;
age: number;
active: boolean;
role: string;
joined: string;
score: number;
};
const ROLES = ["Admin", "User", "Editor", "Viewer", "Manager"] as const;
const ADJECTIVES = ["Eager", "Quick", "Silent", "Bold", "Swift"] as const;
const NOUNS = ["Eagle", "Lion", "Tiger", "Bear", "Wolf"] as const;
/** Generates `count` deterministic demo rows for example previews (seed 42, stable across renders). */
export function generateDemoRows(count: number, seed = 42): DemoRow[] {
const next = createSeededLcg(seed);
const rows: DemoRow[] = [];
for (let i = 0; i < count; i++) {
rows.push({
id: `row-${i}`,
name: `${ADJECTIVES[Math.floor(next() * ADJECTIVES.length)]} ${NOUNS[Math.floor(next() * NOUNS.length)]}`,
email: `user${i}@example.com`,
age: Math.floor(next() * 50) + 18,
active: next() > 0.5,
role: ROLES[Math.floor(next() * ROLES.length)]!, // ROLES is a fixed non-empty literal array
joined: `${2020 + Math.floor(next() * 5)}-${String(Math.floor(next() * 12) + 1).padStart(2, "0")}-${String(Math.floor(next() * 28) + 1).padStart(2, "0")}`,
score: Math.floor(next() * 100),
});
}
return rows;
}