@nacmias/data-grid
v0.1.0
Published
A feature-rich data grid component with toolbar, filtering, sorting, grouping, and row expansion modal
Maintainers
Readme
@nacmias/data-grid
A feature-rich, Airtable-like data grid component for React applications. Built on top of react-data-grid.
Features
- Search - Global search across all columns
- Filter - Column-based filtering with multiple operators
- Sort - Single and multi-column sorting
- Group - Group rows by column values
- Column Visibility - Show/hide columns
- Row Selection - Single and multi-select with checkboxes
- Row Expansion - Modal for viewing/editing full record
- Action Buttons - Customizable actions (expand, webhook, etc.)
- Custom Editors - Select dropdowns, date pickers
- Virtualization - Efficient rendering of large datasets
- TypeScript - Full type support
Installation
npm install @nacmias/data-grid
# or
yarn add @nacmias/data-gridQuick Start
import { DataGrid, type ColumnDefinition } from '@nacmias/data-grid';
import '@nacmias/data-grid/styles.css';
interface Contact {
id: string;
name: string;
email: string;
type: 'person' | 'company';
created_at: string;
}
const columns: ColumnDefinition<Contact>[] = [
{ key: 'name', name: 'Name', sortable: true, filterable: true },
{
key: 'type',
name: 'Type',
fieldType: 'select',
selectOptions: [
{ value: 'person', label: 'Person' },
{ value: 'company', label: 'Company' },
],
groupable: true,
},
{ key: 'email', name: 'Email', fieldType: 'email' },
{ key: 'created_at', name: 'Created', fieldType: 'date' },
];
function App() {
const [contacts, setContacts] = useState<Contact[]>([]);
return (
<div style={{ height: '600px' }}>
<DataGrid
data={contacts}
columns={columns}
rowKeyGetter={(row) => row.id}
onRowChange={(row) => console.log('Row changed:', row)}
onWebhook={(row) => console.log('Webhook:', row)}
/>
</div>
);
}Props
DataGridProps
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| data | T[] | Required | Array of data rows |
| columns | ColumnDefinition<T>[] | Required | Column definitions |
| rowKeyGetter | (row: T) => string | Required | Function to get unique key for each row |
| onRowChange | (row: T) => void | - | Called when a row is edited |
| onRowsChange | (rows: T[]) => void | - | Called when rows are bulk changed |
| onWebhook | (row: T) => void | - | Called when webhook button is clicked |
| onRowExpand | (row: T) => void | - | Called when row is expanded |
| onSelectionChange | (selectedRows: ReadonlySet<string>) => void | - | Called when selection changes |
| enableSearch | boolean | true | Enable search functionality |
| enableFilter | boolean | true | Enable filtering |
| enableSort | boolean | true | Enable sorting |
| enableGroup | boolean | true | Enable grouping |
| enableColumnToggle | boolean | true | Enable column visibility toggle |
| enableSelection | boolean | true | Enable row selection |
| enableActions | boolean | true | Enable action buttons column |
| enableRowExpand | boolean | true | Enable row expansion modal |
| enableWebhook | boolean | true | Enable webhook button |
| height | string \| number | '100%' | Grid height |
| searchPlaceholder | string | 'Search...' | Search input placeholder |
| toolbarColors | Partial<ToolbarColors> | - | Custom toolbar button colors |
| modalTitle | (row: T) => string | - | Custom modal title |
| modalFields | string[] | - | Fields to show in modal |
ColumnDefinition
| Prop | Type | Default | Description |
|------|------|---------|-------------|
| key | string | Required | Unique column key |
| name | string | Required | Column header text |
| width | number | - | Column width in pixels |
| minWidth | number | - | Minimum column width |
| maxWidth | number | - | Maximum column width |
| frozen | boolean | false | Freeze column to left |
| resizable | boolean | true | Allow column resize |
| sortable | boolean | true | Allow sorting |
| filterable | boolean | true | Allow filtering |
| groupable | boolean | false | Allow grouping by this column |
| editable | boolean | true | Allow editing in modal |
| fieldType | FieldType | 'text' | Field type for modal editor |
| selectOptions | SelectOption[] | - | Options for select field type |
| getValue | (row: T) => unknown | - | Custom value getter |
| setValue | (row: T, value: unknown) => T | - | Custom value setter |
| renderCell | (props) => ReactNode | - | Custom cell renderer |
| renderEditCell | (props) => ReactNode | - | Custom cell editor |
FieldType
'text'- Text input'number'- Number input'email'- Email input'phone'- Phone input'select'- Dropdown select'date'- Date picker'datetime'- DateTime picker'readonly'- Read-only display
Toolbar Colors
Customize the Airtable-like color-coded toolbar buttons:
<DataGrid
toolbarColors={{
columns: { main: '#7c3aed', bg: '#f3e8ff' }, // Purple
sort: { main: '#2563eb', bg: '#dbeafe' }, // Blue
filter: { main: '#16a34a', bg: '#dcfce7' }, // Green
group: { main: '#d97706', bg: '#fef3c7' }, // Amber
}}
/>Custom Cell Renderers
const columns: ColumnDefinition<Contact>[] = [
{
key: 'status',
name: 'Status',
renderCell: ({ row }) => (
<span style={{
padding: '2px 8px',
borderRadius: '4px',
background: row.status === 'active' ? '#dcfce7' : '#fee2e2',
color: row.status === 'active' ? '#16a34a' : '#dc2626',
}}>
{row.status}
</span>
),
},
];Nested Values
Handle nested object properties:
const columns: ColumnDefinition<Contact>[] = [
{
key: 'city',
name: 'City',
getValue: (row) => row.address?.city,
setValue: (row, value) => ({
...row,
address: { ...row.address, city: value as string },
}),
},
];Exported Components
You can also use individual components:
import {
DataGrid,
GridToolbar,
RecordModal,
SelectEditor,
DateEditor,
createSelectEditor,
} from '@nacmias/data-grid';Development
# Install dependencies
npm install
# Build
npm run build
# Watch mode
npm run dev
# Type check
npm run typecheckLicense
MIT
