Client-side data loading and processing.
Client mode loads all data at once and handles sorting, filtering, and pagination entirely in the browser. This is ideal for small to medium datasets where all data can be loaded upfront.
<ActiveGrid
mode="client"
data={users}
columns={columns}
{...}
/>type User = {
id: string;
name: string;
email: string;
status: string;
};
const users: User[] = [
{ id: '1', name: 'John Doe', email: 'john@example.com', status: 'active' },
{ id: '2', name: 'Jane Smith', email: 'jane@example.com', status: 'active' },
// ... more rows
];
<ActiveGrid
mode="client"
data={users}
columns={columns}
{...}
/>All features work automatically in client mode:
<ActiveGrid
mode="client"
data={users}
columns={columns}
// Sorting handled client-side
{...}
/><ActiveGrid
mode="client"
data={users}
columns={columns}
toolbar={{
search: { placeholder: 'Search...' },
}}
// Filtering handled client-side
{...}
/><ActiveGrid
mode="client"
data={users}
columns={columns}
pagination={{
enabled: true,
pageSizeOptions: [10, 20, 50],
}}
initialPageSize={20}
// Pagination handled client-side
{...}
/>const data = [
{ id: '1', name: 'John' },
{ id: '2', name: 'Jane' },
];
<ActiveGrid mode="client" data={data} {...} />function UsersTable() {
const [users, setUsers] = useState<User[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
async function loadUsers() {
const response = await api.getUsers();
setUsers(response.data);
setLoading(false);
}
loadUsers();
}, []);
if (loading) return <Spinner />;
return (
<ActiveGrid
mode="client"
data={users}
columns={columns}
/>
);
}import { useQuery } from '@tanstack/react-query';
function UsersTable() {
const { data, isLoading } = useQuery({
queryKey: ['users'],
queryFn: () => api.getUsers(),
});
if (isLoading) return <Spinner />;
return (
<ActiveGrid
mode="client"
data={data?.users || []}
columns={columns}
/>
);
}import useSWR from 'swr';
function UsersTable() {
const { data, error, isLoading } = useSWR('/api/users', fetcher);
if (isLoading) return <Spinner />;
if (error) return <Error />;
return (
<ActiveGrid
mode="client"
data={data.users}
columns={columns}
/>
);
}function UsersTable() {
const [users, setUsers] = useState<User[]>([]);
const refreshData = async () => {
const response = await api.getUsers();
setUsers(response.data);
};
return (
<>
<Button onClick={refreshData}>Refresh</Button>
<ActiveGrid
mode="client"
data={users}
columns={columns}
/>
</>
);
}function UsersTable() {
const [users, setUsers] = useState<User[]>(initialUsers);
const handleCommit = async (payload: EditingCommitPayload<User>) => {
// Optimistically update UI
setUsers(prev =>
prev.map(user =>
user.id === payload.rowId ? payload.newData : user
)
);
try {
await api.updateUser(payload.rowId, payload.changes);
} catch (error) {
// Revert on error
const response = await api.getUsers();
setUsers(response.data);
}
};
return (
<ActiveGrid
mode="client"
data={users}
columns={columns}
editMode="cell"
onDataCommit={handleCommit}
/>
);
}const data = useMemo(() => {
return rawData.map(item => ({
...item,
computed: calculateValue(item),
}));
}, [rawData]);
<ActiveGrid mode="client" data={data} {...} />const columns = useMemo<GridColumnDef<User>[]>(() => [
{ accessorKey: 'name', header: 'Name' },
{ accessorKey: 'email', header: 'Email' },
], []);
<ActiveGrid mode="client" columns={columns} {...} />For larger client-side datasets (1,000+ rows):
Client mode performance degrades with large datasets:
Monitor memory usage for large client-side datasets:
<ActiveGrid
mode="client"
data={largeDataset}
columns={columns}
enableVirtualization={true}
{...}
/><ActiveGrid
mode="client"
data={users}
columns={columns}
toolbar={{
search: { placeholder: 'Search all columns...' },
}}
{...}
/>const columns: GridColumnDef<User>[] = [
{
accessorKey: 'name',
header: 'Name',
meta: {
filterType: 'text',
},
},
{
accessorKey: 'status',
header: 'Status',
meta: {
filterType: 'select',
filterOptions: [
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' },
],
},
},
];{
accessorKey: 'tags',
header: 'Tags',
filterFn: (row, columnId, filterValue: string[]) => {
const rowTags = row.getValue(columnId) as string[];
return filterValue.some(tag => rowTags.includes(tag));
},
}// Auto-sorts based on data type
{
accessorKey: 'name',
header: 'Name',
enableSorting: true,
}{
accessorKey: 'priority',
header: 'Priority',
sortingFn: (rowA, rowB, columnId) => {
const order = { high: 0, medium: 1, low: 2 };
return order[rowA.getValue(columnId)] - order[rowB.getValue(columnId)];
},
}import { useState, useMemo } from 'react';
import { useQuery } from '@tanstack/react-query';
import { ActiveGrid, GridColumnDef } from '@workspace/active-grid';
type Product = {
id: string;
name: string;
price: number;
category: string;
inStock: boolean;
};
function ProductsTable() {
const { data, isLoading, refetch } = useQuery({
queryKey: ['products'],
queryFn: () => api.getProducts(),
});
const columns = useMemo<GridColumnDef<Product>[]>(() => [
{
accessorKey: 'name',
header: 'Product',
meta: {
filterType: 'text',
},
},
{
accessorKey: 'price',
header: 'Price',
meta: {
cellAlign: 'right',
valueFormatter: (value) => `$${value.toFixed(2)}`,
filterType: 'number',
},
},
{
accessorKey: 'category',
header: 'Category',
meta: {
filterType: 'select',
filterOptions: [
{ label: 'Electronics', value: 'electronics' },
{ label: 'Clothing', value: 'clothing' },
],
},
},
{
accessorKey: 'inStock',
header: 'In Stock',
meta: {
filterType: 'boolean',
},
cell: ({ getValue }) => (getValue() ? '✓' : '✗'),
},
], []);
if (isLoading) {
return <div>Loading...</div>;
}
return (
<ActiveGrid
mode="client"
data={data?.products || []}
columns={columns}
toolbar={{
search: {
placeholder: 'Search products...',
},
actions: (
<Button onClick={() => refetch()}>
Refresh
</Button>
),
}}
pagination={{
enabled: true,
pageSizeOptions: [10, 25, 50],
}}
initialPageSize={25}
enableVirtualization={data?.products?.length > 500}
/>
);
}// Approximate memory usage:
// 1,000 rows × 10 columns × 100 bytes = ~1 MB
// 10,000 rows × 10 columns × 100 bytes = ~10 MB
// 100,000 rows × 10 columns × 100 bytes = ~100 MBtype User = {
id: string;
name: string;
email: string;
};
const users: User[] = [...];
<ActiveGrid<User>
mode="client"
data={users}
columns={columns}
{...}
/>