SortPlugin
SortPlugin and AsyncSortPlugin integrate sorting with the reactive store system.
The SortPlugin integrates ZenGrid’s sorting functionality with the reactive store system, supporting both frontend and backend sorting modes.
Overview
SortPlugin runs at phase 10 and provides:
- Reactive sort state management
- Frontend in-memory sorting
- Backend sort delegation
- Single and multi-column sorting
- Sort state persistence
SortPlugin depends on CorePlugin and must be registered after it.
Creation
Create the SortPlugin using factory functions:
import { createSortPlugin, createAsyncSortPlugin } from '@zengrid/core';
// Synchronous sortingconst sortPlugin = createSortPlugin();grid.usePlugin(sortPlugin);
// Asynchronous sortingconst asyncSortPlugin = createAsyncSortPlugin();grid.usePlugin(asyncSortPlugin);Frontend Mode
Frontend mode sorts data in-memory using built-in sorters:
import { createGrid, createSortPlugin } from '@zengrid/core';
const grid = createGrid(container, { columns: [ { id: 'name', field: 'name', sortable: true }, { id: 'age', field: 'age', sortable: true } ], data: users, sorting: { mode: 'frontend', multiColumn: true }});
grid.usePlugin(createSortPlugin());
// Sort by name ascendinggrid.api.sort.setSortState([ { field: 'name', direction: 'asc' }]);Single Column Sorting
Uses SingleColumnSorter for single-column operations:
// Only one column sorted at a timegrid.api.sort.setSortState([ { field: 'age', direction: 'desc' }]);
// Previous sort is replacedstore.get('sort.state'); // [{ field: 'age', direction: 'desc' }]Multi-Column Sorting
Uses MultiColumnSorter for multi-column operations:
const grid = createGrid(container, { sorting: { mode: 'frontend', multiColumn: true }});
// Sort by multiple columnsgrid.api.sort.setSortState([ { field: 'department', direction: 'asc' }, { field: 'name', direction: 'asc' }]);
// Data sorted by department, then by nameMulti-column sorting maintains sort priority based on array order.
Backend Mode
Backend mode delegates sorting to a callback:
const grid = createGrid(container, { columns: [ { id: 'name', field: 'name', sortable: true } ], sorting: { mode: 'backend', onSortRequest: async (sortState) => { const response = await fetch('/api/users', { method: 'POST', body: JSON.stringify({ sort: sortState }) }); const data = await response.json(); grid.api.data.setData(data); } }});
grid.usePlugin(createSortPlugin());AsyncSortPlugin
For async sorting operations with loading states:
import { createAsyncSortPlugin } from '@zengrid/core';
const grid = createGrid(container, { sorting: { mode: 'backend', onSortRequest: async (sortState) => { // Show loading indicator grid.api.loading.show();
try { const data = await fetchSortedData(sortState); grid.api.data.setData(data); } finally { grid.api.loading.hide(); } } }});
grid.usePlugin(createAsyncSortPlugin());Reactive State
SortPlugin creates these reactive signals:
// Current sort statestore.get('sort.state') // Array<{ field: string, direction: 'asc' | 'desc' }>store.set('sort.state', newSort)
// Computed signalsstore.get('sort.hasSorting') // Boolean: any active sortsstore.get('sort.sortedFields') // Array<string>: sorted field namesAPI Methods
SortPlugin registers these methods on grid.api.sort:
// Set sort stategrid.api.sort.setSortState([ { field: 'name', direction: 'asc' }]);
// Get current sort stateconst sortState = grid.api.sort.getSortState();
// Toggle sort on a fieldgrid.api.sort.toggleSort('age');
// Clear all sortinggrid.api.sort.clearSort();
// Sort by field with directiongrid.api.sort.sortByField('name', 'desc');Sort State Structure
interface SortState { field: string; direction: 'asc' | 'desc';}
type SortStateArray = SortState[];Events
SortPlugin emits events for sort changes:
grid.on('sort:change', (sortState) => { console.log('Sort changed:', sortState);});
grid.on('sort:clear', () => { console.log('Sort cleared');});Integration with Store
SortPlugin integrates seamlessly with the reactive store:
// Watch sort changesstore.effect('logSortChanges', () => { const sortState = store.get('sort.state'); console.log('Current sort:', sortState);}, 'MyComponent', 100);
// Computed from sort statestore.computed('sort.summary', () => { const sortState = store.get('sort.state'); return sortState.map(s => `${s.field} ${s.direction}`).join(', ');}, 'MyComponent', 100);Performance
SortPlugin optimizes sorting performance:
- Timsort algorithm: Uses efficient Timsort from
@zengrid/shared - Index-based: Sorts indices, not data
- Stable sorting: Maintains relative order for equal elements
- Lazy evaluation: Only sorts when needed
Frontend mode uses Timsort with O(n log n) average complexity for optimal performance.
Custom Comparators
Define custom sort comparators per column:
const grid = createGrid(container, { columns: [ { id: 'date', field: 'date', sortable: true, sortComparator: (a, b) => { return new Date(a).getTime() - new Date(b).getTime(); } } ]});