Grid plugin for Object UI - Advanced data grid with sorting, filtering, and pagination.
- Data Grid - Enterprise-grade data grid component
- Sorting - Multi-column sorting support
- Filtering - Column-level filtering
- Pagination - Built-in pagination controls
- Row Selection - Single and multi-row selection
- Customizable - Tailwind CSS styling support
pnpm add @object-ui/plugin-grid// In your app entry point (e.g., App.tsx or main.tsx)
import '@object-ui/plugin-grid';
// Now you can use grid types in your schemas
const schema = {
type: 'grid',
columns: [
{ header: 'Name', accessorKey: 'name' },
{ header: 'Email', accessorKey: 'email' }
],
data: []
};import { gridComponents } from '@object-ui/plugin-grid';
import { ComponentRegistry } from '@object-ui/core';
// Register grid components
Object.entries(gridComponents).forEach(([type, component]) => {
ComponentRegistry.register(type, component);
});Data grid with advanced features:
{
type: 'grid',
columns: GridColumn[],
data?: any[],
sortable?: boolean,
filterable?: boolean,
pagination?: boolean | PaginationConfig,
selectable?: boolean,
onRowClick?: (row) => void,
className?: string
}interface GridColumn {
header: string;
accessorKey: string;
sortable?: boolean;
filterable?: boolean;
width?: number | string;
align?: 'left' | 'center' | 'right';
cell?: (value, row) => ReactNode;
}const schema = {
type: 'grid',
columns: [
{ header: 'ID', accessorKey: 'id', width: 80 },
{ header: 'Name', accessorKey: 'name' },
{ header: 'Email', accessorKey: 'email' },
{ header: 'Role', accessorKey: 'role' },
{ header: 'Status', accessorKey: 'status' }
],
data: [
{ id: 1, name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'Active' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'User', status: 'Active' }
],
sortable: true,
filterable: true,
pagination: true
};const schema = {
type: 'grid',
columns: [
{ header: 'Name', accessorKey: 'name' },
{
header: 'Status',
accessorKey: 'status',
cell: (value) => ({
type: 'badge',
label: value,
variant: value === 'Active' ? 'success' : 'default'
})
},
{
header: 'Actions',
accessorKey: 'id',
cell: (value, row) => ({
type: 'button-group',
buttons: [
{ label: 'Edit', onClick: () => console.log('Edit', row) },
{ label: 'Delete', variant: 'destructive', onClick: () => console.log('Delete', row) }
]
})
}
],
data: [/* data */]
};const schema = {
type: 'grid',
columns: [/* columns */],
data: [/* data */],
selectable: true,
onRowClick: (row) => {
console.log('Row clicked:', row);
},
onSelectionChange: (selectedRows) => {
console.log('Selection changed:', selectedRows);
}
};const schema = {
type: 'grid',
columns: [/* columns */],
data: [/* data */],
pagination: {
pageSize: 10,
showSizeChanger: true,
pageSizeOptions: [10, 20, 50, 100]
}
};Connect grid to backend APIs:
import { createObjectStackAdapter } from '@object-ui/data-objectstack';
const dataSource = createObjectStackAdapter({
baseUrl: 'https://api.example.com',
token: 'your-auth-token'
});
const schema = {
type: 'object-grid',
dataSource,
object: 'users',
columns: [
{ header: 'Name', accessorKey: 'name' },
{ header: 'Email', accessorKey: 'email' },
{ header: 'Created', accessorKey: 'created_at' }
],
pagination: true,
sortable: true,
filterable: true
};Enable sorting on columns:
const schema = {
type: 'grid',
sortable: true, // Enable sorting on all columns
columns: [
{ header: 'Name', accessorKey: 'name', sortable: true },
{ header: 'Email', accessorKey: 'email', sortable: false } // Disable for specific column
]
};Enable column filtering:
const schema = {
type: 'grid',
filterable: true,
columns: [
{ header: 'Status', accessorKey: 'status', filterable: true }
]
};Add actions to rows:
const schema = {
type: 'grid',
columns: [/* columns */],
rowActions: [
{ label: 'View', onClick: (row) => console.log('View', row) },
{ label: 'Edit', onClick: (row) => console.log('Edit', row) },
{ label: 'Delete', onClick: (row) => console.log('Delete', row) }
]
};Enable inline cell editing for quick updates:
const schema = {
type: 'object-grid',
objectName: 'users',
columns: [
{ header: 'ID', accessorKey: 'id', editable: false }, // Read-only column
{ header: 'Name', accessorKey: 'name' }, // Editable
{ header: 'Email', accessorKey: 'email' }, // Editable
{ header: 'Status', accessorKey: 'status' } // Editable
],
editable: true, // Enable editing globally
onCellChange: (rowIndex, columnKey, newValue, row) => {
console.log(`Cell at row ${rowIndex}, column ${columnKey} changed to:`, newValue);
console.log('Full row data:', row);
// Update your data source here
// Example: await dataSource.update(row.id, { [columnKey]: newValue });
}
};Inline Editing Features:
- Double-click to edit: Double-click any editable cell to enter edit mode
- Keyboard shortcuts:
- Press
Enteron a focused cell to start editing - Press
Enterwhile editing to save changes - Press
Escapeto cancel editing
- Press
- Column-level control: Set
editable: falseon specific columns to prevent editing - Visual feedback: Editable cells show hover state to indicate they can be edited
- Automatic focus: Input field is automatically focused and selected when entering edit mode
Use Cases:
- Quick data corrections
- Batch data entry
- Spreadsheet-like editing experience
- Real-time updates with backend synchronization
Edit multiple cells across multiple rows and save them individually or all at once:
const schema = {
type: 'object-grid',
objectName: 'products',
columns: [
{ header: 'SKU', accessorKey: 'sku', editable: false },
{ header: 'Name', accessorKey: 'name' },
{ header: 'Price', accessorKey: 'price' },
{ header: 'Stock', accessorKey: 'stock' }
],
editable: true,
rowActions: true, // Show row-level save/cancel buttons
onRowSave: async (rowIndex, changes, row) => {
// Save a single row
console.log('Saving row:', rowIndex, changes);
await dataSource.update(row.id, changes);
},
onBatchSave: async (allChanges) => {
// Save all modified rows at once
console.log('Batch saving:', allChanges);
await Promise.all(
allChanges.map(({ row, changes }) =>
dataSource.update(row.id, changes)
)
);
}
};Batch Editing Features:
- Pending changes tracking: Edit multiple cells across multiple rows before saving
- Visual indicators:
- Modified rows are highlighted with amber background
- Modified cells are shown in bold with amber text
- Toolbar shows count of modified rows
- Row-level actions: Save or cancel changes for individual rows
- Batch operations:
- "Save All" button to save all modified rows at once
- "Cancel All" button to discard all pending changes
- Flexible callbacks:
onRowSave: Called when saving a single rowonBatchSave: Called when saving multiple rows at onceonCellChange: Still called for immediate cell updates (legacy support)
Example Workflow:
- User edits multiple cells across different rows
- Modified rows are visually highlighted
- Toolbar shows "X rows modified" with Save All/Cancel All buttons
- User can:
- Save individual rows using row-level save button
- Save all changes at once using "Save All" button
- Cancel individual row changes or all changes
import type { GridSchema, GridColumn } from '@object-ui/plugin-grid';
const nameColumn: GridColumn = {
header: 'Name',
accessorKey: 'name',
sortable: true
};
const grid: GridSchema = {
type: 'grid',
columns: [nameColumn],
data: [],
sortable: true,
pagination: true
};MIT