@svgrid/grid 1.0.2 → 1.1.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.
Files changed (143) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +137 -39
  3. package/dist/GridFooter.svelte +164 -0
  4. package/dist/GridFooter.svelte.d.ts +29 -0
  5. package/dist/GridMenus.svelte +570 -0
  6. package/dist/GridMenus.svelte.d.ts +31 -0
  7. package/dist/SvGrid.controller.svelte.d.ts +429 -0
  8. package/dist/SvGrid.controller.svelte.js +1732 -0
  9. package/dist/SvGrid.css +1709 -0
  10. package/dist/SvGrid.helpers.d.ts +35 -0
  11. package/dist/SvGrid.helpers.js +160 -0
  12. package/dist/SvGrid.svelte +344 -7043
  13. package/dist/SvGrid.svelte.d.ts +4 -357
  14. package/dist/SvGrid.types.d.ts +436 -0
  15. package/dist/SvGrid.types.js +1 -0
  16. package/dist/SvGridChart.svelte +1060 -23
  17. package/dist/SvGridChart.svelte.d.ts +17 -0
  18. package/dist/build-api.d.ts +5 -0
  19. package/dist/build-api.js +527 -0
  20. package/dist/cell-render.d.ts +15 -0
  21. package/dist/cell-render.js +246 -0
  22. package/dist/cell-values.d.ts +28 -0
  23. package/dist/cell-values.js +89 -0
  24. package/dist/chart.d.ts +370 -3
  25. package/dist/chart.js +1135 -42
  26. package/dist/clipboard.d.ts +15 -0
  27. package/dist/clipboard.js +356 -0
  28. package/dist/columns.d.ts +30 -0
  29. package/dist/columns.js +277 -0
  30. package/dist/core.d.ts +1 -1
  31. package/dist/css.d.ts +3 -0
  32. package/dist/editing.d.ts +24 -0
  33. package/dist/editing.js +343 -0
  34. package/dist/editors/cell-editors.d.ts +1 -1
  35. package/dist/facet-buckets.d.ts +13 -0
  36. package/dist/facet-buckets.js +54 -0
  37. package/dist/features.d.ts +5 -0
  38. package/dist/features.js +30 -0
  39. package/dist/filter-operators.d.ts +16 -0
  40. package/dist/filter-operators.js +69 -0
  41. package/dist/hyperformula-adapter.d.ts +82 -0
  42. package/dist/hyperformula-adapter.js +73 -0
  43. package/dist/index.d.ts +5 -2
  44. package/dist/index.js +5 -2
  45. package/dist/keyboard-handlers.d.ts +7 -0
  46. package/dist/keyboard-handlers.js +197 -0
  47. package/dist/menus.d.ts +40 -0
  48. package/dist/menus.js +389 -0
  49. package/dist/named-views.d.ts +27 -0
  50. package/dist/named-views.js +39 -0
  51. package/dist/row-resize.d.ts +43 -0
  52. package/dist/row-resize.js +158 -0
  53. package/dist/scroll-sync.d.ts +9 -0
  54. package/dist/scroll-sync.js +86 -0
  55. package/dist/selection.d.ts +26 -0
  56. package/dist/selection.js +387 -0
  57. package/dist/spreadsheet.d.ts +80 -0
  58. package/dist/spreadsheet.js +194 -0
  59. package/dist/summaries.d.ts +12 -0
  60. package/dist/summaries.js +65 -0
  61. package/dist/svgrid-wrapper.types.d.ts +12 -1
  62. package/dist/svgrid.comments-autocomplete.test.d.ts +1 -0
  63. package/dist/svgrid.comments-autocomplete.test.js +96 -0
  64. package/dist/svgrid.context-menu.test.d.ts +1 -0
  65. package/dist/svgrid.context-menu.test.js +102 -0
  66. package/dist/svgrid.new-features.wrapper.test.js +30 -4
  67. package/dist/svgrid.wrapper.test.js +27 -1
  68. package/dist/virtualization/column-virtualizer.d.ts +2 -0
  69. package/dist/virtualization/scroll-scaling.d.ts +28 -0
  70. package/dist/virtualization/scroll-scaling.js +64 -0
  71. package/dist/virtualization/scroll-scaling.test.d.ts +1 -0
  72. package/dist/virtualization/scroll-scaling.test.js +86 -0
  73. package/dist/virtualization/svelte-virtualizer.svelte.d.ts +2 -0
  74. package/dist/virtualization/svelte-virtualizer.svelte.js +2 -0
  75. package/dist/virtualization/virtualizer.d.ts +7 -0
  76. package/dist/virtualization/virtualizer.js +30 -0
  77. package/package.json +1 -1
  78. package/src/GridFooter.svelte +164 -0
  79. package/src/GridMenus.svelte +570 -0
  80. package/src/SvGrid.controller.svelte.ts +2195 -0
  81. package/src/SvGrid.css +1747 -0
  82. package/src/SvGrid.helpers.test.ts +415 -0
  83. package/src/SvGrid.helpers.ts +185 -0
  84. package/src/SvGrid.svelte +348 -7043
  85. package/src/SvGrid.types.ts +456 -0
  86. package/src/SvGridChart.svelte +1060 -23
  87. package/src/build-api.coverage.test.ts +532 -0
  88. package/src/build-api.ts +663 -0
  89. package/src/cell-render.test.ts +451 -0
  90. package/src/cell-render.ts +426 -0
  91. package/src/cell-values.ts +114 -0
  92. package/src/chart-export.test.ts +370 -0
  93. package/src/chart.coverage.test.ts +814 -0
  94. package/src/chart.ts +1352 -47
  95. package/src/clipboard.test.ts +731 -0
  96. package/src/clipboard.ts +524 -0
  97. package/src/collaboration.coverage.test.ts +220 -0
  98. package/src/columns.test.ts +702 -0
  99. package/src/columns.ts +419 -0
  100. package/src/core.ts +8 -0
  101. package/src/css.d.ts +3 -0
  102. package/src/editing.test.ts +837 -0
  103. package/src/editing.ts +513 -0
  104. package/src/editors/cell-editors.coverage.test.ts +156 -0
  105. package/src/editors/cell-editors.ts +1 -0
  106. package/src/facet-buckets.test.ts +353 -0
  107. package/src/facet-buckets.ts +67 -0
  108. package/src/features.ts +128 -0
  109. package/src/filter-operators.test.ts +174 -0
  110. package/src/filter-operators.ts +87 -0
  111. package/src/hyperformula-adapter.test.ts +256 -0
  112. package/src/hyperformula-adapter.ts +124 -0
  113. package/src/index.ts +37 -0
  114. package/src/keyboard-handlers.coverage.test.ts +560 -0
  115. package/src/keyboard-handlers.ts +353 -0
  116. package/src/keyboard.ts +97 -97
  117. package/src/menus.test.ts +620 -0
  118. package/src/menus.ts +554 -0
  119. package/src/named-views.coverage.test.ts +210 -0
  120. package/src/named-views.ts +48 -0
  121. package/src/row-resize.test.ts +369 -0
  122. package/src/row-resize.ts +171 -0
  123. package/src/scroll-sync.test.ts +330 -0
  124. package/src/scroll-sync.ts +216 -0
  125. package/src/selection.test.ts +722 -0
  126. package/src/selection.ts +545 -0
  127. package/src/server-data-source.coverage.test.ts +180 -0
  128. package/src/spreadsheet.test.ts +445 -0
  129. package/src/spreadsheet.ts +246 -0
  130. package/src/summaries.ts +204 -0
  131. package/src/sv-grid-scrollbar.ts +13 -1
  132. package/src/svgrid-wrapper.types.ts +12 -1
  133. package/src/svgrid.behavior.test.ts +22 -0
  134. package/src/svgrid.comments-autocomplete.test.ts +112 -0
  135. package/src/svgrid.context-menu.test.ts +126 -0
  136. package/src/svgrid.interaction.test.ts +30 -0
  137. package/src/svgrid.new-features.wrapper.test.ts +65 -4
  138. package/src/svgrid.wrapper.test.ts +27 -1
  139. package/src/test-setup.ts +9 -6
  140. package/src/virtualization/scroll-scaling.test.ts +148 -0
  141. package/src/virtualization/scroll-scaling.ts +121 -0
  142. package/src/virtualization/svelte-virtualizer.svelte.ts +2 -0
  143. package/src/virtualization/virtualizer.ts +26 -0
@@ -0,0 +1,436 @@
1
+ import type { Snippet } from "svelte";
2
+ import type { CellEditorType, ColumnDef, RowData, SvGridApi, TableFeatures } from "./index";
3
+ import type { ConditionalFormat } from "./conditional-formatting";
4
+ /** The cell a context menu was opened on. Passed to every item's callbacks. */
5
+ export type ContextMenuTarget<TData extends RowData = RowData> = {
6
+ rowIndex: number;
7
+ colIndex: number;
8
+ columnId: string;
9
+ /** Stable row id (from getRowId / row model), for keying notes etc. */
10
+ rowId: string;
11
+ row: TData | null;
12
+ };
13
+ /**
14
+ * A context-menu entry. Either a built-in action key, the `"separator"`
15
+ * divider, or a custom item. Built-in keys: `"copy" | "cut" | "paste" |
16
+ * "clear" | "row_above" | "row_below" | "remove_row" | "remove_col"`.
17
+ */
18
+ export type ContextMenuItem<TData extends RowData = RowData> = string | {
19
+ key: string;
20
+ label: string;
21
+ /** Hide the item entirely for this target. */
22
+ hidden?: (target: ContextMenuTarget<TData>) => boolean;
23
+ /** Render the item greyed-out and non-clickable for this target. */
24
+ disabled?: (target: ContextMenuTarget<TData>) => boolean;
25
+ /** Invoked on click. The menu closes afterwards. */
26
+ action: (target: ContextMenuTarget<TData>) => void;
27
+ };
28
+ export type Props<TFeatures extends TableFeatures = TableFeatures, TData extends RowData = RowData> = {
29
+ data: ReadonlyArray<TData>;
30
+ columns: Array<ColumnDef<TFeatures, TData>>;
31
+ /**
32
+ * Right-click context menu. `true` shows the default item set (copy, cut,
33
+ * paste, clear, insert row above/below, remove row, remove column). Pass an
34
+ * array to customize: strings are built-in keys, `"separator"` is a divider,
35
+ * and objects are custom items. Omitted/`false` disables the menu (native
36
+ * browser menu shows instead).
37
+ */
38
+ contextMenu?: boolean | ReadonlyArray<ContextMenuItem<TData>>;
39
+ /**
40
+ * The feature set built with `tableFeatures({ ... })`. Optional - the
41
+ * `sortable` / `filterable` / `groupable` shortcuts below inject the
42
+ * matching feature for you, so a grid can be configured entirely from
43
+ * the boolean shortcuts without importing the feature constants.
44
+ */
45
+ features?: TFeatures;
46
+ /**
47
+ * Convenience shortcuts to switch a whole capability on without wiring
48
+ * `features` or the finer-grained props by hand. Every capability is OFF
49
+ * by default - a bare grid is a plain read-only table - so set the
50
+ * shortcut `true` to opt in. (`false` / omitted both leave it off; the
51
+ * shortcut is mainly there to turn things ON.)
52
+ *
53
+ * `sortable` - column sorting (injects `rowSortingFeature`)
54
+ * `filterable` - column filtering (injects `columnFilteringFeature`)
55
+ * `editable` - inline cell editing (alias of `enableInlineEditing`)
56
+ * `groupable` - row grouping controls(alias of `showGroupingControls`,
57
+ * also injects `columnGroupingFeature`)
58
+ * `pageable` - pagination footer (alias of `showPagination`)
59
+ *
60
+ * Fine-grained props (`enableInlineEditing`, `showPagination`, ...) still
61
+ * work; the shortcut wins only when it is explicitly set.
62
+ */
63
+ sortable?: boolean;
64
+ filterable?: boolean;
65
+ editable?: boolean;
66
+ groupable?: boolean;
67
+ pageable?: boolean;
68
+ loading?: boolean;
69
+ /**
70
+ * Render `loading` as a non-blocking overlay instead of replacing the
71
+ * whole grid: the current rows stay visible (dimmed, with a top progress
72
+ * bar) during a refetch, and the first load shows shimmer skeleton rows.
73
+ * Ideal for server-paged grids so paging/sorting doesn't flash. Defaults
74
+ * to `false` (the classic full "Loading..." replacement).
75
+ */
76
+ loadingOverlay?: boolean;
77
+ /** Skeleton placeholder rows to show on first load. Defaults to 8. */
78
+ loadingSkeletonRows?: number;
79
+ error?: string | null;
80
+ emptyMessage?: string;
81
+ showGlobalFilter?: boolean;
82
+ showColumnFilters?: boolean;
83
+ /**
84
+ * Quick way to pick a single filtering UI. When set it controls which of
85
+ * the three filter surfaces appears (and is overridden per-surface by the
86
+ * `showGlobalFilter` / `showColumnFilters` / `showFilterRow` props).
87
+ * Defaults to `'menu'` (only the column menu's filter section is shown).
88
+ */
89
+ filterMode?: "row" | "menu" | "global" | "none";
90
+ showGroupingControls?: boolean;
91
+ showRowSelection?: boolean;
92
+ showPagination?: boolean;
93
+ /** Initial page size when pagination is enabled. Defaults to 10. */
94
+ pageSize?: number;
95
+ virtualization?: boolean;
96
+ /** Row height in pixels. Pass a function `(rowIndex) => px` for
97
+ * per-row variable heights (e.g. an interactive row-resize feature).
98
+ * Defaults to 30. */
99
+ rowHeight?: number | ((rowIndex: number) => number);
100
+ /**
101
+ * Height (px) of a single column-header level row. With multi-level
102
+ * (grouped) headers the total header height is `levels * headerHeight`,
103
+ * since each level renders as its own row. When omitted, header rows size
104
+ * to their content (the default). Does not affect the filter row.
105
+ */
106
+ headerHeight?: number;
107
+ overscan?: number;
108
+ /**
109
+ * Height of the grid's scrollable shell. A number is treated as pixels;
110
+ * a string is used as-is, so callers can pass `'100%'` or `'auto'` to
111
+ * make the grid fill its parent. Defaults to 520 px.
112
+ */
113
+ containerHeight?: number | string;
114
+ columnVirtualization?: boolean;
115
+ columnOverscan?: number;
116
+ columnWidth?: number;
117
+ /**
118
+ * Columns pinned to the left/right edge on mount. Each entry is a
119
+ * column id (matches `ColumnDef.field` when no explicit id is set).
120
+ * The internal pinning state is seeded once at mount; user-driven
121
+ * pinning via the column menu still works and overrides this default.
122
+ * Requires `columnVirtualization={false}` to be visible in the menu
123
+ * UI (sticky positioning can't co-exist with column virtualization
124
+ * since the virtualizer recycles DOM nodes).
125
+ */
126
+ initialColumnPinning?: {
127
+ left?: ReadonlyArray<string>;
128
+ right?: ReadonlyArray<string>;
129
+ };
130
+ /**
131
+ * When `true`, columns are scaled proportionally so their total width
132
+ * fills the viewport (no empty space on the right). Disabled by
133
+ * default - explicit `width` values are used as-is. User resizes still
134
+ * win once they happen.
135
+ */
136
+ fitColumns?: boolean;
137
+ showFilterMenu?: boolean;
138
+ showFilterRow?: boolean;
139
+ enableCellSelection?: boolean;
140
+ enableInlineEditing?: boolean;
141
+ enableRowSummaries?: boolean;
142
+ /**
143
+ * Excel-style status bar under the grid showing live aggregates of the
144
+ * selected cell range (count, numeric count, sum, average, min, max).
145
+ * `true` shows the default set; pass `{ aggregates: [...] }` to choose
146
+ * which. Requires `enableCellSelection`.
147
+ */
148
+ statusBar?: boolean | {
149
+ aggregates?: ReadonlyArray<"count" | "numericCount" | "sum" | "avg" | "min" | "max">;
150
+ };
151
+ /**
152
+ * Show a docked Columns tool panel - the enterprise sidebar for toggling
153
+ * column visibility, reordering, and grouping without a right-click. A
154
+ * toggle button appears at the grid's top-right; the panel itself docks
155
+ * on the right edge.
156
+ */
157
+ toolPanel?: boolean;
158
+ /**
159
+ * Quick way to pick which selection surfaces are active. `'row'` shows the
160
+ * selection checkbox column only, `'cell'` allows rectangle/range cell
161
+ * selection only, `'both'` (default) enables both, `'none'` disables both.
162
+ * Overridden per-surface by `showRowSelection` / `enableCellSelection`.
163
+ */
164
+ selectionMode?: "row" | "cell" | "both" | "none";
165
+ /**
166
+ * Render a leading row-number column (1-based) before any selection
167
+ * column. Useful as a permanent anchor when scrolling wide grids.
168
+ */
169
+ showRowNumbers?: boolean;
170
+ /**
171
+ * Width (px) of the row-number column. Defaults to 56, which fits up
172
+ * to "99,999"; bump this when the dataset crosses six digits so the
173
+ * largest row number stays fully visible at the bottom of a scroll.
174
+ */
175
+ rowNumberWidth?: number;
176
+ /** Receives the imperative grid API once the component has mounted. */
177
+ onApiReady?: (api: SvGridApi<TFeatures, TData>) => void;
178
+ /**
179
+ * Fires whenever the row-selection state changes. The first argument
180
+ * is the new selection record `{ [rowId]: true }`; the second is the
181
+ * array of selected `TData` rows.
182
+ */
183
+ onRowSelectionChange?: (selection: Record<string, boolean>, rows: TData[]) => void;
184
+ /**
185
+ * Fires whenever the cell-selection rectangle changes (mouse, keyboard,
186
+ * or `api.selectCells()`). `ranges` matches `api.getSelected()` -
187
+ * `[rowStart, colStart, rowEnd, colEnd]` rectangles in grid coords.
188
+ * Empty array when the user clears the selection.
189
+ */
190
+ onCellSelectionChange?: (ranges: Array<[number, number, number, number]>) => void;
191
+ /**
192
+ * When `true`, the grid records sort state (and renders sort indicators
193
+ * + cycling on headers) but does NOT actually re-order the rows. The
194
+ * consumer is expected to sort `data` themselves - typically via
195
+ * `onSortingChange`. Use this for tree/hierarchical data, where a flat
196
+ * global sort would break parent-child adjacency. Defaults to `false`.
197
+ */
198
+ externalSort?: boolean;
199
+ /**
200
+ * Fires whenever the sort clauses change. Receives the new array of
201
+ * `{ id, desc }` entries. Pair with `externalSort={true}` when the
202
+ * consumer wants to own the row ordering.
203
+ */
204
+ onSortingChange?: (sorting: Array<{
205
+ id: string;
206
+ desc: boolean;
207
+ }>) => void;
208
+ /**
209
+ * When `true`, the grid still records column-filter / global-filter /
210
+ * facet state (so the menu UI works and indicators light up) but does
211
+ * NOT actually filter the rows. The consumer is expected to fetch / sort
212
+ * / filter the data themselves - typically via `onFiltersChange`. Used
213
+ * by server-side data sources. Defaults to `false`.
214
+ */
215
+ externalFilter?: boolean;
216
+ /**
217
+ * Fires whenever any of the in-grid filter state changes - global
218
+ * search, per-column operator filters, or facet (value-checklist)
219
+ * filters. Pair with `externalFilter={true}` when the consumer wants to
220
+ * push the query to the server.
221
+ */
222
+ onFiltersChange?: (filters: {
223
+ global: string;
224
+ columns: Array<{
225
+ id: string;
226
+ operator: FilterOperator;
227
+ value: string;
228
+ /**
229
+ * Upper bound for the `between` operator. Only set when
230
+ * `operator === 'between'` AND the user has typed both values.
231
+ */
232
+ valueTo?: string;
233
+ selectedValues?: Array<string>;
234
+ }>;
235
+ }) => void;
236
+ /**
237
+ * Fires when an inline edit is committed (Enter / Tab / blur). Useful
238
+ * for cascade-recompute pipelines: a parent listens, then refreshes
239
+ * derived columns or aggregates. The wrapper has already written the
240
+ * parsed value back into the row by the time this fires.
241
+ */
242
+ /**
243
+ * Resolve a stable id per row. Drives selection, expansion, edit,
244
+ * and active-cell state. When omitted, the row's array index is
245
+ * used - fine for read-only views but the wrong choice if `data`
246
+ * gets reordered or filtered outside the grid (selection would
247
+ * follow positions, not actual rows). Use a database PK, a UUID,
248
+ * or any stable string.
249
+ */
250
+ getRowId?: (row: TData, index: number) => string;
251
+ /**
252
+ * Conditional class(es) added to every `<tr>` body row. Receives
253
+ * the row's `original` data + its data-array index. Return a
254
+ * string, an array of strings, or an object mapping class names to
255
+ * booleans. Useful for "highlight overdue rows", "tint cancelled
256
+ * orders", and similar row-level state mappings.
257
+ */
258
+ rowClass?: (ctx: {
259
+ row: TData;
260
+ rowIndex: number;
261
+ }) => string | ReadonlyArray<string> | Record<string, boolean> | undefined | null;
262
+ /**
263
+ * Per-cell notes - longer free-form comments shown as a corner
264
+ * indicator + tooltip on hover. Keyed by row id then column id;
265
+ * empty / missing entries mean "no note". The grid owns rendering;
266
+ * you own storage (write your own callbacks to add / edit notes).
267
+ */
268
+ notes?: Record<string, Record<string, string>>;
269
+ /**
270
+ * Allow editing per-cell notes/comments through the UI: the context menu
271
+ * gains an "Edit comment" item that opens a popover editor. Edits are
272
+ * applied to an internal overlay for immediate feedback and emitted via
273
+ * `onNoteChange` so you can persist them back into `notes`.
274
+ */
275
+ editableComments?: boolean;
276
+ /** Fires when a comment is saved or removed (removed = empty `note`). */
277
+ onNoteChange?: (event: {
278
+ rowId: string;
279
+ columnId: string;
280
+ note: string;
281
+ }) => void;
282
+ /**
283
+ * Excel-style conditional formatting. A list of value-driven rules that
284
+ * color cells: `colorScale` (gradient across the column range),
285
+ * `dataBar` (in-cell proportional bar), `iconSet` (arrows / traffic /
286
+ * triangles by threshold), and `rule` (apply a style when a predicate
287
+ * matches). Scope a format to specific columns with `columns: [...]`,
288
+ * or omit it to apply to every column. Later entries win on conflict.
289
+ */
290
+ conditionalFormats?: ReadonlyArray<ConditionalFormat<TData>>;
291
+ onCellValueChange?: (event: {
292
+ rowIndex: number;
293
+ columnId: string;
294
+ oldValue: unknown;
295
+ newValue: unknown;
296
+ row: TData;
297
+ }) => void;
298
+ /**
299
+ * Fires whenever the active cell changes - click, keyboard move,
300
+ * tab, page-up/down, etc. Consumers (toolbars, ribbon UIs) use this
301
+ * to stay synced with the grid's selection without polling the DOM.
302
+ */
303
+ onActiveCellChange?: (cell: {
304
+ rowIndex: number;
305
+ colIndex: number;
306
+ columnId: string;
307
+ }) => void;
308
+ /**
309
+ * Fires when a data cell (and therefore a row) is single-clicked.
310
+ * Group-header rows are excluded. `value` is the displayed cell value.
311
+ */
312
+ onCellClick?: (event: {
313
+ rowIndex: number;
314
+ colIndex: number;
315
+ columnId: string;
316
+ value: unknown;
317
+ row: TData;
318
+ }) => void;
319
+ /** Fires when a data row is single-clicked (any cell). Group rows excluded. */
320
+ onRowClick?: (event: {
321
+ rowIndex: number;
322
+ columnId: string;
323
+ row: TData;
324
+ }) => void;
325
+ /**
326
+ * Fires when a data cell is double-clicked - independent of whether the
327
+ * cell is editable, so it fires even on read-only grids. Group rows excluded.
328
+ */
329
+ onCellDoubleClick?: (event: {
330
+ rowIndex: number;
331
+ colIndex: number;
332
+ columnId: string;
333
+ value: unknown;
334
+ row: TData;
335
+ }) => void;
336
+ /** Fires when a data row is double-clicked (any cell). Group rows excluded. */
337
+ onRowDoubleClick?: (event: {
338
+ rowIndex: number;
339
+ columnId: string;
340
+ row: TData;
341
+ }) => void;
342
+ /**
343
+ * Fires once each time the body is scrolled to (within ~32px of) the
344
+ * bottom. Re-arms after the user scrolls back up. The canonical hook for
345
+ * infinite / lazy loading - append more rows to `data` when it fires.
346
+ */
347
+ onScrollBottomReached?: (event: {
348
+ scrollTop: number;
349
+ scrollHeight: number;
350
+ clientHeight: number;
351
+ }) => void;
352
+ /**
353
+ * Marks a row as an expandable "detail row". When this returns true the
354
+ * grid renders that row as a SINGLE full-width cell (colspan across every
355
+ * column) using `renderDetailRow`, instead of the normal per-column cells
356
+ * - the canonical Stripe / GitHub "expand a rich panel beneath the row"
357
+ * pattern. Insert the detail rows into `data` yourself (typically right
358
+ * after the row they belong to) and toggle them with your own expanded
359
+ * state. Pair with `virtualization={false}` so the variable-height detail
360
+ * isn't clipped by the fixed-row-height virtualizer.
361
+ */
362
+ isDetailRow?: (row: TData, rowIndex: number) => boolean;
363
+ /**
364
+ * Snippet rendered inside the full-width detail cell for rows where
365
+ * `isDetailRow` is true. Receives the row's data and its index.
366
+ */
367
+ renderDetailRow?: Snippet<[{
368
+ row: TData;
369
+ rowIndex: number;
370
+ }]>;
371
+ /**
372
+ * Rows to pin to the TOP of the grid - rendered above the regular
373
+ * rows and sticky-positioned so they stay visible while the user
374
+ * scrolls. Typical use: a "totals" or "headline" row that should
375
+ * always be in view. Rows are read-only (no inline editing, no
376
+ * row-selection checkbox). They share the column schema with the
377
+ * main grid; field/format/cell/cellClass all apply.
378
+ */
379
+ pinnedTopRows?: ReadonlyArray<TData>;
380
+ /**
381
+ * Rows to pin to the BOTTOM of the grid - rendered below the regular
382
+ * rows and sticky-positioned (sticks to the bottom of the viewport
383
+ * while the user scrolls). Typical use: a "page totals" or "grand
384
+ * total" row computed from `getDisplayedRows()`.
385
+ */
386
+ pinnedBottomRows?: ReadonlyArray<TData>;
387
+ /**
388
+ * Enables drag-to-reorder on the grid's column headers. When `true`,
389
+ * every header gets `draggable=true` and a drop indicator paints
390
+ * between headers during a drag. On drop the grid mutates its
391
+ * internal column order and fires `onColumnOrderChange` with the
392
+ * new order. Defaults to `false`.
393
+ */
394
+ enableColumnReorder?: boolean;
395
+ /**
396
+ * Initial column order, by `id` (falls back to `field`). When the
397
+ * user reorders columns, this is the starting state. After mount,
398
+ * the grid owns the order internally and emits `onColumnOrderChange`
399
+ * on every change - persist that to `localStorage` to restore.
400
+ */
401
+ columnOrder?: ReadonlyArray<string>;
402
+ /** Fires every time the column order changes (drag or `api.setColumnOrder`). */
403
+ onColumnOrderChange?: (order: ReadonlyArray<string>) => void;
404
+ /**
405
+ * BCP-47 locale tag (or array of fallbacks) used for accent- and
406
+ * case-insensitive text filtering / sorting / search. Powered by
407
+ * `Intl.Collator` with `sensitivity: 'base'`, so "cafe", "Café"
408
+ * and "CAFÉ" all match "cafe" without strain. Defaults to the
409
+ * browser's locale.
410
+ */
411
+ filterLocale?: string | ReadonlyArray<string>;
412
+ };
413
+ export type SelectionPoint = {
414
+ rowIndex: number;
415
+ colIndex: number;
416
+ };
417
+ export type SelectionRange = {
418
+ anchor: SelectionPoint | null;
419
+ focus: SelectionPoint | null;
420
+ };
421
+ export type CellEditState = {
422
+ rowId: string;
423
+ columnId: string;
424
+ editorType: CellEditorType;
425
+ value: unknown;
426
+ } | null;
427
+ export type FilterOperator = "contains" | "equals" | "startsWith" | "greaterThan" | "lessThan" | "between" | "isBlank";
428
+ export type FilterOption = {
429
+ value: FilterOperator;
430
+ label: string;
431
+ iconName: string;
432
+ };
433
+ export type MenuPosition = {
434
+ x: number;
435
+ y: number;
436
+ };
@@ -0,0 +1 @@
1
+ export {};