Pre-built cell components for common use cases.
The ActiveGrid provides pre-built cell components for common use cases. These components handle formatting, styling, and interactions consistently across your grids.
import { TextCell, BadgeCell, DateCell, LinkCell } from '@workspace/active-grid';Simple text display with truncation support.
import { TextCell } from '@workspace/active-grid';
{
accessorKey: 'description',
header: 'Description',
cell: ({ getValue }) => (
<TextCell
value={getValue()}
truncate={true}
className="text-muted-foreground"
/>
),
}string | number - Content to displayboolean - Enable text truncation (default: true)string - Additional CSS classes// Basic usage
<TextCell value="Hello World" />
// Without truncation
<TextCell value="Long text..." truncate={false} />
// With styling
<TextCell
value="Important"
className="font-bold text-primary"
/>Display status or category badges.
import { BadgeCell } from '@workspace/active-grid';
{
accessorKey: 'status',
header: 'Status',
cell: ({ getValue }) => (
<BadgeCell
value={getValue()}
variant="default"
labelMap={{
ACTIVE: 'Active',
INACTIVE: 'Inactive',
PENDING: 'Pending',
}}
/>
),
}string - Badge value'default' | 'secondary' | 'outline' | 'destructive' - Badge styleRecord<string, string> - Value to label mappingstring - Additional CSS classes// Basic usage
<BadgeCell value="ACTIVE" />
// With label mapping
<BadgeCell
value="PENDING"
labelMap={{
ACTIVE: 'Active',
PENDING: 'Pending',
INACTIVE: 'Inactive',
}}
/>
// With variant
<BadgeCell
value="ERROR"
variant="destructive"
/>
// Custom styling
<BadgeCell
value="NEW"
variant="outline"
className="uppercase"
/>{
accessorKey: 'status',
header: 'Status',
cell: ({ getValue }) => {
const status = getValue() as string;
const variant =
status === 'active' ? 'default' :
status === 'pending' ? 'secondary' :
'outline';
return <BadgeCell value={status} variant={variant} />;
},
}Format and display dates consistently.
import { DateCell } from '@workspace/active-grid';
{
accessorKey: 'createdAt',
header: 'Created',
cell: ({ getValue }) => (
<DateCell
value={getValue()}
formatString="dd-MM-yyyy"
/>
),
}Date | string | number - Date valuestring - date-fns format string (default: 'PP')string - Additional CSS classesCommon date-fns format patterns:
PP - Jan 1, 2024dd-MM-yyyy - 01-01-2024dd/MM/yyyy - 01/01/2024yyyy-MM-dd - 2024-01-01PPp - Jan 1, 2024, 9:00 AMdd-MM-yyyy HH:mm - 01-01-2024 09:00Create navigational links.
string - Link textstring | ((value: string) => string) - Link destinationboolean - Open in new tab (default: false)string - Additional CSS classesCheckbox for row selection.
boolean - Checkbox stateboolean - Indeterminate state (for header)boolean - Disable checkbox(checked: boolean) => void - Change handlerDisplay row numbers.
New in v5.1
Toggle row expansion for detail panels.
All cell components accept className prop:
All cell components include proper accessibility attributes:
// Default format (e.g., "Jan 1, 2024")
<DateCell value={new Date()} />
// Custom format
<DateCell
value="2024-01-15"
formatString="dd-MM-yyyy"
/>
// Time included
<DateCell
value={timestamp}
formatString="dd-MM-yyyy HH:mm"
/>
// Relative format
<DateCell
value={date}
formatString="PPp"
/>
// With styling
<DateCell
value={date}
className="tabular-nums text-muted-foreground"
/>import { LinkCell } from '@workspace/active-grid';
{
accessorKey: 'name',
header: 'Name',
cell: ({ getValue, row }) => (
<LinkCell
value={getValue()}
href={`/users/${row.original.id}`}
/>
),
}// Static href
<LinkCell
value="View Details"
href="/details/123"
/>
// Dynamic href
<LinkCell
value="Edit"
href={(value) => `/edit/${value}`}
/>
// External link
<LinkCell
value="Documentation"
href="https://example.com/docs"
isExternal={true}
/>
// With styling
<LinkCell
value="Profile"
href="/profile"
className="font-semibold"
/>{
accessorKey: 'email',
header: 'Email',
cell: ({ getValue }) => (
<LinkCell
value={getValue()}
href={`mailto:${getValue()}`}
isExternal={true}
/>
),
}import { SelectionCell, getSelectionColumn } from '@workspace/active-grid';const columns = [
getSelectionColumn<User>(),
{ accessorKey: 'name', header: 'Name' },
// ... other columns
];{
id: 'select',
size: 40,
header: ({ table }) => (
<SelectionCell
checked={table.getIsAllRowsSelected()}
indeterminate={table.getIsSomeRowsSelected()}
onCheckedChange={(value) => table.toggleAllRowsSelected(!!value)}
/>
),
cell: ({ row }) => (
<SelectionCell
checked={row.getIsSelected()}
disabled={!row.getCanSelect()}
onCheckedChange={(value) => row.toggleSelected(!!value)}
/>
),
}import { getRowNumberColumn } from '@workspace/active-grid';
const columns = [
getRowNumberColumn<User>({
header: '#',
size: 50,
className: 'font-mono text-xs text-muted-foreground',
}),
// ... other columns
];getRowNumberColumn<TData>({
header?: string; // Header label (default: '#')
size?: number; // Column width (default: 50)
className?: string; // Cell CSS classes
enableSorting?: boolean; // Allow sorting (default: false)
enableHiding?: boolean; // Allow hiding (default: false)
})import { getExpanderColumn } from '@workspace/active-grid';
const columns = [
getExpanderColumn<Order>(),
// ... other columns
];
<ActiveGrid
columns={columns}
data={orders}
enableExpanding={true}
renderDetailPanel={(row) => (
<OrderDetails order={row.original} />
)}
/>import {
getSelectionColumn,
getRowNumberColumn,
BadgeCell,
DateCell,
LinkCell,
} from '@workspace/active-grid';
const columns: GridColumnDef<User>[] = [
getSelectionColumn<User>(),
getRowNumberColumn<User>(),
{
accessorKey: 'name',
header: 'Name',
cell: ({ getValue, row }) => (
<LinkCell
value={getValue()}
href={`/users/${row.original.id}`}
/>
),
},
{
accessorKey: 'status',
header: 'Status',
cell: ({ getValue }) => (
<BadgeCell
value={getValue()}
variant={
getValue() === 'active' ? 'default' : 'secondary'
}
/>
),
},
{
accessorKey: 'createdAt',
header: 'Created',
cell: ({ getValue }) => (
<DateCell
value={getValue()}
formatString="dd-MM-yyyy"
/>
),
},
];const columns: GridColumnDef<Order>[] = [
getExpanderColumn<Order>(),
{
accessorKey: 'orderNumber',
header: 'Order #',
cell: ({ getValue, row }) => (
<LinkCell
value={getValue()}
href={`/orders/${row.original.id}`}
className="font-mono"
/>
),
},
{
accessorKey: 'status',
header: 'Status',
cell: ({ getValue }) => {
const status = getValue() as string;
return (
<BadgeCell
value={status}
variant={
status === 'completed' ? 'default' :
status === 'pending' ? 'secondary' :
status === 'cancelled' ? 'destructive' :
'outline'
}
labelMap={{
pending: 'Pending',
completed: 'Completed',
cancelled: 'Cancelled',
}}
/>
);
},
},
{
accessorKey: 'createdAt',
header: 'Date',
cell: ({ getValue }) => (
<DateCell
value={getValue()}
formatString="dd MMM yyyy"
className="text-muted-foreground"
/>
),
},
];<BadgeCell
value="VIP"
className="uppercase tracking-wide"
/>
<DateCell
value={date}
className="tabular-nums font-mono text-sm"
/>
<LinkCell
value="View"
href="/view"
className="font-semibold hover:underline"
/>{
accessorKey: 'price',
header: 'Price',
meta: {
valueFormatter: (value) => `$${value.toFixed(2)}`,
},
cell: ({ getValue }) => (
<TextCell
value={getValue()}
className="font-mono"
/>
),
}import { BadgeCell, DateCell } from '@workspace/active-grid';
type User = {
name: string;
status: 'active' | 'inactive';
createdAt: Date;
};
const columns: GridColumnDef<User>[] = [
{
accessorKey: 'status',
header: 'Status',
cell: ({ getValue }) => {
const status = getValue() as User['status'];
return <BadgeCell value={status} />;
},
},
];