@jielga/tmdatagrid 0.3.0 → 1.0.0-beta.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 +25 -2
- package/dist/index.d.ts +1789 -64
- package/dist/index.js +4432 -1561
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/styles.layer.css +1 -0
- package/package.json +13 -3
- package/skills/columns/SKILL.md +1 -1
- package/skills/features/SKILL.md +61 -11
- package/skills/getting-started/SKILL.md +1 -1
- package/skills/options/SKILL.md +12 -2
- package/skills/server-side/SKILL.md +1 -1
- package/skills/testing/SKILL.md +198 -0
- package/src/tmdatagrid/TMDataGridContext.ts +26 -0
- package/src/tmdatagrid/components/TMDataGrid.module.css +21 -0
- package/src/tmdatagrid/components/TMDataGrid.tsx +57 -1
- package/src/tmdatagrid/components/TMDataGridCellEditor.tsx +256 -0
- package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +38 -15
- package/src/tmdatagrid/components/TMDataGridDetailsColumn.module.css +33 -0
- package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +163 -0
- package/src/tmdatagrid/components/TMDataGridEditActions.tsx +62 -0
- package/src/tmdatagrid/components/TMDataGridEditColumn.tsx +237 -0
- package/src/tmdatagrid/components/TMDataGridEntryRows.tsx +164 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +131 -38
- package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +11 -4
- package/src/tmdatagrid/components/TMDataGridFooter.tsx +21 -22
- package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +25 -11
- package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +15 -3
- package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +191 -53
- package/src/tmdatagrid/components/TMDataGridRowNumberColumn.tsx +44 -0
- package/src/tmdatagrid/components/TMDataGridSearch.tsx +124 -0
- package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +26 -13
- package/src/tmdatagrid/components/TMDataGridTable.module.css +333 -6
- package/src/tmdatagrid/components/TMDataGridTable.tsx +1819 -62
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +41 -13
- package/src/tmdatagrid/components/editors/TMDataGridBooleanEditor.tsx +29 -0
- package/src/tmdatagrid/components/editors/TMDataGridDateEditor.tsx +57 -0
- package/src/tmdatagrid/components/editors/TMDataGridMultiSelectEditor.tsx +45 -0
- package/src/tmdatagrid/components/editors/TMDataGridNumberEditor.tsx +38 -0
- package/src/tmdatagrid/components/editors/TMDataGridSelectEditor.tsx +53 -0
- package/src/tmdatagrid/components/editors/TMDataGridStringEditor.tsx +31 -0
- package/src/tmdatagrid/components/editors/editorShared.ts +48 -0
- package/src/tmdatagrid/components/filters/DgAutocompleteFilter.tsx +46 -0
- package/src/tmdatagrid/components/filters/DgDateRangeFilter.tsx +43 -0
- package/src/tmdatagrid/components/filters/DgRangeSliderFilter.tsx +52 -0
- package/src/tmdatagrid/components/filters/DgTriStateFilter.tsx +38 -0
- package/src/tmdatagrid/components/filters/TMDataGridFilterValueInput.tsx +122 -0
- package/src/tmdatagrid/components/icons.ts +5 -0
- package/src/tmdatagrid/components/sticky.module.css +77 -16
- package/src/tmdatagrid/core/autosize.ts +125 -0
- package/src/tmdatagrid/core/capabilities.ts +77 -0
- package/src/tmdatagrid/core/cellExport.ts +321 -0
- package/src/tmdatagrid/core/cellNavigation.ts +144 -0
- package/src/tmdatagrid/core/cellRange.ts +118 -0
- package/src/tmdatagrid/core/columnOptions.ts +123 -0
- package/src/tmdatagrid/core/columnUtils.ts +44 -1
- package/src/tmdatagrid/core/editEngine.ts +857 -0
- package/src/tmdatagrid/core/expanding.ts +93 -0
- package/src/tmdatagrid/core/filterControls.ts +45 -0
- package/src/tmdatagrid/core/filterOperators.ts +243 -14
- package/src/tmdatagrid/core/labels.ts +278 -0
- package/src/tmdatagrid/core/labelsSv.ts +131 -0
- package/src/tmdatagrid/core/matchHighlight.ts +96 -0
- package/src/tmdatagrid/core/persistence.ts +97 -3
- package/src/tmdatagrid/core/quickSearch.ts +144 -0
- package/src/tmdatagrid/core/rowPinning.ts +37 -0
- package/src/tmdatagrid/core/rowSelection.ts +10 -1
- package/src/tmdatagrid/core/summary.ts +35 -0
- package/src/tmdatagrid/index.ts +121 -0
- package/src/tmdatagrid/useTMDataGrid.tsx +782 -25
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
import { ActionIcon, Group, Loader, Tooltip } from "@mantine/core";
|
|
2
|
+
import { useSelector } from "@tanstack/react-store";
|
|
3
|
+
import type { ColumnDef, Row, RowData } from "@tanstack/react-table";
|
|
4
|
+
import {
|
|
5
|
+
useCellControlTabIndex,
|
|
6
|
+
useTMDataGridContext,
|
|
7
|
+
} from "../TMDataGridContext";
|
|
8
|
+
import type { TMDataGridFeatures } from "../useTMDataGrid";
|
|
9
|
+
import { firstErrorText } from "./editors/editorShared";
|
|
10
|
+
import {
|
|
11
|
+
CheckIcon,
|
|
12
|
+
CloseIcon,
|
|
13
|
+
PencilIcon,
|
|
14
|
+
RestoreIcon,
|
|
15
|
+
TrashIcon,
|
|
16
|
+
} from "./icons";
|
|
17
|
+
|
|
18
|
+
export const EDIT_COLUMN_ID = "__edit__";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* One row's slot in the edit lane. Three states, driven off the edit store:
|
|
22
|
+
* a pencil while idle, Save/Cancel while the row's form is open, a loader
|
|
23
|
+
* while its commit is in flight. A row error turns the Save red and puts the
|
|
24
|
+
* message in its tooltip — the pathless `.refine()` has nowhere else to land.
|
|
25
|
+
*/
|
|
26
|
+
function EditLaneCell<TData extends RowData>({
|
|
27
|
+
row,
|
|
28
|
+
}: {
|
|
29
|
+
row: Row<TMDataGridFeatures, TData>;
|
|
30
|
+
}) {
|
|
31
|
+
const { edit, features, labels } = useTMDataGridContext();
|
|
32
|
+
const tabIndex = useCellControlTabIndex();
|
|
33
|
+
const rowId = row.id;
|
|
34
|
+
const isOpen = useSelector(edit.store, (state) =>
|
|
35
|
+
state.openRowIds.includes(rowId),
|
|
36
|
+
);
|
|
37
|
+
const projection = useSelector(edit.store, (state) => state.rows[rowId]);
|
|
38
|
+
const isNew = useSelector(edit.store, (state) =>
|
|
39
|
+
state.newRows.some((newRow) => newRow.tempId === rowId),
|
|
40
|
+
);
|
|
41
|
+
const isMarkedDeleted = useSelector(edit.store, (state) =>
|
|
42
|
+
state.deletedRowIds.includes(rowId),
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
if (row.getIsGrouped()) return null;
|
|
46
|
+
|
|
47
|
+
// An entry row: ✓ adds it (not under batch, where submitAll does), ✕
|
|
48
|
+
// discards the entry.
|
|
49
|
+
if (isNew) {
|
|
50
|
+
return (
|
|
51
|
+
<Group gap={0} wrap="nowrap">
|
|
52
|
+
{features.editMode !== "batch" && (
|
|
53
|
+
<ActionIcon
|
|
54
|
+
variant="subtle"
|
|
55
|
+
color="green"
|
|
56
|
+
size="sm"
|
|
57
|
+
tabIndex={tabIndex}
|
|
58
|
+
aria-label={labels.confirmNewRow}
|
|
59
|
+
data-dg-part="confirm-new-row"
|
|
60
|
+
data-row-id={rowId}
|
|
61
|
+
onClick={() => void edit.commit(rowId)}
|
|
62
|
+
>
|
|
63
|
+
<CheckIcon size={16} stroke={2} />
|
|
64
|
+
</ActionIcon>
|
|
65
|
+
)}
|
|
66
|
+
<ActionIcon
|
|
67
|
+
variant="subtle"
|
|
68
|
+
color="gray"
|
|
69
|
+
size="sm"
|
|
70
|
+
tabIndex={tabIndex}
|
|
71
|
+
aria-label={labels.discardNewRow}
|
|
72
|
+
data-dg-part="discard-new-row"
|
|
73
|
+
data-row-id={rowId}
|
|
74
|
+
onClick={() => edit.cancel(rowId)}
|
|
75
|
+
>
|
|
76
|
+
<CloseIcon size={16} stroke={1.6} />
|
|
77
|
+
</ActionIcon>
|
|
78
|
+
</Group>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// A batch deletion mark is a draft like any other — restorable in place.
|
|
83
|
+
if (isMarkedDeleted) {
|
|
84
|
+
return (
|
|
85
|
+
<ActionIcon
|
|
86
|
+
variant="subtle"
|
|
87
|
+
color="gray"
|
|
88
|
+
size="sm"
|
|
89
|
+
tabIndex={tabIndex}
|
|
90
|
+
aria-label={labels.restoreRow}
|
|
91
|
+
data-dg-part="restore-row"
|
|
92
|
+
data-row-id={rowId}
|
|
93
|
+
onClick={(event) => {
|
|
94
|
+
event.stopPropagation();
|
|
95
|
+
edit.deleteRow(rowId);
|
|
96
|
+
}}
|
|
97
|
+
>
|
|
98
|
+
<RestoreIcon size={16} stroke={1.6} />
|
|
99
|
+
</ActionIcon>
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// The pencil means "this row edits"; a row that does not gets nothing.
|
|
104
|
+
if (!edit.canEditRow(row as never)) return null;
|
|
105
|
+
|
|
106
|
+
if (!isOpen) {
|
|
107
|
+
return (
|
|
108
|
+
<Group gap={0} wrap="nowrap">
|
|
109
|
+
{features.editMode === "row" && (
|
|
110
|
+
<ActionIcon
|
|
111
|
+
variant="subtle"
|
|
112
|
+
color="gray"
|
|
113
|
+
size="sm"
|
|
114
|
+
tabIndex={tabIndex}
|
|
115
|
+
aria-label={labels.editRow}
|
|
116
|
+
data-dg-part="edit-row"
|
|
117
|
+
data-row-id={rowId}
|
|
118
|
+
onClick={(event) => {
|
|
119
|
+
event.stopPropagation();
|
|
120
|
+
edit.begin({ rowId, columnId: null });
|
|
121
|
+
}}
|
|
122
|
+
>
|
|
123
|
+
<PencilIcon size={16} stroke={1.6} />
|
|
124
|
+
</ActionIcon>
|
|
125
|
+
)}
|
|
126
|
+
{edit.canDeleteRows() && (
|
|
127
|
+
<ActionIcon
|
|
128
|
+
variant="subtle"
|
|
129
|
+
color="gray"
|
|
130
|
+
size="sm"
|
|
131
|
+
tabIndex={tabIndex}
|
|
132
|
+
aria-label={labels.deleteRow}
|
|
133
|
+
data-dg-part="delete-row"
|
|
134
|
+
data-row-id={rowId}
|
|
135
|
+
onClick={(event) => {
|
|
136
|
+
event.stopPropagation();
|
|
137
|
+
edit.deleteRow(rowId);
|
|
138
|
+
}}
|
|
139
|
+
>
|
|
140
|
+
<TrashIcon size={16} stroke={1.6} />
|
|
141
|
+
</ActionIcon>
|
|
142
|
+
)}
|
|
143
|
+
</Group>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
if (projection?.isSubmitting) {
|
|
148
|
+
return <Loader size="xs" aria-label={labels.loading} />;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const hasErrors =
|
|
152
|
+
projection !== undefined &&
|
|
153
|
+
(projection.hasRowError || projection.errorFields.length > 0);
|
|
154
|
+
const rowError = hasErrors
|
|
155
|
+
? (firstErrorText(edit.getForm(rowId)?.state.errors ?? []) ??
|
|
156
|
+
labels.editRowErrors)
|
|
157
|
+
: null;
|
|
158
|
+
|
|
159
|
+
const save = (
|
|
160
|
+
<ActionIcon
|
|
161
|
+
variant="subtle"
|
|
162
|
+
color={hasErrors ? "red" : "green"}
|
|
163
|
+
size="sm"
|
|
164
|
+
tabIndex={tabIndex}
|
|
165
|
+
aria-label={labels.saveRow}
|
|
166
|
+
data-dg-part="save-row"
|
|
167
|
+
data-row-id={rowId}
|
|
168
|
+
onClick={(event) => {
|
|
169
|
+
event.stopPropagation();
|
|
170
|
+
void edit.commit(rowId);
|
|
171
|
+
}}
|
|
172
|
+
>
|
|
173
|
+
<CheckIcon size={16} stroke={2} />
|
|
174
|
+
</ActionIcon>
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
return (
|
|
178
|
+
<Group gap={0} wrap="nowrap">
|
|
179
|
+
{rowError === null ? (
|
|
180
|
+
save
|
|
181
|
+
) : (
|
|
182
|
+
<Tooltip label={rowError} withArrow>
|
|
183
|
+
{save}
|
|
184
|
+
</Tooltip>
|
|
185
|
+
)}
|
|
186
|
+
<ActionIcon
|
|
187
|
+
variant="subtle"
|
|
188
|
+
color="gray"
|
|
189
|
+
size="sm"
|
|
190
|
+
tabIndex={tabIndex}
|
|
191
|
+
aria-label={labels.cancelRowEdit}
|
|
192
|
+
data-dg-part="cancel-row"
|
|
193
|
+
data-row-id={rowId}
|
|
194
|
+
onClick={(event) => {
|
|
195
|
+
event.stopPropagation();
|
|
196
|
+
edit.cancel(rowId);
|
|
197
|
+
}}
|
|
198
|
+
>
|
|
199
|
+
<CloseIcon size={16} stroke={1.6} />
|
|
200
|
+
</ActionIcon>
|
|
201
|
+
</Group>
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* The generated edit lane, appended and pinned right under
|
|
207
|
+
* `editMode: "row"` — the row's Save at the end of the row, mirroring the
|
|
208
|
+
* checkbox lane's build on the left.
|
|
209
|
+
*/
|
|
210
|
+
export function createEditColumn<TData extends RowData>(
|
|
211
|
+
label = "Edit",
|
|
212
|
+
): ColumnDef<TMDataGridFeatures, TData, unknown> {
|
|
213
|
+
return {
|
|
214
|
+
id: EDIT_COLUMN_ID,
|
|
215
|
+
meta: {
|
|
216
|
+
label,
|
|
217
|
+
align: "center",
|
|
218
|
+
enableOrdering: false,
|
|
219
|
+
},
|
|
220
|
+
// Wide enough for the Save/Cancel pair it holds while editing.
|
|
221
|
+
size: 64,
|
|
222
|
+
minSize: 64,
|
|
223
|
+
maxSize: 64,
|
|
224
|
+
enableResizing: false,
|
|
225
|
+
enableSorting: false,
|
|
226
|
+
enableColumnFilter: false,
|
|
227
|
+
enableGlobalFilter: false,
|
|
228
|
+
// Structurally pinned to the right; not movable.
|
|
229
|
+
enablePinning: false,
|
|
230
|
+
header: () => null,
|
|
231
|
+
cell: ({ row }) => <EditLaneCell row={row} />,
|
|
232
|
+
// Group rows: same reasoning as the checkbox lane — without this the
|
|
233
|
+
// cell renders blank on aggregated rows, but here blank is also correct,
|
|
234
|
+
// so the aggregated cell renders the same (null for groups).
|
|
235
|
+
aggregatedCell: ({ row }) => <EditLaneCell row={row} />,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {
|
|
2
|
+
flexRender,
|
|
3
|
+
useTable,
|
|
4
|
+
type Column,
|
|
5
|
+
type Row,
|
|
6
|
+
} from "@tanstack/react-table";
|
|
7
|
+
import { useSelector } from "@tanstack/react-store";
|
|
8
|
+
import { useMemo } from "react";
|
|
9
|
+
import classes from "./TMDataGridTable.module.css";
|
|
10
|
+
import sticky from "./sticky.module.css";
|
|
11
|
+
import { type TMDataGridRowData, useTMDataGridContext } from "../TMDataGridContext";
|
|
12
|
+
import { getColumnAlign, isControlColumn } from "../core/columnUtils";
|
|
13
|
+
import { getEditFieldName } from "../core/editEngine";
|
|
14
|
+
import {
|
|
15
|
+
tmDataGridFeatures,
|
|
16
|
+
type TMDataGridFeatures,
|
|
17
|
+
} from "../useTMDataGrid";
|
|
18
|
+
import { TMDataGridCellEditor } from "./TMDataGridCellEditor";
|
|
19
|
+
import { EDIT_COLUMN_ID } from "./TMDataGridEditColumn";
|
|
20
|
+
import type { TMDataGridColumnLayout } from "./TMDataGridTable";
|
|
21
|
+
|
|
22
|
+
type ErasedColumn = Column<TMDataGridFeatures, TMDataGridRowData, unknown>;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Whether an entry cell edits. `edit.canEditCell` asks the main table for
|
|
26
|
+
* the row, and an entry row is precisely not there yet — so the structural
|
|
27
|
+
* half of the same rule is applied to the entry table's own row.
|
|
28
|
+
*/
|
|
29
|
+
function isEntryCellEditable(
|
|
30
|
+
row: Row<TMDataGridFeatures, TMDataGridRowData>,
|
|
31
|
+
column: ErasedColumn,
|
|
32
|
+
): boolean {
|
|
33
|
+
if (isControlColumn(column.id)) return false;
|
|
34
|
+
if (getEditFieldName(column) === null) return false;
|
|
35
|
+
const editable = column.columnDef.meta?.editable;
|
|
36
|
+
if (editable === false) return false;
|
|
37
|
+
if (typeof editable === "function" && !editable(row)) return false;
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* The sticky entry block — one row of open editors per `edit.addRow()`,
|
|
43
|
+
* pinned under the header. The one place stickiness is genuinely required:
|
|
44
|
+
* an existing row that scrolls away has a place to scroll back to, a row
|
|
45
|
+
* being typed into does not exist anywhere else.
|
|
46
|
+
*
|
|
47
|
+
* A second, tiny table instance over the new rows' seed values — same
|
|
48
|
+
* columns, its own `useTable`, no sorting or filtering ever exercised — so
|
|
49
|
+
* these are real `Cell`s and the editor host, the typed editors and the
|
|
50
|
+
* validators all apply unchanged. The forms live in the same engine map as
|
|
51
|
+
* every other draft, keyed by their temporary ids.
|
|
52
|
+
*
|
|
53
|
+
* Enter commits the entry (`onRowAdd`) under the immediate modes and parks
|
|
54
|
+
* it under batch, where `submitAll` reports it in `added`; Escape discards
|
|
55
|
+
* it. The edit lane, when present, offers the same pair as buttons.
|
|
56
|
+
*/
|
|
57
|
+
export function TMDataGridEntryRows({
|
|
58
|
+
orderedColumns,
|
|
59
|
+
layoutFor,
|
|
60
|
+
rowHeight,
|
|
61
|
+
}: {
|
|
62
|
+
orderedColumns: ReadonlyArray<ErasedColumn>;
|
|
63
|
+
layoutFor: (columnId: string) => TMDataGridColumnLayout;
|
|
64
|
+
rowHeight: number;
|
|
65
|
+
}) {
|
|
66
|
+
const { table, edit } = useTMDataGridContext();
|
|
67
|
+
const newRows = useSelector(edit.store, (state) => state.newRows);
|
|
68
|
+
|
|
69
|
+
// The seed values, frozen at addRow: the live values belong to the forms,
|
|
70
|
+
// which the editors read directly — this table only provides row and cell
|
|
71
|
+
// identity.
|
|
72
|
+
const data = useMemo(
|
|
73
|
+
() =>
|
|
74
|
+
newRows.map(
|
|
75
|
+
({ tempId }) =>
|
|
76
|
+
(edit.getForm(tempId)?.options.defaultValues ??
|
|
77
|
+
{}) as TMDataGridRowData,
|
|
78
|
+
),
|
|
79
|
+
[newRows, edit],
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
const entryTable = useTable({
|
|
83
|
+
features: tmDataGridFeatures,
|
|
84
|
+
columns: table.options.columns,
|
|
85
|
+
data,
|
|
86
|
+
getRowId: (_row, index) => newRows[index]?.tempId ?? String(index),
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
if (newRows.length === 0) return null;
|
|
90
|
+
|
|
91
|
+
const entryRows = entryTable.getCoreRowModel().rows;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<div role="rowgroup" data-dg-entry-block className={classes.entryBlock}>
|
|
95
|
+
{entryRows.map((entryRow) => {
|
|
96
|
+
const cellsById = new Map(
|
|
97
|
+
entryRow.getAllCells().map((cell) => [cell.column.id, cell]),
|
|
98
|
+
);
|
|
99
|
+
const firstEditableColumnId = orderedColumns.find((column) =>
|
|
100
|
+
isEntryCellEditable(entryRow, column),
|
|
101
|
+
)?.id;
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
key={entryRow.id}
|
|
105
|
+
role="row"
|
|
106
|
+
data-dg-part="entry-row"
|
|
107
|
+
data-row-id={entryRow.id}
|
|
108
|
+
className={classes.entryRow}
|
|
109
|
+
>
|
|
110
|
+
{orderedColumns.map((column) => {
|
|
111
|
+
const cell = cellsById.get(column.id);
|
|
112
|
+
const layout = layoutFor(column.id);
|
|
113
|
+
const editable =
|
|
114
|
+
cell !== undefined && isEntryCellEditable(entryRow, column);
|
|
115
|
+
return (
|
|
116
|
+
<div
|
|
117
|
+
key={column.id}
|
|
118
|
+
role="cell"
|
|
119
|
+
data-column-id={column.id}
|
|
120
|
+
data-align={getColumnAlign(column)}
|
|
121
|
+
data-control-column={isControlColumn(column.id)}
|
|
122
|
+
className={[
|
|
123
|
+
classes.entryCell,
|
|
124
|
+
layout.isBoundary && layout.pinnedAt === "left"
|
|
125
|
+
? sticky.stickyLeft
|
|
126
|
+
: "",
|
|
127
|
+
layout.isBoundary && layout.pinnedAt === "right"
|
|
128
|
+
? sticky.stickyRight
|
|
129
|
+
: "",
|
|
130
|
+
]
|
|
131
|
+
.filter(Boolean)
|
|
132
|
+
.join(" ")}
|
|
133
|
+
style={{
|
|
134
|
+
minHeight: rowHeight,
|
|
135
|
+
left: layout.pinnedAt === "left" ? layout.offset : undefined,
|
|
136
|
+
right:
|
|
137
|
+
layout.pinnedAt === "right" ? layout.offset : undefined,
|
|
138
|
+
position: layout.pinnedAt ? "sticky" : undefined,
|
|
139
|
+
zIndex: layout.pinnedAt
|
|
140
|
+
? "var(--dg-z-pinned-row-pinned-cell, 5)"
|
|
141
|
+
: undefined,
|
|
142
|
+
}}
|
|
143
|
+
>
|
|
144
|
+
{editable && cell !== undefined ? (
|
|
145
|
+
<TMDataGridCellEditor
|
|
146
|
+
cell={cell}
|
|
147
|
+
row={entryRow}
|
|
148
|
+
takeSeedText={() => undefined}
|
|
149
|
+
autoFocus={column.id === firstEditableColumnId}
|
|
150
|
+
onClose={() => {}}
|
|
151
|
+
/>
|
|
152
|
+
) : cell !== undefined && column.id === EDIT_COLUMN_ID ? (
|
|
153
|
+
// The lane's cell — the entry row's ✓/✕ pair.
|
|
154
|
+
flexRender(cell.column.columnDef.cell, cell.getContext())
|
|
155
|
+
) : null}
|
|
156
|
+
</div>
|
|
157
|
+
);
|
|
158
|
+
})}
|
|
159
|
+
</div>
|
|
160
|
+
);
|
|
161
|
+
})}
|
|
162
|
+
</div>
|
|
163
|
+
);
|
|
164
|
+
}
|