npm package: @quartix/grid
Description: A feature-rich, performant React data grid component with virtualization, grouping, filtering, and export capabilities
Author: Your Name
Latest version: 2.2.3

# Quartix Grid

A feature-rich, performant React data grid component with virtualization, grouping, filtering, sorting, and export capabilities.

> **Note**: This package requires a license key for production use.

## Features

- **Virtualization**: Efficiently render large datasets with both vertical and horizontal virtualization
- **Grouping**: Multi-level grouping with expandable/collapsible groups
- **Filtering**: Global and column-specific filtering with multiple filter types
- **Sorting**: Multi-column sorting with customizable sort functions
- **Pagination**: Client and server-side pagination support
- **Export**: Export data to CSV, JSON, and Excel formats
- **Selection**: Row and cell selection with keyboard navigation
- **Responsive**: Flexible column sizing with flex support
- **Accessibility**: Full keyboard navigation and screen reader support
- **TypeScript**: Built with TypeScript for excellent type safety

## Installation

```bash
npm install @quartix/grid
```

## Basic Usage

```tsx
import React from "react";
import { DataGrid } from "@quartix/grid";

const columns = [
  { key: "id", header: "ID", width: 80 },
  { key: "name", header: "Name", width: 200, sortable: true },
  { key: "email", header: "Email", width: 300, sortable: true },
  { key: "department", header: "Department", width: 150, sortable: true },
  {
    key: "salary",
    header: "Salary",
    width: 120,
    sortable: true,
    aggregate: "avg",
  },
];

const data = [
  {
    id: 1,
    name: "John Doe",
    email: "john@example.com",
    department: "Engineering",
    salary: 75000,
  },
  {
    id: 2,
    name: "Jane Smith",
    email: "jane@example.com",
    department: "Marketing",
    salary: 65000,
  },
  // ... more data
];

function App() {
  return (
    <div style={{ height: 600 }}>
      <DataGrid
        licenseKey="YOUR_LICENSE_KEY"
        data={data}
        columns={columns}
        getRowId={(row) => row.id}
        height={600}
        filterable={true}
        sortable={true}
        groupable={true}
        virtualized={true}
        pagination={{
          enabled: true,
          mode: "client",
          pageSize: 20,
        }}
      />
    </div>
  );
}
```

## Advanced Features

### Column Configuration

```tsx
const columns = [
  {
    key: "status",
    header: "Status",
    width: 120,
    filterable: {
      type: "multiselect",
      options: [
        { label: "Active", value: "active" },
        { label: "Inactive", value: "inactive" },
        { label: "Pending", value: "pending" },
      ],
    },
    formatter: (value) => value.toUpperCase(),
    aggregate: "count",
  },
  {
    key: "createdAt",
    header: "Created",
    width: 150,
    filterable: {
      type: "date",
      placeholder: "Filter by date...",
    },
    formatter: (value) => new Date(value).toLocaleDateString(),
  },
  {
    key: "actions",
    header: "Actions",
    width: 100,
    cellRenderer: (value, row) => (
      <button onClick={() => handleEdit(row)}>Edit</button>
    ),
  },
];
```

### Server-Side Operations

```tsx
function ServerGrid() {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(false);
  const [pagination, setPagination] = useState({
    page: 1,
    pageSize: 20,
    total: 0,
  });

  const handleServerPagination = async (page: number, pageSize: number) => {
    setLoading(true);
    const result = await fetchServerData(page, pageSize);
    setData(result.data);
    setPagination((prev) => ({ ...prev, page, pageSize, total: result.total }));
    setLoading(false);
  };

  const handleServerFilter = async (filters: any) => {
    setLoading(true);
    const result = await fetchFilteredData(filters);
    setData(result.data);
    setLoading(false);
  };

  return (
    <DataGrid
      licenseKey="YOUR_LICENSE_KEY"
      data={data}
      columns={columns}
      pagination={{
        enabled: true,
        mode: "server",
        pageSize: pagination.pageSize,
        serverConfig: {
          onPageChange: handleServerPagination,
          loading: loading,
          totalRows: pagination.total,
        },
      }}
      onFilterChange={handleServerFilter}
      isLoading={loading}
    />
  );
}
```

### Custom Styling

```tsx
const customRowStyle = (row) => ({
  backgroundColor: row.status === "active" ? "#f0fff4" : "#fff5f5",
});

const customCellStyle = (value, row) => ({
  color: row.priority === "high" ? "#dc2626" : "#1f2937",
});

<DataGrid
  licenseKey="YOUR_LICENSE_KEY"
  // ... other props
  rowStyle={customRowStyle}
  columns={columns.map((col) => ({
    ...col,
    cellStyle: customCellStyle,
  }))}
/>;
```

### Event Handling

```tsx
const handleRowClick = (row, event) => {
  console.log("Row clicked:", row);
};

const handleCellClick = ({ row, column, value, event }) => {
  console.log("Cell clicked:", { row, column, value });
};

const handleSelectionChange = (selectedRows) => {
  console.log("Selected rows:", Array.from(selectedRows));
};

const handleSort = (columnKey, direction) => {
  console.log("Sort changed:", { columnKey, direction });
};

<DataGrid
  licenseKey="YOUR_LICENSE_KEY"
  // ... other props
  onRowClick={handleRowClick}
  onCellClick={handleCellClick}
  onSelectedRowsChange={handleSelectionChange}
  onSort={handleSort}
  selectable={true}
/>;
```

## API Reference

### DataGrid Props

| Prop                   | Type                                                      | Default              | Description                                           |
| ---------------------- | --------------------------------------------------------- | -------------------- | ----------------------------------------------------- |
| `licenseKey`           | `string`                                                  | Required             | License key for the grid (will not render without it) |
| `data`                 | `GridRow[]`                                               | Required             | Array of data rows to display                         |
| `columns`              | `GridColumn[]`                                            | Required             | Array of column definitions                           |
| `getRowId`             | `(row: GridRow) => string \| number`                      | Optional             | Function to extract unique ID from row                |
| `height`               | `number`                                                  | 400                  | Grid height in pixels                                 |
| `density`              | `'sm' \| 'md' \| 'lg'`                                    | `'md'`               | Row density (affects row height)                      |
| `selectable`           | `boolean`                                                 | `false`              | Enable row selection                                  |
| `filterable`           | `boolean`                                                 | `true`               | Enable filtering                                      |
| `sortable`             | `boolean`                                                 | `true`               | Enable sorting                                        |
| `groupable`            | `boolean`                                                 | `false`              | Enable grouping                                       |
| `virtualized`          | `boolean`                                                 | `true`               | Enable virtualization                                 |
| `pagination`           | `PaginationOptions`                                       | `{ enabled: false }` | Pagination configuration                              |
| `loading`              | `boolean`                                                 | `false`              | Show loading state or skeleton                        |
| `editable`             | `boolean`                                                 | `false`              | Enable grid-level inline editing                      |
| `onRowSelect`          | `(row: GridRow) => void`                                  | Optional             | Row selection callback                                |
| `onSelectedRowsChange` | `(selectedRows: Set<string \| number>) => void`           | Optional             | Selection change callback                             |
| `onFilterChange`       | `(filters: ServerFilterChangePayload) => void`            | Optional             | Filter change callback                                |
| `onSort`               | `(columnKey: string, direction: 'asc' \| 'desc') => void` | Optional             | Sort change callback                                  |
| `onCellEdit`           | `(params: CellEditParams) => void`                        | Optional             | Called when a cell edit is committed                  |

### Imperative API (via React Ref)

The `DataGrid` component exposes several methods through its ref:

| Method              | Params                      | Description                               |
| ------------------- | --------------------------- | ----------------------------------------- |
| `scrollToRow`       | `(rowId: string \| number)` | Scrolls to a specific row by its ID       |
| `scrollToColumn`    | `(columnKey: string)`       | Scrolls to a specific column by its key   |
| `expandAllGroups`   | `()`                        | Expands all collapsed groups              |
| `collapseAllGroups` | `()`                        | Collapses all expanded groups             |
| `clearAllFilters`   | `()`                        | Clears global and column-specific filters |

### Column Definition

| Property           | Type                                                      | Default  | Description               |
| ------------------ | --------------------------------------------------------- | -------- | ------------------------- |
| `key`              | `string`                                                  | Required | Unique column identifier  |
| `header`           | `string`                                                  | Required | Column header text        |
| `width`            | `number`                                                  | 100      | Column width in pixels    |
| `flex`             | `boolean \| number`                                       | `false`  | Flexible column sizing    |
| `sortable`         | `boolean`                                                 | `true`   | Enable column sorting     |
| `filterable`       | `boolean \| ColumnFilter`                                 | `false`  | Enable column filtering   |
| `formatter`        | `(value: any) => string`                                  | Optional | Custom value formatter    |
| `cellRenderer`     | `(value: any, row: GridRow) => ReactNode`                 | Optional | Custom cell renderer      |
| `aggregate`        | `'sum' \| 'avg' \| 'min' \| 'max' \| function`            | Optional | Group aggregate function  |
| `footer_aggregate` | `'count' \| 'sum' \| 'avg' \| 'min' \| 'max' \| function` | Optional | Footer aggregate function |

## Performance Tips

1. **Enable Virtualization**: For datasets with > 1000 rows, always enable virtualization
2. **Use Server-Side Operations**: For very large datasets, use server-side pagination and filtering
3. **Optimize Renderers**: Avoid creating new objects/functions in cell renderers
4. **Limit Column Count**: Horizontal virtualization kicks in at 50+ columns
5. **Use Memoization**: Memoize expensive calculations in formatters and renderers

## Browser Support

- Chrome 80+
- Firefox 75+
- Safari 13+
- Edge 80+

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

If you encounter any issues or have questions, please [open an issue](https://github.com/yourusername/@quartix/grid/issues) on GitHub.