@jielga/tmdatagrid 2.0.0-beta.9 → 2.0.0
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 +5 -212
- package/dist/index.d.ts +1281 -768
- package/dist/index.js +4607 -3250
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/docs/adding-rows.md +132 -0
- package/docs/anatomy.md +119 -0
- package/docs/card-view.md +108 -0
- package/docs/cell-selection.md +194 -0
- package/docs/column-layout.md +182 -0
- package/docs/column-menu.md +66 -0
- package/docs/columns.md +268 -0
- package/docs/components.md +311 -0
- package/docs/draft-store.md +242 -0
- package/docs/editing.md +303 -0
- package/docs/editors.md +250 -0
- package/docs/export.md +319 -0
- package/docs/filtering.md +362 -0
- package/docs/getting-started.md +123 -0
- package/docs/grouping.md +165 -0
- package/docs/loading-and-empty.md +92 -0
- package/docs/localization.md +79 -0
- package/docs/menu.md +143 -0
- package/docs/migrating-to-2.md +163 -0
- package/docs/pagination.md +144 -0
- package/docs/persistence.md +114 -0
- package/docs/portfolio-rebalancer.md +94 -0
- package/docs/query-builder.md +179 -0
- package/docs/quick-search.md +84 -0
- package/docs/row-details.md +115 -0
- package/docs/row-interaction.md +149 -0
- package/docs/row-pinning.md +132 -0
- package/docs/row-selection.md +136 -0
- package/docs/row-styling.md +133 -0
- package/docs/scrolling.md +112 -0
- package/docs/server-query.md +246 -0
- package/docs/server-side.md +206 -0
- package/docs/sorting.md +101 -0
- package/docs/styling.md +126 -0
- package/docs/summary-row.md +76 -0
- package/docs/testing.md +744 -0
- package/docs/toolbar.md +161 -0
- package/docs/use-tm-data-grid.md +361 -0
- package/package.json +22 -46
- package/skills/appearance/SKILL.md +72 -19
- package/skills/cell-selection/SKILL.md +46 -47
- package/skills/columns/SKILL.md +90 -34
- package/skills/data/SKILL.md +86 -16
- package/skills/editing/SKILL.md +67 -40
- package/skills/editing/references/common-mistakes.md +77 -69
- package/skills/editing/references/editing-api.md +22 -19
- package/skills/editing/references/editors-and-validation.md +24 -17
- package/skills/filtering/SKILL.md +148 -40
- package/skills/getting-started/SKILL.md +17 -15
- package/skills/grouping/SKILL.md +31 -16
- package/skills/options/SKILL.md +7 -7
- package/skills/rows/SKILL.md +22 -18
- package/skills/server-side/SKILL.md +170 -17
- package/skills/testing/SKILL.md +150 -32
- package/skills/testing-components/SKILL.md +230 -0
- package/skills/testing-editing/SKILL.md +240 -0
- package/src/{tmdatagrid/components → components}/TMDataGrid.tsx +38 -21
- package/src/{tmdatagrid/components → components}/TMDataGridCellEditor.tsx +54 -8
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.module.css +5 -1
- package/src/{tmdatagrid/components → components}/TMDataGridColumnsPanel.tsx +47 -55
- package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.tsx +5 -51
- package/src/{tmdatagrid/components → components}/TMDataGridDraftActions.tsx +41 -24
- package/src/{tmdatagrid/components → components}/TMDataGridEditColumn.tsx +12 -59
- package/src/{tmdatagrid/components → components}/TMDataGridEntryRows.tsx +164 -92
- package/src/components/TMDataGridExportPicker.module.css +77 -0
- package/src/components/TMDataGridExportPicker.tsx +234 -0
- package/src/components/TMDataGridFilterPanel.module.css +54 -0
- package/src/components/TMDataGridFilterPanel.tsx +348 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.tsx +15 -8
- package/src/components/TMDataGridFilterSurface.module.css +54 -0
- package/src/components/TMDataGridFilterSurface.tsx +167 -0
- package/src/{tmdatagrid/components → components}/TMDataGridFooter.tsx +53 -90
- package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.tsx +5 -69
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.module.css +12 -2
- package/src/{tmdatagrid/components → components}/TMDataGridHeaderCell.tsx +58 -21
- package/src/components/TMDataGridHeaderFilterRow.module.css +51 -0
- package/src/components/TMDataGridHeaderFilterRow.tsx +301 -0
- package/src/components/TMDataGridMenu.tsx +357 -0
- package/src/{tmdatagrid/components → components}/TMDataGridSelectColumn.tsx +11 -48
- package/src/{tmdatagrid/components → components}/TMDataGridTable.module.css +69 -56
- package/src/{tmdatagrid/components → components}/TMDataGridTable.tsx +240 -138
- package/src/{tmdatagrid/components → components}/TMDataGridToolbar.module.css +5 -0
- package/src/components/TMDataGridToolbar.tsx +181 -0
- package/src/{tmdatagrid/components → components}/editors/TMDataGridBooleanEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridDateEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridMultiSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridNumberEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridSelectEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/TMDataGridStringEditor.tsx +3 -3
- package/src/{tmdatagrid/components → components}/editors/editorShared.ts +16 -2
- package/src/{tmdatagrid/components → components}/filters/DgAutocompleteFilter.tsx +5 -4
- package/src/{tmdatagrid/components → components}/filters/DgDateRangeFilter.tsx +22 -5
- package/src/{tmdatagrid/components → components}/filters/DgRangeSliderFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/DgTriStateFilter.tsx +5 -1
- package/src/{tmdatagrid/components → components}/filters/TMDataGridFilterValueInput.tsx +44 -28
- package/src/components/filters/controlLayout.ts +32 -0
- package/src/components/filters/filterControlFor.ts +65 -0
- package/src/components/generatedColumns.tsx +187 -0
- package/src/{tmdatagrid/components → components}/icons.ts +1 -0
- package/src/{tmdatagrid/components → components}/sticky.module.css +44 -0
- package/src/components/useHideableColumns.ts +52 -0
- package/src/{tmdatagrid/core → core}/autosize.ts +5 -2
- package/src/{tmdatagrid/core → core}/columnOptions.ts +60 -8
- package/src/{tmdatagrid/core → core}/columnOrdering.ts +33 -14
- package/src/{tmdatagrid/core → core}/columnUtils.ts +44 -5
- package/src/core/controlledStateSync.ts +108 -0
- package/src/core/deletedRows.ts +34 -0
- package/src/core/dom.ts +74 -0
- package/src/{tmdatagrid/core → core}/editEngine.ts +1107 -460
- package/src/core/export.ts +704 -0
- package/src/{tmdatagrid/core → core}/filterControls.ts +38 -1
- package/src/{tmdatagrid/core → core}/filterOperators.ts +64 -1
- package/src/core/filterSurface.ts +99 -0
- package/src/{tmdatagrid/core → core}/grouping.ts +21 -0
- package/src/{tmdatagrid/core → core}/labels.ts +51 -6
- package/src/{tmdatagrid/core → core}/labelsSv.ts +27 -6
- package/src/core/pageReset.ts +120 -0
- package/src/core/pagination.ts +81 -0
- package/src/{tmdatagrid/core → core}/persistence.ts +22 -5
- package/src/{tmdatagrid/core → core}/summary.ts +20 -4
- package/src/{tmdatagrid/index.ts → index.ts} +69 -35
- package/src/{tmdatagrid/useTMDataGrid.tsx → useTMDataGrid.tsx} +428 -109
- package/src/useTMDataGridExport.ts +78 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +0 -35
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +0 -354
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +0 -161
- package/src/tmdatagrid/core/cellExport.ts +0 -320
- /package/src/{tmdatagrid/TMDataGridContext.ts → TMDataGridContext.ts} +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGrid.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridDetailsColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFilterPills.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridFooter.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridGroupColumn.module.css +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridRowNumberColumn.tsx +0 -0
- /package/src/{tmdatagrid/components → components}/TMDataGridSearch.tsx +0 -0
- /package/src/{tmdatagrid/core → core}/capabilities.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellNavigation.ts +0 -0
- /package/src/{tmdatagrid/core → core}/cellRange.ts +0 -0
- /package/src/{tmdatagrid/core → core}/controlledState.ts +0 -0
- /package/src/{tmdatagrid/core → core}/draftCellContext.ts +0 -0
- /package/src/{tmdatagrid/core → core}/editorFocus.ts +0 -0
- /package/src/{tmdatagrid/core → core}/expanding.ts +0 -0
- /package/src/{tmdatagrid/core → core}/matchHighlight.ts +0 -0
- /package/src/{tmdatagrid/core → core}/quickSearch.ts +0 -0
- /package/src/{tmdatagrid/core → core}/resizePreview.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowPinning.ts +0 -0
- /package/src/{tmdatagrid/core → core}/rowSelection.ts +0 -0
- /package/src/{tmdatagrid/core → core}/sizes.ts +0 -0
- /package/src/{tmdatagrid/core → core}/useSettledTableState.ts +0 -0
|
@@ -9,7 +9,7 @@ kind.
|
|
|
9
9
|
| --- | --- | --- | --- |
|
|
10
10
|
| `editing` | `TMDataGridEditingOptions` | off | The editing namespace. Setting it turns editing on. |
|
|
11
11
|
| `editing.mode` | `"cell" \| "cellConfirm" \| "row"` | – | What counts as a commit, and which controls trigger it. |
|
|
12
|
-
| `editing.draft` | `boolean` | `false` | Where a commit goes. On, it
|
|
12
|
+
| `editing.draft` | `boolean` | `false` | Where a commit goes. On, it is held in the grid's draft store until `edit.saveDrafts()`. |
|
|
13
13
|
| `getRowId` | `(row) => string` | – | A TanStack table option, required once `editing` is set. Drafts are keyed by it. |
|
|
14
14
|
| `editing.columns` | `ReadonlyArray<string>` | every column mapping to a data path | The column ids that take edits. Gates before `meta.edit`, never past it: a column left out takes no edits whatever its meta says, and a listed column still answers to its `meta.edit.enabled`. Also decides which cells an entry row opens. |
|
|
15
15
|
| `editing.isRowEditable` | `(row) => boolean` | – | Closes a whole row to editing, in every mode. |
|
|
@@ -28,8 +28,7 @@ the type.
|
|
|
28
28
|
| Name | Argument | What it does |
|
|
29
29
|
| --- | --- | --- |
|
|
30
30
|
| `editing.onCommit` | `{ rowId, value, original, changes, source }` | Applies one row's change. Reject to keep the draft and show the error. |
|
|
31
|
-
| `editing.onSaveDrafts` | `{ updated, created, deleted }` | `draft: true` only. One call for the whole draft store. Without it, `saveDrafts` loops `editing.onCommit`, `editing.onRowAdd` and `editing.onRowDelete`. |
|
|
32
|
-
| `editing.onCommitDrafts` | `{ updated, created, deleted }` | **Deprecated** - renamed to `onSaveDrafts`. Still honoured; the new name wins if both are set. |
|
|
31
|
+
| `editing.onSaveDrafts` | `{ updated, created, deleted }` | `draft: true` only. One call for the whole draft store. May return a `TMDataGridSaveDraftsResponse` naming the ids that failed; they stay in the draft store. Without it, `saveDrafts` loops `editing.onCommit`, `editing.onRowAdd` and `editing.onRowDelete`. |
|
|
33
32
|
| `editing.onRowAdd` | `{ tempId, value }` | Commits an entry row. Mint the real id here. |
|
|
34
33
|
| `editing.onRowDelete` | `{ rowId, row }` | Deletes a row. Shows the trash; under `draft: true`, `onSaveDrafts` shows it too. |
|
|
35
34
|
|
|
@@ -54,24 +53,25 @@ path, which may be dotted.
|
|
|
54
53
|
| Member | Signature | Notes |
|
|
55
54
|
| --- | --- | --- |
|
|
56
55
|
| `begin` | `({ rowId, columnId }) => void` | Row mode opens the entire row either way. `columnId` selects which cell takes the caret; `null` (the pencil) uses its first editable one. On a committed row it reopens it, taking it back out of the draft store. |
|
|
57
|
-
| `commit` | `(rowId) => Promise<boolean>` | The OK gesture: submits the row's form. `false` keeps it open with its errors, and the message outlives the editor that found it. Under `draft: true` a pass
|
|
58
|
-
| `commitAll` | `() => Promise<
|
|
59
|
-
| `saveDrafts` | `() => Promise<
|
|
56
|
+
| `commit` | `(rowId) => Promise<boolean>` | The OK gesture: submits the row's form. `false` keeps it open with its errors, and the message outlives the editor that found it. Under `draft: true` a pass commits the row into the draft store - no consumer callback runs until `saveDrafts`. Column rules run whether or not an editor is mounted. |
|
|
57
|
+
| `commitAll` | `() => Promise<TMDataGridCommitAllResult>` | Submits every open row. Rows that fail stay open. Resolves `{ ok, committed, open }`: every row open at the call is in exactly one list, and `ok` is `false` when one stayed open. |
|
|
58
|
+
| `saveDrafts` | `() => Promise<TMDataGridSaveDraftsResult>` | Sends the draft store, re-running `editing.tableValidators` only; a committed row that fails is reopened with its errors. Open rows are left alone and stay open. Resolves `{ ok, saved, kept, reopened }` over row ids and temp ids, all kinds mixed: `saved` left the draft store, `kept` is still in it for the next save (reported failed by `onSaveDrafts`, sent when it threw, or a deletion whose per-row `onRowDelete` threw), `reopened` is open again with an error (a table rule, or a throwing per-row `onCommit` / `onRowAdd`). `ok` is `false` when anything was kept or reopened. A call during a save joins it and resolves the same result. |
|
|
60
59
|
| `cancel` | `(rowId) => void` | Drops one draft. |
|
|
61
60
|
| `cancelAll` | `() => void` | Drops every draft. |
|
|
62
61
|
| `deactivate` | `() => void` | Closes the editor without touching the draft, as blur does under `"cellConfirm"`. |
|
|
63
|
-
| `submitAll` | `() => Promise<boolean>` | **Deprecated** - `commitAll()` then `saveDrafts()`. |
|
|
64
62
|
| `clearCell` | `(rowId, columnId) => Promise<boolean>` | What Delete does: writes the type's empty value and commits. |
|
|
65
|
-
| `setCellValue` | `(rowId, columnId, value) => Promise<boolean>` | Writes one cell and commits the row, with no editor - toolbar actions and bulk fills. The row need not be mounted; a row inside a collapsed group takes the write. `value` is the stored value, so `meta.edit.mapValue` does not run and `meta.edit.validate` does. Under `draft: true` the row
|
|
63
|
+
| `setCellValue` | `(rowId, columnId, value) => Promise<boolean>` | Writes one cell and commits the row, with no editor - toolbar actions and bulk fills. The row need not be mounted; a row inside a collapsed group takes the write. `value` is the stored value, so `meta.edit.mapValue` does not run and `meta.edit.validate` does. Under `draft: true` the row is committed into the draft store like any hand-made edit. `false` when the cell takes no edit, or when validation refused the value and left the row open with its errors. |
|
|
66
64
|
| `setRowValues` | `(rowId, values) => Promise<boolean>` | `setCellValue` for several cells of one row in a single commit - one consumer call and one draft entry. Keys are column ids. All or nothing: if any named cell takes no edit, nothing is written and it resolves `false`. |
|
|
67
65
|
| `addRow` | `(values?) => string` | Opens an entry row, returns its `tempId`. `values` overrides `editing.newRowDefaults` key by key for that row; with no argument the row is `newRowDefaults` alone. |
|
|
68
|
-
| `addRows` | `(rows, options?) => Promise<
|
|
69
|
-
| `deleteRow` | `(rowId) => void` | `editing.onRowDelete`, or a deletion mark under `draft: true`.
|
|
66
|
+
| `addRows` | `(rows, options?) => Promise<TMDataGridAddRowsResult>` | Opens a batch in one write, each row seeded as `addRow` seeds. `{ commit: true }` submits each as it lands - valid rows commit, invalid ones stay open with their errors. Resolves `{ ok, committed, open }`; `ok` is `false` when a row stayed open. |
|
|
67
|
+
| `deleteRow` | `(rowId) => void` | `editing.onRowDelete`, or a deletion mark under `draft: true`. Idempotent: a second call leaves the row marked; `restoreRow` is the undo. |
|
|
70
68
|
| `canEditCell` | `(row, column) => boolean` | The check the built-in controls use. Both halves: the column's and the row's. |
|
|
71
69
|
| `canEditRow` | `(row) => boolean` | The pencil's gate. |
|
|
72
70
|
| `isColumnEditable` | `(column) => boolean` | The column's half alone, with no row in hand: it maps to a field, `editing.columns` lists it when that is set, and `meta.edit.enabled` is not `false`. |
|
|
73
71
|
| `canDeleteRows` | `() => boolean` | Whether the delete control should be shown. |
|
|
74
|
-
| `getForm` | `(rowId) => TMDataGridRowEditForm \| undefined` | The row's live `FormApi
|
|
72
|
+
| `getForm` | `(rowId) => TMDataGridRowEditForm \| undefined` | The open row's live `FormApi`; `undefined` for a committed row. |
|
|
73
|
+
| `getRowValues` | `(rowId) => TData \| undefined` | The row as shown: the open form's values, else the committed draft, else the `data` value. `undefined` for an unknown row. |
|
|
74
|
+
| `getRows` | `() => ReadonlyArray<TMDataGridEditRowSnapshot>` | Every row as shown, from the core row model: drafts overlaid, entry rows appended, deletion-marked rows included and flagged `deleted`. |
|
|
75
75
|
| `state` | `TMDataGridEditState` | Snapshot, for reads outside React. |
|
|
76
76
|
| `store` | `Store<TMDataGridEditState>` | For `useSelector`. |
|
|
77
77
|
|
|
@@ -81,10 +81,10 @@ path, which may be dotted.
|
|
|
81
81
|
type TMDataGridEditState = {
|
|
82
82
|
// The cell the last open gesture named - where the caret goes.
|
|
83
83
|
active: { rowId: string; columnId: string | null } | null;
|
|
84
|
-
//
|
|
85
|
-
// here and not in `committedRowIds`.
|
|
84
|
+
// Every row the grid holds work for: open rows and committed rows. A row
|
|
85
|
+
// is *open* when it is in here and not in `committedRowIds`.
|
|
86
86
|
openRowIds: ReadonlyArray<string>;
|
|
87
|
-
// One `TMDataGridEditRowProjection` per
|
|
87
|
+
// One `TMDataGridEditRowProjection` per row in `openRowIds`.
|
|
88
88
|
rows: Record<
|
|
89
89
|
string,
|
|
90
90
|
{
|
|
@@ -96,8 +96,8 @@ type TMDataGridEditState = {
|
|
|
96
96
|
values: TMDataGridRowData;
|
|
97
97
|
}
|
|
98
98
|
>;
|
|
99
|
-
// The draft store's edit slice: existing rows
|
|
100
|
-
//
|
|
99
|
+
// The draft store's edit slice: existing rows that passed their commit,
|
|
100
|
+
// held as values for `saveDrafts`. Empty without `editing.draft`.
|
|
101
101
|
committedRowIds: ReadonlyArray<string>;
|
|
102
102
|
// What a committed row *is* to the table: the draft store's values per row,
|
|
103
103
|
// snapshotted at each commit and kept across a reopen, so the row holds its
|
|
@@ -108,6 +108,8 @@ type TMDataGridEditState = {
|
|
|
108
108
|
// a commit adds through `onRowAdd`, so it stays `false`.
|
|
109
109
|
newRows: ReadonlyArray<{ tempId: string; committed: boolean }>;
|
|
110
110
|
deletedRowIds: ReadonlyArray<string>;
|
|
111
|
+
// `true` while `saveDrafts` is in flight.
|
|
112
|
+
isSaving: boolean;
|
|
111
113
|
};
|
|
112
114
|
```
|
|
113
115
|
|
|
@@ -119,12 +121,13 @@ type TMDataGridEditState = {
|
|
|
119
121
|
| `TMDataGridDraftActions` | Export | The same component, for use outside the namespace. |
|
|
120
122
|
| `EDIT_COLUMN_ID` | Export | `"__edit__"`, the generated edit lane's id. |
|
|
121
123
|
| `clearedValueForType` | Export | `(type) => unknown` - what Delete writes per column type. |
|
|
124
|
+
| `hasPendingEdits` | Export | `(state) => boolean` - unsaved work: an open row with a changed value, any entry row, the draft store, or a save in flight. `useSelector(grid.edit.store, hasPendingEdits)` for a navigation blocker; do not use `openRowIds.length`, which also counts committed rows and rows that are only open. |
|
|
122
125
|
| `getEditFieldName` | Export | `(column) => string` - the data path a column's edits write to. |
|
|
123
126
|
| `normalizeFieldValidate` | Export | `(validate) => validators` - a bare schema into Form's shape. |
|
|
124
127
|
| `TMDataGridStringEditor` … `TMDataGridMultiSelectEditor` | Exports | The six built-in editors, for wrapping. |
|
|
125
128
|
|
|
126
129
|
Types: `TMDataGridEditMode`, `TMDataGridEditApi`, `TMDataGridEditState`,
|
|
127
|
-
`TMDataGridEditCommitArgs`, `
|
|
130
|
+
`TMDataGridEditCommitArgs`, `TMDataGridSaveDraftsArgs`,
|
|
128
131
|
`TMDataGridEditChange`, `TMDataGridEditorArgs`, `TMDataGridEditorComponent`,
|
|
129
132
|
`TMDataGridEditField`, `TMDataGridEditRowProjection`, `TMDataGridFieldValidate`,
|
|
130
133
|
`TMDataGridRowValidators`, `TMDataGridRowEditForm`, `TMDataGridRowAddArgs`,
|
|
@@ -148,11 +151,11 @@ The trash itself shows when the deletion has somewhere to report to:
|
|
|
148
151
|
mark is part of the save.
|
|
149
152
|
|
|
150
153
|
What the lane holds follows the row's state, one axis each. An open row shows
|
|
151
|
-
the mode's own controls, `save-row` and `cancel-row`. A
|
|
154
|
+
the mode's own controls, `save-row` and `cancel-row`. A committed row shows
|
|
152
155
|
`row-state` instead, whose `data-state` is `new`, `edited` or `deleted`,
|
|
153
156
|
together with `revert-row` on an edited row, `restore-row` on one marked for
|
|
154
157
|
deletion, and `edit-row` plus `discard-new-row` on an entered new row - never a
|
|
155
|
-
save, which the engine would only
|
|
158
|
+
save, which the engine would only commit again. A committed row hides `delete-row`.
|
|
156
159
|
Every control carries a tooltip from the labels, `revertRow`, `rowStateNew`,
|
|
157
160
|
`rowStateEdited` and `rowStateDeleted` among them.
|
|
158
161
|
|
|
@@ -63,11 +63,11 @@ Bind any control to `field` exactly as inside any TanStack Form:
|
|
|
63
63
|
`field.state.value`, `field.state.meta.errors`, `field.handleChange`,
|
|
64
64
|
`field.handleBlur`.
|
|
65
65
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
binds
|
|
69
|
-
|
|
70
|
-
|
|
66
|
+
The message itself is the host's: it shows in a tooltip on the editor, opened
|
|
67
|
+
by focus and by hover, for a custom editor as much as a built-in one. What an
|
|
68
|
+
editor binds is the invalid state - the built-ins pass a boolean to the input's
|
|
69
|
+
`error` prop for the border alone, and an editor that binds nothing looks
|
|
70
|
+
unchanged while the commit is refused.
|
|
71
71
|
|
|
72
72
|
```tsx
|
|
73
73
|
import { Slider } from "@mantine/core";
|
|
@@ -193,8 +193,13 @@ meta: { edit: { validate: z.string().min(2, "At least two characters") } }
|
|
|
193
193
|
// Object form: pick the trigger.
|
|
194
194
|
meta: { edit: { validate: { onBlur: z.string().email("Not an email address") } } }
|
|
195
195
|
|
|
196
|
-
// A plain function works too.
|
|
197
|
-
meta: {
|
|
196
|
+
// A plain function works too. `value` is typed `never`, so annotate the parameter.
|
|
197
|
+
meta: {
|
|
198
|
+
edit: {
|
|
199
|
+
validate: ({ value }: { value: unknown }) =>
|
|
200
|
+
typeof value === "number" && value > 0 ? undefined : "Must be positive",
|
|
201
|
+
},
|
|
202
|
+
}
|
|
198
203
|
```
|
|
199
204
|
|
|
200
205
|
`normalizeFieldValidate(validate)` is exported for consumers building their own
|
|
@@ -224,8 +229,8 @@ const grid = useTMDataGrid({
|
|
|
224
229
|
```
|
|
225
230
|
|
|
226
231
|
Issues with a path land on the matching column's cell; pathless issues land on
|
|
227
|
-
the row, where the message shows in the edit lane's tooltip
|
|
228
|
-
row's
|
|
232
|
+
the row, where the message shows in the edit lane's tooltip on the open
|
|
233
|
+
row's ✓. A nested schema's issues follow the
|
|
229
234
|
same rule, so a `address.city` issue lands on the column whose `editField` is
|
|
230
235
|
`"address.city"`.
|
|
231
236
|
|
|
@@ -261,9 +266,9 @@ row's cells. `onSubmit` runs first, and its failure stands without
|
|
|
261
266
|
`onSubmitAsync` running. Errors land on the committing row only.
|
|
262
267
|
|
|
263
268
|
The rules run at every commit - typed, ✓, `edit.setCellValue`, an entry
|
|
264
|
-
row's - after the row's own validators, and again for every
|
|
265
|
-
`saveDrafts
|
|
266
|
-
|
|
269
|
+
row's - after the row's own validators, and again for every committed row during
|
|
270
|
+
`saveDrafts`, the only rules that run there: a committed row that a later edit
|
|
271
|
+
invalidated is reopened with its errors, and the save reports it in `reopened`.
|
|
267
272
|
|
|
268
273
|
## Server-side errors
|
|
269
274
|
|
|
@@ -283,9 +288,9 @@ rowValidators: {
|
|
|
283
288
|
},
|
|
284
289
|
```
|
|
285
290
|
|
|
286
|
-
A commit blocked by validation keeps the editor open with the message
|
|
287
|
-
|
|
288
|
-
row.
|
|
291
|
+
A commit blocked by validation keeps the editor open, invalid, with the message
|
|
292
|
+
in its tooltip. A rejected `editing.onCommit` keeps the draft too, with the
|
|
293
|
+
error on the row.
|
|
289
294
|
|
|
290
295
|
## Where the state shows
|
|
291
296
|
|
|
@@ -294,11 +299,13 @@ row.
|
|
|
294
299
|
| The cell's own value | A held draft is displayed: the cell renders the draft value through the column's `cell` renderer, in every mode |
|
|
295
300
|
| Blue cell corner | The field is dirty against its original value |
|
|
296
301
|
| Red cell corner | The field carries a validation error |
|
|
297
|
-
|
|
|
302
|
+
| Field error message | In a tooltip on the open editor, shown while the input has focus and on hover |
|
|
303
|
+
| Row error text | A pathless rule failed, or a commit was rejected. In the lane's tooltip, on the open row's ✓ |
|
|
298
304
|
| `data-dirty` on the row | The row holds a dirty draft |
|
|
299
305
|
|
|
300
306
|
The same information is readable from `edit.store`: `rows[rowId].dirtyFields`,
|
|
301
307
|
`rows[rowId].errorFields`, `rows[rowId].errorMessages` (`{ field, message }`
|
|
302
308
|
pairs), `rows[rowId].hasRowError`, `rows[rowId].isSubmitting`, and
|
|
303
309
|
`rows[rowId].values` for the draft itself. The pathless message's text is not
|
|
304
|
-
in the store; read it from `edit.getForm(rowId)?.state.errors
|
|
310
|
+
in the store; read it from `edit.getForm(rowId)?.state.errors` on the open
|
|
311
|
+
row that carries it.
|
|
@@ -3,24 +3,27 @@ name: filtering
|
|
|
3
3
|
description: >
|
|
4
4
|
Narrow the rows a TMDataGrid shows. Covers the shared tmDataGrid filter
|
|
5
5
|
function and its {operator, value} model, the eighteen operators and which
|
|
6
|
-
meta.type offers each, meta.filter.
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
meta.type offers each, meta.filter.operators to offer a column only a subset
|
|
7
|
+
of them, meta.filter.defaultOperator, isFilterActive and the half-typed
|
|
8
|
+
filter, the filters option and its surfaces (popup, sidebar, none, plus
|
|
9
|
+
inHeader for header filters), TMDataGrid.FilterPanel and its layout prop,
|
|
10
|
+
TMDataGrid.FilterButton, TMDataGrid.FilterPills with its api prop,
|
|
11
|
+
openColumnFilter, replacing a value control with DgRangeSliderFilter /
|
|
12
|
+
DgDateRangeFilter / DgAutocompleteFilter / DgTriStateFilter or a
|
|
13
|
+
meta.filter.control component, per-column filterFn, and the quick search:
|
|
14
|
+
TMDataGrid.Search, quickSearchMode fuzzy or contains, fuzzyGlobalFilterFn,
|
|
15
|
+
enableMatchHighlighting and enableGlobalFilter. Load when adding filters,
|
|
16
|
+
choosing operators, building a filter control, showing active filters outside
|
|
17
|
+
the grid, or wiring a search box.
|
|
15
18
|
metadata:
|
|
16
19
|
type: core
|
|
17
20
|
library: '@jielga/tmdatagrid'
|
|
18
|
-
library_version: '2.0.0
|
|
21
|
+
library_version: '2.0.0'
|
|
19
22
|
sources:
|
|
20
|
-
- 'Jielga/TMDataGrid:
|
|
21
|
-
- 'Jielga/TMDataGrid:
|
|
22
|
-
- 'Jielga/TMDataGrid:
|
|
23
|
-
- 'Jielga/TMDataGrid:
|
|
23
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/filtering.md'
|
|
24
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/quick-search.md'
|
|
25
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/filterOperators.ts'
|
|
26
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/quickSearch.ts'
|
|
24
27
|
---
|
|
25
28
|
|
|
26
29
|
# TMDataGrid - Filtering
|
|
@@ -48,7 +51,9 @@ leaving that end open).
|
|
|
48
51
|
|
|
49
52
|
A filter with an empty value **stays in state** so the panel keeps its row while
|
|
50
53
|
the user types. It matches every row, does not set the header indicator and
|
|
51
|
-
produces no pill. `isFilterActive(value)` tests for that state
|
|
54
|
+
produces no pill. `isFilterActive(value)` tests for that state, and
|
|
55
|
+
`activeColumnFilters(columnFilters | table)` applies it across the slice and
|
|
56
|
+
types what it hands back (entries in any other value shape are dropped); presence in
|
|
52
57
|
`columnFilters` does not.
|
|
53
58
|
|
|
54
59
|
## Operators
|
|
@@ -80,16 +85,105 @@ columnHelper.accessor("salary", {
|
|
|
80
85
|
});
|
|
81
86
|
```
|
|
82
87
|
|
|
83
|
-
|
|
88
|
+
`meta.filter.operators` narrows the list a column offers to a subset of its
|
|
89
|
+
type's - for a column whose backend answers only some operators, so the user is
|
|
90
|
+
never offered one the query cannot express. The panel dropdown and the header
|
|
91
|
+
funnel show only those, in the type's order. An operator the type does not
|
|
92
|
+
offer is ignored; a list that leaves nothing falls back to the type's full set.
|
|
93
|
+
Without `defaultOperator`, a fresh filter opens on the type's default when it is
|
|
94
|
+
offered, else on the first offered operator.
|
|
84
95
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
```tsx
|
|
97
|
+
columnHelper.accessor("customer", {
|
|
98
|
+
header: "Customer",
|
|
99
|
+
meta: { filter: { operators: ["contains", "equals", "isEmpty", "isNotEmpty"] } },
|
|
100
|
+
});
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
`getColumnOperators(column)` returns the resolved list and
|
|
104
|
+
`getColumnDefaultOperator(column)` the operator a fresh filter opens on. The
|
|
105
|
+
`server-side` skill shows the list typed together with the API mapping table.
|
|
106
|
+
|
|
107
|
+
## The filters option
|
|
108
|
+
|
|
109
|
+
`filters` on `useTMDataGrid` picks the surface. It is read field by field, so a
|
|
110
|
+
literal is fine.
|
|
111
|
+
|
|
112
|
+
| Option | Type | Default | What it does |
|
|
113
|
+
| --- | --- | --- | --- |
|
|
114
|
+
| `surface` | `"popup" \| "sidebar" \| "none"` | `"popup"` | What `TMDataGrid.Table` renders and `FilterButton` toggles. |
|
|
115
|
+
| `sidebarSide` | `"left" \| "right"` | `"right"` | Which side the sidebar sits on. Ignored by the other surfaces. |
|
|
116
|
+
| `sidebarWidth` | `string` | `"280px"` | Sidebar width, any CSS length. Ignored by the other surfaces. |
|
|
117
|
+
| `defaultOpen` | `boolean` | `true` under `"sidebar"`, else `false` | Whether the surface starts open. Read once, at mount. Under `"none"`, the starting value of `ui.state.filterPanelOpen`. |
|
|
118
|
+
| `inHeader` | `boolean` | `false` | A second header row of per-column controls. Independent of `surface`. |
|
|
119
|
+
|
|
120
|
+
`surface` and `inHeader` are separate choices: `{ surface: "none", inHeader: true }`
|
|
121
|
+
is header filters alone, `{ inHeader: true }` keeps the popup as well.
|
|
122
|
+
|
|
123
|
+
```tsx
|
|
124
|
+
useTMDataGrid({ data, columns, filters: { surface: "sidebar", inHeader: true } });
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
**Popup** - the default. Floats over the first body rows. A pointerdown
|
|
128
|
+
outside, Escape, and emptying it (the last row removed, or **Clear all**) all
|
|
129
|
+
close it; `FilterButton` is exempt from the click-away so it stays a toggle.
|
|
130
|
+
|
|
131
|
+
**Sidebar** - the same panel beside the rows, inside the grid frame and under
|
|
132
|
+
the toolbar. The rows give up the width rather than being covered, a click in
|
|
133
|
+
the table does not dismiss it, and clearing the filters leaves it standing.
|
|
134
|
+
Escape closes it. It starts open, being a layout choice; its rows are
|
|
135
|
+
`layout="stacked"`, since 280px has no room for the triple.
|
|
136
|
+
|
|
137
|
+
**Header filters** - `inHeader: true` adds a header row of value controls, one
|
|
138
|
+
per filterable column, on the same column tracks as everything else. The
|
|
139
|
+
column and operator dropdowns are not there: the column is the one the cell
|
|
140
|
+
sits over, and the operator is a funnel button beside the input, tinted off its
|
|
141
|
+
default. The column menu's Filter item and the funnel indicator both come off,
|
|
142
|
+
having nothing left to reveal; the filtered column's tinted title stays. A
|
|
143
|
+
narrow column clips its control - give it a `minSize`.
|
|
90
144
|
|
|
91
|
-
|
|
92
|
-
|
|
145
|
+
Clearing a header control removes the column's `columnFilters` entry rather
|
|
146
|
+
than leaving an empty one, unless the user also picked a non-default operator,
|
|
147
|
+
which is kept. Panel rows still keep their empty filters.
|
|
148
|
+
|
|
149
|
+
`FilterButton` still toggles whatever `surface` names. `openColumnFilter` does
|
|
150
|
+
not: under `inHeader` it always focuses the header control and leaves the
|
|
151
|
+
surface closed.
|
|
152
|
+
|
|
153
|
+
**None** - `surface: "none"` renders no panel and no `FilterButton`, so a
|
|
154
|
+
hand-placed `TMDataGrid.FilterPanel` is the only one. Read
|
|
155
|
+
`ui.state.filterPanelOpen` if it belongs behind a control of your own.
|
|
156
|
+
|
|
157
|
+
## TMDataGrid.FilterPanel
|
|
158
|
+
|
|
159
|
+
The panel of filter rows - one column / operator / value triple per filter, over "Add filter" and "Clear all".
|
|
160
|
+
A plain block with no title, no close button and no open state: it renders wherever it is mounted, and the popup and sidebar surfaces are wrappers around it.
|
|
161
|
+
It must be inside `<TMDataGrid>` (it reads the grid from context) and it only reads and writes `columnFilters`, so a `manualFiltering` grid gets it for free.
|
|
162
|
+
Closing a surface only hides it; the filters stay.
|
|
163
|
+
**Clear all** drops every filter, half-typed ones included.
|
|
164
|
+
|
|
165
|
+
| Prop | Type | Default | Description |
|
|
166
|
+
| --- | --- | --- | --- |
|
|
167
|
+
| `layout` | `"row" \| "stacked"` | `"row"` | `"row"` is side by side and wants about 550px; `"stacked"` fills a narrow host. Passed to every value control as its `layout`. |
|
|
168
|
+
|
|
169
|
+
```tsx
|
|
170
|
+
<Drawer opened={open} onClose={close}>
|
|
171
|
+
<TMDataGrid.FilterPanel layout="stacked" />
|
|
172
|
+
</Drawer>
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## TMDataGrid.FilterButton
|
|
176
|
+
|
|
177
|
+
The toolbar button that toggles the filter surface, tinted with the count of active filters.
|
|
178
|
+
Opening an empty panel seeds a filter row on the first filterable column; with filters already in state it opens on those.
|
|
179
|
+
Renders nothing when no column can be filtered, and nothing under `surface: "none"`.
|
|
180
|
+
No props.
|
|
181
|
+
|
|
182
|
+
## TMDataGrid.FilterPills
|
|
183
|
+
|
|
184
|
+
One pill per **active** filter, `First name: Sofia ✕`, where the ✕ clears it and a click on the label calls `openColumnFilter`.
|
|
185
|
+
The label spells the operator out unless it is the type's default: `Age is greater than 30`, but `First name: Sofia`.
|
|
186
|
+
It takes the grid as an `api` prop instead of reading context, so it renders anywhere on the page.
|
|
93
187
|
|
|
94
188
|
```tsx
|
|
95
189
|
import { TMDataGridFilterPills } from "@jielga/tmdatagrid";
|
|
@@ -97,11 +191,18 @@ import { TMDataGridFilterPills } from "@jielga/tmdatagrid";
|
|
|
97
191
|
<TMDataGridFilterPills api={grid} onPillClick={(columnId) => focus(columnId)} />;
|
|
98
192
|
```
|
|
99
193
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
`
|
|
104
|
-
|
|
194
|
+
| Prop | Type | Default | Description |
|
|
195
|
+
| --- | --- | --- | --- |
|
|
196
|
+
| `api` | `TMDataGridApi<TData>` | - | The object returned by `useTMDataGrid`. |
|
|
197
|
+
| `size` | `MantineSize` | `"sm"` | Pill size. |
|
|
198
|
+
| `showClearAll` | `boolean` | `true` | "Clear all", shown once two filters are active. |
|
|
199
|
+
| `onPillClick` | `(columnId: string) => void` | - | Replaces the default click behaviour. |
|
|
200
|
+
| `className` | `string` | - | Added to the wrapper class. |
|
|
201
|
+
|
|
202
|
+
## openColumnFilter
|
|
203
|
+
|
|
204
|
+
`openColumnFilter(api, columnId)` seeds an empty filter if the column has none, then opens the surface on that column's panel row - or, under `inHeader`, scrolls the column's header control into view and focuses it, leaving the surface closed.
|
|
205
|
+
It is what a pill's label and the column menu's Filter item both call.
|
|
105
206
|
|
|
106
207
|
## Replacing the value control
|
|
107
208
|
|
|
@@ -220,12 +321,13 @@ const activeCount = columnFilters.length;
|
|
|
220
321
|
Correct:
|
|
221
322
|
|
|
222
323
|
```tsx
|
|
223
|
-
import {
|
|
324
|
+
import { activeColumnFilters } from "@jielga/tmdatagrid";
|
|
224
325
|
|
|
225
|
-
|
|
326
|
+
// The entries that narrow anything, with `value` typed rather than `unknown`.
|
|
327
|
+
const active = activeColumnFilters(columnFilters);
|
|
226
328
|
```
|
|
227
329
|
|
|
228
|
-
Source: `
|
|
330
|
+
Source: `packages/tmdatagrid/docs/filtering.md` (How a filter is stored).
|
|
229
331
|
|
|
230
332
|
### HIGH Assuming `value` is always a string
|
|
231
333
|
|
|
@@ -246,7 +348,7 @@ if (operatorTakesRangeValue(operator)) {
|
|
|
246
348
|
}
|
|
247
349
|
```
|
|
248
350
|
|
|
249
|
-
Source: `
|
|
351
|
+
Source: `packages/tmdatagrid/src/core/filterOperators.ts`.
|
|
250
352
|
|
|
251
353
|
### HIGH A numeric column with no `meta.type`
|
|
252
354
|
|
|
@@ -255,7 +357,7 @@ Source: `src/tmdatagrid/core/filterOperators.ts`.
|
|
|
255
357
|
`between` never appear in the panel, and comparisons run as text, where `"9"`
|
|
256
358
|
sorts above `"10"`.
|
|
257
359
|
|
|
258
|
-
Source: `
|
|
360
|
+
Source: `packages/tmdatagrid/docs/filtering.md` (Operators).
|
|
259
361
|
|
|
260
362
|
### HIGH A filter control defined inside the component
|
|
261
363
|
|
|
@@ -272,7 +374,7 @@ const StatusFilter: TMDataGridFilterControlComponent = (args) => { /* … */ };
|
|
|
272
374
|
meta: { filter: { control: StatusFilter } }
|
|
273
375
|
```
|
|
274
376
|
|
|
275
|
-
Source: `
|
|
377
|
+
Source: `packages/tmdatagrid/docs/filtering.md` (Writing your own).
|
|
276
378
|
|
|
277
379
|
### MEDIUM Writing the whole filter from a custom control
|
|
278
380
|
|
|
@@ -292,7 +394,7 @@ Correct:
|
|
|
292
394
|
onChange(picked);
|
|
293
395
|
```
|
|
294
396
|
|
|
295
|
-
Source: `
|
|
397
|
+
Source: `packages/tmdatagrid/docs/filtering.md` (Writing your own).
|
|
296
398
|
|
|
297
399
|
### MEDIUM Expecting match highlighting in a custom cell
|
|
298
400
|
|
|
@@ -301,7 +403,7 @@ does not modify a custom renderer's output. A column with a `cell` renderer
|
|
|
301
403
|
shows no marks whatever `enableMatchHighlighting` is set to. Equality operators
|
|
302
404
|
highlight nothing either.
|
|
303
405
|
|
|
304
|
-
Source: `
|
|
406
|
+
Source: `packages/tmdatagrid/docs/quick-search.md` (Match highlighting).
|
|
305
407
|
|
|
306
408
|
### MEDIUM Expecting fuzzy ranking to survive a sort
|
|
307
409
|
|
|
@@ -309,7 +411,7 @@ The rank ordering applies only while the search is the sole narrowing. Any sort
|
|
|
309
411
|
or grouping replaces it. The ordering is derived and never written into
|
|
310
412
|
`sorting`, so there is nothing to clear afterwards.
|
|
311
413
|
|
|
312
|
-
Source: `
|
|
414
|
+
Source: `packages/tmdatagrid/docs/quick-search.md` (Fuzzy by default).
|
|
313
415
|
|
|
314
416
|
## Reference
|
|
315
417
|
|
|
@@ -318,20 +420,26 @@ Source: `src/docs/quick-search.md` (Fuzzy by default).
|
|
|
318
420
|
| `enableColumnFilters` | Table option | `boolean` | `true` | `false` removes the panel, the button and the menu item. |
|
|
319
421
|
| `enableColumnFilter` | Column option | `boolean` | `true` | `false` takes one column out of filtering. |
|
|
320
422
|
| `meta.type` | Column meta | `TMDataGridColumnType` | `"string"` | Selects the operators and the value control. |
|
|
321
|
-
| `meta.filter.
|
|
423
|
+
| `meta.filter.operators` | Column meta | `readonly TMDataGridFilterOperator[]` | The type's list | The operators this column offers, a subset of its type's. |
|
|
424
|
+
| `meta.filter.defaultOperator` | Column meta | `TMDataGridFilterOperator` | The type's default, else the first offered | The operator a fresh filter opens on. |
|
|
322
425
|
| `meta.filter.control` | Column meta | `TMDataGridFilterControlComponent` | By type and operator | Replaces the value control. Module scope. |
|
|
323
426
|
| `filterFn` | Column option | name or fn | `"tmDataGrid"` | Custom matching for one column. |
|
|
324
427
|
| `quickSearchMode` | Option | `"fuzzy" \| "contains"` | `"fuzzy"` | How the quick search matches. |
|
|
325
428
|
| `enableMatchHighlighting` | Option | `boolean` | `false` | Mark matched text in default-rendered cells. |
|
|
326
429
|
| `enableGlobalFilter` | Table option | `boolean` | `true` | Also a column option. Removes the input, or one column's participation. |
|
|
327
430
|
| `globalFilterFn` | Table option | filter fn | fuzzy | Overrides the matching, and the ranking with it. |
|
|
328
|
-
| `TMDataGrid.FilterPanel` | Component |
|
|
431
|
+
| `TMDataGrid.FilterPanel` | Component | `layout: "row" \| "stacked"`, Mantine `BoxProps` | `"row"` | The panel of filter rows, as a plain block. Style props set on it. |
|
|
432
|
+
| `filters` | Table option | `TMDataGridFiltersOptions` | `{ surface: "popup" }` | Which surface holds the filter controls. |
|
|
433
|
+
| `TMDataGridFilterControlArgs.layout` | Type | `"row" \| "stacked" \| "header"` | – | How much room a value control has, and whether it names itself. |
|
|
434
|
+
| `filterValueShape` | Export | `(operator) => "scalar" \| "set" \| "range"` | – | Which shape an operator's value takes. |
|
|
329
435
|
| `TMDataGrid.FilterButton` | Component | – | – | Toolbar button opening the panel, with an active count. |
|
|
330
|
-
| `TMDataGrid.FilterPills` | Component | `api`, `size`, `showClearAll`, `onPillClick`, `
|
|
436
|
+
| `TMDataGrid.FilterPills` | Component | `api`, `size`, `showClearAll`, `onPillClick`, Mantine `BoxProps` | – | Active filters as removable pills, renderable anywhere. Style props set on the wrapper. |
|
|
331
437
|
| `TMDataGrid.Search` | Component | `placeholder`, `debounce` (`250`), `w` (`220`) | – | The debounced quick-search input. |
|
|
332
438
|
| `openColumnFilter` | Export | `(api, columnId) => void` | – | Opens the panel on a column. |
|
|
333
439
|
| `isFilterActive` | Export | `(value) => boolean` | – | Whether a filter value narrows anything. |
|
|
440
|
+
| `activeColumnFilters` | Export | `(columnFilters \| table) => Array<{ id, value }>` | – | The filters in the grid's own value shape that narrow anything, typed. |
|
|
334
441
|
| `getOperatorsForType` | Export | `(type) => operators` | – | The operator list a type offers. |
|
|
442
|
+
| `getColumnOperators` · `getColumnDefaultOperator` | Exports | `(column) => operators` · `(column) => operator` | – | One column's list after `meta.filter.operators`, and the operator a fresh filter on it opens on. |
|
|
335
443
|
| `FILTER_OPERATOR_LABELS` | Export | record | – | The label shown for each operator. |
|
|
336
444
|
| `formatFilterLabel` | Export | `({ label, type, filter }) => string` | – | The one-line description used on the pills. |
|
|
337
445
|
| `emptyValueForOperator` · `operatorNeedsValue` · `operatorTakesArrayValue` · `operatorTakesRangeValue` | Exports | – | – | What shape of value an operator expects. |
|
|
@@ -4,19 +4,19 @@ description: >
|
|
|
4
4
|
Set up TMDataGrid, a compound React data grid built on TanStack Table v9 and
|
|
5
5
|
Mantine. Covers useTMDataGrid, the TMDataGrid root, context, the component
|
|
6
6
|
catalog (Table, Footer, Toolbar, Spacer, SummaryCount, Search,
|
|
7
|
-
LoadingIndicator, DraftActions, FilterButton,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
LoadingIndicator, DraftActions, FilterButton, Menu, FilterPanel, FilterPills,
|
|
8
|
+
ColumnsPanel), the size scale and the bounded-height layout requirement. Load
|
|
9
|
+
when adding a grid, choosing which parts to render, or when rows do not
|
|
10
|
+
appear.
|
|
11
11
|
metadata:
|
|
12
12
|
type: core
|
|
13
13
|
library: '@jielga/tmdatagrid'
|
|
14
|
-
library_version: '2.0.0
|
|
14
|
+
library_version: '2.0.0'
|
|
15
15
|
sources:
|
|
16
|
-
- 'Jielga/TMDataGrid:
|
|
17
|
-
- 'Jielga/TMDataGrid:
|
|
18
|
-
- 'Jielga/TMDataGrid:
|
|
19
|
-
- 'Jielga/TMDataGrid:
|
|
16
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/getting-started.md'
|
|
17
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/docs/anatomy.md'
|
|
18
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/components/TMDataGrid.tsx'
|
|
19
|
+
- 'Jielga/TMDataGrid:packages/tmdatagrid/src/core/sizes.ts'
|
|
20
20
|
---
|
|
21
21
|
|
|
22
22
|
# TMDataGrid - Getting started
|
|
@@ -80,7 +80,9 @@ export function Employees({ data }: { data: Employee[] }) {
|
|
|
80
80
|
<TMDataGrid.SummaryCount />
|
|
81
81
|
<TMDataGrid.Spacer />
|
|
82
82
|
<TMDataGrid.FilterButton />
|
|
83
|
-
<TMDataGrid.
|
|
83
|
+
<TMDataGrid.Menu>
|
|
84
|
+
<TMDataGrid.Menu.Columns />
|
|
85
|
+
</TMDataGrid.Menu>
|
|
84
86
|
</TMDataGrid.Toolbar>
|
|
85
87
|
|
|
86
88
|
<TMDataGrid.Table<Employee> />
|
|
@@ -149,7 +151,7 @@ flex column.
|
|
|
149
151
|
| Component | Props | Notes |
|
|
150
152
|
| --- | --- | --- |
|
|
151
153
|
| `TMDataGrid` | `table`, `ui`, `features`, `size`, `className`, `style` | Root. Provides context. `style` also takes CSS variables: `--dg-row-selected-bg`, `--dg-row-height`, `--dg-header-height`, `--dg-font-size`, `--dg-padding`. |
|
|
152
|
-
| `TMDataGrid.Table` | `onRowClick(row)`, `renderRowContextMenu`, `renderColumnMenuItems`, `rowContextMenuProps` | Header, virtualized body, filter
|
|
154
|
+
| `TMDataGrid.Table` | `onRowClick(row)`, `renderRowContextMenu`, `renderColumnMenuItems`, `rowContextMenuProps` | Header, virtualized body, and whichever filter surface the `filters` option asks for. `onRowClick` runs in addition to selection under `selectionMode: "row"`. |
|
|
153
155
|
| `TMDataGrid.Footer` | `pageSizeOptions` (default `[10, 25, 50, 100]`), `pagination` render prop | Pagination controls. Renders nothing unless pagination is enabled. |
|
|
154
156
|
| `TMDataGrid.Toolbar` | `children` | Flex row above the grid. |
|
|
155
157
|
| `TMDataGrid.Spacer` | - | Pushes later toolbar items right. |
|
|
@@ -157,10 +159,10 @@ flex column.
|
|
|
157
159
|
| `TMDataGrid.Search` | `placeholder`, `debounce` (default `250`), `w` (default `220`) | Quick search over every column, debounced into `globalFilter`. Renders nothing under `enableGlobalFilter: false`. |
|
|
158
160
|
| `TMDataGrid.LoadingIndicator` | - | Small spinner while `meta.loading` is `true` and rows stay on screen. |
|
|
159
161
|
| `TMDataGrid.DraftActions` | `renderActions` | Save with the pending count, and Discard. Renders nothing while editing is off - see the `editing` skill. |
|
|
160
|
-
| `TMDataGrid.FilterButton` | - | Toggles filter
|
|
161
|
-
| `TMDataGrid.
|
|
162
|
-
| `TMDataGrid.FilterPanel` |
|
|
163
|
-
| `TMDataGrid.ColumnsPanel` | - |
|
|
162
|
+
| `TMDataGrid.FilterButton` | - | Toggles the filter surface, seeding a filter row on the first filterable column. Renders nothing if no column is filterable, or under `filters.surface: "none"`. |
|
|
163
|
+
| `TMDataGrid.Menu` | `children`, `icon`, `label`, Mantine `MenuProps` | The burger and its dropdown: your own `Menu.Item`s, and `TMDataGrid.Menu.Columns`, the column chooser as menu items (renders nothing if no column is hideable). See the `appearance` skill. |
|
|
164
|
+
| `TMDataGrid.FilterPanel` | `layout` (`"row"` \| `"stacked"`, default `"row"`) | Filter rows over "Add filter" / "Clear all", as a plain block. Rendered by `.Table` inside the popup and the sidebar; place it yourself under `filters.surface: "none"`. See the `filtering` skill. |
|
|
165
|
+
| `TMDataGrid.ColumnsPanel` | - | The column chooser as plain controls, for a Popover or a Drawer. |
|
|
164
166
|
| `TMDataGrid.FilterPills` | `api`, `size` (default `"sm"`), `showClearAll` (default `true`), `onPillClick(columnId)`, `className` | One pill per active filter, ✕ to clear it. Takes the api as a prop, so it can be rendered outside the grid. Also exported as `TMDataGridFilterPills`. |
|
|
165
167
|
|
|
166
168
|
Pass the row type so `onRowClick` stays typed:
|