react-gridix 0.2.3 → 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +353 -71
- package/package.json +9 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# react-gridix Documentation
|
|
2
2
|
|
|
3
|
-
A React `DataGrid` with row selection, server-side mode, typed per-column filters, date columns, in-cell editing, resizing and pinning, virtualization, CSV
|
|
3
|
+
A React `DataGrid` with row selection, server-side mode, typed per-column filters, date columns, in-cell editing, resizing and pinning, virtualization, export to CSV / Excel / JSON / PDF, 12 row animations, filter comparisons and 8 themes, plus the `Checkbox` it uses.
|
|
4
4
|
|
|
5
5
|
**Contents**
|
|
6
6
|
|
|
@@ -11,9 +11,7 @@ A React `DataGrid` with row selection, server-side mode, typed per-column filter
|
|
|
11
11
|
5. [Checkbox](#5-checkbox)
|
|
12
12
|
6. [DataGrid](#6-datagrid)
|
|
13
13
|
7. [Demos](#7-demos)
|
|
14
|
-
8. [Troubleshooting](#
|
|
15
|
-
9. [Migrating from the earlier version](#10-migrating-from-the-earlier-version)
|
|
16
|
-
|
|
14
|
+
8. [Troubleshooting](#8-troubleshooting)
|
|
17
15
|
---
|
|
18
16
|
|
|
19
17
|
## 1. Overview
|
|
@@ -45,6 +43,11 @@ A React `DataGrid` with row selection, server-side mode, typed per-column filter
|
|
|
45
43
|
Everything is written in TypeScript, ships its own type definitions, and uses plain CSS (no CSS-in-JS runtime). The grid is 100% of its container's width by default. There is deliberately **no column reordering**.
|
|
46
44
|
|
|
47
45
|
---
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+

|
|
49
|
+
|
|
50
|
+

|
|
48
51
|
|
|
49
52
|
## 2. Installation
|
|
50
53
|
|
|
@@ -62,6 +65,15 @@ import "react-gridix/style.css";
|
|
|
62
65
|
|
|
63
66
|
The library does not inject CSS by itself. If the grid looks unstyled, this import is missing.
|
|
64
67
|
|
|
68
|
+
**Optional: PDF export.** CSV, Excel (`.xlsx`) and JSON export need nothing extra. PDF export uses three small libraries that are loaded only when someone exports a PDF, so install them only if you use it:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm install jspdf jspdf-autotable # the PDF itself and its table
|
|
72
|
+
npm install html2canvas # only if the PDF header / footer is a React element (it is drawn to a picture)
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Without them, a PDF export reports an error that names the missing package (see `onExportError`) and everything else keeps working.
|
|
76
|
+
|
|
65
77
|
---
|
|
66
78
|
|
|
67
79
|
## 3. Quick start
|
|
@@ -427,7 +439,8 @@ The grid is generic: `DataGrid<T>` infers `T` from `rows`, and `ColumnDef<T>` ch
|
|
|
427
439
|
| `virtualize` | `boolean` | `false` | Render only the visible rows |
|
|
428
440
|
| `rowHeight` | `number` | `40` | Row height in px when virtualizing |
|
|
429
441
|
| `overscan` | `number` | `6` | Extra rows drawn above and below the window |
|
|
430
|
-
| `exportable` | `boolean \| ExportOptions` | `false` | Show an "Export CSV"
|
|
442
|
+
| `exportable` | `boolean \| ExportOptions` | `false` | Show an export button in the toolbar. `true` gives "Export CSV"; `{ formats: ["csv", "xlsx", "json", "pdf"] }` gives an "Export" menu. See [6.19](#619-export-and-the-api) |
|
|
443
|
+
| `onExportError` | `(error: Error, format: ExportFormat) => void` | | Called when an export fails (for example `jspdf` is not installed). Without it the error is logged to the console |
|
|
431
444
|
| `apiRef` | `MutableRefObject<DataGridApi<T> \| null>` | | Call `exportCsv()`, `getSelectedRows()` and more from outside |
|
|
432
445
|
|
|
433
446
|
**Look and feel**
|
|
@@ -438,10 +451,16 @@ The grid is generic: `DataGrid<T>` infers `T` from `rows`, and `ColumnDef<T>` ch
|
|
|
438
451
|
| `toolbar` | `ReactNode` | | Extra content on the right of the toolbar |
|
|
439
452
|
| `showToolbar` | `boolean` | `true` | Set `false` to remove the toolbar row completely (search box, Columns, Export, selected count and your `toolbar`), even when those features are on |
|
|
440
453
|
| `emptyMessage` | `ReactNode` | `"No rows to show"` | Shown when no rows match |
|
|
454
|
+
| `emptyComponent` | `ComponentType<EmptyStateProps<T>>` | | Your own component shown instead of `emptyMessage`. Receives `{ reason, search, filters, columns, clearAll }`. See [6.26](#626-custom-empty-state) |
|
|
455
|
+
| `sortIndicator` | `"default" \| "arrow" \| ComponentType<SortIndicatorProps<T>>` | `"default"` | The arrow in sortable headers. See [6.25](#625-sort-indicator) |
|
|
441
456
|
| `striped` | `boolean` | `false` | Alternate row shading |
|
|
442
457
|
| `stripeColors` | `[string, string]` | | Two colours for the alternating rows. Implies `striped`. See [striped rows](#striped-rows) |
|
|
443
|
-
| `animateRows` | `boolean` | `true` | Rows
|
|
444
|
-
| `
|
|
458
|
+
| `animateRows` | `boolean` | `true` | Rows animate in when they appear and out when they leave. See [row animation](#row-animation) |
|
|
459
|
+
| `rowAnimation` | `RowAnimationName \| { enter?, exit? }` | `"slide-up"` | Which of the 12 built-in animations to use (`"fade"`, `"zoom"`, `"flip-x"`, ...), for both directions or `{ enter, exit }` |
|
|
460
|
+
| `rowAnimationDuration` | `number` | `380` | Milliseconds an entrance takes (an exit takes 80% of it) |
|
|
461
|
+
| `rowAnimationStagger` | `number` | `28` | Milliseconds between rows that appear together. `0` starts them all at once |
|
|
462
|
+
| `rowExitAnimationClassName` | `string \| (row, rowIndex) => string` | | Your own CSS class for rows that leave, like `rowAnimationClassName` is for rows that arrive |
|
|
463
|
+
| `rowAnimationClassName` | `string \| (row, rowIndex) => string` | | Your own CSS class for the entrance animation. Replaces the built-in one. See [custom row animation](#custom-row-animation) |
|
|
445
464
|
| `checkboxVariant` | `"button" \| "tick" \| "native"` | `"native"` | Checkbox look for boolean columns and row selection. Columns can override it |
|
|
446
465
|
| `maxHeight` | `number \| string` | | Makes the body scroll, with a sticky header. Example: `400` or `"60vh"` |
|
|
447
466
|
| `className` | `string` | | Classes for the root element (Tailwind works). The grid is `width: 100%` of its container by default |
|
|
@@ -480,6 +499,9 @@ const columns: ColumnDef<Employee>[] = [
|
|
|
480
499
|
| `filterType` | `"text" \| "exact" \| "number" \| "date" \| "select"` | Which filter controls the popup shows. Default follows `type` |
|
|
481
500
|
| `filterOptions` | `(string \| FilterOption)[]` | Choices for a `"select"` filter. Without it they are built from the data |
|
|
482
501
|
| `filterPlaceholder` | `string` | Placeholder of the text filter box |
|
|
502
|
+
| `filterOperators` | `boolean \| TextFilterOperator[]` | Adds a drop-down to the text filter popup: contains, does not contain, equals, not equal, starts with, ... Off by default (the column then always means "contains"). See [6.24](#624-filter-comparisons) |
|
|
503
|
+
| `filterOperator` | `TextFilterOperator` | The comparison selected first when `filterOperators` is on. Default `"contains"` |
|
|
504
|
+
| `sortIndicator` | `"default" \| "arrow" \| Component` | Overrides the grid's `sortIndicator` for this column |
|
|
483
505
|
| `filterDebounce` | `number` | Milliseconds to wait after typing in **this** column's text / exact / number filter before it is applied. Overrides the grid's `filterDebounce` (default 300). `0` applies on every keystroke |
|
|
484
506
|
| `filterIndicator` | `ComponentType<FilterIndicatorProps<T>>` | Your own component drawn instead of the default dot |
|
|
485
507
|
| `filterIndicatorClassName` / `filterIndicatorStyle` | `string` / `CSSProperties` | Classes and inline styles for this column's indicator button |
|
|
@@ -1234,7 +1256,9 @@ Add `headerCheckbox: true` to a boolean column. The header label becomes a check
|
|
|
1234
1256
|
| `pageInfo` | The "Page 1 of 20" text |
|
|
1235
1257
|
| `pageSize` | The rows-per-page `<select>` |
|
|
1236
1258
|
| `pagination` | Wrapper around the page-size menu and buttons |
|
|
1237
|
-
| `toolButton` | Toolbar buttons (Columns, Export
|
|
1259
|
+
| `toolButton` | Toolbar buttons (Columns, Export, Retry) |
|
|
1260
|
+
| `exportMenu` | The "Export" button when several formats are offered (in addition to `toolButton`) |
|
|
1261
|
+
| `sortIndicator` | The wrapper of the arrow in a sortable header |
|
|
1238
1262
|
| `skeleton` | The shimmering bars of the loading skeleton |
|
|
1239
1263
|
| `pageButton` | Each first/previous/next/last button |
|
|
1240
1264
|
| `checkbox` | Root of each checkbox in a `type: "boolean"` column |
|
|
@@ -1304,28 +1328,59 @@ Rows alternate between the two colours, starting with the first. `stripeColors`
|
|
|
1304
1328
|
|
|
1305
1329
|
#### Row animation
|
|
1306
1330
|
|
|
1307
|
-
|
|
1331
|
+
Rows animate when they appear and when they leave. It is on by default (a slide up, and a slide up and fade out). The important part is that **rows are matched by their id (`getRowId`)**, so the grid never replays the animation on rows that stay:
|
|
1332
|
+
|
|
1333
|
+
- A **new row** adds itself to the list with the "in" animation, while every other row stays exactly where it is.
|
|
1334
|
+
- A **removed row** (deleted, or hidden by a search or filter) stays on screen for a moment, plays the "out" animation where it was, then goes. The rows around it do not move until it is gone.
|
|
1335
|
+
- Changing the **page** (or the page size) replaces the rows at once with the "in" animation: it would be odd to show the old page leaving.
|
|
1336
|
+
- Sorting moves rows without animating them.
|
|
1308
1337
|
|
|
1309
1338
|
```tsx
|
|
1310
|
-
<DataGrid animateRows={false} />
|
|
1339
|
+
<DataGrid animateRows={false} /> // turn it off
|
|
1340
|
+
<DataGrid rowAnimation="zoom" /> // zoom in, zoom out
|
|
1341
|
+
<DataGrid rowAnimation={{ enter: "slide-left", exit: "fade" }} /> // mix the two directions
|
|
1342
|
+
<DataGrid rowAnimation={{ enter: "bounce", exit: "none" }} /> // "none": rows just disappear
|
|
1343
|
+
<DataGrid rowAnimation="flip-x" rowAnimationDuration={600} rowAnimationStagger={60} />
|
|
1311
1344
|
```
|
|
1312
1345
|
|
|
1313
|
-
|
|
1346
|
+
The built-in animations (each has an "in" and an "out" version):
|
|
1347
|
+
|
|
1348
|
+
| Name | In | Out |
|
|
1349
|
+
| --- | --- | --- |
|
|
1350
|
+
| `"fade"` | fades in | fades out |
|
|
1351
|
+
| `"slide-up"` (default) | rises from below | floats up |
|
|
1352
|
+
| `"slide-down"` | drops from above | sinks down |
|
|
1353
|
+
| `"slide-left"` | slides in from the left | slides out to the left |
|
|
1354
|
+
| `"slide-right"` | slides in from the right | slides out to the right |
|
|
1355
|
+
| `"zoom"` | grows from small | shrinks away |
|
|
1356
|
+
| `"flip-x"` | flips up around its horizontal axis | flips away |
|
|
1357
|
+
| `"flip-y"` | swings in around its vertical axis | swings out |
|
|
1358
|
+
| `"rotate"` | turns and scales in | turns and scales out |
|
|
1359
|
+
| `"skew"` | slides in leaning over | slides out leaning over |
|
|
1360
|
+
| `"blur"` | comes into focus | blurs away |
|
|
1361
|
+
| `"bounce"` | drops in and bounces | hops and jumps out |
|
|
1362
|
+
| `"none"` | no animation | removed at once |
|
|
1363
|
+
|
|
1364
|
+
Use a row id that does not change: `getRowId={(row) => row.id}`. Without it the grid uses the row's position as its id, and removing a row from the middle makes every row after it look different, so the wrong row animates out.
|
|
1365
|
+
|
|
1366
|
+
Tuning: `rowAnimationDuration` (default 380 ms; exits take 80%), `rowAnimationStagger` (default 28 ms between rows that appear together, up to 24 rows). The same values exist as CSS variables on the grid: `--rg-row-duration`, `--rg-row-exit-duration` and `--rg-row-stagger`, so you can also set them in your own CSS. Visitors who ask their system for reduced motion get no animation, and rows leave at once. Animation is also off while `virtualize` is on.
|
|
1314
1367
|
|
|
1315
1368
|
#### Custom row animation
|
|
1316
1369
|
|
|
1317
|
-
Pass your own CSS class to replace the built-in
|
|
1370
|
+
Pass your own CSS class to replace the built-in animation: `rowAnimationClassName` for rows that arrive and `rowExitAnimationClassName` for rows that leave. The class should set `animation`; an exit class should end in the hidden state and keep it (`forwards`). Every row also gets the CSS variable `--rg-i` (its position among the rows that appear or leave together, 0 to 24), so a delay of `calc(var(--rg-i) * 40ms)` makes rows come one after another.
|
|
1318
1371
|
|
|
1319
1372
|
```css
|
|
1320
1373
|
@keyframes fade-left { from { opacity: 0; transform: translateX(-24px); } to { opacity: 1; transform: none; } }
|
|
1321
|
-
|
|
1374
|
+
@keyframes fade-right { to { opacity: 0; transform: translateX(24px); } }
|
|
1375
|
+
.row-fade-left { animation: fade-left 0.45s ease-out both; animation-delay: calc(var(--rg-i, 0) * 45ms); }
|
|
1376
|
+
.row-fade-right { animation: fade-right 0.3s ease-in forwards; }
|
|
1322
1377
|
```
|
|
1323
1378
|
|
|
1324
1379
|
```tsx
|
|
1325
|
-
<DataGrid rowAnimationClassName="row-fade-left" ... />
|
|
1380
|
+
<DataGrid rowAnimationClassName="row-fade-left" rowExitAnimationClassName="row-fade-right" ... />
|
|
1326
1381
|
```
|
|
1327
1382
|
|
|
1328
|
-
|
|
1383
|
+
Both can be functions of the row, for example to flash new rows:
|
|
1329
1384
|
|
|
1330
1385
|
```tsx
|
|
1331
1386
|
<DataGrid rowAnimationClassName={(row) => (row.isNew ? "row-flash" : "row-fade-left")} ... />
|
|
@@ -1333,9 +1388,10 @@ It can also be a function of the row, for example to animate new rows differentl
|
|
|
1333
1388
|
|
|
1334
1389
|
With Tailwind, define the keyframes in your config and use the utility, for example `rowAnimationClassName="animate-fade-in-left [animation-delay:calc(var(--rg-i)*40ms)]"`.
|
|
1335
1390
|
|
|
1336
|
-
-
|
|
1337
|
-
-
|
|
1338
|
-
-
|
|
1391
|
+
- A custom class replaces the built-in animation of its direction only: you can customise just the entrance and keep the built-in exit, or the reverse.
|
|
1392
|
+
- A leaving row is removed when its animation ends (or after 2.5 seconds if your class has none).
|
|
1393
|
+
- `animateRows={false}` turns every row animation off, custom or not.
|
|
1394
|
+
- Reduced motion: the built-in animations stop for people who ask for it. Your own class is yours to handle: wrap it in `@media (prefers-reduced-motion: no-preference) { ... }`.
|
|
1339
1395
|
|
|
1340
1396
|
#### What does `classNames={{ cell: "border border-teal-400 py-2" }}` do?
|
|
1341
1397
|
|
|
@@ -1507,7 +1563,7 @@ const [current, setCurrent] = useState<Person | null>(null);
|
|
|
1507
1563
|
{current && <PersonDetails person={current} />}
|
|
1508
1564
|
```
|
|
1509
1565
|
|
|
1510
|
-
**From outside the grid**, with `apiRef` (see [6.19](#619-
|
|
1566
|
+
**From outside the grid**, with `apiRef` (see [6.19](#619-export-and-the-api)):
|
|
1511
1567
|
|
|
1512
1568
|
```tsx
|
|
1513
1569
|
const api = useRef<DataGridApi<Person> | null>(null);
|
|
@@ -1704,7 +1760,7 @@ api.current?.refresh();
|
|
|
1704
1760
|
|
|
1705
1761
|
**Server mode and the other features.**
|
|
1706
1762
|
|
|
1707
|
-
- Selection, [CSV export of selected rows](#619-
|
|
1763
|
+
- Selection, [CSV export of selected rows](#619-export-and-the-api) and keyboard navigation work on the loaded page.
|
|
1708
1764
|
- With `scope: "filtered"` the CSV contains the rows currently loaded (the current page), because the grid does not have the rest.
|
|
1709
1765
|
- `defaultSort` is sent in the first query. `multiSort` lets users send several sort columns.
|
|
1710
1766
|
- `onQueryChange` is the only place the grid asks for data. Without `serverSide`, the grid never calls it.
|
|
@@ -1858,7 +1914,7 @@ With `virtualize`, moving past the visible window scrolls the target row into vi
|
|
|
1858
1914
|
|
|
1859
1915
|
Without `keyboardNavigation`, cells are reachable with Tab (editable cells) or the mouse, as before.
|
|
1860
1916
|
|
|
1861
|
-
### 6.19
|
|
1917
|
+
### 6.19 Export and the API
|
|
1862
1918
|
|
|
1863
1919
|
**The export button.** Switch on `exportable` for an "Export CSV" button in the toolbar. It downloads what the user sees: the visible columns, in order, for every row matching the search and filters (across all pages).
|
|
1864
1920
|
|
|
@@ -1869,12 +1925,146 @@ Without `keyboardNavigation`, cells are reachable with Tab (editable cells) or t
|
|
|
1869
1925
|
<DataGrid exportable={{ scope: "selected" }} rowSelection ... /> // only the selected rows
|
|
1870
1926
|
```
|
|
1871
1927
|
|
|
1928
|
+
**More formats: Excel, JSON and PDF.** List the formats you want and the button becomes an "Export" menu:
|
|
1929
|
+
|
|
1930
|
+
```tsx
|
|
1931
|
+
<DataGrid
|
|
1932
|
+
rowSelection
|
|
1933
|
+
pagination
|
|
1934
|
+
exportable={{ filename: "employees", formats: ["csv", "xlsx", "json", "pdf"] }}
|
|
1935
|
+
columns={columns} rows={rows} getRowId={(r) => r.id}
|
|
1936
|
+
/>
|
|
1937
|
+
```
|
|
1938
|
+
|
|
1939
|
+
The menu has two parts. **Rows to export** lets the user pick *Visible rows* (what is on screen: the current page), *All matching rows* (every page; only offered with `pagination`) or *Selected rows* (only offered with `rowSelection`, and disabled while nothing is selected). Each choice shows how many rows it covers. **Download as** has one button per format. The menu remembers the last choice. With a single format (the default `["csv"]`) you get the plain "Export CSV" / "Export Excel" / "Export JSON" / "Export PDF" button instead, using `scope` from `exportable`.
|
|
1940
|
+
|
|
1941
|
+
| Format | What you get | Needs |
|
|
1942
|
+
| --- | --- | --- |
|
|
1943
|
+
| `"csv"` | Text of the displayed values, opens in any spreadsheet | nothing |
|
|
1944
|
+
| `"xlsx"` | A real Excel workbook: bold coloured header row that stays in place while you scroll, auto-filter, sized columns, real numbers, real dates and real booleans | nothing (written by the library itself) |
|
|
1945
|
+
| `"json"` | An array of objects, one per row, with real numbers and booleans and ISO dates (`"2026-11-05"`) | nothing |
|
|
1946
|
+
| `"pdf"` | A paged table with an optional title, header, footer and "Page 1 of 3" | `jspdf` and `jspdf-autotable` (and `html2canvas` for a header / footer element) |
|
|
1947
|
+
|
|
1948
|
+
The same exports are available from code, for your own buttons:
|
|
1949
|
+
|
|
1950
|
+
```tsx
|
|
1951
|
+
const api = useRef<DataGridApi<Employee> | null>(null);
|
|
1952
|
+
<DataGrid apiRef={api} rowSelection ... />
|
|
1953
|
+
|
|
1954
|
+
api.current?.exportXlsx({ scope: "selected", filename: "picked", sheetName: "Picked" });
|
|
1955
|
+
api.current?.exportJson({ scope: "visible", jsonKeys: "header", jsonIndent: 0 });
|
|
1956
|
+
await api.current?.exportPdf({ scope: "filtered", pdf: { title: "All employees" } });
|
|
1957
|
+
await api.current?.exportAs("csv", { scope: "page" }); // any format by name
|
|
1958
|
+
|
|
1959
|
+
const json: string = api.current!.getJson({ scope: "filtered" }); // build without downloading
|
|
1960
|
+
const blob: Blob = await api.current!.getXlsx(); // e.g. upload it to your server
|
|
1961
|
+
const pdf: Blob = await api.current!.getPdf();
|
|
1962
|
+
const csv: string = api.current!.getCsv();
|
|
1963
|
+
```
|
|
1964
|
+
|
|
1965
|
+
`exportXlsx` and `exportPdf` return promises. They **reject** when something goes wrong (a missing library, for instance), so `try / catch` them in your own code. The toolbar menu catches errors for you and sends them to `onExportError`:
|
|
1966
|
+
|
|
1967
|
+
```tsx
|
|
1968
|
+
<DataGrid
|
|
1969
|
+
onExportError={(error, format) => toast.error(`${format} export failed: ${error.message}`)}
|
|
1970
|
+
exportable={{ formats: ["csv", "pdf"] }}
|
|
1971
|
+
/>
|
|
1972
|
+
```
|
|
1973
|
+
|
|
1974
|
+
**Which rows.** `scope` accepts `"filtered"` (default), `"visible"` or `"page"` (the same: the rows on screen) and `"selected"`. A page export continues the row numbers of a `sequence` column (page 2 starts at 11) unless the column has `sequenceRestartEachPage`.
|
|
1975
|
+
|
|
1976
|
+
**What each format writes.** CSV and PDF write the displayed text (`valueFormatter` applied, `Yes` / `No` for booleans, dates as `YYYY-MM-DD`). Excel and JSON write real values: a number column stays a number (`52000`, not `"$52,000"`), a boolean column stays `true` / `false`, a date column is a real Excel date, a column with a `valueFormatter` that changes text (for example codes shown as names) writes the shown text. A column's `exportValue(value, row)` overrides all of this in every format.
|
|
1977
|
+
|
|
1978
|
+
#### PDF header and footer
|
|
1979
|
+
|
|
1980
|
+
`pdf.header` and `pdf.footer` accept **a string or a React element**, and appear on every page.
|
|
1981
|
+
|
|
1982
|
+
```tsx
|
|
1983
|
+
// A string. {page}, {pages} and {date} are replaced on each page.
|
|
1984
|
+
<DataGrid
|
|
1985
|
+
exportable={{
|
|
1986
|
+
formats: ["pdf"],
|
|
1987
|
+
pdf: {
|
|
1988
|
+
title: "Employee list",
|
|
1989
|
+
header: "Acme Corporation, People report ({date})",
|
|
1990
|
+
footer: "Confidential, page {page} of {pages}",
|
|
1991
|
+
},
|
|
1992
|
+
}}
|
|
1993
|
+
/>
|
|
1994
|
+
```
|
|
1995
|
+
|
|
1996
|
+
```tsx
|
|
1997
|
+
// A component: a logo, colours, borders, anything you can style. Images and inline styles work.
|
|
1998
|
+
import logo from "./logo.png";
|
|
1999
|
+
|
|
2000
|
+
<DataGrid
|
|
2001
|
+
exportable={{
|
|
2002
|
+
formats: ["pdf"],
|
|
2003
|
+
pdf: {
|
|
2004
|
+
header: (
|
|
2005
|
+
<div style={{ display: "flex", alignItems: "center", gap: 12, borderBottom: "3px solid #4f46e5", paddingBottom: 6 }}>
|
|
2006
|
+
<img src={logo} alt="" width={40} height={40} style={{ borderRadius: 8 }} />
|
|
2007
|
+
<div>
|
|
2008
|
+
<div style={{ fontSize: 20, fontWeight: 700, color: "#312e81" }}>Acme Corporation</div>
|
|
2009
|
+
<div style={{ fontSize: 12, color: "#6b7280" }}>People & Culture report</div>
|
|
2010
|
+
</div>
|
|
2011
|
+
</div>
|
|
2012
|
+
),
|
|
2013
|
+
footer: <div style={{ textAlign: "center", fontSize: 11, color: "#6b7280" }}>Confidential. Do not share.</div>,
|
|
2014
|
+
},
|
|
2015
|
+
}}
|
|
2016
|
+
/>
|
|
2017
|
+
```
|
|
2018
|
+
|
|
2019
|
+
An element is drawn off-screen, turned into a picture with `html2canvas`, and placed on each page, shrunk to fit the page width and `maxImageHeight` (default 90 pt) with its proportions kept. A few things to know about elements:
|
|
2020
|
+
|
|
2021
|
+
- They fill the page width, so lay them out with `display: flex` and `justify-content` inside (the `headerAlign` / `footerAlign` options move strings, not elements).
|
|
2022
|
+
- They are drawn once, so they cannot show the page number. Use a string footer for "page 2 of 5", or both: an element header and a string footer.
|
|
2023
|
+
- Images must be loadable from the page: your own assets, data URLs, or servers that allow cross-origin use (CORS). Otherwise the browser blocks the picture.
|
|
2024
|
+
- Inline styles and plain CSS classes work. Very new CSS features may not be supported by `html2canvas`.
|
|
2025
|
+
|
|
2026
|
+
Other `pdf` options:
|
|
2027
|
+
|
|
2028
|
+
| Option | Default | Meaning |
|
|
2029
|
+
| --- | --- | --- |
|
|
2030
|
+
| `title` | | A heading above the table on the first page |
|
|
2031
|
+
| `header`, `footer` | | A string or element, on every page |
|
|
2032
|
+
| `headerAlign`, `footerAlign` | `"left"`, `"center"` | Where a **string** goes: `"left"`, `"center"`, `"right"` |
|
|
2033
|
+
| `orientation` | `"auto"` | `"portrait"`, `"landscape"`, or `"auto"` (landscape when there are more than 6 columns) |
|
|
2034
|
+
| `pageSize` | `"a4"` | `"a3"`, `"a4"`, `"a5"`, `"letter"`, `"legal"` |
|
|
2035
|
+
| `margin` | `36` | Points around the page (72 points = 1 inch) |
|
|
2036
|
+
| `fontSize` | `9` | Table text size in points |
|
|
2037
|
+
| `tableTheme` | `"striped"` | `"striped"`, `"grid"` or `"plain"` |
|
|
2038
|
+
| `headColor`, `headTextColor` | `"#4f46e5"`, `"#ffffff"` | Colours of the table's header row, as hex |
|
|
2039
|
+
| `pageNumbers` | `true` | "Page 1 of 3" in the bottom right |
|
|
2040
|
+
| `maxImageHeight` | `90` | Tallest header / footer picture, in points |
|
|
2041
|
+
| `fontName`, `beforeRender` | | Use another font (see below) |
|
|
2042
|
+
|
|
2043
|
+
jsPDF's built-in fonts cover Western European letters. For other alphabets (Arabic, Chinese, ...) register a font in `beforeRender` and name it in `fontName`:
|
|
2044
|
+
|
|
2045
|
+
```tsx
|
|
2046
|
+
pdf: {
|
|
2047
|
+
fontName: "NotoSans",
|
|
2048
|
+
beforeRender: (doc) => {
|
|
2049
|
+
doc.addFileToVFS("NotoSans.ttf", notoSansBase64); // your font file as base64
|
|
2050
|
+
doc.addFont("NotoSans.ttf", "NotoSans", "normal");
|
|
2051
|
+
},
|
|
2052
|
+
}
|
|
2053
|
+
```
|
|
2054
|
+
|
|
2055
|
+
#### Export options
|
|
2056
|
+
|
|
1872
2057
|
| `ExportOptions` | Default | Meaning |
|
|
1873
2058
|
| --- | --- | --- |
|
|
1874
|
-
| `filename` | `"export"` | File name without
|
|
1875
|
-
| `scope` | `"filtered"` | `"filtered"` all rows matching search and filters, `"page"` the
|
|
2059
|
+
| `filename` | `"export"` | File name without the extension |
|
|
2060
|
+
| `scope` | `"filtered"` | `"filtered"` all rows matching search and filters, `"visible"` / `"page"` the rows on screen, `"selected"` the selected rows |
|
|
1876
2061
|
| `includeHidden` | `false` | Also write hidden columns |
|
|
1877
|
-
| `sanitize` | `true` |
|
|
2062
|
+
| `sanitize` | `true` | CSV only: put an apostrophe in front of text starting with `=`, `+`, `-` or `@`, so Excel does not run it as a formula |
|
|
2063
|
+
| `formats` | `["csv"]` | The formats the toolbar offers: any of `"csv"`, `"xlsx"`, `"json"`, `"pdf"` |
|
|
2064
|
+
| `sheetName` | `"Sheet1"` | Excel only: the worksheet's name |
|
|
2065
|
+
| `jsonKeys` | `"field"` | JSON only: use each column's `"field"` or its `"header"` text as the key |
|
|
2066
|
+
| `jsonIndent` | `2` | JSON only: spaces of indentation (`0` for one line) |
|
|
2067
|
+
| `pdf` | | PDF only: see above |
|
|
1878
2068
|
|
|
1879
2069
|
**What goes in the file.** The header row uses the column header names. Cell values are the displayed text (the result of `valueFormatter`, `Yes` / `No` for booleans), except that dates are written as `YYYY-MM-DD`. Numbers therefore export formatted (`$52,000`) unless you give an `exportValue`. To decide a column's value yourself, add `exportValue`:
|
|
1880
2070
|
|
|
@@ -2131,7 +2321,132 @@ const markDone = () => setRows((rs) => rs.map((r) => (ids.includes(r.id) ? { ...
|
|
|
2131
2321
|
<DataGrid serverSide pagination searchable multiSort theme="aurora" columns={columns} rows={rows} rowCount={total} onQueryChange={load} />
|
|
2132
2322
|
```
|
|
2133
2323
|
|
|
2134
|
-
### 6.24
|
|
2324
|
+
### 6.24 Filter comparisons
|
|
2325
|
+
|
|
2326
|
+
A text filter normally means "contains". Switch on `filterOperators` on a column and its popup gets a drop-down on top, so the user chooses **how** to compare:
|
|
2327
|
+
|
|
2328
|
+
| Choice | A row passes when its text... |
|
|
2329
|
+
| --- | --- |
|
|
2330
|
+
| Contains | has the typed text anywhere |
|
|
2331
|
+
| Does not contain | does not have it anywhere |
|
|
2332
|
+
| Equals | is exactly the typed text |
|
|
2333
|
+
| Not equal | is anything else |
|
|
2334
|
+
| Starts with | begins with it |
|
|
2335
|
+
| Does not start with | does not begin with it |
|
|
2336
|
+
| Ends with | ends with it |
|
|
2337
|
+
| Does not end with | does not end with it |
|
|
2338
|
+
|
|
2339
|
+
All comparisons ignore upper / lower case. Changing the choice filters straight away; typing waits for `filterDebounce` as usual.
|
|
2340
|
+
|
|
2341
|
+
```tsx
|
|
2342
|
+
const columns: ColumnDef<User>[] = [
|
|
2343
|
+
{ field: "name", filterable: true, filterOperators: true }, // all eight
|
|
2344
|
+
{ field: "email", filterable: true,
|
|
2345
|
+
filterOperators: ["contains", "startsWith", "endsWith", "equals"], // only these four
|
|
2346
|
+
filterOperator: "startsWith" }, // selected first
|
|
2347
|
+
{ field: "department", filterable: true }, // no drop-down: always "contains"
|
|
2348
|
+
];
|
|
2349
|
+
```
|
|
2350
|
+
|
|
2351
|
+
- It is **off by default**. A column without `filterOperators` shows just the box and always means "contains" (or "equals" for `filterType: "exact"`).
|
|
2352
|
+
- It applies to text columns (`filterType` `"text"` or `"exact"`). It does nothing for number, date or select filters, nor when you supply your own `filterRenderer`.
|
|
2353
|
+
- Pass `true` for all eight, or a list to offer fewer. The list keeps the order shown above. `filterOperator` sets the first choice (default `"contains"`).
|
|
2354
|
+
- Keyboard: focus the drop-down, then Up / Down open it and move, Enter or Space choose, Esc closes just the list.
|
|
2355
|
+
|
|
2356
|
+
**The filter value.** With `filterOperators` on, the column's filter is an object, not a string: `{ operator: "startsWith", value: "ann" }` (type `TextFilter`). You see it in `filters` / `onFiltersChange` (controlled mode) and in the `serverSide` query, where your API applies it:
|
|
2357
|
+
|
|
2358
|
+
```tsx
|
|
2359
|
+
onQueryChange={async (query) => {
|
|
2360
|
+
const nameFilter = query.filters.name; // string, or { operator, value } when filterOperators is on
|
|
2361
|
+
const { operator, value } = typeof nameFilter === "string" ? { operator: "contains", value: nameFilter } : nameFilter;
|
|
2362
|
+
// ... translate to your database: operator "startsWith" -> LIKE 'value%'
|
|
2363
|
+
}}
|
|
2364
|
+
```
|
|
2365
|
+
|
|
2366
|
+
Controlled filters work the same way, and a plain string is still accepted (it is read as "contains"):
|
|
2367
|
+
|
|
2368
|
+
```tsx
|
|
2369
|
+
<DataGrid filters={{ name: { operator: "notContains", value: "test" } }} onFiltersChange={setFilters} ... />
|
|
2370
|
+
```
|
|
2371
|
+
|
|
2372
|
+
### 6.25 Sort indicator
|
|
2373
|
+
|
|
2374
|
+
The arrow in sortable headers can be changed. The default is the small text arrow (▲ ▼ ↕). Two other choices:
|
|
2375
|
+
|
|
2376
|
+
```tsx
|
|
2377
|
+
<DataGrid sortIndicator="arrow" ... /> // a smooth arrow that turns around
|
|
2378
|
+
<DataGrid sortIndicator={MyIndicator} ... /> // your own component
|
|
2379
|
+
```
|
|
2380
|
+
|
|
2381
|
+
**`"arrow"`** is an SVG arrow. Ascending points up, descending points down, and "not sorted" is a dim up arrow. When the sort changes it **rotates smoothly** (a CSS transition of `--rg-sort-turn`, default `0.28s`, off for reduced motion). It always keeps turning the same way (up, down, back up), so each click is one clean half-turn. With several sorted columns it shows each column's priority number.
|
|
2382
|
+
|
|
2383
|
+
**Your own component** receives `{ column, direction, priority }`: `direction` is `"asc"`, `"desc"` or `null`, and `priority` is 1, 2, ... when several columns are sorted. The grid keeps the component mounted in the same place, so a CSS `transition` on it animates between states. Define it outside any component:
|
|
2384
|
+
|
|
2385
|
+
```tsx
|
|
2386
|
+
import { SortArrow, type SortIndicatorProps } from "react-gridix";
|
|
2387
|
+
|
|
2388
|
+
// Reuse the rotating arrow with your own size and colour
|
|
2389
|
+
function BigArrow({ direction }: SortIndicatorProps<User>) {
|
|
2390
|
+
return <SortArrow direction={direction} size={18} style={{ color: "tomato" }} />;
|
|
2391
|
+
}
|
|
2392
|
+
|
|
2393
|
+
// Or draw anything, turned with CSS
|
|
2394
|
+
function Chevron({ direction }: SortIndicatorProps<User>) {
|
|
2395
|
+
return (
|
|
2396
|
+
<span style={{ display: "inline-block", transition: "transform .3s", transform: direction === "desc" ? "rotate(180deg)" : "none", opacity: direction ? 1 : 0.3 }}>
|
|
2397
|
+
⌃
|
|
2398
|
+
</span>
|
|
2399
|
+
);
|
|
2400
|
+
}
|
|
2401
|
+
|
|
2402
|
+
<DataGrid sortIndicator={BigArrow} columns={columns} rows={rows} />
|
|
2403
|
+
```
|
|
2404
|
+
|
|
2405
|
+
A single column can use its own: `{ field: "name", sortable: true, sortIndicator: "arrow" }`. The wrapper `<span>` has the `sortIndicator` slot (`classNames={{ sortIndicator: "..." }}`) and a `data-direction` attribute (`asc`, `desc` or `none`) you can style.
|
|
2406
|
+
|
|
2407
|
+
### 6.26 Custom empty state
|
|
2408
|
+
|
|
2409
|
+
When there are no rows to show, the grid draws `emptyMessage` (default "No rows to show"). For more than a sentence, pass a component with `emptyComponent`. It replaces the message and receives:
|
|
2410
|
+
|
|
2411
|
+
| Prop | Meaning |
|
|
2412
|
+
| --- | --- |
|
|
2413
|
+
| `reason` | `"no-data"` when the grid was given no rows, `"no-results"` when the search or filters hide them all |
|
|
2414
|
+
| `search` | The search text (empty when none) |
|
|
2415
|
+
| `filters` | The active filters, by field |
|
|
2416
|
+
| `columns` | The visible columns |
|
|
2417
|
+
| `clearAll()` | Clears the search and all filters, which brings the rows back |
|
|
2418
|
+
|
|
2419
|
+
```tsx
|
|
2420
|
+
import type { EmptyStateProps } from "react-gridix";
|
|
2421
|
+
|
|
2422
|
+
function NothingHere({ reason, clearAll, search }: EmptyStateProps<User>) {
|
|
2423
|
+
if (reason === "no-data") {
|
|
2424
|
+
return (
|
|
2425
|
+
<div style={{ textAlign: "center" }}>
|
|
2426
|
+
<img src="/empty-box.svg" alt="" width={96} />
|
|
2427
|
+
<h3>No users yet</h3>
|
|
2428
|
+
<button onClick={openAddUserDialog}>Add the first user</button>
|
|
2429
|
+
</div>
|
|
2430
|
+
);
|
|
2431
|
+
}
|
|
2432
|
+
return (
|
|
2433
|
+
<div style={{ textAlign: "center" }}>
|
|
2434
|
+
<h3>Nothing matches{search ? ` "${search}"` : ""}</h3>
|
|
2435
|
+
<button onClick={clearAll}>Clear search and filters</button>
|
|
2436
|
+
</div>
|
|
2437
|
+
);
|
|
2438
|
+
}
|
|
2439
|
+
|
|
2440
|
+
<DataGrid emptyComponent={NothingHere} columns={columns} rows={users} />
|
|
2441
|
+
```
|
|
2442
|
+
|
|
2443
|
+
- It is drawn inside one full-width table cell (class `rg-grid__empty rg-grid__empty--custom`, slot `empty`), so `classNames={{ empty: "py-10" }}` still works.
|
|
2444
|
+
- Define the component outside render so it keeps its identity (and its state).
|
|
2445
|
+
- While loading, the skeleton is shown, not this. After a failed load, the error message and Retry button are shown.
|
|
2446
|
+
- When rows are removed with an exit animation, the component appears once the last row has left.
|
|
2447
|
+
- Keep using `emptyMessage` for a plain sentence. `emptyComponent` wins when both are set.
|
|
2448
|
+
|
|
2449
|
+
### 6.27 Known limitations
|
|
2135
2450
|
|
|
2136
2451
|
Not included:
|
|
2137
2452
|
|
|
@@ -2154,6 +2469,9 @@ Behaviours to be aware of:
|
|
|
2154
2469
|
- Pinned columns only stick when the table is wider than its container.
|
|
2155
2470
|
- In `serverSide` mode the grid cannot export or select rows it has never loaded.
|
|
2156
2471
|
- The date calendar starts weeks on Sunday and has no week numbers or time of day.
|
|
2472
|
+
- Excel export writes one worksheet. It does not carry the grid's colours or fonts, only a styled header row.
|
|
2473
|
+
- PDF text uses jsPDF's built-in Western European fonts unless you register another one (`pdf.fontName`). A PDF header / footer element is a picture: its text cannot be selected.
|
|
2474
|
+
- Rows that leave play their exit animation as a copy in place; the table closes the gap when the animation ends instead of sliding the rows below up.
|
|
2157
2475
|
|
|
2158
2476
|
---
|
|
2159
2477
|
|
|
@@ -2176,6 +2494,7 @@ The repository contains a playground with one page per feature:
|
|
|
2176
2494
|
| Large data (`#large`) | 20,000 virtualized rows with search, sorting and a theme |
|
|
2177
2495
|
| Dates and filters (`#dates`) | `type: "date"` with the calendar editor and range-calendar filter, `dateMin` / `dateMax`, a `Date`-object column, from/to, number range, select and exact filters |
|
|
2178
2496
|
| Themes (`#themes`) | A switcher for none and all 8 themes |
|
|
2497
|
+
| Animations and export (`#features`) | Pick the "in" and "out" animation from 12, add and remove rows (top, end, selected, all) and watch the other rows stay put; the rotating sort arrow, the default arrow and a custom indicator component; the Export menu (CSV, Excel, JSON, PDF) with a visible / selected / all choice and a PDF header and footer given as a string or as a styled component with a logo; filter comparison drop-downs (all eight, a short list, and none); a custom empty-state component |
|
|
2179
2498
|
|
|
2180
2499
|
Run it:
|
|
2181
2500
|
|
|
@@ -2189,6 +2508,8 @@ Open the URL it prints (usually `http://localhost:5173`). Link straight to a dem
|
|
|
2189
2508
|
The Styling demo loads Tailwind from its CDN, so it needs an internet connection. The rest works offline.
|
|
2190
2509
|
|
|
2191
2510
|
---
|
|
2511
|
+
|
|
2512
|
+
|
|
2192
2513
|
## 8. Troubleshooting
|
|
2193
2514
|
|
|
2194
2515
|
| Problem | Cause and fix |
|
|
@@ -2203,6 +2524,12 @@ The Styling demo loads Tailwind from its CDN, so it needs an internet connection
|
|
|
2203
2524
|
| The date calendar never opens | The cell must be editable (`editable` on the grid or the column), then double-click it or press Enter / F2 |
|
|
2204
2525
|
| A sequence column shows nothing or a type error | Give it `type: "sequence"` and a `field` that starts with `#`, for example `{ field: "#", type: "sequence" }` |
|
|
2205
2526
|
| My custom row animation does nothing | `animateRows` is `false`, `virtualize` is on, or your class does not set `animation`. Check that the keyframes exist and that the class name is spelled the same in CSS |
|
|
2527
|
+
| PDF export fails with `needs the package "jspdf"` | Install the optional packages: `npm install jspdf jspdf-autotable` (and `html2canvas` for a header / footer element). Handle the error with `onExportError` |
|
|
2528
|
+
| The PDF header / footer element has no image | The image must be loadable by the browser without being blocked: a bundled asset, a data URL, or a server that sends CORS headers |
|
|
2529
|
+
| The comparison drop-down does not show in the filter popup | Add `filterOperators: true` (or a list) to that column. It applies to text columns only, and not with a custom `filterRenderer` |
|
|
2530
|
+
| The wrong row animates out when I delete one | Give the grid `getRowId={(row) => row.id}`. Without it rows are identified by position |
|
|
2531
|
+
| Removed rows do not animate | `animateRows` is off, `virtualize` is on, the exit animation is `"none"`, or the system asks for reduced motion. Rows are also replaced at once when the page changes |
|
|
2532
|
+
| "Selected rows" is greyed out in the export menu | Nothing is selected yet, or `rowSelection` is off |
|
|
2206
2533
|
| The number filter popup asks for Min and Max, but I wanted text | Number columns default to a range filter. Set `filterType: "text"` |
|
|
2207
2534
|
| A typed filter feels slow, or fires on every key | Change the wait with `filterDebounce` on the grid (default 300 ms) or on one column. Use `0` for no waiting |
|
|
2208
2535
|
| Select filter lists the wrong labels | Pass `filterOptions` with `{ value, label }` pairs. `value` must equal what is stored in the row |
|
|
@@ -2230,49 +2557,4 @@ The Styling demo loads Tailwind from its CDN, so it needs an internet connection
|
|
|
2230
2557
|
| A checkbox in a boolean column is greyed out and won't toggle | The cell isn't editable. Set `editable` on the grid, or `editable: true` on that column |
|
|
2231
2558
|
| Type error: `field` not assignable | `field` must be a key of your row type. Check the spelling, and that `ColumnDef<T>` uses the same `T` as `rows` |
|
|
2232
2559
|
|
|
2233
|
-
---
|
|
2234
|
-
|
|
2235
|
-
## 9. Migrating from the earlier version
|
|
2236
|
-
|
|
2237
|
-
### Renamed: react-gridix
|
|
2238
|
-
|
|
2239
|
-
The library is now **`react-gridix`**, and every CSS prefix changed from `rk` to `rg`.
|
|
2240
|
-
|
|
2241
|
-
| Before | Now |
|
|
2242
|
-
| --- | --- |
|
|
2243
|
-
| `npm install react-ui-kit` | `npm install react-gridix` |
|
|
2244
|
-
| `import ... from "react-ui-kit"` | `import ... from "react-gridix"` |
|
|
2245
|
-
| `import "react-ui-kit/style.css"` | `import "react-gridix/style.css"` |
|
|
2246
|
-
| CSS variables `--rk-header-bg`, `--rk-primary`, ... | `--rg-header-bg`, `--rg-primary`, ... |
|
|
2247
|
-
| Classes `.rk-grid__row`, `.rk-checkbox`, ... | `.rg-grid__row`, `.rg-checkbox`, ... |
|
|
2248
|
-
| Theme selector `[data-rk-theme="brand"]` | `[data-rg-theme="brand"]` |
|
|
2249
|
-
|
|
2250
|
-
Search your project's CSS for `rk-` and replace it with `rg-`. A one-line fix in a Unix shell: `sed -i 's/\brk-/rg-/g' src/**/*.css`.
|
|
2251
|
-
|
|
2252
|
-
### Other changes
|
|
2253
|
-
|
|
2254
|
-
Also new in this release: `filterDebounce`, a smaller default checkbox (17px instead of 20px, with a tighter gap and a narrower selection column), a calendar for date cells and date filters, the `sequence` column type, `rowAnimationClassName`, and re-tuned theme colours (stronger header contrast, clearer inputs in the dark themes).
|
|
2255
|
-
|
|
2256
|
-
### Changed defaults
|
|
2257
|
-
|
|
2258
|
-
Three defaults changed so that every feature is opt-in.
|
|
2259
|
-
|
|
2260
|
-
| Before | Now | What to do |
|
|
2261
|
-
| --- | --- | --- |
|
|
2262
|
-
| Grid prop `sortable` (default `true`), column `sortable` override | **Column** `sortable` only, default `false`. The grid-level prop is gone | Add `sortable: true` to each column that should sort. Remove `sortable` / `sortable={false}` from the grid |
|
|
2263
|
-
| `defaultSort` / `onSortChange` used one `SortModel` or `null` | `defaultSort` takes one `SortModel` **or an array**. `onSortChange` receives an **array** (empty when unsorted) | Change `(sort) => sort?.field` to `(sort) => sort[0]?.field` |
|
|
2264
|
-
| `searchable` default `true` | Default `false` | Add `searchable` to grids that should show the search box |
|
|
2265
|
-
| `pagination` default `true` | Default `false`. With it off there is no footer and no row count | Add `pagination` to grids that should page |
|
|
2266
|
-
| Filters were text only | Filter kinds: text, exact, number, date, select | Nothing to change. Number columns now get a Min / Max popup, boolean columns a checkbox list |
|
|
2267
|
-
| `FilterRendererProps` | Unchanged (`value: string`) | |
|
|
2268
|
-
|
|
2269
|
-
A quick way to get the old behaviour everywhere:
|
|
2270
|
-
|
|
2271
|
-
```tsx
|
|
2272
|
-
// before: <DataGrid columns={columns} rows={rows} />
|
|
2273
|
-
const withSorting = (cols: ColumnDef<Row>[]) => cols.map((c) => ({ sortable: true, ...c }));
|
|
2274
|
-
|
|
2275
|
-
<DataGrid columns={withSorting(columns)} rows={rows} searchable pagination />
|
|
2276
|
-
```
|
|
2277
|
-
|
|
2278
|
-
Everything else in this document is new and optional.
|
|
2560
|
+
---
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-gridix",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"description": "A simple React library for displaying arrays in tables",
|
|
5
5
|
"author": "Felix Ongom",
|
|
6
6
|
"type": "module",
|
|
@@ -25,14 +25,20 @@
|
|
|
25
25
|
"typecheck": "tsc --noEmit"
|
|
26
26
|
},
|
|
27
27
|
"peerDependencies": {
|
|
28
|
-
"react": ">=
|
|
29
|
-
"react-dom": ">=
|
|
28
|
+
"react": ">=18",
|
|
29
|
+
"react-dom": ">=18",
|
|
30
|
+
"jspdf": ">=2",
|
|
31
|
+
"jspdf-autotable": ">=3.5",
|
|
32
|
+
"html2canvas": ">=1.4"
|
|
30
33
|
},
|
|
31
34
|
"devDependencies": {
|
|
32
35
|
"@types/node": "^20.14.0",
|
|
33
36
|
"@types/react": "^18.3.0",
|
|
34
37
|
"@types/react-dom": "^18.3.0",
|
|
35
38
|
"@vitejs/plugin-react": "^4.3.0",
|
|
39
|
+
"html2canvas": "^1.4.1",
|
|
40
|
+
"jspdf": "^2.5.2",
|
|
41
|
+
"jspdf-autotable": "^3.8.4",
|
|
36
42
|
"react": "^18.3.1",
|
|
37
43
|
"react-dom": "^18.3.1",
|
|
38
44
|
"typescript": "^5.5.0",
|