npm package: @21jumpclick/data-table
Description: Custom data table made with MUI and TanStack table
Author: 21JumpClick
Latest version: 1.0.0-beta.14

# 21 DataTable

🚀 **A powerful and customizable React data table library** built with Material-UI and TanStack Table, designed to handle everything from simple data display to complex enterprise-grade table requirements.

[![npm version](https://img.shields.io/badge/npm-v1.0.0--beta.3-blue.svg)](https://www.npmjs.com/package/@21jumpclick/data-table)
[![TypeScript](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)

## 🎯 Why Choose 21 DataTable?

**All-in-one solution** - From basic data display to advanced enterprise features, this library provides everything you need for modern data tables without the complexity.

### ⚡ Ready-to-use Components
- **BasicDataTable** - Perfect for static data with client-side operations
- **ClientDataTable** - Integrates seamlessly with React Query for data fetching
- **ServerDataTable** - Handles server-side pagination, sorting, and filtering

### 🎨 Advanced Features Out of the Box
- **Smart column management** - Sorting, filtering, grouping, aggregation, pinning, resizing
- **Intelligent search** - Global search + advanced smart filters
- **Modern UX** - Loading states, pagination, row selection, hover effects
- **Developer-friendly** - TypeScript support, extensive customization, URL state sharing

## 📦 Quick Installation

```bash
npm install @21jumpclick/data-table
```

**Required peer dependencies:**
```bash
npm install @mui/material @mui/icons-material @emotion/react @emotion/styled
npm install @tanstack/react-table @tanstack/react-query  # For ClientDataTable/ServerDataTable
```

## 🚀 Quick Start

### 1. Setup the Provider

```tsx
import { DataTableProvider, frTranslations } from '@21jumpclick/data-table';
import { ThemeProvider } from '@mui/material';

function App() {
  return (
    <ThemeProvider theme={yourTheme}>
      <DataTableProvider values={{
        translations: frTranslations, // or enTranslations
        columnTypeDefs: [], // Your custom column types
        // ... other global options
      }}>
        <YourApp />
      </DataTableProvider>
    </ThemeProvider>
  );
}
```

### 2. Create Your First Table

```tsx
import { BasicDataTable } from '@21jumpclick/data-table';
import type { ColumnDef } from '@tanstack/react-table';

interface User {
  id: string;
  name: string;
  email: string;
  role: string;
}

const columns: ColumnDef<User>[] = [
  { accessorKey: 'name', header: 'Name' },
  { accessorKey: 'email', header: 'Email' },
  { accessorKey: 'role', header: 'Role' },
];

function UsersTable() {
  return (
    <BasicDataTable
      columns={columns}
      data={users}
      enableRowSelection
      onRowClick={(row) => console.log('Clicked:', row)}
    />
  );
}
```

## 📊 Table Variants

### BasicDataTable - Static Data
Perfect for displaying arrays of data with all features handled client-side.

```tsx
<BasicDataTable
  columns={columns}
  data={staticData}
  isLoading={false}
/>
```

### ClientDataTable - React Query Integration
Handles data fetching with React Query, processes all features client-side.

```tsx
<ClientDataTable
  columns={columns}
  useTableQuery={() => useQuery({
    queryKey: ['users'],
    queryFn: fetchUsers
  })}
/>
```

### ServerDataTable - Server-Side Processing
Delegates pagination, sorting, and filtering to your backend for optimal performance.

```tsx
<ServerDataTable
  columns={columns}
  useTableQuery={(params) => useQuery({
    queryKey: ['users', params],
    queryFn: () => fetchUsersFromServer(params)
  })}
/>
```

## 🎨 Theming & Customization

### Built-in Themes
Choose from pre-designed themes or create your own:

- [Bordered theme options](lib/themes/bordered.themeOptions.ts) - Adds borders to all table elements
- [Stripped theme options](lib/themes/stripped.themeOptions.ts) - Alternating row colors

```tsx
import { 
  borderedThemeOptions,
  strippedThemeOptions, 
  mergeThemeOptions 
} from '@21jumpclick/data-table';

const customThemeOptions = mergeThemeOptions(
  borderedThemeOptions,    // Add borders
  strippedThemeOptions,    // Alternate row colors
  {
    // Your custom overrides
    components: {
      DTTableRow: {
        styleOverrides: {
          root: ({ theme }) => ({
            '&:hover': {
              backgroundColor: theme.palette.action.hover,
            },
          }),
        },
      },
    },
  }
);
```

> 💡 **Pro tip:** Use `mergeThemeOptions` to properly combine theme functions - it handles `styleOverrides` function merging automatically!

### Complete Theme Example
See our [comprehensive theme implementation](./src/theme.ts) with light/dark mode support.

## 🔧 Advanced Features

### Column Types - Smart Column Formatting

Column types provide automatic formatting and behavior for specific data types. Instead of manually configuring each column, simply specify a `columnType` and get intelligent defaults.

#### Built-in Column Types

```tsx
const columns: ColumnDef<Product>[] = [
  {
    accessorKey: 'name',
    header: 'Product Name',
    columnType: 'string' // Default string handling
  },
  {
    accessorKey: 'price',
    header: 'Price',
    columnType: 'currency' // Automatic currency formatting
  },
  {
    accessorKey: 'quantity',
    header: 'Stock',
    columnType: 'number' // Number formatting with aggregation
  },
  {
    accessorKey: 'releaseDate',
    header: 'Release Date',
    columnType: 'date' // Date formatting and date-specific filters
  },
  {
    accessorKey: 'isActive',
    header: 'Active',
    columnType: 'boolean' // Boolean display with true/false filters
  },
  {
    accessorKey: 'createdAt',
    header: 'Created',
    columnType: 'dateTime' // Date and time formatting
  }
];
```

#### Creating Custom Column Types

Create reusable column types for your specific data structures:

```tsx
// Example: Custom tags column type
import type { ColumnTypeDef } from '@21jumpclick/data-table';

export const tagsTypeDef: ColumnTypeDef<{ tags: string[] }> = {
  type: 'tags',
  cell: ({ getValue }) => {
    const tags = getValue() as string[];
    return (
      <div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
        {tags.map(tag => (
          <Chip key={tag} label={tag} size="small" />
        ))}
      </div>
    );
  },
  enableSorting: false,
  enableAggregation: false
  // ...
};

// Register in DataTableProvider
<DataTableProvider values={{
  columnTypeDefs: [tagsTypeDef],
  // ...
}}>
```

Then use it in your columns:

```tsx
{
  accessorKey: 'myTags',
  header: 'My Tags',
  columnType: 'tags' // Uses your custom type
}
```

**Real examples:**
- [Tags Column Type](./src/ColumnTypeDef/tagsTypeDef.tsx) - Display array of tags as chips
- [Users Column Type](./src/ColumnTypeDef/usersTypeDef.tsx) - User objects with avatar and smart filtering

### Smart Filters - Advanced Column Filtering

Smart filters provide intelligent, type-aware filtering interfaces that understand your data structure. The system works through two main components: **Column Types** that define which filters are allowed, and **Smart Filter Items** that implement the actual filtering logic.

#### How Smart Filters Work

1. **Column Types** define which smart filter operations are allowed via `allowedSmartFilters`
2. **Smart Filter Items** implement the filtering logic and UI components
3. **Users** can apply multiple smart filters per column through the UI

#### Built-in Smart Filters

Smart filters are automatically available based on column types:

```tsx
// String columns get text-based filters:
// - "contains", "equals", "startsWith", "endsWith", "isEmpty", "isNotEmpty"

// Number columns get numeric filters:
// - "equals", "greaterThan", "lessThan", "between", "isEmpty", "isNotEmpty"

// Date columns get date-specific filters:
// - "equals", "before", "after", "between", "isEmpty", "isNotEmpty"

// Boolean columns get boolean filters:
// - "equals" (true/false), "isEmpty", "isNotEmpty"
```

#### Creating Custom Smart Filters

Build domain-specific filters for complex data types:

```tsx
import type { SmartFilterItem } from '@21jumpclick/data-table';

// Step 1: Create the smart filter item
export const userSmartFilterItem: SmartFilterItem = {
  // React component for the filter UI
  component: ({ value, onChange }) => {
    const users = useUsersFromTable(); // Get unique users from table data
    
    return (
      <Autocomplete
        value={value}
        onChange={(_, newValue) => onChange(newValue)}
        options={users}
        getOptionLabel={(user) => user.name}
        renderInput={(params) => (
          <TextField {...params} label="Select User" />
        )}
      />
    );
  },
  
  // Filter logic
  filterFn: (row, columnId, filterValue) => {
    const user = row.getValue(columnId);
    return user?.id === filterValue?.id;
  },
  
  // Display formatter for selected filter
  valueFormatter: (user) => user?.name || '',
  
  // Template for filter chip display
  label: 'User is {{value}}'
};

// Step 2: Register in DataTableProvider
<DataTableProvider values={{
  smartFilterItems: {
    isEqualUser: userSmartFilterItem // Key becomes the operation name
  },
}} />

// Step 4: Use in your columns
{
  accessorKey: 'assignedUser',
  header: 'Assigned To',
  allowedSmartFilters: ['isEqualUser'] // Define allowedSmartFilters for current column
}
```

#### Advanced Smart Filter Features

**Multiple Filters per Column:**
Users can apply multiple smart filters to the same column - they are combined with AND logic.

**Custom Value Formatters:**
Format complex values for display in filter chips:

```tsx
// Single value
valueFormatter: (user) => user?.name || ''

// Multiple values (for "between" filters)
valueFormatter: (values) => values.map(v => v.toString())
```

**Filter Function Helpers:**
Smart filters can implement `resolveFilterValue` for preprocessing:

```tsx
filterFn: (row, columnId, filterValue) => {
  // Your filtering logic
},
resolveFilterValue: (value) => {
  // Preprocess the value before filtering
  return value?.toLowerCase();
}
```

**Real example:** [User Smart Filter](./src/CustomSmartFilters/userSmartFilter.tsx) - Autocomplete filter for user objects

### Programmatic Control - Table Instance Access

Access the underlying TanStack Table instance and DOM elements for advanced control:

```tsx
import { useRef } from 'react';
import type { ClientDataTableRef } from '@21jumpclick/data-table';

function AdvancedTable() {
  const tableRef = useRef<ClientDataTableRef<User>>(null);

  const handleExportData = () => {
    // Get filtered and sorted data
    const table = tableRef.current?.table;
    const filteredRows = table?.getFilteredRowModel().rows;
    const data = filteredRows?.map(row => row.original);
    
    // Export logic here
    exportToCsv(data);
  };

  const handleResetFilters = () => {
    const table = tableRef.current?.table;
    table?.resetGlobalFilter();
    table?.resetColumnFilters();
    table?.resetSorting();
    // Reset smart filters
    table?.setSmartFilters([]);
  };

  const handleScrollToTop = () => {
    tableRef.current?.elementsRef.current?.tableRef.current?.scrollIntoView();
  };

  return (
    <>
      <div>
        <Button onClick={handleExportData}>Export Filtered Data</Button>
        <Button onClick={handleResetFilters}>Reset All Filters</Button>
        <Button onClick={handleScrollToTop}>Scroll to Top</Button>
      </div>
      
      <ClientDataTable
        ref={tableRef}
        columns={columns}
        useTableQuery={useUsersQuery}
        additionalTools={{
          end: [() => <Button onClick={handleExportData}>Export</Button>]
        }}
      />
    </>
  );
}
```

#### Available Ref Properties

```tsx
interface ClientDataTableRef<T> {
  // TanStack Table instance - full table control
  table: Table<T>;
  
  // React Query result - data and loading states
  query: UseQueryResult<T[]>;
  
  // DOM element references
  elementsRef: {
    tableRef: RefObject<HTMLDivElement>;      // Table container
    toolbarRef: RefObject<HTMLDivElement>;    // Toolbar
    containerRef: RefObject<HTMLDivElement>;  // Full component
    paginationRef: RefObject<HTMLDivElement>; // Pagination
  };
}
```

### Column Features Configuration

Fine-tune each column's behavior with detailed options:

```tsx
const columns: ColumnDef<Product>[] = [
  {
    accessorKey: 'name',
    header: 'Product Name',
    columnType: 'string',
    
    // Aggregation control
    enableAggregation: true,
    aggregationFn: 'count',
    
    // Smart filter control (inherited from columnType, can be overridden)
    enableSmartFilter: true,
    
    // Column sizing
    size: 200,
    minSize: 100,
    maxSize: 400,
    
    // Pinning
    enablePinning: true,
    
    // Sorting
    enableSorting: true,
    sortDescFirst: false,
    
    // Filtering
    enableColumnFilter: true,
    enableGlobalFilter: true
  }
];
```

### State Management & URL Sharing

Control table state and enable URL sharing for bookmarkable table states:

```tsx
<BasicDataTable
  columns={columns}
  data={data}
  
  // Enable URL state persistence
  enableQueryParams={true}
  
  // Initial state
  pagination={{ pageIndex: 0, pageSize: 25 }}
  sortBy={[{ id: 'name', desc: false }]}
  smartFilters={[
    { field: 'status', value: 'active', type: 'equals' }
  ]}
  columnPinning={{ left: ['name'], right: ['actions'] }}
  visibility={{ internalId: false }}
  
  // State change handlers
  onPaginationChange={(pagination) => {
    console.log('Pagination changed:', pagination);
  }}
  onSortingChange={(sorting) => {
    console.log('Sorting changed:', sorting);
  }}
/>
```

### Server-Side Integration

For `ServerDataTable`, implement server endpoints that handle the query parameters:

```tsx
// Frontend
<ServerDataTable
  columns={columns}
  useTableQuery={(params) => 
    useQuery({
      queryKey: ['products', params],
      queryFn: () => fetchProducts(params)
    })
  }
/>

// Backend integration example
interface TableQuery {
  offset?: number;        // Skip N rows
  limit?: number;         // Take N rows
  search?: string;        // Global search term
  order?: 'asc' | 'desc' | null; // Sort direction
  orderBy?: string;       // Sort column
  filters?: Filter[];     // Column-specific filters (including smart filters)
}

interface Filter {
  field: string;          // Column identifier
  value: any;             // Filter value
  type: string;           // Filter operation (equals, contains, isEqualUser, etc.)
}

// Your API should return:
interface TableResult<T> {
  data: T[];              // Current page data
  count: number;          // Total records (for pagination)
}
```

## 🌍 Internationalization

Full i18n support with multiple localization layers:

```tsx
import { frTranslations, enTranslations } from '@21jumpclick/data-table';
import { fr } from 'date-fns/locale';
import { frFR } from '@mui/material/locale';

<DataTableProvider values={{
  translations: frTranslations,        // UI labels
  dateFnsLocale: fr,                   // Date formatting
  i18nLocale: 'fra',                   // ISO 639-2 code
}}>
  <ThemeProvider theme={createTheme({}, frFR)}> {/* MUI locale */}
    <YourApp />
  </ThemeProvider>
</DataTableProvider>
```

## 📋 Feature Matrix

| Feature | BasicDataTable | ClientDataTable | ServerDataTable |
|---------|---------------|-----------------|------------|
| Column sorting | ✅  | ✅  | ✅ |
| Column filtering | ✅  | ✅  | ✅|
| Global search | ✅  | ✅  | ✅|
| Pagination | ✅  | ✅  | ✅|
| Smart filters | ✅  | ✅  | ✅|
| Row selection | ✅ | ✅ | ✅ |
| Column grouping | ✅ | ✅ | ✅ |
| Column aggregation | ✅ | ✅ | ✅ |
| Column pinning | ✅ | ✅ | ✅ |
| URL state sharing | ✅ | ✅ | ✅ |
| Loading states | - | ✅ | ✅ |
| Refresh button | - | ✅ | ✅ |

## 🔗 TypeScript Support

Full TypeScript support with comprehensive type definitions:

```tsx
import type { 
  ColumnDef,
  BasicDataTableProps,
  ClientDataTableRef,
  DefaultTableState 
} from '@21jumpclick/data-table';

// All components are fully typed
// IntelliSense works out of the box
// Type-safe column definitions
// Proper ref typing
```

## 📚 Examples & Documentation

- **Live Demo:** [Complete example app](./src/App.tsx) with all features demonstrated
- **Column Types:** [Custom column implementations](./src/ColumnTypeDef/)
- **Smart Filters:** [Advanced filtering examples](./src/CustomSmartFilters/)
- **Theming:** [Theme customization guide](./src/theme.ts)
- **Type Definitions:** [Extended table types](./lib/table.d.ts)

## 🛠 Built With

- **[TanStack Table v8](https://tanstack.com/table/latest)** - Powerful table logic
- **[Material-UI v5/v6](https://mui.com/)** - Beautiful, accessible components
- **[TanStack Query v5](https://tanstack.com/query/latest)** - Server state management
- **[TypeScript](https://www.typescriptlang.org/)** - Type safety and great DX

## 📄 License

MIT © [21JumpClick](https://github.com/21JumpClick/DataTable)

---

**Ready to build amazing data tables?** Start with our [Quick Start](#-quick-start) guide or explore the [live examples](./src/App.tsx) to see all features in action! 🚀