npm package: @object-ui/plugin-grid
Description: Grid plugin for Object UI
Latest version: 3.1.5

# @object-ui/plugin-grid

Grid plugin for Object UI - Advanced data grid with sorting, filtering, and pagination.

## Features

- **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

## Installation

```bash
pnpm add @object-ui/plugin-grid
```

## Usage

### Automatic Registration (Side-Effect Import)

```typescript
// 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: []
};
```

### Manual Registration

```typescript
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);
});
```

## Schema API

### Grid

Data grid with advanced features:

```typescript
{
  type: 'grid',
  columns: GridColumn[],
  data?: any[],
  sortable?: boolean,
  filterable?: boolean,
  pagination?: boolean | PaginationConfig,
  selectable?: boolean,
  onRowClick?: (row) => void,
  className?: string
}
```

### Column Definition

```typescript
interface GridColumn {
  header: string;
  accessorKey: string;
  sortable?: boolean;
  filterable?: boolean;
  width?: number | string;
  align?: 'left' | 'center' | 'right';
  cell?: (value, row) => ReactNode;
}
```

## Examples

### Basic Grid

```typescript
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
};
```

### Grid with Custom Cells

```typescript
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 */]
};
```

### Selectable Grid

```typescript
const schema = {
  type: 'grid',
  columns: [/* columns */],
  data: [/* data */],
  selectable: true,
  onRowClick: (row) => {
    console.log('Row clicked:', row);
  },
  onSelectionChange: (selectedRows) => {
    console.log('Selection changed:', selectedRows);
  }
};
```

### Grid with Pagination

```typescript
const schema = {
  type: 'grid',
  columns: [/* columns */],
  data: [/* data */],
  pagination: {
    pageSize: 10,
    showSizeChanger: true,
    pageSizeOptions: [10, 20, 50, 100]
  }
};
```

## Integration with Data Sources

Connect grid to backend APIs:

```typescript
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
};
```

## Features

### Sorting

Enable sorting on columns:

```typescript
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
  ]
};
```

### Filtering

Enable column filtering:

```typescript
const schema = {
  type: 'grid',
  filterable: true,
  columns: [
    { header: 'Status', accessorKey: 'status', filterable: true }
  ]
};
```

### Row Actions

Add actions to rows:

```typescript
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) }
  ]
};
```

### Inline Editing

Enable inline cell editing for quick updates:

```typescript
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 `Enter` on a focused cell to start editing
  - Press `Enter` while editing to save changes
  - Press `Escape` to cancel editing
- **Column-level control**: Set `editable: false` on 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

### Batch Editing & Multi-Row Save

Edit multiple cells across multiple rows and save them individually or all at once:

```typescript
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 row
  - `onBatchSave`: Called when saving multiple rows at once
  - `onCellChange`: Still called for immediate cell updates (legacy support)

**Example Workflow:**
1. User edits multiple cells across different rows
2. Modified rows are visually highlighted
3. Toolbar shows "X rows modified" with Save All/Cancel All buttons
4. 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

## TypeScript Support

```typescript
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
};
```

## License

MIT