agentsclimarketplace

Materialreacttable mastery

Skill hackermanishackerman/claude-skills-vault/.claude/skills/materialreacttable-mastery

πŸ› οΈ Curate and enhance your coding skills with Claude Skills Vault, a collection of commands and MCP server guides for efficient development.

Install
npx -y skills add hackermanishackerman/claude-skills-vault --skill materialreacttable-mastery

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 4 stars4 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Material React Table V3 expert skill. Use when building feature-rich data tables w/ MUI styling, server-side ops, CRUD editing, virtualization, or complex filtering/sorting.

SKILL.md

10.2 KB, as published. Nobody here has run it

Material React Table Mastery

Build production-grade data tables w/ MRT V3 (TanStack Table V8 + MUI).

When to Use

  • Building data tables with MUI styling
  • Server-side pagination/filtering/sorting
  • CRUD editing (inline, modal, cell, table)
  • Large dataset virtualization (10k+ rows)
  • Complex filtering (date range, multi-select, faceted)
  • Migrating between MRT versions (V1β†’V2β†’V3)
  • MUI v7 compatibility issues

Triggers

  • /mrt-init - Initialize MRT setup w/ dependencies
  • /mrt-column - Generate typed column definitions
  • /mrt-crud - Add CRUD editing capabilities
  • /mrt-server - Configure server-side pagination/filtering/sorting
  • /mrt-migrate - Migrate between MRT versions (V1β†’V2β†’V3)
  • /mrt-state - State management, persistence, controlled state
  • /mrt-export - Data export (CSV, Excel, PDF)
  • /mrt-a11y - Accessibility & keyboard navigation setup

Reference Files

CategoryReferenceWhen to Load
Columnsreferences/column_definitions.mdAccessors, formatters, grouping, aggregation, V1β†’V2β†’V3 migration
Filteringreferences/filtering_sorting.mdFilter variants, global search, faceted
Paginationreferences/pagination_virtualization.mdServer-side, infinite scroll, virtualization
Editingreferences/editing_crud.mdInline, modal, row, cell, validation
Selectionreferences/row_selection.mdMulti-select, actions, bulk ops
Treereferences/tree_data.mdHierarchical data, expand/collapse
Customreferences/customization.mdToolbar, styling, mrtTheme, localization, z-index
Statereferences/state_management_apis.mdTable/row/cell APIs, state persistence, events
Advancedreferences/advanced_features.mdA11y, export, drag & drop, click-to-copy
Versionsreferences/version_compatibility.mdVersion matrix, migrations, prop renames

Core Tenets

1. TanStack Table Foundation

MRT wraps TanStack Table V8. Use useMaterialReactTable hook for full control.

import { useMaterialReactTable, MaterialReactTable } from 'material-react-table';

const table = useMaterialReactTable({
  columns,
  data,
  enableColumnFilters: true,
  enableGlobalFilter: true,
  enablePagination: true,
});

return <MaterialReactTable table={table} />;

2. Column Definitions in useMemo

ALWAYS wrap columns in useMemo to prevent unnecessary re-renders.

const columns = useMemo<MRT_ColumnDef<Person>[]>(() => [
  { accessorKey: 'name', header: 'Name', size: 200 },
  {
    accessorFn: (row) => `${row.firstName} ${row.lastName}`,
    id: 'fullName',
    header: 'Full Name',
  },
  {
    accessorKey: 'status',
    header: 'Status',
    filterVariant: 'select',
    filterSelectOptions: ['Active', 'Inactive', 'Pending'],
    Cell: ({ cell }) => (
      <Chip
        label={cell.getValue<string>()}
        color={cell.getValue() === 'Active' ? 'success' : 'default'}
      />
    ),
  },
  {
    accessorKey: 'salary',
    header: 'Salary',
    filterVariant: 'range-slider',
    Cell: ({ cell }) => cell.getValue<number>().toLocaleString('en-US', {
      style: 'currency', currency: 'USD',
    }),
    aggregationFn: 'sum',
    AggregatedCell: ({ cell }) => `Total: ${cell.getValue()}`,
  },
], []);

3. Server-Side Operations

For datasets > 100 rows, use server-side pagination/filtering/sorting.

const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });
const [sorting, setSorting] = useState<MRT_SortingState>([]);
const [globalFilter, setGlobalFilter] = useState('');

const { data, isLoading } = useQuery({
  queryKey: ['users', pagination, sorting, globalFilter],
  queryFn: () => fetchUsers({ pagination, sorting, globalFilter }),
});

const table = useMaterialReactTable({
  columns,
  data: data?.rows ?? [],
  rowCount: data?.totalCount ?? 0,
  manualPagination: true,
  manualSorting: true,
  manualFiltering: true,
  state: { pagination, sorting, globalFilter, isLoading },
  onPaginationChange: setPagination,
  onSortingChange: setSorting,
  onGlobalFilterChange: setGlobalFilter,
});

4. CRUD Editing

Support inline, modal, cell, or table editing modes.

const table = useMaterialReactTable({
  columns,
  data,
  enableEditing: true,
  editDisplayMode: 'row', // 'modal' | 'cell' | 'table'
  onEditingRowSave: async ({ values, row, table }) => {
    await updateUser(row.original.id, values);
    table.setEditingRow(null);
  },
  renderRowActions: ({ row, table }) => (
    <Box sx={{ display: 'flex', gap: '1rem' }}>
      <Tooltip title="Edit">
        <IconButton onClick={() => table.setEditingRow(row)}>
          <EditIcon />
        </IconButton>
      </Tooltip>
      <Tooltip title="Delete">
        <IconButton color="error" onClick={() => handleDelete(row.original.id)}>
          <DeleteIcon />
        </IconButton>
      </Tooltip>
    </Box>
  ),
});

5. Virtualization for Large Data

Enable row virtualization for 10,000+ rows.

const table = useMaterialReactTable({
  columns,
  data: largeDataset,
  enableRowVirtualization: true,
  rowVirtualizerOptions: { overscan: 5 },
  muiTableBodyRowProps: { sx: { height: 53 } }, // Fixed height for perf
});

Decision Tree

Dataset size?
β”œβ”€ < 100 rows β†’ Client-side (default)
β”œβ”€ 100-10,000 rows β†’ Server-side pagination
└─ > 10,000 rows β†’ Virtualization + server-side

Common Configurations

Use CaseConfiguration
Basic displayenableColumnFilters: false, enablePagination: false
EditableenableEditing: true, editDisplayMode: 'row'
SelectionenableRowSelection: true, enableMultiRowSelection: true
ExpandableenableExpanding: true, renderDetailPanel: ({row}) => <Details />
Tree dataenableExpanding: true, getSubRows: (row) => row.children
Server-sidemanualPagination: true, manualFiltering: true, manualSorting: true

Customization

Toolbar

renderTopToolbar: ({ table }) => (
  <Box sx={{ display: 'flex', gap: 2, p: 2 }}>
    <MRT_GlobalFilterTextField table={table} />
    <ExportButton data={data} />
  </Box>
),

Row Styling

muiTableBodyRowProps: ({ row }) => ({
  sx: { backgroundColor: row.original.isHighlighted ? 'action.hover' : undefined },
}),

Localization

import { MRT_Localization_ES } from 'material-react-table/locales/es';

localization: MRT_Localization_ES,

Filter Variants

TypeVariantUse Case
Text'text' (default)Free text search
Select'select'Enum/status fields
Multi-select'multi-select'Tags, categories
Range'range'Numeric ranges
Range Slider'range-slider'Price, age
Date'date'Date fields
Date Range'date-range'Date ranges
Autocomplete'autocomplete'Large option sets
Checkbox'checkbox'Boolean fields

React Query Integration

function UsersTable() {
  const [columnFilters, setColumnFilters] = useState<MRT_ColumnFiltersState>([]);
  const [globalFilter, setGlobalFilter] = useState('');
  const [sorting, setSorting] = useState<MRT_SortingState>([]);
  const [pagination, setPagination] = useState({ pageIndex: 0, pageSize: 10 });

  const { data, isLoading, isError } = useQuery({
    queryKey: ['users', columnFilters, globalFilter, pagination, sorting],
    queryFn: () => fetchUsers({ columnFilters, globalFilter, pagination, sorting }),
    placeholderData: keepPreviousData,
  });

  const table = useMaterialReactTable({
    columns,
    data: data?.users ?? [],
    rowCount: data?.meta?.totalRowCount ?? 0,
    manualFiltering: true,
    manualPagination: true,
    manualSorting: true,
    state: { columnFilters, globalFilter, isLoading, pagination, showAlertBanner: isError, sorting },
    onColumnFiltersChange: setColumnFilters,
    onGlobalFilterChange: setGlobalFilter,
    onPaginationChange: setPagination,
    onSortingChange: setSorting,
  });

  return <MaterialReactTable table={table} />;
}

Anti-Patterns

Don'tDo
Recreate columns on every renderWrap in useMemo
Fetch all data for server-sideImplement backend pagination
Skip virtualization for 10k+ rowsEnable enableRowVirtualization
Custom filter UI for common casesUse built-in filterVariant
Ignore loading statesUse isLoading state prop
Inline column definitionsDefine outside component or useMemo
Hardcode table textUse localization prop

Dependencies

npm install material-react-table @mui/material @mui/x-date-pickers @mui/icons-material @emotion/react @emotion/styled @tanstack/react-query

Version Compatibility

MRTMUIReactNotes
V36+ (v7 experimental)18+Current - keyboard nav default
V25.11+17+Maintenance
V15.0+17+Deprecated

MUI v7 Status: ⚠️ Not officially supported yet. Known issues: dark mode broken, TypeScript errors. Use --legacy-peer-deps if required. Track GitHub #1401.

Key V2β†’V3 changes: text β†’ label in select options, keyboard nav enabled by default.

Checklist

  • Columns wrapped in useMemo
  • Proper accessors (accessorKey | accessorFn + id)
  • filterVariant set per column type
  • Server-side for > 100 rows
  • Virtualization for > 10k rows
  • isLoading state connected
  • Error states handled (showAlertBanner)
  • Validation in onEditingRowSave
  • Row actions labeled for a11y
  • LocalizationProvider if using date filters
  • Version-appropriate props (V1β†’V2β†’V3 renames)
  • z-index handled if table in modal/drawer

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.