Full-featured DataGrid
import { html, atom, nothing, renderApp } from 'mates';
import { Avatar, Badge, Chip, DataGrid, Text, dataGridExportCsv, filterDataGridRows, sortDataGridRows } from 'mates-ui';
const USERS = Array.from({ length: 50 }, (_, i) => ({
id: String(i + 1),
name: "User " + (i + 1),
email: "user" + (i + 1) + "@example.com",
role: (["Admin", "Editor", "Viewer"])[i % 3],
status: (["active", "inactive", "pending"])[i % 3],
joined: "Jan 2024",
}));
const STATUS_BADGE = { active: "success", inactive: "neutral", pending: "warning" };
const BASE_COLUMNS = [
{ id: "name", header: "Name", sortable: true, filterable: true, minWidth: 192, accessor: (r) => r.name,
cell: (r) => html`<div style="display:flex;align-items:center;gap:var(--md-space-2);">${Avatar({ name: r.name, size: "sm" })}<span style="font-weight:600;">${r.name}</span></div>` },
{ id: "email", header: "Email", sortable: true, filterable: true, minWidth: 224, accessor: (r) => r.email,
cell: (r) => html`<span style="color:var(--md-color-text-muted);">${r.email}</span>` },
{ id: "role", header: "Role", sortable: true, filterable: true, minWidth: 128, accessor: (r) => r.role,
cell: (r) => Chip(r.role, { variant: "assist" }) },
{ id: "status", header: "Status", sortable: true, minWidth: 112, align: "center", accessor: (r) => r.status,
cell: (r) => Badge(r.status, { variant: STATUS_BADGE[r.status] }) },
{ id: "joined", header: "Joined", sortable: true, minWidth: 128, accessor: (r) => r.joined,
cell: (r) => html`<span style="color:var(--md-color-text-muted);font-size:var(--md-text-xs);">${r.joined}</span>` },
];
const App = () => {
const colsAtom = atom([...BASE_COLUMNS]);
const sortBy = atom("name");
const sortDir = atom("asc");
const sel = atom([]);
const page = atom(1);
const pageSize = atom(8);
const globalFilter = atom("");
const colFilterModel = atom([]);