gm-datagrid
v0.1.23
Published
Enterprise Excel-like data grid with Rust/Wasm engine, featuring inline-aligned group subtotals and automatic group aggregate preloading
Downloads
643
Maintainers
Readme
gm-datagrid
Enterprise-grade, Excel-like data grid for React — powered by a Rust/WebAssembly core engine.
- ⚡ Handles 100 000+ rows at 60 FPS with canvas-free virtualization
- 🦥 Sorting, filtering, and Excel export run inside Rust/Wasm — off the main thread
- 📋 Excel-compatible clipboard (Ctrl+C / Ctrl+V TSV)
- ✏️ Inline cell editing with async validation and automatic revert on error
- 📊 Column subtotals updated live as filters change
- 🔢 Inline Group Aggregations — column-aligned aggregates visible directly in group headers (even when collapsed)
- 🔢 Aggregation footer row —
sum,avg,min,max,sizeper column; MUI DataGrid Premium compatibleaggregationModelAPI - 📅 Date filter operators — is / is not / is after / is before / is empty / is not empty
- 📥 Multi-format export — toolbar picker for
xlsx(styled, freeze pane, zebra striping via ExcelJS),csv,txt,json - 🌐 Built-in i18n —
locale="es"/locale="en"with full label overrides - 🔒 Feature flags — selectively disable export, filters, sort, or grouping per instance
- 🧹 Clear all filters button in toolbar (desktop + mobile)
- 🎨 Built on MUI — inherits your existing theme automatically
Installation
# npm
npm install gm-datagrid
# pnpm
pnpm add gm-datagrid
# yarn
yarn add gm-datagridPeer dependencies
npm install react react-dom @mui/material @mui/icons-material @emotion/react @emotion/styledQuick start
import { GMDatagrid, ColumnDataTypesEnum } from 'gm-datagrid'
const columns = [
{ field: 'id', headerName: 'ID', type: ColumnDataTypesEnum.ID },
{ field: 'name', headerName: 'Name', type: ColumnDataTypesEnum.STRING, sortable: true },
{ field: 'price', headerName: 'Price', type: ColumnDataTypesEnum.PRICE, calculateSubTotal: true },
{ field: 'stock', headerName: 'Stock', type: ColumnDataTypesEnum.INT },
]
async function fetchProducts(params) {
const res = await fetch('/api/products?' + new URLSearchParams(params))
const data = await res.json()
return { success: true, data }
}
export default function ProductsPage() {
return (
<GMDatagrid
title="Products"
columns={columns}
sourceApi={fetchProducts}
apiParameters={{ active: true }}
/>
)
}Props
| Prop | Type | Default | Description |
|---|---|---|---|
| title | string | required | Grid heading shown in the toolbar |
| columns | ColumnDef[] | required | Column definitions (see below) |
| sourceApi | (params) => Promise<{ success, data }> | — | Async data fetcher. Called on mount and after every refresh() |
| apiParameters | object | {} | Extra params merged into every sourceApi call |
| localData | Row[] | — | Static data — skips sourceApi entirely |
| apiContext | ApiContext | — | Injected into every sourceApi call (e.g. companyId, authToken) |
| processRowUpdate | (newRow, oldRow) => Row \| Promise<Row> | — | Called when a cell is saved. Throw to reject and revert |
| quickFilter | boolean | true | Show / hide the global search input in the toolbar |
| quickFilterPlaceholder | string | — | Placeholder text for the quick-filter input |
| rowColorGetter | (row) => { backgroundColor?, color? } | — | Per-row color highlights (e.g. overdue rows in red) |
| onRowDetail | (row) => void | — | Called when the user opens a row detail (double-click or menu action) |
| checkboxSelection | boolean | false | Prepend a checkbox column for row selection |
| onRowSelectionChange | (rows: Row[]) => void | — | Fires on every selection change with the full array of selected rows |
| locale | 'es' \| 'en' | 'es' | Built-in UI language. See Internationalisation |
Pagination props
| Prop | Type | Default | Description |
|---|---|---|---|
| paginationMode | 'client' \| 'server' | 'client' | Client-side (engine) or server-side pagination |
| paginationModel | { page: number; pageSize: number } | { page: 0, pageSize: 25 } | Controlled pagination state |
| onPaginationModelChange | (model) => void | — | Called when the user changes page or page size |
| pageSizeOptions | number[] | [25, 50, 100] | Rows-per-page options shown in the footer selector |
| rowCount | number | — | Total row count for server-side pagination |
Feature flags
Control which toolbar actions and column interactions are available without touching individual column definitions.
| Prop | Type | Default | Description |
|---|---|---|---|
| exportable | boolean | true | Show / hide the Export button in the toolbar |
| exportFormats | ExportFormat[] | ['xlsx', 'csv'] | Which formats appear in the export menu. A single format skips the menu and downloads directly |
| exportableColumns | string[] | — | Whitelist of field values included in the .xlsx export. Omit to export all visible columns |
| filterable | boolean | true | Show / hide the filter panel toggle button and the per-column filter row |
| filterableColumns | string[] | — | Only these fields render a filter input in the filter panel |
| sortable | boolean | true | Enable / disable sort on all column headers globally |
| sortableColumns | string[] | — | Only these fields respond to header click-to-sort. Overrides per-column sortable |
| groupable | boolean | false | Show / hide the group-by picker in the toolbar |
| groupableColumns | string[] | — | Fields offered in the group-by picker. Falls back to all columns when omitted |
| editable | boolean | false | Enable / disable inline editing globally |
| editableColumns | string[] | — | Only these fields are editable (overrides per-column editable flag) |
| aggregable | boolean | false | Enable the aggregation footer row. Off by default — zero overhead when unused |
| aggregationModel | AggregationModel | — | Controlled { field: fn } map (see Aggregation) |
| onAggregationModelChange | (model: AggregationModel) => void | — | Fired when the aggregation model changes |
| initialState | { aggregation?: { model: AggregationModel } } | — | Uncontrolled seed — mirrors MUI DataGrid Premium initialState.aggregation.model |
Example — read-only reporting grid with restricted export:
<GMDatagrid
title="Sales Report"
columns={columns}
sourceApi={fetchSales}
sortable={false} // no sort at all
filterable // filters on (default)
filterableColumns={['customer', 'status', 'date']}
exportable
exportableColumns={['customer', 'total', 'date']} // exclude internal fields
groupable
groupableColumns={['customer', 'status']}
/>Per-column flags still apply. If you set
sortable={true}globally but a column hassortable: falsein itsColumnDef, that column remains non-sortable. The whitelist (sortableColumns) is intersected with the per-column flag — a field must pass both to be interactive.
Column definition (ColumnDef)
interface ColumnDef {
field: string // key in the row object
headerName?: string // display label (falls back to field)
type: ColumnDataTypesEnum // controls rendering, formatting and export
width?: number // initial width in px
minWidth?: number // minimum resize width in px
flex?: number // flex-grow factor (like CSS flex)
hide?: boolean // exclude column from render
pin?: 'left' | 'right' // sticky pinned columns
sortable?: boolean // enable header click to sort
filterable?: boolean // include in filter panel
editable?: boolean // enable inline cell editing
calculateSubTotal?: boolean // show live aggregate in header; default fn chosen by column type
aggregable?: boolean // set false to exclude from aggregation footer
availableAggregationFunctions?: AggregationFunction[] // restrict fn picker per column
renderCell?: (params: CellRenderParams) => ReactNode // custom renderer
valueGetter?: (row: Row) => unknown // transform raw value before render
valueFormatter?: (value: unknown) => string // format to display string
statusMap?: Record<string, { label: string; color: string }> // for `status` type
}Column types (ColumnDataTypesEnum)
| Value | Renders as | Notes |
|---|---|---|
| STRING | Plain text | Default |
| NUMBER | 1,234 | Right-aligned |
| PRICE | 1,234.0000 | 4 decimal places, right-aligned |
| TOTAL | 1,234.00 | 2 decimal places, right-aligned |
| DISCOUNT | Progress bar | 0–100 range |
| PERCENT | Progress bar | 0–100 range |
| TAX | Progress bar | 0–100 range |
| MARGIN | Progress bar | 0–100 range |
| DATE | DD/MM/YYYY | Date operator filter panel |
| DATE_TIME | DD/MM/YYYY HH:mm:ss | Date operator filter panel |
| STATUS | Coloured chip | Use statusMap to configure labels/colors |
| LABELS | Array of chips | Cell value must be string[] |
| IMAGE | 40 px avatar | Cell value is a URL |
| ACTION | Custom renderer | Provide renderCell |
| MENU_ACTION | Icon button + menu | Triggers onRowDetail |
| ID | Plain text | |
| INT | 1,234 | Integer, right-aligned |
| CODE | Plain text | Monospace hint |
| ARRAY | Comma-joined | Cell value is string[] |
| TEXT | Plain text | Multi-line friendly |
Ref API (imperative handle)
Use GMGridContainer when you need to refresh the grid or update its parameters from outside:
import { useRef } from 'react'
import { GMGridContainer } from 'gm-datagrid'
import type { GMGridContainerRef } from 'gm-datagrid'
export default function OrdersPage() {
const gridRef = useRef<GMGridContainerRef>(null)
return (
<>
<button onClick={() => gridRef.current?.refresh()}>Refresh</button>
<button onClick={() => gridRef.current?.setParams({ status: 'PENDING' })}>
Show pending
</button>
<GMGridContainer
ref={gridRef}
title="Orders"
columns={columns}
sourceApi={fetchOrders}
/>
</>
)
}| Method | Signature | Description |
|---|---|---|
| refresh() | () => void | Re-fetches data with the current params |
| setParams(p) | (params: object) => void | Replaces apiParameters and re-fetches |
GMDatagrid also supports a ref with an extended handle:
import { useRef } from 'react'
import { GMDatagrid } from 'gm-datagrid'
import type { GMDatagridRef } from 'gm-datagrid'
const ref = useRef<GMDatagridRef>(null)
// Programmatic row selection
ref.current?.getSelectedRows() // Row[]
ref.current?.clearSelection()
ref.current?.setSelectedIds(['id1', 'id2'])
ref.current?.refresh()Context hook (useGMGrid)
Access the grid state from any child component rendered inside GMDatagrid:
import { useGMGrid } from 'gm-datagrid'
function OrderSummary() {
const { data, loading, totalCount } = useGMGrid()
if (loading) return null
return <p>{totalCount} orders loaded</p>
}| Field | Type | Description |
|---|---|---|
| data | Row[] | All rows currently in the dataset |
| loading | boolean | true while sourceApi is in flight |
| totalCount | number | Total filtered row count (for pagination display) |
| handleRefresh | () => void | Trigger a manual refresh |
| selectedIds | Set<string> | IDs of currently selected rows |
Pagination
The grid renders a footer with page pills and a rows-per-page selector.
Client-side (default)
The Wasm engine slices rows in memory — no extra API calls on page change:
<GMDatagrid
title="Products"
columns={columns}
sourceApi={fetchProducts}
pageSizeOptions={[10, 25, 50]}
/>Server-side
Control pagination yourself and pass the total row count:
const [paginationModel, setPaginationModel] = useState({ page: 0, pageSize: 25 })
async function fetchPage(params) {
const { page, pageSize } = params
const res = await api.get('/products', { page, pageSize })
return { success: true, data: res.rows, total: res.total }
}
<GMDatagrid
title="Products"
columns={columns}
sourceApi={fetchPage}
paginationMode="server"
paginationModel={paginationModel}
onPaginationModelChange={setPaginationModel}
rowCount={totalFromServer}
pageSizeOptions={[25, 50, 100]}
/>Row selection
Enable checkboxes and respond to selection changes:
const [selected, setSelected] = useState([])
<GMDatagrid
title="Invoices"
columns={columns}
sourceApi={fetchInvoices}
checkboxSelection
onRowSelectionChange={setSelected}
/>
// Bulk action button
<button disabled={selected.length === 0} onClick={() => bulkDelete(selected)}>
Delete {selected.length} rows
</button>Programmatic control via ref:
const ref = useRef<GMDatagridRef>(null)
ref.current?.getSelectedRows() // get current selection
ref.current?.setSelectedIds(['a', 'b']) // select programmatically
ref.current?.clearSelection() // deselect allDate filter operators
DATE and DATE_TIME columns show an operator dropdown in the filter panel:
| Operator | Description |
|---|---|
| is | Exact date match |
| is not | Excludes the selected date |
| is after | Strictly after the selected date |
| is on or after | On or after the selected date |
| is before | Strictly before the selected date |
| is on or before | On or before the selected date |
| is empty | Cell is null or empty — no calendar shown |
| is not empty | Cell has any value — no calendar shown |
The filter value is represented as DateFilterValue:
import type { DateFilterValue, DateFilterOp } from 'gm-datagrid'
// { op: 'gt', value: '2026-01-01' }
// { op: 'isNull', value: '' }Inline editing
Enable editable: true on a column and provide processRowUpdate:
async function saveRow(newRow, oldRow) {
const res = await fetch(`/api/products/${newRow.id}`, {
method: 'PATCH',
body: JSON.stringify(newRow),
})
if (!res.ok) throw new Error('Save failed')
return newRow
}
<GMDatagrid
title="Products"
columns={[
{ field: 'name', type: ColumnDataTypesEnum.STRING, editable: true },
{ field: 'price', type: ColumnDataTypesEnum.PRICE, editable: true },
]}
sourceApi={fetchProducts}
processRowUpdate={saveRow}
/>Keyboard shortcuts while editing:
| Key | Action |
|---|---|
| Any printable key | Enter edit mode, replace value |
| F2 | Enter edit mode, keep current value |
| Enter | Save and move to the next row |
| Tab / Shift+Tab | Save and move right / left |
| Escape | Discard and exit edit mode |
| Arrow keys | Move focused cell (view mode only) |
| Ctrl+Arrow / Meta+Arrow | Passed through to the browser — never hijacked |
Focus-scoped keyboard handling — all grid keyboard shortcuts are active only when focus is inside the grid. Arrow keys,
Shift+Arrow,Ctrl+Arrow, and clipboard shortcuts (Ctrl+C/Ctrl+V) in other inputs or text areas on the same page are never intercepted by the grid.
Custom cell renderer
import { ColumnDataTypesEnum } from 'gm-datagrid'
const columns = [
{
field: 'status',
type: ColumnDataTypesEnum.ACTION,
renderCell: ({ row, value }) => (
<span style={{ color: value === 'ACTIVE' ? 'green' : 'red' }}>
{String(value)}
</span>
),
},
]The renderCell function receives:
| Param | Type | Description |
|---|---|---|
| row | Row | The full row object |
| field | string | The column field name |
| value | unknown | The (possibly valueGetter-transformed) cell value |
| colDef | ColumnDef | The full column definition |
Row colour highlights
<GMDatagrid
title="Invoices"
columns={columns}
sourceApi={fetchInvoices}
rowColorGetter={(row) => {
if (row.overdue) return { backgroundColor: '#fff3f3', color: '#c62828' }
if (row.status === 'PAID') return { backgroundColor: '#f3fff5' }
return {}
}}
/>Multi-tenant / authenticated APIs
Use apiContext to inject auth tokens or tenant IDs without modifying each sourceApi:
import { useSession } from './contexts/SessionContext'
function App() {
const { token, companyId } = useSession()
return (
<GMDatagrid
title="Customers"
columns={columns}
sourceApi={fetchCustomers}
apiContext={{ authToken: token, companyId }}
/>
)
}Multi-format export
By default the toolbar shows an export button that downloads both .xlsx and .csv. When more than one format is enabled a format picker menu opens on click:
<GMDatagrid
title="Products"
columns={columns}
sourceApi={fetchProducts}
exportFormats={['xlsx', 'csv', 'txt', 'json']} // all four formats
/>
// xlsx only — no menu, direct download
<GMDatagrid exportFormats={['xlsx']} ... />
// Disable export entirely
<GMDatagrid exportable={false} ... />Supported formats
| Format | Extension | Notes |
|---|---|---|
| xlsx | .xlsx | Client-side via ExcelJS — styled headers, freeze pane, zebra striping, native number/date cell types |
| csv | .csv | RFC 4180, UTF-8 BOM — opens correctly in Excel |
| txt | .txt | Tab-separated values — paste directly into Excel |
| json | .json | Array of objects keyed by column field |
ACTION, MENU_ACTION, and IMAGE columns are automatically excluded from all exports.
xlsx formatting
The generated .xlsx file includes:
| Feature | Detail |
|---|---|
| Header row | Bold white text, GStore blue (#251BBC) fill, medium bottom border |
| Freeze pane | Header row stays visible while scrolling |
| Zebra striping | Alternating light grey rows for readability |
| Number formats | #,##0 (NUMBER/INT), #,##0.0000 (PRICE), #,##0.00 (TOTAL), 0.00 (progress types) |
| Date formats | Native Excel date cells — dd/mm/yyyy / dd/mm/yyyy hh:mm:ss |
| Alignment | Numeric columns are right-aligned |
| Column widths | Auto-sized from header + first 200 rows (clamped 8–60 chars) |
| valueFormatter | Applied to string/status/label columns — same output as csv/txt |
Subtotals
Set calculateSubTotal: true on any column to display a live aggregate in the column header. The value updates as filters change. No aggregationModel prop is needed — the default aggregation function is chosen automatically based on the column type:
| Column type | Default function |
|---|---|
| number, price, total, int, discount, percent, tax, margin | sum |
| date, dateTime | count-distinct |
| boolean / field named active | count-true |
| status, labels | count-distinct |
| string, text, all others | count |
{ field: 'amount', type: ColumnDataTypesEnum.TOTAL, calculateSubTotal: true } // → sum
{ field: 'date', type: ColumnDataTypesEnum.DATE, calculateSubTotal: true } // → count-distinct
{ field: 'active', type: ColumnDataTypesEnum.STRING, calculateSubTotal: true } // → count-true
{ field: 'status', type: ColumnDataTypesEnum.STATUS, calculateSubTotal: true } // → count-distinctYou can still override the function or restrict which functions appear in the picker:
{ field: 'price', type: ColumnDataTypesEnum.PRICE, calculateSubTotal: true,
availableAggregationFunctions: ['avg', 'min', 'max'] }Aggregation
Show a sticky footer row with computed aggregate values per column. Compatible with MUI DataGrid Premium's aggregationModel API.
Feature flag — disabled by default. Set
aggregableto opt in.
Basic usage
<GMDatagrid
aggregable // enable the feature
aggregationModel={{ total: 'sum', price: 'avg', id: 'size' }}
columns={columns}
sourceApi={fetchData}
/>Controlled model with change callback
const [aggModel, setAggModel] = useState({ total: 'sum' });
<GMDatagrid
aggregable
aggregationModel={aggModel}
onAggregationModelChange={setAggModel}
...
/>Uncontrolled initial state (MUI-compatible)
<GMDatagrid
aggregable
initialState={{ aggregation: { model: { total: 'sum', price: 'avg' } } }}
...
/>Per-column control
// Exclude a column from the footer and picker entirely
{ field: 'code', type: ColumnDataTypesEnum.CODE, aggregable: false }
// Restrict which functions appear in the column's picker
{ field: 'price', type: ColumnDataTypesEnum.PRICE, availableAggregationFunctions: ['avg', 'min', 'max'] }Built-in aggregation functions
| Function | Symbol | Description |
|---|---|---|
| sum | Σ | Sum of all non-null values |
| avg | x̄ | Arithmetic mean of non-null values |
| min | min | Smallest value (lexicographic for strings/dates) |
| max | max | Largest value (lexicographic for strings/dates) |
| size | # | Count of non-null cells |
| count | # | Count of non-null cells (alias for size) |
| count-distinct | ≠# | Count of unique non-null values |
| count-true | ✓ | Count of truthy / "true" / true values |
| count-false | ✗ | Count of falsy / "false" / false values |
Interactive function picker
Columns with calculateSubTotal: true show a small pill in the column header with the active function symbol (Σ, x̄, min, max, #, ≠#, ✓, ✗). Clicking the pill opens a Popover listing the functions available for that column's type (or the availableAggregationFunctions override). Selecting a function updates the model and fires onAggregationModelChange. A Remove aggregation option clears the column from the model.
Group aggregation sub-rows
When both aggregable and groupable are enabled, every expanded group shows a compact sub-row (blue left border, muted background) with per-group aggregate values aligned to their columns.
<GMDatagrid
aggregable
groupable
aggregationModel={{ total: 'sum', price: 'avg' }}
onAggregationModelChange={setAggModel}
columns={[
{ field: 'customer', type: ColumnDataTypesEnum.STRING },
{ field: 'total', type: ColumnDataTypesEnum.TOTAL },
{ field: 'price', type: ColumnDataTypesEnum.PRICE, availableAggregationFunctions: ['avg', 'min', 'max'] },
{ field: 'code', type: ColumnDataTypesEnum.CODE, aggregable: false },
]}
sourceApi={fetchOrders}
/>Aggregation props
| Prop | Type | Default | Description |
|---|---|---|---|
| aggregable | boolean | false | Enable the aggregation footer row and group sub-rows |
| aggregationModel | AggregationModel | — | Controlled { field: fn } map |
| onAggregationModelChange | (model) => void | — | Fired when the model changes (picker or programmatic) |
| initialState.aggregation.model | AggregationModel | — | Uncontrolled seed — mirrors MUI DataGrid Premium initialState |
TypeScript
All types are exported from the package root:
import type {
ColumnDef,
GMDatagridProps,
GMDatagridRef,
GMGridContainerRef,
Row,
CellRenderParams,
CellEditParams,
ExportFormat,
AggregationFunction,
AggregationModel,
AggregationResults,
FilterGroup,
FilterCellValue,
DateFilterValue,
DateFilterOp,
RangeValue,
SortKey,
ApiContext,
GridLabels,
GridLocale,
FilterCellLabels,
} from 'gm-datagrid'
import { ColumnDataTypesEnum, isRangeValue, isDateFilterValue } from 'gm-datagrid'Editing
Per-column editability
Set editable: true on each ColumnDef you want users to edit. The global editable prop and editableColumns whitelist take precedence.
Editing events (MUI DataGrid compatible)
import type { CellEditParams } from 'gm-datagrid'
<GMDatagrid
title="Products"
columns={columns}
sourceApi={fetchProducts}
editable
editableColumns={['name', 'price', 'stock']}
processRowUpdate={async (newRow, oldRow) => {
await api.patch(`/products/${newRow.id}`, newRow)
return newRow
}}
onCellEditStart={(params: CellEditParams) => {
console.log('editing started', params.field, params.value)
}}
onCellEditStop={(params: CellEditParams) => {
console.log('editing stopped', params.field)
}}
isCellEditable={(params: CellEditParams) => {
// Only allow editing rows that are in DRAFT status
return params.row.status === 'DRAFT'
}}
/>Programmatic editing via ref
import { useRef } from 'react'
import { GMDatagrid } from 'gm-datagrid'
import type { GMDatagridRef } from 'gm-datagrid'
const ref = useRef<GMDatagridRef>(null)
// Start editing a specific cell
ref.current?.startCellEditMode({ id: 'row-1', field: 'name' })
// Save and exit
ref.current?.stopCellEditMode({ id: 'row-1', field: 'name' })
// Discard changes and exit
ref.current?.stopCellEditMode({ id: 'row-1', field: 'name', ignoreModifications: true })CellEditParams interface
interface CellEditParams {
id: string | number // row id
field: string // column field name
value: unknown // current cell value
row: Row // full row object
}Editability hierarchy
All four levels must pass for a cell to be editable:
editableprop — global feature flag (falseby default)editableColumnswhitelist — if set, field must be in the listcol.editable— per-column flag inColumnDefisCellEditable(params)callback — per-row guard
Internationalisation (locale)
All built-in toolbar and filter labels are translated automatically when you set the locale prop.
// Spanish (default)
<GMDatagrid locale="es" title="Productos" columns={columns} sourceApi={fetchProducts} />
// English
<GMDatagrid locale="en" title="Products" columns={columns} sourceApi={fetchProducts} />Supported locales
| Code | Language |
|---|---|
| 'es' | Spanish (default) |
| 'en' | English |
Custom labels
Need a label that doesn't match either locale, or want to override a single string? Import GridLabels and pass a labels prop directly (takes priority over locale):
import type { GridLabels } from 'gm-datagrid'
const myLabels: Partial<GridLabels> = {
// Toolbar / filter
search: 'Rechercher…',
filterBy: 'Filtrer par colonne',
hideFilters: 'Masquer les filtres',
clearFilters: 'Effacer les filtres',
all: 'Tous',
yes: 'Oui',
no: 'Non',
min: 'Min',
max: 'Max',
noGroup: 'Sans regroupement',
// Pagination
noRows: '0 enregistrements',
rowsRange: '{from}–{to} sur {total} enregistrements',
rowsPerPage: 'Lignes par page :',
firstPage: 'Première page',
prevPage: 'Page précédente',
nextPage: 'Page suivante',
lastPage: 'Dernière page',
// Row selection
selectAll: 'Tout sélectionner',
deselectAll: 'Tout désélectionner',
selectionSingular: 'élément sélectionné',
selectionPlural: 'éléments sélectionnés',
clearSelection: 'Effacer',
// Groups
emptyGroup: '(Vide)',
// Engine error
engineError: "Impossible d'initialiser le moteur de données",
// Aggregation
aggregationFns: {
sum: 'Somme',
avg: 'Moyenne',
min: 'Minimum',
max: 'Maximum',
size: 'Nombre',
},
aggregationTooltipLabel: '{fn} : {value}',
// Date filter operators
dateOps: {
equals: 'est',
not: "n'est pas",
gt: 'est après',
gte: 'est le ou après',
lt: 'est avant',
lte: 'est le ou avant',
isNull: 'est vide',
isNotNull: "n'est pas vide",
},
}
<GMDatagrid labels={myLabels} title="Produits" columns={columns} sourceApi={fetchProducts} />All fields are optional — omit any key to fall back to the active locale.
GridLabels reference
| Key | es default | en default |
|---|---|---|
| search | Buscar… | Search… |
| filterBy | Filtrar por columna | Filter by column |
| hideFilters | Ocultar filtros | Hide filters |
| clearFilters | Limpiar filtros | Clear filters |
| noRows | 0 registros | 0 records |
| rowsRange | {from}–{to} de {total} registros | {from}–{to} of {total} records |
| rowsPerPage | Filas por página: | Rows per page: |
| firstPage | Primera página | First page |
| prevPage | Página anterior | Previous page |
| nextPage | Página siguiente | Next page |
| lastPage | Última página | Last page |
| selectAll | Seleccionar todo | Select all |
| deselectAll | Deseleccionar todo | Deselect all |
| selectionSingular | elemento seleccionado | item selected |
| selectionPlural | elementos seleccionados | items selected |
| clearSelection | Limpiar | Clear |
| emptyGroup | (Sin valor) | (Empty) |
| engineError | No se pudo inicializar el motor de datos | Could not initialize the data engine |
| aggregationFns.sum | Suma | Sum |
| aggregationFns.avg | Promedio | Average |
| aggregationFns.min | Mínimo | Minimum |
| aggregationFns.max | Máximo | Maximum |
| aggregationFns.size | Cantidad | Count |
| aggregationTooltipLabel | {fn}: {value} | {fn}: {value} |
Changelog
See CHANGELOG.md.
License
MIT
