@svgrid/grid 2.6.20 → 2.6.22
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/CHANGELOG.md +62 -0
- package/README.md +22 -0
- package/dist/GridMenus.svelte +17 -12
- package/dist/SvGrid.controller.svelte.d.ts +14 -8
- package/dist/SvGrid.controller.svelte.js +214 -74
- package/dist/SvGrid.css +1 -1
- package/dist/SvGrid.svelte +112 -57
- package/dist/SvGrid.types.d.ts +191 -1
- package/dist/ai.d.ts +28 -0
- package/dist/ai.js +6 -0
- package/dist/cdn/{GridMenus-B0F9iBrG.js → GridMenus-BuoBPqxx.js} +137 -132
- package/dist/cdn/GridMenus-n4llxoOI.js +494 -0
- package/dist/cdn/column-resize-DsfNXMom.js +102 -0
- package/dist/cdn/row-resize-BRcimkUT.js +95 -0
- package/dist/cdn/{src-Cd0tearp.js → src-C9Hihx1W.js} +3497 -3487
- package/dist/cdn/{src-B1TdiyS8.js → src-D1lXwq1l.js} +8258 -8248
- package/dist/cdn/svgrid.js +10 -8
- package/dist/cdn/svgrid.svelte-external.js +10 -8
- package/dist/cdn/validate-_CDJzgIo.js +75 -0
- package/dist/cell-formatting.d.ts +2 -0
- package/dist/cell-formatting.js +2 -0
- package/dist/chart-export.d.ts +1 -0
- package/dist/chart.d.ts +31 -5
- package/dist/chart.js +9 -3
- package/dist/column-groups.js +1 -1
- package/dist/column-resize.d.ts +46 -0
- package/dist/column-resize.js +205 -0
- package/dist/columns.d.ts +0 -3
- package/dist/columns.js +0 -57
- package/dist/core.d.ts +216 -4
- package/dist/core.js +532 -119
- package/dist/createTree.svelte.d.ts +3 -0
- package/dist/createTree.svelte.js +1 -0
- package/dist/datetime/date-core.d.ts +2 -0
- package/dist/datetime/date-restrict.d.ts +1 -0
- package/dist/datetime/timezone.d.ts +1 -0
- package/dist/dock-manager-model.d.ts +3 -0
- package/dist/dock-manager-model.js +1 -0
- package/dist/dock-model.d.ts +6 -0
- package/dist/dock-model.js +3 -0
- package/dist/editor-contract.d.ts +1 -0
- package/dist/filtering/excel-filters.js +28 -0
- package/dist/group-display.d.ts +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +6 -0
- package/dist/list-option.d.ts +1 -0
- package/dist/menus.js +1 -1
- package/dist/positioning.d.ts +2 -0
- package/dist/row-resize.d.ts +11 -0
- package/dist/row-resize.js +7 -1
- package/dist/scheduler-ical.d.ts +1 -0
- package/dist/scheduler-model.d.ts +1 -0
- package/dist/selection.js +9 -0
- package/dist/spreadsheet.d.ts +1 -1
- package/dist/spreadsheet.js +1 -1
- package/dist/summaries.js +22 -0
- package/dist/svgrid-wrapper.types.d.ts +5 -0
- package/dist/toast-store.svelte.d.ts +4 -0
- package/dist/validate.d.ts +50 -0
- package/dist/validate.js +187 -0
- package/package.json +4 -1
- package/src/GridMenus.svelte +17 -12
- package/src/SvGrid.controller.svelte.ts +223 -76
- package/src/SvGrid.css +1 -1
- package/src/SvGrid.svelte +112 -57
- package/src/SvGrid.types.ts +191 -1
- package/src/ai.ts +28 -0
- package/src/cell-formatting.ts +2 -0
- package/src/chart-export.ts +1 -0
- package/src/chart.ts +31 -5
- package/src/column-groups.ts +1 -1
- package/src/column-resize.test.ts +381 -0
- package/src/column-resize.ts +227 -0
- package/src/columns.test.ts +0 -103
- package/src/columns.ts +0 -58
- package/src/core.aggregate.test.ts +134 -0
- package/src/core.filter.test.ts +156 -0
- package/src/core.grouping.test.ts +146 -0
- package/src/core.row-shape.test.ts +119 -0
- package/src/core.rowmodel-cache.test.ts +121 -0
- package/src/core.sort.test.ts +293 -0
- package/src/core.ts +723 -119
- package/src/createTree.svelte.ts +3 -0
- package/src/datetime/date-core.ts +2 -0
- package/src/datetime/date-restrict.ts +1 -0
- package/src/datetime/timezone.ts +1 -0
- package/src/dock-manager-model.ts +3 -0
- package/src/dock-model.ts +6 -0
- package/src/editor-contract.ts +1 -0
- package/src/filtering/excel-filters.ts +30 -0
- package/src/filtering/normalize-fast-path.test.ts +104 -0
- package/src/group-display.ts +1 -1
- package/src/index.ts +12 -1
- package/src/list-option.ts +1 -0
- package/src/menus.ts +1 -1
- package/src/positioning.ts +2 -0
- package/src/resize-props.test.ts +361 -0
- package/src/row-resize.test.ts +31 -0
- package/src/row-resize.ts +21 -3
- package/src/scheduler-ical.ts +1 -0
- package/src/scheduler-model.ts +1 -0
- package/src/selection.ts +9 -0
- package/src/spreadsheet.ts +1 -1
- package/src/summaries.ts +21 -0
- package/src/svgrid-wrapper.types.ts +5 -0
- package/src/svgrid.summaries.test.ts +217 -0
- package/src/toast-store.svelte.ts +4 -0
- package/src/validate.test.ts +207 -0
- package/src/validate.ts +269 -0
- package/dist/cdn/GridMenus-IHK_l7m6.js +0 -489
package/src/SvGrid.css
CHANGED
|
@@ -1573,7 +1573,7 @@ select.sv-grid-fr-editor {
|
|
|
1573
1573
|
position: relative;
|
|
1574
1574
|
}
|
|
1575
1575
|
/* Declarative cell validation (column `validate` hook). Invalid cells get a
|
|
1576
|
-
* soft red wash and a red inset ring -
|
|
1576
|
+
* soft red wash and a red inset ring - the conventional spreadsheet invalid-cell look. The
|
|
1577
1577
|
* value keeps rendering as-is; the message (if any) shows as the tooltip. */
|
|
1578
1578
|
.sv-grid-cell-invalid {
|
|
1579
1579
|
background-color: var(--sg-invalid-bg, rgba(239, 68, 68, 0.14)) !important;
|
package/src/SvGrid.svelte
CHANGED
|
@@ -15,6 +15,8 @@
|
|
|
15
15
|
} from "./index";
|
|
16
16
|
import "./sv-grid-scrollbar";
|
|
17
17
|
import "./SvGrid.css";
|
|
18
|
+
import type { RowResizeOptions } from "./row-resize";
|
|
19
|
+
import type { ColumnResizeOptions } from "./column-resize";
|
|
18
20
|
import {
|
|
19
21
|
RenderSnippetConfig,
|
|
20
22
|
RenderComponentConfig,
|
|
@@ -167,7 +169,9 @@
|
|
|
167
169
|
const hideTooltip = $derived(ctrl.hideTooltip);
|
|
168
170
|
const findHits = $derived(ctrl.findHits);
|
|
169
171
|
const headerHeight = $derived(ctrl.headerHeight);
|
|
170
|
-
|
|
172
|
+
// Column resizing has always been unconditional; `columnResize={false}` is
|
|
173
|
+
// the opt-out, so the default has to stay on when the prop is absent.
|
|
174
|
+
const columnResizeEnabled = $derived(opt.columnResize === true);
|
|
171
175
|
const selectionColumnWidth = $derived(ctrl.selectionColumnWidth);
|
|
172
176
|
const rowNumberColumnWidth = $derived(ctrl.rowNumberColumnWidth);
|
|
173
177
|
const showRowNumbersEffective = $derived(ctrl.showRowNumbersEffective);
|
|
@@ -184,6 +188,7 @@
|
|
|
184
188
|
ctrl.showInlineColumnFilterEffective,
|
|
185
189
|
);
|
|
186
190
|
const showRowSelectionEffective = $derived(ctrl.showRowSelectionEffective);
|
|
191
|
+
const rowSummariesEnabled = $derived(ctrl.rowSummariesEnabled);
|
|
187
192
|
const grid = $derived(ctrl.grid);
|
|
188
193
|
const allColumns = $derived(ctrl.allColumns);
|
|
189
194
|
const headerGroups = $derived(ctrl.headerGroups);
|
|
@@ -263,6 +268,23 @@
|
|
|
263
268
|
// Row-grouping display modes: group state lives in synthetic columns instead
|
|
264
269
|
// of a full-width banner row.
|
|
265
270
|
const groupColumnMode = $derived(ctrl.groupColumnMode);
|
|
271
|
+
/**
|
|
272
|
+
* True when a cell's content needs none of the wrapper snippets.
|
|
273
|
+
*
|
|
274
|
+
* A cell body normally renders through `cellBodyWithFormat` ->
|
|
275
|
+
* `cellBodyFormatted` -> `cellBody`, and with no grouping, no tree data and
|
|
276
|
+
* no conditional formats the first two are pure pass-throughs: three snippet
|
|
277
|
+
* renders and two `{#if}` blocks per cell to reach content that one render
|
|
278
|
+
* produces. Measured by ablation, that chain is 4.2 ms of a 17.4 ms mount at
|
|
279
|
+
* 28 rows x 9 columns - about a quarter of the whole mount, and the largest
|
|
280
|
+
* single per-cell cost.
|
|
281
|
+
*
|
|
282
|
+
* Computed once per render rather than per cell, so the fast path costs one
|
|
283
|
+
* boolean read at each of the ~250 cells instead of two snippet frames.
|
|
284
|
+
*/
|
|
285
|
+
const plainCellBody = $derived(
|
|
286
|
+
!groupColumnMode && !treeData && !hasConditionalFormats,
|
|
287
|
+
);
|
|
266
288
|
const autoGroupCell = $derived(ctrl.autoGroupCell);
|
|
267
289
|
const isAutoGroupColumn = (id: string): boolean =>
|
|
268
290
|
id === "__autoGroup" || id.startsWith("__group_");
|
|
@@ -279,7 +301,60 @@
|
|
|
279
301
|
// The fixed row height, matching what the virtualized path takes from the virtualizer.
|
|
280
302
|
// The non-virtualized (`virtualization={false}`) body must apply this too, else its rows
|
|
281
303
|
// fall back to content height and look shorter than a virtualized grid's.
|
|
304
|
+
/**
|
|
305
|
+
* `rowResize` and `columnResize` are both opt-in and both default to OFF, so
|
|
306
|
+
* neither module is imported statically - a grid that leaves them alone must
|
|
307
|
+
* not carry their bytes. This wraps an action so its module is fetched on
|
|
308
|
+
* first enable and never otherwise. The handles appear a microtask after the
|
|
309
|
+
* first paint, which is invisible for a drag affordance.
|
|
310
|
+
*
|
|
311
|
+
* One helper for both: two hand-rolled copies of this bookkeeping would cost
|
|
312
|
+
* more base bundle than the deferral saves.
|
|
313
|
+
*/
|
|
314
|
+
type LazyHandle<O> = { update(o: O): void; destroy(): void };
|
|
315
|
+
function lazyAction<O extends { disabled?: boolean }>(
|
|
316
|
+
load: () => Promise<(node: HTMLElement, opts: O) => LazyHandle<O>>,
|
|
317
|
+
) {
|
|
318
|
+
return (node: HTMLElement, opts: O): LazyHandle<O> => {
|
|
319
|
+
let handle: LazyHandle<O> | null = null;
|
|
320
|
+
let current = opts;
|
|
321
|
+
let destroyed = false;
|
|
322
|
+
const ensure = () => {
|
|
323
|
+
if (handle || destroyed || current.disabled) return;
|
|
324
|
+
void load().then((make) => {
|
|
325
|
+
// The prop can be switched back off, or the grid unmounted, while
|
|
326
|
+
// the chunk is still in flight.
|
|
327
|
+
if (destroyed || current.disabled || handle) return;
|
|
328
|
+
handle = make(node, current);
|
|
329
|
+
});
|
|
330
|
+
};
|
|
331
|
+
ensure();
|
|
332
|
+
return {
|
|
333
|
+
update(next: O) {
|
|
334
|
+
current = next;
|
|
335
|
+
if (handle) handle.update(next);
|
|
336
|
+
else ensure();
|
|
337
|
+
},
|
|
338
|
+
destroy() {
|
|
339
|
+
destroyed = true;
|
|
340
|
+
handle?.destroy();
|
|
341
|
+
},
|
|
342
|
+
};
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
const lazyRowResize = lazyAction<RowResizeOptions>(() =>
|
|
347
|
+
import("./row-resize").then((m) => m.rowResize),
|
|
348
|
+
);
|
|
349
|
+
const lazyColumnResize = lazyAction<ColumnResizeOptions>(() =>
|
|
350
|
+
import("./column-resize").then((m) => m.columnResize),
|
|
351
|
+
);
|
|
352
|
+
|
|
282
353
|
const rowSizePx = (i: number): number => {
|
|
354
|
+
// A height the user dragged wins over the declared one, so the row stays
|
|
355
|
+
// where they put it across re-renders and virtualization recycling.
|
|
356
|
+
const dragged = ctrl.rowResizeHeightPx(i);
|
|
357
|
+
if (dragged != null) return dragged;
|
|
283
358
|
const rh = opt.rowHeight;
|
|
284
359
|
return typeof rh === "function" ? rh(i) : (rh ?? 30);
|
|
285
360
|
};
|
|
@@ -357,26 +432,10 @@
|
|
|
357
432
|
return "sv-grid-cell-flash";
|
|
358
433
|
}
|
|
359
434
|
|
|
360
|
-
// Keyboard-accessible column resize (#79): focus a resize handle and use the
|
|
361
|
-
// arrow keys (Shift = fine 1px step). Complements the pointer-drag resize.
|
|
362
|
-
function resizeColumnByKeyboard(e: KeyboardEvent, columnId: string) {
|
|
363
|
-
let delta = 0;
|
|
364
|
-
const step = e.shiftKey ? 1 : 10;
|
|
365
|
-
if (e.key === "ArrowLeft") delta = -step;
|
|
366
|
-
else if (e.key === "ArrowRight") delta = step;
|
|
367
|
-
else return;
|
|
368
|
-
e.preventDefault();
|
|
369
|
-
const current = ctrl.getColumnWidth(columnId);
|
|
370
|
-
ctrl.columnWidths = {
|
|
371
|
-
...ctrl.columnWidths,
|
|
372
|
-
[columnId]: Math.max(40, current + delta),
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
|
|
376
435
|
// ---- Full-row editing -------------------------------------------------
|
|
377
436
|
const fullRowEdit = $derived(ctrl.fullRowEdit);
|
|
378
437
|
// Commit the whole row when the user clicks away from its editors (Excel /
|
|
379
|
-
//
|
|
438
|
+
// spreadsheet feel). Clicking within any full-row editor keeps editing.
|
|
380
439
|
// Stays here rather than in SvGridCellEditor: that component is instantiated
|
|
381
440
|
// once PER editable cell during a full-row edit, so a document listener there
|
|
382
441
|
// would be attached N times and commit N times.
|
|
@@ -428,7 +487,6 @@
|
|
|
428
487
|
const setActiveCell = $derived(ctrl.setActiveCell);
|
|
429
488
|
const scrollActiveCellIntoView = $derived(ctrl.scrollActiveCellIntoView);
|
|
430
489
|
const getColumnWidth = $derived(ctrl.getColumnWidth);
|
|
431
|
-
const startColumnResize = $derived(ctrl.startColumnResize);
|
|
432
490
|
const getCellRangeEdges = $derived(ctrl.getCellRangeEdges);
|
|
433
491
|
const fillHandleCell = $derived(ctrl.fillHandleCell);
|
|
434
492
|
const isInFillPreview = $derived(ctrl.isInFillPreview);
|
|
@@ -1293,6 +1351,26 @@
|
|
|
1293
1351
|
class="sv-grid-root"
|
|
1294
1352
|
class:sv-grid-root-fill={opt.containerHeight === "100%"}
|
|
1295
1353
|
style={chartDockReserveStyle}
|
|
1354
|
+
use:lazyRowResize={{
|
|
1355
|
+
disabled: !ctrl.rowResizeOn,
|
|
1356
|
+
// No gutter column on most grids, so fall back to the first body cell -
|
|
1357
|
+
// otherwise `rowResize` would be a prop that silently does nothing.
|
|
1358
|
+
anchor: "row",
|
|
1359
|
+
onResize: (index, height) => ctrl.setRowResizeHeight(index, height),
|
|
1360
|
+
}}
|
|
1361
|
+
use:lazyColumnResize={{
|
|
1362
|
+
disabled: !columnResizeEnabled,
|
|
1363
|
+
getWidth: (columnId) => ctrl.getColumnWidth(columnId),
|
|
1364
|
+
onResize: (columnId, width) => {
|
|
1365
|
+
ctrl.columnWidths = { ...ctrl.columnWidths, [columnId]: width };
|
|
1366
|
+
},
|
|
1367
|
+
label: (columnId) => {
|
|
1368
|
+
const col = ctrl.findColumnById(columnId);
|
|
1369
|
+
return col ? toolPanelHeaderLabel(col) : columnId;
|
|
1370
|
+
},
|
|
1371
|
+
canResize: (columnId) => ctrl.columnResizable(columnId),
|
|
1372
|
+
onAutosize: (columnId) => ctrl.autosizeColumn(columnId),
|
|
1373
|
+
}}
|
|
1296
1374
|
>
|
|
1297
1375
|
{#if showGlobalFilterEffective}
|
|
1298
1376
|
<label class="sv-grid-global-filter">
|
|
@@ -1746,32 +1824,6 @@
|
|
|
1746
1824
|
}}
|
|
1747
1825
|
/>
|
|
1748
1826
|
{/if}
|
|
1749
|
-
<div
|
|
1750
|
-
class="sv-grid-resize-handle"
|
|
1751
|
-
class:is-resizing={resizingColumnId ===
|
|
1752
|
-
header.column.id}
|
|
1753
|
-
role="separator"
|
|
1754
|
-
aria-orientation="vertical"
|
|
1755
|
-
aria-label={`Resize ${toolPanelHeaderLabel(header.column)}`}
|
|
1756
|
-
tabindex="0"
|
|
1757
|
-
{...(() => {
|
|
1758
|
-
// A focusable separator is a widget, so ARIA requires
|
|
1759
|
-
// aria-valuenow. The value it exposes is the column
|
|
1760
|
-
// width the arrow keys change; 40 is the floor
|
|
1761
|
-
// enforced in resizeColumnByKeyboard.
|
|
1762
|
-
const w = Math.round(ctrl.getColumnWidth(header.column.id));
|
|
1763
|
-
return {
|
|
1764
|
-
"aria-valuenow": w,
|
|
1765
|
-
"aria-valuemin": 40,
|
|
1766
|
-
"aria-valuetext": `${w} pixels`,
|
|
1767
|
-
};
|
|
1768
|
-
})()}
|
|
1769
|
-
onpointerdown={(event) =>
|
|
1770
|
-
startColumnResize(event, header.column.id)}
|
|
1771
|
-
onkeydown={(event) =>
|
|
1772
|
-
resizeColumnByKeyboard(event, header.column.id)}
|
|
1773
|
-
ondblclick={(event) => event.stopPropagation()}
|
|
1774
|
-
></div>
|
|
1775
1827
|
{/if}
|
|
1776
1828
|
</th>
|
|
1777
1829
|
{/if}
|
|
@@ -2176,12 +2228,11 @@
|
|
|
2176
2228
|
rendered.column.columnDef.cellFlash,
|
|
2177
2229
|
),
|
|
2178
2230
|
}}
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
})}
|
|
2231
|
+
role="gridcell"
|
|
2232
|
+
id={getGridCellDomId(ctrl.gridDomId, rowIndex, colIndex)}
|
|
2233
|
+
aria-colindex={colIndex + 1}
|
|
2234
|
+
aria-rowindex={rowIndex + 1}
|
|
2235
|
+
aria-selected={isRowSelected(row.id)}
|
|
2185
2236
|
>
|
|
2186
2237
|
{#if inRowEdit || isEditing}
|
|
2187
2238
|
<!-- The editing cell stays empty until the lazy
|
|
@@ -2193,11 +2244,15 @@
|
|
|
2193
2244
|
<CellEditor {ctrl} column={rendered.column} {row} fullRow={inRowEdit} />
|
|
2194
2245
|
{/if}
|
|
2195
2246
|
{:else}
|
|
2196
|
-
{
|
|
2197
|
-
row,
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2247
|
+
{#if plainCellBody}
|
|
2248
|
+
{@render cellBody(row, rendered.column, cellValue)}
|
|
2249
|
+
{:else}
|
|
2250
|
+
{@render cellBodyWithFormat(
|
|
2251
|
+
row,
|
|
2252
|
+
rendered.column,
|
|
2253
|
+
cellValue,
|
|
2254
|
+
)}
|
|
2255
|
+
{/if}
|
|
2201
2256
|
{/if}
|
|
2202
2257
|
{#if !isEditing && fillHandleCell && fillHandleCell.rowIndex === rowIndex && fillHandleCell.colIndex === colIndex}
|
|
2203
2258
|
<!-- Excel-style fill handle: drag down/right to
|
|
@@ -2519,7 +2574,7 @@
|
|
|
2519
2574
|
{/each}
|
|
2520
2575
|
</tbody>
|
|
2521
2576
|
{/if}
|
|
2522
|
-
{#if
|
|
2577
|
+
{#if rowSummariesEnabled}
|
|
2523
2578
|
<!-- svelte-ignore a11y_no_redundant_roles -->
|
|
2524
2579
|
<tfoot class="sv-grid-foot" role="rowgroup">
|
|
2525
2580
|
<tr
|
package/src/SvGrid.types.ts
CHANGED
|
@@ -1029,7 +1029,21 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1029
1029
|
* work; the shortcut wins only when it is explicitly set.
|
|
1030
1030
|
*/
|
|
1031
1031
|
sortable?: boolean;
|
|
1032
|
+
/**
|
|
1033
|
+
* Click a header to filter that column. Injects `columnFilteringFeature`,
|
|
1034
|
+
* so you do not import it yourself. Which filter surface appears is a
|
|
1035
|
+
* separate question - see `filterMode` (default `'menu'`).
|
|
1036
|
+
*
|
|
1037
|
+
* <SvGrid {data} {columns} filterable />
|
|
1038
|
+
*/
|
|
1032
1039
|
filterable?: boolean;
|
|
1040
|
+
/**
|
|
1041
|
+
* Inline cell editing. Alias of `enableInlineEditing`, and wins over it when
|
|
1042
|
+
* both are set. A column also needs an `editorType` to be editable; without
|
|
1043
|
+
* one it falls back to a text editor.
|
|
1044
|
+
*
|
|
1045
|
+
* <SvGrid {data} {columns} editable />
|
|
1046
|
+
*/
|
|
1033
1047
|
editable?: boolean;
|
|
1034
1048
|
/**
|
|
1035
1049
|
* Cell selection - click a cell to select it, drag or shift-click to extend
|
|
@@ -1081,6 +1095,16 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1081
1095
|
/** Indent per depth level, in px. Default `12`. */
|
|
1082
1096
|
indentPx?: number;
|
|
1083
1097
|
};
|
|
1098
|
+
/**
|
|
1099
|
+
* Show the grouping controls: "Group by this column" in the column menu, and
|
|
1100
|
+
* the group panel when `showGroupPanel` is on. Alias of
|
|
1101
|
+
* `showGroupingControls`, and also injects `columnGroupingFeature`.
|
|
1102
|
+
*
|
|
1103
|
+
* This turns on the UI for grouping. To group without asking the user, set
|
|
1104
|
+
* `groupBy` instead.
|
|
1105
|
+
*
|
|
1106
|
+
* <SvGrid {data} {columns} groupable />
|
|
1107
|
+
*/
|
|
1084
1108
|
groupable?: boolean;
|
|
1085
1109
|
/**
|
|
1086
1110
|
* Group the rows by these column ids, outermost first - `['region',
|
|
@@ -1158,7 +1182,19 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1158
1182
|
autoGroupColumnHeader?: string;
|
|
1159
1183
|
/** Width (px) of each auto-group column. Default `220`. */
|
|
1160
1184
|
autoGroupColumnWidth?: number;
|
|
1185
|
+
/**
|
|
1186
|
+
* Show the pagination footer. Alias of `showPagination`, and wins over it
|
|
1187
|
+
* when both are set. Page size starts at `pageSize` (default 10).
|
|
1188
|
+
*
|
|
1189
|
+
* <SvGrid {data} {columns} pageable pageSize={25} />
|
|
1190
|
+
*/
|
|
1161
1191
|
pageable?: boolean;
|
|
1192
|
+
/**
|
|
1193
|
+
* Show the loading state instead of the rows. By default this replaces the
|
|
1194
|
+
* grid body with "Loading..."; set `loadingOverlay` to keep the current rows
|
|
1195
|
+
* visible under a dimmed overlay instead, which is what you usually want for
|
|
1196
|
+
* a server-paged grid.
|
|
1197
|
+
*/
|
|
1162
1198
|
loading?: boolean;
|
|
1163
1199
|
/**
|
|
1164
1200
|
* Render `loading` as a non-blocking overlay instead of replacing the
|
|
@@ -1170,7 +1206,16 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1170
1206
|
loadingOverlay?: boolean;
|
|
1171
1207
|
/** Skeleton placeholder rows to show on first load. Defaults to 8. */
|
|
1172
1208
|
loadingSkeletonRows?: number;
|
|
1209
|
+
/**
|
|
1210
|
+
* Render an error message in place of the rows. `null` or omitted means no
|
|
1211
|
+
* error. Takes precedence over `loading` and over the empty state.
|
|
1212
|
+
*/
|
|
1173
1213
|
error?: string | null;
|
|
1214
|
+
/**
|
|
1215
|
+
* Text shown when there are no rows to display - either the data is empty or
|
|
1216
|
+
* a filter matched nothing. Defaults to the localized `noRows` string, so
|
|
1217
|
+
* prefer `localization.text.noRows` when you are translating the whole grid.
|
|
1218
|
+
*/
|
|
1174
1219
|
emptyMessage?: string;
|
|
1175
1220
|
/**
|
|
1176
1221
|
* The single place to localize the grid. One object with two fields:
|
|
@@ -1190,7 +1235,21 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1190
1235
|
* Omitting it (or any field) is a no-op. See {@link GridMessages}.
|
|
1191
1236
|
*/
|
|
1192
1237
|
localization?: GridLocalization;
|
|
1238
|
+
/**
|
|
1239
|
+
* Show the single search box that filters across every column. Explicitly
|
|
1240
|
+
* setting this wins over `filterMode`; leaving it unset means it appears only
|
|
1241
|
+
* when `filterMode` is `'global'`.
|
|
1242
|
+
*/
|
|
1193
1243
|
showGlobalFilter?: boolean;
|
|
1244
|
+
/**
|
|
1245
|
+
* Show the filter section inside each column's menu. Explicitly setting this
|
|
1246
|
+
* wins over `filterMode`; unset, it follows `filterMode` (default `'menu'`,
|
|
1247
|
+
* so this is normally on).
|
|
1248
|
+
*
|
|
1249
|
+
* Setting it `true` also adds the inline "floating filter" input under each
|
|
1250
|
+
* header - that surface requires the explicit opt-in, since it otherwise
|
|
1251
|
+
* duplicates the menu's own filter popover.
|
|
1252
|
+
*/
|
|
1194
1253
|
showColumnFilters?: boolean;
|
|
1195
1254
|
/**
|
|
1196
1255
|
* Quick way to pick a single filtering UI. When set it controls which of
|
|
@@ -1199,8 +1258,23 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1199
1258
|
* Defaults to `'menu'` (only the column menu's filter section is shown).
|
|
1200
1259
|
*/
|
|
1201
1260
|
filterMode?: "row" | "menu" | "global" | "none";
|
|
1261
|
+
/**
|
|
1262
|
+
* Show the grouping affordances (the column menu's "Group by this column",
|
|
1263
|
+
* and the group panel). The `groupable` shortcut sets this and registers the
|
|
1264
|
+
* grouping feature in one go; prefer that unless you have already registered
|
|
1265
|
+
* `columnGroupingFeature` yourself.
|
|
1266
|
+
*/
|
|
1202
1267
|
showGroupingControls?: boolean;
|
|
1268
|
+
/**
|
|
1269
|
+
* Show the row-selection checkbox column, including the select-all checkbox
|
|
1270
|
+
* in the header. Unset, it follows `selectionMode` (default `'both'`, so
|
|
1271
|
+
* row selection is on).
|
|
1272
|
+
*/
|
|
1203
1273
|
showRowSelection?: boolean;
|
|
1274
|
+
/**
|
|
1275
|
+
* Show the pagination footer. Off by default. `pageable` is the shortcut
|
|
1276
|
+
* alias and wins when both are set.
|
|
1277
|
+
*/
|
|
1204
1278
|
showPagination?: boolean;
|
|
1205
1279
|
/** Initial page size when pagination is enabled. Defaults to 10. */
|
|
1206
1280
|
pageSize?: number;
|
|
@@ -1230,6 +1304,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1230
1304
|
* is on. Fetch that page and update `data` / `rowCount` / `pageIndex`.
|
|
1231
1305
|
*/
|
|
1232
1306
|
onPaginationChange?: (pagination: { pageIndex: number; pageSize: number }) => void;
|
|
1307
|
+
/**
|
|
1308
|
+
* Render only the rows in view instead of all of them. **On by default** -
|
|
1309
|
+
* this is what keeps a 100,000-row grid responsive.
|
|
1310
|
+
*
|
|
1311
|
+
* Turn it off when a row's height cannot be known up front and must not be
|
|
1312
|
+
* clipped, such as a variable-height master-detail panel. Expect the DOM to
|
|
1313
|
+
* hold every row when you do.
|
|
1314
|
+
*/
|
|
1233
1315
|
virtualization?: boolean;
|
|
1234
1316
|
/** Row height in pixels. Pass a function `(rowIndex) => px` for
|
|
1235
1317
|
* per-row variable heights (e.g. an interactive row-resize feature).
|
|
@@ -1247,6 +1329,28 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1247
1329
|
* supplying per-row heights).
|
|
1248
1330
|
*/
|
|
1249
1331
|
autoRowHeight?: boolean;
|
|
1332
|
+
/**
|
|
1333
|
+
* Let the user drag a row's bottom edge to change its height. **Off by
|
|
1334
|
+
* default**, because a resizable row needs somewhere to grab and most grids
|
|
1335
|
+
* do not want a drag target on every row.
|
|
1336
|
+
*
|
|
1337
|
+
* The grid remembers the heights itself, so this works as a bare boolean -
|
|
1338
|
+
* no `rowHeight` function required. Drag, or focus the grip and use Up/Down
|
|
1339
|
+
* (Shift for 1px steps).
|
|
1340
|
+
*
|
|
1341
|
+
* Turning this on also turns on the **row header column** ({@link
|
|
1342
|
+
* showRowNumbers}), because that is where the grip lives and where a
|
|
1343
|
+
* spreadsheet puts it - a drag target on the edge of a data cell works but
|
|
1344
|
+
* reads as an accident. An explicit `showRowNumbers={false}` still wins; the
|
|
1345
|
+
* grip then falls back to the row's first cell, and a column of your own
|
|
1346
|
+
* carrying `cellClass: 'sv-row-gutter'` is used ahead of either.
|
|
1347
|
+
*
|
|
1348
|
+
* Ignored under `autoRowHeight`, where the content decides the height and a
|
|
1349
|
+
* manual one would immediately be overwritten. For full control of the
|
|
1350
|
+
* heights - persisting them, sharing them between grids - pass a
|
|
1351
|
+
* function-valued {@link rowHeight} and use the `rowResize` action directly.
|
|
1352
|
+
*/
|
|
1353
|
+
rowResize?: boolean;
|
|
1250
1354
|
/**
|
|
1251
1355
|
* Height (px) of a single column-header level row. With multi-level
|
|
1252
1356
|
* (grouped) headers the total header height is `levels * headerHeight`,
|
|
@@ -1254,6 +1358,11 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1254
1358
|
* to their content (the default). Does not affect the filter row.
|
|
1255
1359
|
*/
|
|
1256
1360
|
headerHeight?: number;
|
|
1361
|
+
/**
|
|
1362
|
+
* Extra rows rendered above and below the viewport, so fast scrolling does
|
|
1363
|
+
* not reach empty space before the next batch renders. Defaults to 8.
|
|
1364
|
+
* Raise it for very tall rows, lower it to trim DOM work.
|
|
1365
|
+
*/
|
|
1257
1366
|
overscan?: number;
|
|
1258
1367
|
/**
|
|
1259
1368
|
* Height of the grid's scrollable shell. A number is treated as pixels;
|
|
@@ -1261,8 +1370,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1261
1370
|
* make the grid fill its parent. Defaults to 520 px.
|
|
1262
1371
|
*/
|
|
1263
1372
|
containerHeight?: number | string;
|
|
1373
|
+
/**
|
|
1374
|
+
* Render only the columns in view, the horizontal counterpart of
|
|
1375
|
+
* `virtualization`. **On by default**, which is what makes a 100-column grid
|
|
1376
|
+
* scroll smoothly.
|
|
1377
|
+
*
|
|
1378
|
+
* It recycles column DOM nodes, so it cannot coexist with sticky pinned
|
|
1379
|
+
* columns - turn it off if you need pinning to survive horizontal scrolling.
|
|
1380
|
+
*/
|
|
1264
1381
|
columnVirtualization?: boolean;
|
|
1382
|
+
/**
|
|
1383
|
+
* Extra columns rendered either side of the viewport when
|
|
1384
|
+
* `columnVirtualization` is on. Defaults to 3.
|
|
1385
|
+
*/
|
|
1265
1386
|
columnOverscan?: number;
|
|
1387
|
+
/**
|
|
1388
|
+
* Fallback width in pixels for columns whose `ColumnDef` sets no `width`.
|
|
1389
|
+
* Defaults to 140.
|
|
1390
|
+
*/
|
|
1266
1391
|
columnWidth?: number;
|
|
1267
1392
|
/**
|
|
1268
1393
|
* Columns pinned to the left/right edge on mount. Each entry is a
|
|
@@ -1284,6 +1409,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1284
1409
|
* win once they happen.
|
|
1285
1410
|
*/
|
|
1286
1411
|
fitColumns?: boolean;
|
|
1412
|
+
/**
|
|
1413
|
+
* Let the user drag a column's edge to change its width. **Off by default**,
|
|
1414
|
+
* so `width` means the width you asked for until you say otherwise.
|
|
1415
|
+
*
|
|
1416
|
+
* Turn it on for grids the reader is meant to arrange - a spreadsheet, a
|
|
1417
|
+
* dense report, anything with columns whose content varies in length. Leave
|
|
1418
|
+
* it off for layouts you control, and for columns that must keep their size:
|
|
1419
|
+
* a row-number gutter, a checkbox column, an icon column.
|
|
1420
|
+
*
|
|
1421
|
+
* It is grid-wide rather than per-column: there is no `resizable: false` on a
|
|
1422
|
+
* single column definition. `api.autosizeColumn()`, `fitColumns` and
|
|
1423
|
+
* programmatic width changes work either way - this only governs the drag
|
|
1424
|
+
* handle.
|
|
1425
|
+
*
|
|
1426
|
+
* The handles come from the `columnResize` action, loaded on demand: a grid
|
|
1427
|
+
* that leaves this off never fetches that code.
|
|
1428
|
+
*/
|
|
1429
|
+
columnResize?: boolean;
|
|
1287
1430
|
/**
|
|
1288
1431
|
* Make the grid usable on narrow screens. When the grid's own width drops
|
|
1289
1432
|
* below the breakpoint (default `640`px), pinned columns are un-pinned so the
|
|
@@ -1293,8 +1436,24 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1293
1436
|
* breakpoint; pass `{ breakpoint }` to change it. Off by default.
|
|
1294
1437
|
*/
|
|
1295
1438
|
responsive?: boolean | { breakpoint?: number };
|
|
1439
|
+
/**
|
|
1440
|
+
* @deprecated Has no effect - nothing in the grid reads this prop. It is kept
|
|
1441
|
+
* only so existing code keeps compiling. The column menu's filter section is
|
|
1442
|
+
* controlled by `showColumnFilters`, or by `filterMode="menu"` (the default).
|
|
1443
|
+
*/
|
|
1296
1444
|
showFilterMenu?: boolean;
|
|
1445
|
+
/**
|
|
1446
|
+
* Show the always-visible filter row under the header. Explicitly setting
|
|
1447
|
+
* this wins over `filterMode`; unset, it appears only when `filterMode` is
|
|
1448
|
+
* `'row'`.
|
|
1449
|
+
*/
|
|
1297
1450
|
showFilterRow?: boolean;
|
|
1451
|
+
/**
|
|
1452
|
+
* Cell selection - click to select, drag or shift-click to extend to a range,
|
|
1453
|
+
* which is what clipboard copy and the range fill handle operate on. Unset,
|
|
1454
|
+
* it follows `selectionMode` (default `'both'`, so this is on). `selectable`
|
|
1455
|
+
* is the shortcut alias and wins over it.
|
|
1456
|
+
*/
|
|
1298
1457
|
enableCellSelection?: boolean;
|
|
1299
1458
|
/**
|
|
1300
1459
|
* Highlight the row under the pointer. Default **false** - the hover tint can
|
|
@@ -1320,6 +1479,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1320
1479
|
rowIndex: number;
|
|
1321
1480
|
columnId: string;
|
|
1322
1481
|
}) => unknown;
|
|
1482
|
+
/**
|
|
1483
|
+
* Inline cell editing: F2 or double-click opens an editor in the active cell,
|
|
1484
|
+
* Enter commits, Esc cancels. Off by default.
|
|
1485
|
+
*
|
|
1486
|
+
* A column still needs an `editorType` to pick its editor (text, number,
|
|
1487
|
+
* date, checkbox, list, ...); without one it gets a plain text editor.
|
|
1488
|
+
* `editable` is the shortcut alias and wins over this.
|
|
1489
|
+
*/
|
|
1323
1490
|
enableInlineEditing?: boolean;
|
|
1324
1491
|
/**
|
|
1325
1492
|
* Full-row editing. When `true`, starting an edit puts the WHOLE row into
|
|
@@ -1329,7 +1496,22 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1329
1496
|
* text / number / date / datetime / checkbox / list-select editor types.
|
|
1330
1497
|
*/
|
|
1331
1498
|
fullRowEditing?: boolean;
|
|
1499
|
+
/**
|
|
1500
|
+
* Append a sticky footer row aggregating every filtered row: the sum of a
|
|
1501
|
+
* numeric column, `Count: N` otherwise. Choose a different aggregate per
|
|
1502
|
+
* column with that column's own `summary` option, or set it to `false` there
|
|
1503
|
+
* to leave the cell blank.
|
|
1504
|
+
*
|
|
1505
|
+
* Off by default. `summary` is the shortcut alias and wins when both are set.
|
|
1506
|
+
*
|
|
1507
|
+
* <SvGrid {data} {columns} summary />
|
|
1508
|
+
*/
|
|
1332
1509
|
enableRowSummaries?: boolean;
|
|
1510
|
+
/**
|
|
1511
|
+
* Shortcut alias for {@link enableRowSummaries}. Wins over it when both are
|
|
1512
|
+
* set, the same precedence `selectable` has over `enableCellSelection`.
|
|
1513
|
+
*/
|
|
1514
|
+
summary?: boolean;
|
|
1333
1515
|
/**
|
|
1334
1516
|
* Excel-style status bar under the grid showing live aggregates of the
|
|
1335
1517
|
* selected cell range (count, numeric count, sum, average, min, max).
|
|
@@ -1356,7 +1538,7 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1356
1538
|
charting?: boolean | ChartingConfig<TData>;
|
|
1357
1539
|
/**
|
|
1358
1540
|
* Render the header column menu (⋮) as a tabbed popover - **General**,
|
|
1359
|
-
* **Filter**, and **Columns** tabs (the
|
|
1541
|
+
* **Filter**, and **Columns** tabs (the tabbed layout). Defaults to `false`,
|
|
1360
1542
|
* which keeps the flat menu (actions list + "Choose columns" submenu).
|
|
1361
1543
|
*/
|
|
1362
1544
|
columnMenuTabs?: boolean;
|
|
@@ -1544,6 +1726,14 @@ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends
|
|
|
1544
1726
|
* filter.
|
|
1545
1727
|
*/
|
|
1546
1728
|
conditionalStatScope?: "filtered" | "visible" | "all";
|
|
1729
|
+
/**
|
|
1730
|
+
* Fires after an inline edit commits, with the cell's old and new value and
|
|
1731
|
+
* the row it belongs to. This is where you persist the change.
|
|
1732
|
+
*
|
|
1733
|
+
* The grid has already applied the edit to its own state by the time this
|
|
1734
|
+
* runs, so it is a notification, not a veto - reject a value with the
|
|
1735
|
+
* column's `valueParser` or a validation rule instead.
|
|
1736
|
+
*/
|
|
1547
1737
|
onCellValueChange?: (event: {
|
|
1548
1738
|
rowIndex: number;
|
|
1549
1739
|
columnId: string;
|