@jielga/tmdatagrid 0.2.0 → 0.5.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 (50) hide show
  1. package/dist/index.d.ts +1337 -94
  2. package/dist/index.js +2812 -1189
  3. package/dist/index.js.map +1 -1
  4. package/dist/styles.css +1 -1
  5. package/package.json +2 -2
  6. package/skills/columns/SKILL.md +1 -1
  7. package/skills/features/SKILL.md +61 -11
  8. package/skills/getting-started/SKILL.md +41 -6
  9. package/skills/options/SKILL.md +12 -2
  10. package/skills/server-side/SKILL.md +1 -1
  11. package/src/tmdatagrid/TMDataGridContext.ts +26 -0
  12. package/src/tmdatagrid/components/TMDataGrid.module.css +21 -1
  13. package/src/tmdatagrid/components/TMDataGrid.tsx +29 -1
  14. package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +12 -6
  15. package/src/tmdatagrid/components/TMDataGridDetailsColumn.module.css +33 -0
  16. package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +160 -0
  17. package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +15 -0
  18. package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +192 -37
  19. package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +35 -0
  20. package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +136 -0
  21. package/src/tmdatagrid/components/TMDataGridFooter.module.css +8 -0
  22. package/src/tmdatagrid/components/TMDataGridFooter.tsx +63 -43
  23. package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +48 -0
  24. package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +159 -0
  25. package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +18 -0
  26. package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +249 -44
  27. package/src/tmdatagrid/components/TMDataGridSearch.tsx +122 -0
  28. package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +103 -16
  29. package/src/tmdatagrid/components/TMDataGridTable.module.css +160 -5
  30. package/src/tmdatagrid/components/TMDataGridTable.tsx +1380 -43
  31. package/src/tmdatagrid/components/TMDataGridToolbar.tsx +33 -7
  32. package/src/tmdatagrid/components/icons.ts +6 -0
  33. package/src/tmdatagrid/components/sticky.module.css +77 -16
  34. package/src/tmdatagrid/core/autosize.ts +125 -0
  35. package/src/tmdatagrid/core/capabilities.ts +122 -11
  36. package/src/tmdatagrid/core/cellExport.ts +321 -0
  37. package/src/tmdatagrid/core/cellNavigation.ts +103 -0
  38. package/src/tmdatagrid/core/cellRange.ts +118 -0
  39. package/src/tmdatagrid/core/columnOptions.ts +123 -0
  40. package/src/tmdatagrid/core/columnUtils.ts +18 -0
  41. package/src/tmdatagrid/core/expanding.ts +93 -0
  42. package/src/tmdatagrid/core/filterOperators.ts +198 -12
  43. package/src/tmdatagrid/core/grouping.ts +21 -0
  44. package/src/tmdatagrid/core/labels.ts +211 -0
  45. package/src/tmdatagrid/core/labelsSv.ts +108 -0
  46. package/src/tmdatagrid/core/persistence.ts +12 -0
  47. package/src/tmdatagrid/core/rowSelection.ts +202 -0
  48. package/src/tmdatagrid/core/summary.ts +35 -0
  49. package/src/tmdatagrid/index.ts +96 -2
  50. package/src/tmdatagrid/useTMDataGrid.tsx +558 -37
@@ -0,0 +1,108 @@
1
+ import type { TMDataGridLabels } from "./labels";
2
+
3
+ /**
4
+ * The complete Swedish dictionary. Typed as {@link TMDataGridLabels} rather
5
+ * than as an override, so a label added to the grid without a Swedish
6
+ * translation is a compile error here instead of English quietly leaking
7
+ * through.
8
+ *
9
+ * ```tsx
10
+ * useTMDataGrid({ data, columns, labels: TMDATAGRID_LABELS_SV });
11
+ * ```
12
+ */
13
+ export const TMDATAGRID_LABELS_SV: TMDataGridLabels = {
14
+ operators: {
15
+ contains: "innehåller",
16
+ equals: "är lika med",
17
+ notEquals: "är inte lika med",
18
+ startsWith: "börjar med",
19
+ endsWith: "slutar med",
20
+ greaterThan: "är större än",
21
+ greaterThanOrEqual: "är större än eller lika med",
22
+ lessThan: "är mindre än",
23
+ lessThanOrEqual: "är mindre än eller lika med",
24
+ before: "är före",
25
+ after: "är efter",
26
+ onOrBefore: "är på eller före",
27
+ onOrAfter: "är på eller efter",
28
+ isAnyOf: "är någon av",
29
+ isNoneOf: "är ingen av",
30
+ isEmpty: "är tom",
31
+ isNotEmpty: "är inte tom",
32
+ },
33
+
34
+ manageColumns: "Hantera kolumner",
35
+ filters: "Filter",
36
+ searchPlaceholder: "Sök",
37
+ searchLabel: "Sök rader",
38
+ clearSearch: "Rensa sökningen",
39
+
40
+ columnsSearchPlaceholder: "Sök",
41
+ columnsNoMatch: (search) => `Inga kolumner matchar ”${search}”`,
42
+ columnsShowHideAll: "Visa/dölj alla",
43
+ columnsReset: "ÅTERSTÄLL",
44
+
45
+ filterColumn: "Kolumn",
46
+ filterOperator: "Operator",
47
+ filterValue: "Värde",
48
+ filterValuePlaceholder: "Filtervärde",
49
+ booleanTrue: "Ja",
50
+ booleanFalse: "Nej",
51
+ addFilter: "Lägg till filter",
52
+ clearAllFilters: "Rensa alla",
53
+ closeFilters: "Stäng filter",
54
+ removeFilter: "Ta bort filter",
55
+
56
+ activeFilters: "Aktiva filter",
57
+ clearFilter: (column) => `Rensa filtret för ${column}`,
58
+
59
+ sortAsc: "Sortera stigande",
60
+ sortDesc: "Sortera fallande",
61
+ filterMenuItem: "Filtrera",
62
+ groupBy: (column) => `Gruppera på ${column}`,
63
+ ungroup: (column) => `Avgruppera ${column}`,
64
+ expandAllGroups: "Expandera alla grupper",
65
+ collapseAllGroups: "Fäll ihop alla grupper",
66
+ pinLeft: "Fäst till vänster",
67
+ pinRight: "Fäst till höger",
68
+ unpin: "Lossa",
69
+ moveLeft: "Flytta åt vänster",
70
+ moveRight: "Flytta åt höger",
71
+ autosizeColumn: "Anpassa kolumnbredd",
72
+ hideColumn: "Dölj kolumn",
73
+ filterOn: (column) => `Filtrera på ${column}`,
74
+ sortColumn: (column) => `Sortera ${column}`,
75
+ columnMenu: (column) => `Kolumnmeny för ${column}`,
76
+
77
+ rowsPerPage: "Rader per sida:",
78
+ pageRange: ({ from, to, total }) => `${from}–${to} av ${total}`,
79
+ groupedAllRows: (total) => `Grupperad · alla ${total} rader`,
80
+ pagingSuspendedHint:
81
+ "Sidindelningen är avstängd medan raderna är grupperade: hela trädet renderas och virtualiseras. Avgruppera för att bläddra igen.",
82
+ previousPage: "Föregående sida",
83
+ nextPage: "Nästa sida",
84
+
85
+ noResults: "Inga rader matchar dina filter",
86
+ loading: "Laddar",
87
+
88
+ cellCount: (count) => (count === 1 ? "1 cell" : `${count} celler`),
89
+ copy: "Kopiera",
90
+ exportCsv: "Exportera som CSV för Excel",
91
+ includeHeaders: "Inkludera rubriker",
92
+
93
+ selectColumnLabel: "Kryssrutemarkering",
94
+ selectAllRows: "Markera alla rader",
95
+ selectRow: "Markera rad",
96
+ selectGroup: "Markera grupp",
97
+
98
+ detailsColumnLabel: "Detaljer",
99
+ showDetails: "Visa detaljer",
100
+ hideDetails: "Dölj detaljer",
101
+ expandAllDetails: "Expandera alla detaljer",
102
+ collapseAllDetails: "Fäll ihop alla detaljer",
103
+
104
+ groupColumnLabel: "Grupp",
105
+ blankGroupValue: "(Tom)",
106
+ expandGroup: (label) => `Expandera ${label}`,
107
+ collapseGroup: (label) => `Fäll ihop ${label}`,
108
+ };
@@ -28,6 +28,10 @@ export const DATA_STATE_SLICES = [
28
28
  "globalFilter",
29
29
  "sorting",
30
30
  "pagination",
31
+ // Which groups are open. Keyed by group ids built from the values themselves
32
+ // (`department:Design`), so a restored entry for a group the data no longer
33
+ // produces is simply never looked up.
34
+ "expanded",
31
35
  ] as const satisfies ReadonlyArray<keyof GridState>;
32
36
 
33
37
  /**
@@ -39,6 +43,10 @@ export const SETTINGS_STATE_SLICES = [
39
43
  "columnSizing",
40
44
  "columnOrder",
41
45
  "columnPinning",
46
+ // Which columns the rows are grouped by. A settings slice rather than a data
47
+ // one: it names columns, not values, so it survives the data changing under
48
+ // it the way the column layout does.
49
+ "grouping",
42
50
  ] as const satisfies ReadonlyArray<keyof GridState>;
43
51
 
44
52
  export type TMDataGridDataSlice = (typeof DATA_STATE_SLICES)[number];
@@ -162,6 +170,9 @@ const SLICE_GUARDS: Record<
162
170
  pageSize > 0
163
171
  );
164
172
  },
173
+ // `true` is a legal ExpandedState of its own, meaning every row is open.
174
+ expanded: (value) =>
175
+ value === true || isRecordOf(value, (entry) => typeof entry === "boolean"),
165
176
  columnVisibility: (value) =>
166
177
  isRecordOf(value, (entry) => typeof entry === "boolean"),
167
178
  columnSizing: (value) => isRecordOf(value, isFiniteNumber),
@@ -169,6 +180,7 @@ const SLICE_GUARDS: Record<
169
180
  columnPinning: (value) =>
170
181
  isArrayOf(prop(value, "left"), isString) &&
171
182
  isArrayOf(prop(value, "right"), isString),
183
+ grouping: (value) => isArrayOf(value, isString),
172
184
  };
173
185
 
174
186
  function isValidSlice(slice: keyof GridState, value: unknown): boolean {
@@ -0,0 +1,202 @@
1
+ import type { Row, RowData, RowSelectionState } from "@tanstack/react-table";
2
+ import type { TMDataGridFeatureFlags } from "./capabilities";
3
+ import { getGroupDataRows } from "./grouping";
4
+ import type { TMDataGridFeatures, TMDataGridTable } from "../useTMDataGrid";
5
+
6
+ /**
7
+ * Rows in the order they are displayed, which is the order a shift-click range
8
+ * is measured over — so a range follows the active sort and skips filtered-out
9
+ * rows. Under pagination it is the current page, so a range cannot cross a page
10
+ * boundary.
11
+ *
12
+ * Once a column is grouped this includes the group rows, and only the leaves of
13
+ * groups that are open — and paging is suspended, so it is the whole tree. That
14
+ * is the right list for a range: it is what the user can see, and a range that
15
+ * swept collapsed rows would select things off screen. What a group row in the
16
+ * range contributes is decided by {@link getSelectableRowIds}.
17
+ */
18
+ export function getDisplayedRows<TData extends RowData>(
19
+ table: TMDataGridTable<TData>,
20
+ features: TMDataGridFeatureFlags,
21
+ ): Array<Row<TMDataGridFeatures, TData>> {
22
+ return isPagingActive(table, features)
23
+ ? table.getPaginatedRowModel().rows
24
+ : table.getPrePaginatedRowModel().rows;
25
+ }
26
+
27
+ /**
28
+ * Whether the built-in pager is actually slicing anything.
29
+ *
30
+ * Grouping suspends it. A page can only count one kind of thing, and once the
31
+ * rows are a tree neither answer works: counting every row splits a group
32
+ * across a page boundary and strands the rest of the tree on pages the user has
33
+ * to go looking for, and counting only the top-level rows quietly redefines
34
+ * "rows per page" as groups per page, so a page of 25 can hold thousands of
35
+ * rows. Rather than pick, the grid renders the whole tree and leans on the
36
+ * virtualizer — which is its default mode anyway, pagination being opt-in.
37
+ *
38
+ * `TMDataGrid.Footer` reads this too, and greys the pager out rather than
39
+ * hiding it, so the pager going quiet is visible instead of mysterious.
40
+ */
41
+ export function isPagingActive<TData extends RowData>(
42
+ table: TMDataGridTable<TData>,
43
+ features: TMDataGridFeatureFlags,
44
+ ): boolean {
45
+ return features.pagination && table.store.state.grouping.length === 0;
46
+ }
47
+
48
+ /**
49
+ * Which modifiers were held. Named for what they mean rather than for the keys,
50
+ * because the keys differ per platform — `toggle` is Ctrl on Windows/Linux and
51
+ * Cmd on macOS.
52
+ */
53
+ export type TMDataGridRowClickModifiers = {
54
+ toggle: boolean;
55
+ extend: boolean;
56
+ };
57
+
58
+ export type ResolveRowSelectionClickArgs<TData extends RowData> = {
59
+ /** Displayed order — see {@link getDisplayedRows}. */
60
+ rows: ReadonlyArray<Row<TMDataGridFeatures, TData>>;
61
+ rowId: string;
62
+ /** The pivot a shift-click extends from. */
63
+ anchorRowId: string | null;
64
+ modifiers: TMDataGridRowClickModifiers;
65
+ selection: RowSelectionState;
66
+ /**
67
+ * Whether this gesture is allowed to clear rows it did not touch.
68
+ *
69
+ * `true` for a bare row click, where replacing is the whole point. `false` for
70
+ * a checkbox, which is only ever additive — ticking one box has never cleared
71
+ * the others, and shift-clicking one adds the range rather than becoming it.
72
+ */
73
+ canReplaceSelection: boolean;
74
+ };
75
+
76
+ export type ResolvedRowSelection = {
77
+ selection: RowSelectionState;
78
+ anchorRowId: string | null;
79
+ };
80
+
81
+ /**
82
+ * The row ids one gesture on this row selects.
83
+ *
84
+ * A group row is never selected itself: it holds no record, and TanStack
85
+ * derives its checked state from its descendants. So ticking a group means
86
+ * ticking every selectable leaf under it, which is also what makes the group's
87
+ * own box light up.
88
+ *
89
+ * Leaves rather than direct children, so one click on a top-level group takes
90
+ * the whole subtree however deeply it nests.
91
+ */
92
+ export function getSelectableRowIds<TData extends RowData>(
93
+ row: Row<TMDataGridFeatures, TData>,
94
+ ): Array<string> {
95
+ return getGroupDataRows(row)
96
+ .filter((dataRow) => dataRow.getCanSelect())
97
+ .map((dataRow) => dataRow.id);
98
+ }
99
+
100
+ /**
101
+ * Turns one click into the next selection, following the convention every
102
+ * desktop list uses:
103
+ *
104
+ * | Gesture | Effect |
105
+ * | ------- | ------ |
106
+ * | Click | selection becomes only this row |
107
+ * | Ctrl/Cmd + click | toggle this row, leave the rest |
108
+ * | Shift + click | selection becomes the range anchor → this row |
109
+ * | Ctrl/Cmd + Shift + click | add that range to the selection |
110
+ *
111
+ * The anchor is a *pivot*, not "the last row touched": only a plain or
112
+ * Ctrl-click moves it, which is what lets a run of shift-clicks grow and shrink
113
+ * the same range from a fixed point.
114
+ *
115
+ * Selection state is rebuilt here and handed to `setRowSelection` wholesale
116
+ * rather than going through `row.toggleSelected()` per row, which would publish
117
+ * one state update each. That skips TanStack's sub-row cascade, so the cascade
118
+ * is done here instead: every row in the gesture is expanded through
119
+ * {@link getSelectableRowIds} before it reaches the map. Under grouping that is
120
+ * what makes one tick on a group select all of it.
121
+ */
122
+ export function resolveRowSelectionClick<TData extends RowData>({
123
+ rows,
124
+ rowId,
125
+ anchorRowId,
126
+ modifiers,
127
+ selection,
128
+ canReplaceSelection,
129
+ }: ResolveRowSelectionClickArgs<TData>): ResolvedRowSelection {
130
+ const index = rows.findIndex((row) => row.id === rowId);
131
+ const clickedRow = rows[index];
132
+ // Clicked row is not in the displayed set — nothing sensible to resolve.
133
+ if (index === -1 || clickedRow === undefined) return { selection, anchorRowId };
134
+
135
+ const targets = getSelectableRowIds(clickedRow);
136
+ // Nothing selectable under this gesture: a row the predicate refuses, or a
137
+ // group whose every leaf refuses.
138
+ if (targets.length === 0) return { selection, anchorRowId };
139
+
140
+ // `enableMultiRowSelection: false`, or the per-row predicate saying no: one
141
+ // row at a time, so the modifiers have nothing to build on and every gesture
142
+ // collapses to a single id.
143
+ //
144
+ // This has to be enforced here. Rebuilding the map and handing it to
145
+ // `setRowSelection` skips `mutateRowIsSelected`, which is where TanStack
146
+ // clears the other rows — so without this, Ctrl and Shift would quietly
147
+ // produce the multi-selection the option ruled out.
148
+ if (!clickedRow.getCanMultiSelect()) {
149
+ // A group stands for several rows, which single-select cannot express. The
150
+ // checkbox column drops the box on those rows for the same reason.
151
+ const only = targets.length === 1 ? targets[0] : undefined;
152
+ if (only === undefined) return { selection, anchorRowId };
153
+ // A checkbox must still be able to untick the one selected row; a row click
154
+ // only ever sets, so re-clicking it cannot empty the selection.
155
+ const untick = !canReplaceSelection && selection[only] === true;
156
+ return {
157
+ selection: untick ? {} : { [only]: true },
158
+ anchorRowId: rowId,
159
+ };
160
+ }
161
+
162
+ const anchorIndex =
163
+ anchorRowId === null
164
+ ? -1
165
+ : rows.findIndex((row) => row.id === anchorRowId);
166
+
167
+ // A range needs a pivot that is still on screen. When the anchor has been
168
+ // filtered or paged away, fall through and treat this as a fresh click.
169
+ if (modifiers.extend && anchorIndex !== -1) {
170
+ const from = Math.min(anchorIndex, index);
171
+ const to = Math.max(anchorIndex, index);
172
+ // Ctrl+Shift adds to what is already selected; Shift alone becomes the
173
+ // range — unless the gesture may not replace, in which case it also adds.
174
+ const next: RowSelectionState =
175
+ modifiers.toggle || !canReplaceSelection ? { ...selection } : {};
176
+ for (const row of rows.slice(from, to + 1)) {
177
+ // A group row inside the range brings its whole subtree, including leaves
178
+ // that are collapsed out of `rows` — sweeping past a closed group selects
179
+ // it entire, which is the only reading that matches what it displays.
180
+ for (const id of getSelectableRowIds(row)) next[id] = true;
181
+ }
182
+ // The pivot deliberately stays put.
183
+ return { selection: next, anchorRowId };
184
+ }
185
+
186
+ if (modifiers.toggle || !canReplaceSelection) {
187
+ const next: RowSelectionState = { ...selection };
188
+ // Asked of the targets rather than of `rowId`: a group row carries no id in
189
+ // the map, so it counts as selected exactly when all of its leaves do —
190
+ // which is also when its checkbox shows a tick rather than a dash.
191
+ const allSelected = targets.every((id) => selection[id] === true);
192
+ for (const id of targets) {
193
+ if (allSelected) delete next[id];
194
+ else next[id] = true;
195
+ }
196
+ return { selection: next, anchorRowId: rowId };
197
+ }
198
+
199
+ const next: RowSelectionState = {};
200
+ for (const id of targets) next[id] = true;
201
+ return { selection: next, anchorRowId: rowId };
202
+ }
@@ -0,0 +1,35 @@
1
+ import { aggregationFns, type RowData } from "@tanstack/react-table";
2
+ import type { TMDataGridRowData } from "../TMDataGridContext";
3
+ import type { TMDataGridTable } from "../useTMDataGrid";
4
+
5
+ /** The registered aggregation names — the same set `aggregationFn` accepts. */
6
+ export type TMDataGridAggregationName = keyof typeof aggregationFns;
7
+
8
+ /**
9
+ * One column aggregated over every filtered row — the number a summary-row
10
+ * `footer` wants:
11
+ *
12
+ * ```tsx
13
+ * columnHelper.accessor("salary", {
14
+ * footer: ({ table }) => sek(Number(aggregateColumn({ table, columnId: "salary" }))),
15
+ * });
16
+ * ```
17
+ *
18
+ * Filtered rather than paginated rows, so the total covers everything the
19
+ * filters left — all pages — and follows the filters as they change. Reuses
20
+ * TanStack's registered aggregation functions; `fn` defaults to `"sum"`.
21
+ */
22
+ export function aggregateColumn<TData extends RowData>({
23
+ table,
24
+ columnId,
25
+ fn = "sum",
26
+ }: {
27
+ table: TMDataGridTable<TData>;
28
+ columnId: string;
29
+ fn?: TMDataGridAggregationName;
30
+ }): unknown {
31
+ const erased = table as unknown as TMDataGridTable<TMDataGridRowData>;
32
+ const rows = erased.getFilteredRowModel().rows;
33
+ // Leaf and child rows are the same set here: the filtered model is flat.
34
+ return aggregationFns[fn](columnId, rows, rows);
35
+ }
@@ -1,16 +1,24 @@
1
1
  export { TMDataGrid, type TMDataGridProps } from "./components/TMDataGrid";
2
2
  export {
3
+ useCellControlTabIndex,
3
4
  useTMDataGridContext,
4
5
  type TMDataGridContextValue,
5
6
  type TMDataGridRowData,
6
7
  } from "./TMDataGridContext";
7
8
  export { SELECT_COLUMN_ID } from "./components/TMDataGridSelectColumn";
9
+ export { DETAILS_COLUMN_ID } from "./components/TMDataGridDetailsColumn";
10
+ export {
11
+ formatGroupValue,
12
+ GROUP_COLUMN_ID,
13
+ } from "./components/TMDataGridGroupColumn";
8
14
  export {
9
15
  createTMDataGridColumnHelper,
10
16
  openColumnFilter,
11
17
  tmDataGridFeatures,
12
18
  type TMDataGridApi,
13
19
  type TMDataGridColumnMeta,
20
+ type TMDataGridDetailsArgs,
21
+ type TMDataGridDetailsRenderer,
14
22
  type TMDataGridFeatures,
15
23
  type TMDataGridTable,
16
24
  type TMDataGridTableMeta,
@@ -20,18 +28,88 @@ export {
20
28
  useTMDataGrid,
21
29
  type UseTMDataGridOptions,
22
30
  } from "./useTMDataGrid";
31
+ export {
32
+ TMDataGridFilterPills,
33
+ type TMDataGridFilterPillsProps,
34
+ } from "./components/TMDataGridFilterPills";
35
+ export {
36
+ TMDataGridSearch,
37
+ type TMDataGridSearchProps,
38
+ } from "./components/TMDataGridSearch";
23
39
  export {
24
40
  type TMDataGridColumnType,
25
41
  type TMDataGridFilterOperator,
26
42
  type TMDataGridFilterValue,
27
43
  FILTER_OPERATOR_LABELS,
44
+ formatFilterLabel,
45
+ getDefaultOperator,
46
+ getOperatorsForType,
28
47
  isFilterActive,
48
+ operatorNeedsValue,
49
+ operatorTakesArrayValue,
29
50
  } from "./core/filterOperators";
51
+ export {
52
+ optionsToComboboxData,
53
+ resolveColumnOptions,
54
+ type TMDataGridOption,
55
+ type TMDataGridOptionsArgs,
56
+ type TMDataGridOptionsSource,
57
+ } from "./core/columnOptions";
58
+ export {
59
+ mergeLabels,
60
+ TMDATAGRID_LABELS_EN,
61
+ type TMDataGridLabels,
62
+ type TMDataGridLabelsOverride,
63
+ } from "./core/labels";
64
+ export { TMDATAGRID_LABELS_SV } from "./core/labelsSv";
30
65
  export {
31
66
  getColumnLabel,
32
67
  getColumnType,
33
68
  isColumnReorderable,
69
+ isControlColumn,
34
70
  } from "./core/columnUtils";
71
+ export { getGroupDataRows } from "./core/grouping";
72
+ export {
73
+ aggregateColumn,
74
+ type TMDataGridAggregationName,
75
+ } from "./core/summary";
76
+ export { autosizeColumn, measureColumnContentWidth } from "./core/autosize";
77
+ export {
78
+ isSameCell,
79
+ resolveCellMove,
80
+ type ResolveCellMoveArgs,
81
+ type TMDataGridCellCoords,
82
+ type TMDataGridCellPosition,
83
+ } from "./core/cellNavigation";
84
+ export {
85
+ boundsCellCount,
86
+ boundsEdges,
87
+ isWithinBounds,
88
+ resolveRangeBounds,
89
+ type ResolveRangeBoundsArgs,
90
+ type TMDataGridCellRange,
91
+ type TMDataGridRangeBounds,
92
+ } from "./core/cellRange";
93
+ export {
94
+ buildCellMatrix,
95
+ buildGridCellMatrix,
96
+ DEFAULT_CELL_EXPORT_OPTIONS,
97
+ downloadTextFile,
98
+ exportGridToCsv,
99
+ formatExportValue,
100
+ toClipboardText,
101
+ toExcelCsv,
102
+ writeClipboardText,
103
+ type BuildCellMatrixArgs,
104
+ type TMDataGridCellExportOptions,
105
+ type TMDataGridCellMatrix,
106
+ } from "./core/cellExport";
107
+ export {
108
+ areAllRowsExpanded,
109
+ resolveExpandAll,
110
+ type TMDataGridExpandAllArgs,
111
+ type TMDataGridExpandTarget,
112
+ } from "./core/expanding";
35
113
  export {
36
114
  getColumnRegion,
37
115
  getStepTargetColumn,
@@ -46,11 +124,21 @@ export {
46
124
  getColumnCapabilities,
47
125
  getGridCapabilities,
48
126
  readFeatureFlags,
127
+ type TMDataGridCellSelectionMode,
49
128
  type TMDataGridCapabilities,
50
129
  type TMDataGridColumnCapabilities,
51
130
  type TMDataGridFeatureFlags,
52
- type TMDataGridRowSelectionMode,
131
+ type TMDataGridSelectionMode,
53
132
  } from "./core/capabilities";
133
+ export {
134
+ getDisplayedRows,
135
+ getSelectableRowIds,
136
+ isPagingActive,
137
+ resolveRowSelectionClick,
138
+ type ResolvedRowSelection,
139
+ type ResolveRowSelectionClickArgs,
140
+ type TMDataGridRowClickModifiers,
141
+ } from "./core/rowSelection";
54
142
  export {
55
143
  DEFAULT_TMDATAGRID_SIZE,
56
144
  SIZE_CONTROL_SIZE,
@@ -66,7 +154,13 @@ export {
66
154
  type TMDataGridSettingsSlice,
67
155
  type TMDataGridStorageMode,
68
156
  } from "./core/persistence";
69
- export type { TMDataGridColumnLayout } from "./components/TMDataGridTable";
157
+ export type {
158
+ TMDataGridCellNav,
159
+ TMDataGridColumnLayout,
160
+ TMDataGridRowContextMenu,
161
+ TMDataGridRowContextMenuArgs,
162
+ TMDataGridTableProps,
163
+ } from "./components/TMDataGridTable";
70
164
  export {
71
165
  getTMDataGridPaginationApi,
72
166
  type TMDataGridFooterProps,