Examples
Every working example of active-grid on one page, with its kind and the file that renders it.
@workspace/active-grid 11.0.0Status unknowncontent differs from the recorded release 11.0.0baseline ce081dc3
The kinds are explained on Client, server and simulation. The data is a seeded set of invented orders: every reader sees the same rows.
Orders in client modeClient
Full source examples/grid/client-orders.tsx
// apps/docs/examples/grid/client-orders.tsx'use client';
import '@workspace/active-grid/styles.css';
import {useMemo} from 'react';import {generateOrders, type Order} from '@/lib/examples/orders';
import { composePresentationContext, toIanaTimeZone,} from '@workspace/active-format';import { ActiveGrid, createColumnHelper, englishGridTranslator, type GridColumnDef,} from '@workspace/active-grid';
// The presentation: language, notation and the time zone the date filter// needs for its relative presets and calendar.const presentation = composePresentationContext( 'en-GB', null, toIanaTimeZone('Europe/Amsterdam'),);
const STATUS = [ {label: 'Pending', value: 'pending'}, {label: 'Processing', value: 'processing'}, {label: 'Shipped', value: 'shipped'}, {label: 'Delivered', value: 'delivered'}, {label: 'Cancelled', value: 'cancelled'},];
const ch = createColumnHelper<Order>();const columns: GridColumnDef<Order>[] = [ ch.accessor('id', {header: 'Order', meta: {filterType: 'text'}}), ch.accessor('customer', {header: 'Customer', meta: {filterType: 'text'}}), ch.accessor('category', { header: 'Category', meta: {filterType: 'select'}, }), ch.accessor('quantity', {header: 'Qty', type: 'number'}), ch.accessor('total', { header: 'Total', type: 'currency', meta: {currencyCode: 'EUR', filterType: 'number'}, }), ch.accessor('orderDate', {header: 'Ordered', type: 'date'}), ch.accessor('status', { header: 'Status', type: 'badge', meta: { filterType: 'select', filterOptions: STATUS, statusTones: { pending: 'warning', processing: 'info', shipped: 'info', delivered: 'success', cancelled: 'danger', }, }, }),];
/** Client mode: all 500 rows are in the browser; the grid sorts, filters and pages them there. */export default function ClientOrders() { const data = useMemo(() => generateOrders(500), []); return ( <ActiveGrid<Order> gridId="docs-client-orders" mode="client" data={data} columns={columns} height={420} locale={presentation} t={englishGridTranslator} enableRowSelection pagination={{enabled: true, pageSizeOptions: [10, 25, 50]}} toolbar={{search: {enabled: true}, showColumnChooser: true}} /> );}Server mode against an imitated serverSimulation: A server imitated in your browser: shows the interaction, not a working server integration.
Full source examples/grid/simulated-orders.tsx
// apps/docs/examples/grid/simulated-orders.tsx'use client';
import '@workspace/active-grid/styles.css';
import {useCallback, useMemo, useState} from 'react';import {generateOrders, queryOrders, type Order} from '@/lib/examples/orders';
import { composePresentationContext, toIanaTimeZone,} from '@workspace/active-format';import { ActiveGrid, createColumnHelper, englishGridTranslator, scalarField, type GridColumnDef, type ServerFetchFunction,} from '@workspace/active-grid';import { Field, FieldLabel,} from '@workspace/active-ui/components/primitives/field';import {Switch} from '@workspace/active-ui/components/primitives/switch';
const presentation = composePresentationContext( 'en-GB', null, toIanaTimeZone('Europe/Amsterdam'),);
const ch = createColumnHelper<Order>();const columns: GridColumnDef<Order>[] = [ ch.accessor('id', { header: 'Order', meta: {filterType: 'text'}, server: scalarField(), }), ch.accessor('product', { header: 'Product', meta: {filterType: 'text'}, server: scalarField(), }), ch.accessor('quantity', { header: 'Qty', type: 'number', server: scalarField(), }), ch.accessor('total', { header: 'Total', type: 'currency', meta: {currencyCode: 'EUR', filterType: 'number'}, server: scalarField(), }),];
const wait = (ms: number, signal: AbortSignal) => new Promise<void>((resolve, reject) => { const timer = setTimeout(resolve, ms); signal.addEventListener('abort', () => { clearTimeout(timer); reject(signal.reason); }); });
/** * Server mode against a server imitated in the browser: a fetchFn with a * delay over rows that are already here, and a switch that makes it fail. * It shows the grid's loading, paging and error states, not a server. */export default function SimulatedOrders() { const orders = useMemo(() => generateOrders(2000), []); const [failing, setFailing] = useState(false); const fetchOrders = useCallback<ServerFetchFunction<Order>>( async ({signal, ...params}) => { await wait(600, signal); if (failing) throw new Error('The simulated server is down'); return queryOrders(orders, params); }, [orders, failing], ); return ( <div className="flex flex-col gap-4"> <Field orientation="horizontal"> <Switch id="simulated-failure" // Named in the server HTML already, not only after hydration. aria-labelledby="simulated-failure-label" checked={failing} onCheckedChange={setFailing} /> <FieldLabel id="simulated-failure-label" htmlFor="simulated-failure"> Make the next request fail </FieldLabel> </Field> <ActiveGrid<Order> key={String(failing)} gridId="docs-simulated-orders" mode="server" fetchFn={fetchOrders} columns={columns} height={360} locale={presentation} t={englishGridTranslator} pagination={{enabled: true}} serverOptions={{blockSize: 25, retryCount: 0}} /> </div> );}Server mode against a real routeServer: Calls a real route of this site, which does the work on the server.
Requests (POST /api/examples/grid/orders)
Full source examples/grid/server-orders.tsx
// apps/docs/examples/grid/server-orders.tsx'use client';
import '@workspace/active-grid/styles.css';
import {useCallback, useState} from 'react';import type {Order} from '@/lib/examples/orders';
import { composePresentationContext, toIanaTimeZone,} from '@workspace/active-format';import { ActiveGrid, createColumnHelper, englishGridTranslator, globalField, scalarField, type GridColumnDef, type PagedResponse, type ServerFetchFunction,} from '@workspace/active-grid';
const presentation = composePresentationContext( 'en-GB', null, toIanaTimeZone('Europe/Amsterdam'),);
const ch = createColumnHelper<Order>();// In server mode the column contract (`server`) declares what the server can// sort and filter; the grid offers exactly that, and nothing the server would// refuse.const columns: GridColumnDef<Order>[] = [ ch.accessor('id', { header: 'Order', meta: {filterType: 'text'}, server: {...scalarField(), global: globalField()}, }), ch.accessor('customer', { header: 'Customer', meta: {filterType: 'text'}, server: {...scalarField(), global: globalField()}, }), ch.accessor('category', { header: 'Category', meta: {filterType: 'select'}, server: {...scalarField(), global: globalField()}, }), ch.accessor('total', { header: 'Total', type: 'currency', meta: {currencyCode: 'EUR', filterType: 'number'}, server: scalarField(), }), ch.accessor('orderDate', { header: 'Ordered', type: 'date', meta: {filterType: 'date'}, server: scalarField(), }), ch.accessor('status', { header: 'Status', meta: {filterType: 'select'}, server: scalarField(), }),];
interface Exchange { n: number; request: string; answer: string;}
/** * Server mode against a real route of this site. The browser sends the * grid's request (page, block size, sorting, filters, search); the server * filters, sorts and pages 5,000 orders and answers with one block. */export default function ServerOrders() { const [log, setLog] = useState<Exchange[]>([]); const fetchOrders = useCallback<ServerFetchFunction<Order>>( async ({signal, ...params}) => { const body = JSON.stringify(params); const response = await fetch('/api/examples/grid/orders', { method: 'POST', headers: {'Content-Type': 'application/json'}, body, signal, }); const text = await response.text(); if (!response.ok) throw new Error(`The server refused: ${text}`); const page = JSON.parse(text) as PagedResponse<Order>; setLog((list) => [ { n: (list[0]?.n ?? 0) + 1, request: body, answer: `${page.data.length} rows of ${page.totalCount}, ${(text.length / 1024).toFixed(1)} kB`, }, ...list, ].slice(0, 5), ); return page; }, [], ); return ( <div className="flex flex-col gap-4"> <ActiveGrid<Order> gridId="docs-server-orders" mode="server" fetchFn={fetchOrders} columns={columns} height={380} locale={presentation} t={englishGridTranslator} pagination={{enabled: true, pageSizeOptions: [10, 25, 50]}} toolbar={{search: {enabled: true}}} serverOptions={{blockSize: 50, retryCount: 0}} /> <section aria-label="Requests to the server" data-request-log> <h3 className="mb-2 text-sm font-semibold"> Requests (POST /api/examples/grid/orders) </h3> <ol className="flex flex-col gap-2"> {log.map((exchange) => ( <li key={exchange.n} className="bg-muted rounded-md p-2 font-mono text-xs break-all" data-request={exchange.n} > <div> #{exchange.n} → {exchange.request} </div> <div className="text-muted-foreground">← {exchange.answer}</div> </li> ))} </ol> </section> </div> );}