@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.
- package/dist/index.d.ts +1337 -94
- package/dist/index.js +2812 -1189
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
- package/skills/columns/SKILL.md +1 -1
- package/skills/features/SKILL.md +61 -11
- package/skills/getting-started/SKILL.md +41 -6
- package/skills/options/SKILL.md +12 -2
- package/skills/server-side/SKILL.md +1 -1
- package/src/tmdatagrid/TMDataGridContext.ts +26 -0
- package/src/tmdatagrid/components/TMDataGrid.module.css +21 -1
- package/src/tmdatagrid/components/TMDataGrid.tsx +29 -1
- package/src/tmdatagrid/components/TMDataGridColumnsPanel.tsx +12 -6
- package/src/tmdatagrid/components/TMDataGridDetailsColumn.module.css +33 -0
- package/src/tmdatagrid/components/TMDataGridDetailsColumn.tsx +160 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.module.css +15 -0
- package/src/tmdatagrid/components/TMDataGridFilterPanel.tsx +192 -37
- package/src/tmdatagrid/components/TMDataGridFilterPills.module.css +35 -0
- package/src/tmdatagrid/components/TMDataGridFilterPills.tsx +136 -0
- package/src/tmdatagrid/components/TMDataGridFooter.module.css +8 -0
- package/src/tmdatagrid/components/TMDataGridFooter.tsx +63 -43
- package/src/tmdatagrid/components/TMDataGridGroupColumn.module.css +48 -0
- package/src/tmdatagrid/components/TMDataGridGroupColumn.tsx +159 -0
- package/src/tmdatagrid/components/TMDataGridHeaderCell.module.css +18 -0
- package/src/tmdatagrid/components/TMDataGridHeaderCell.tsx +249 -44
- package/src/tmdatagrid/components/TMDataGridSearch.tsx +122 -0
- package/src/tmdatagrid/components/TMDataGridSelectColumn.tsx +103 -16
- package/src/tmdatagrid/components/TMDataGridTable.module.css +160 -5
- package/src/tmdatagrid/components/TMDataGridTable.tsx +1380 -43
- package/src/tmdatagrid/components/TMDataGridToolbar.tsx +33 -7
- package/src/tmdatagrid/components/icons.ts +6 -0
- package/src/tmdatagrid/components/sticky.module.css +77 -16
- package/src/tmdatagrid/core/autosize.ts +125 -0
- package/src/tmdatagrid/core/capabilities.ts +122 -11
- package/src/tmdatagrid/core/cellExport.ts +321 -0
- package/src/tmdatagrid/core/cellNavigation.ts +103 -0
- package/src/tmdatagrid/core/cellRange.ts +118 -0
- package/src/tmdatagrid/core/columnOptions.ts +123 -0
- package/src/tmdatagrid/core/columnUtils.ts +18 -0
- package/src/tmdatagrid/core/expanding.ts +93 -0
- package/src/tmdatagrid/core/filterOperators.ts +198 -12
- package/src/tmdatagrid/core/grouping.ts +21 -0
- package/src/tmdatagrid/core/labels.ts +211 -0
- package/src/tmdatagrid/core/labelsSv.ts +108 -0
- package/src/tmdatagrid/core/persistence.ts +12 -0
- package/src/tmdatagrid/core/rowSelection.ts +202 -0
- package/src/tmdatagrid/core/summary.ts +35 -0
- package/src/tmdatagrid/index.ts +96 -2
- package/src/tmdatagrid/useTMDataGrid.tsx +558 -37
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { Checkbox } from "@mantine/core";
|
|
2
2
|
import { useSelector } from "@tanstack/react-store";
|
|
3
3
|
import type { ColumnDef, Row, RowData } from "@tanstack/react-table";
|
|
4
|
+
import {
|
|
5
|
+
useCellControlTabIndex,
|
|
6
|
+
useTMDataGridContext,
|
|
7
|
+
} from "../TMDataGridContext";
|
|
8
|
+
import {
|
|
9
|
+
getDisplayedRows,
|
|
10
|
+
getSelectableRowIds,
|
|
11
|
+
resolveRowSelectionClick,
|
|
12
|
+
} from "../core/rowSelection";
|
|
4
13
|
import type { TMDataGridFeatures, TMDataGridTable } from "../useTMDataGrid";
|
|
5
14
|
|
|
6
15
|
export const SELECT_COLUMN_ID = "__select__";
|
|
@@ -25,6 +34,7 @@ function SelectAllCheckbox<TData extends RowData>({
|
|
|
25
34
|
}: {
|
|
26
35
|
table: TMDataGridTable<TData>;
|
|
27
36
|
}) {
|
|
37
|
+
const { labels } = useTMDataGridContext();
|
|
28
38
|
const allSelected = useSelector(table.store, () =>
|
|
29
39
|
table.getIsAllRowsSelected(),
|
|
30
40
|
);
|
|
@@ -35,7 +45,7 @@ function SelectAllCheckbox<TData extends RowData>({
|
|
|
35
45
|
return (
|
|
36
46
|
<Checkbox
|
|
37
47
|
size="xs"
|
|
38
|
-
aria-label=
|
|
48
|
+
aria-label={labels.selectAllRows}
|
|
39
49
|
checked={allSelected}
|
|
40
50
|
indeterminate={someSelected && !allSelected}
|
|
41
51
|
onChange={table.getToggleAllRowsSelectedHandler()}
|
|
@@ -43,24 +53,95 @@ function SelectAllCheckbox<TData extends RowData>({
|
|
|
43
53
|
);
|
|
44
54
|
}
|
|
45
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Drops the select-all box when only one row may be selected. Read from the
|
|
58
|
+
* feature flags rather than `table.options.enableMultiRowSelection` directly:
|
|
59
|
+
* the flags are re-derived from a fresh object every render, so the switch
|
|
60
|
+
* cannot be cached along with a `table` identity that survives an options
|
|
61
|
+
* change — the same reason the rest of the chrome reads them. See
|
|
62
|
+
* readFeatureFlags.
|
|
63
|
+
*/
|
|
64
|
+
function SelectAllHeader<TData extends RowData>({
|
|
65
|
+
table,
|
|
66
|
+
}: {
|
|
67
|
+
table: TMDataGridTable<TData>;
|
|
68
|
+
}) {
|
|
69
|
+
const { features } = useTMDataGridContext();
|
|
70
|
+
if (!features.multiRowSelection) return null;
|
|
71
|
+
return <SelectAllCheckbox table={table} />;
|
|
72
|
+
}
|
|
73
|
+
|
|
46
74
|
function SelectRowCheckbox<TData extends RowData>({
|
|
47
75
|
row,
|
|
48
76
|
}: {
|
|
49
77
|
row: Row<TMDataGridFeatures, TData>;
|
|
50
78
|
}) {
|
|
51
|
-
|
|
79
|
+
// Cells render inside the grid's provider, so the checkbox can reach the
|
|
80
|
+
// chrome store — it needs the shift-click pivot, and the feature flags to know
|
|
81
|
+
// which row model a range is measured over.
|
|
82
|
+
const { ui, features, labels } = useTMDataGridContext();
|
|
83
|
+
// Out of the tab order once the grid has a cell cursor — see
|
|
84
|
+
// useCellControlTabIndex. Enter on the lane still steps in, and Space on any
|
|
85
|
+
// cell of the row ticks it.
|
|
86
|
+
const tabIndex = useCellControlTabIndex();
|
|
87
|
+
const isGroupRow = row.subRows.length > 0;
|
|
88
|
+
|
|
89
|
+
// A group row is never selected by id: `rowSelection` only ever holds the
|
|
90
|
+
// leaves, and TanStack's `getIsSelected()` is a plain lookup in that map. So
|
|
91
|
+
// a group asks about its descendants instead, which is also the honest
|
|
92
|
+
// reading — the box means "all of these", and it goes indeterminate as soon
|
|
93
|
+
// as that stops being true.
|
|
94
|
+
const selected = useSelector(row.table.store, () =>
|
|
95
|
+
isGroupRow ? row.getIsAllSubRowsSelected() : row.getIsSelected(),
|
|
96
|
+
);
|
|
52
97
|
const someSelected = useSelector(row.table.store, () =>
|
|
53
98
|
row.getIsSomeSelected(),
|
|
54
99
|
);
|
|
55
100
|
|
|
101
|
+
// The resolver expands a tick back out to the descendant ids; all the group
|
|
102
|
+
// case needs here is to know whether any of them may be selected at all.
|
|
103
|
+
const selectableIds = getSelectableRowIds(row);
|
|
104
|
+
|
|
105
|
+
// Single-select has no way to express "this group": one box for several rows
|
|
106
|
+
// would either overrun the limit or lie about what it did.
|
|
107
|
+
if (isGroupRow && !row.getCanMultiSelect()) return null;
|
|
108
|
+
|
|
56
109
|
return (
|
|
57
110
|
<Checkbox
|
|
58
111
|
size="xs"
|
|
59
|
-
|
|
112
|
+
tabIndex={tabIndex}
|
|
113
|
+
aria-label={isGroupRow ? labels.selectGroup : labels.selectRow}
|
|
60
114
|
checked={selected}
|
|
61
|
-
disabled={
|
|
115
|
+
disabled={selectableIds.length === 0}
|
|
62
116
|
indeterminate={someSelected && !selected}
|
|
63
|
-
|
|
117
|
+
// Every tick goes through the resolver, shift held or not — plain becomes
|
|
118
|
+
// a toggle that moves the pivot, so a later shift-click extends from the
|
|
119
|
+
// box the user last touched.
|
|
120
|
+
//
|
|
121
|
+
// All of it in `onChange`, not split with an `onClick`: React derives a
|
|
122
|
+
// checkbox's change event from the click, so the modifier keys ride along
|
|
123
|
+
// on the native event, and a `preventDefault()` in a click handler cannot
|
|
124
|
+
// stop the change from firing anyway. Trying to do the range in `onClick`
|
|
125
|
+
// silently loses the clicked row, which `onChange` then toggles back off.
|
|
126
|
+
onChange={(event) => {
|
|
127
|
+
const native = event.nativeEvent;
|
|
128
|
+
const isMouse = native instanceof MouseEvent;
|
|
129
|
+
const resolved = resolveRowSelectionClick({
|
|
130
|
+
rows: getDisplayedRows(row.table, features),
|
|
131
|
+
rowId: row.id,
|
|
132
|
+
anchorRowId: ui.state.selectionAnchorRowId,
|
|
133
|
+
modifiers: {
|
|
134
|
+
toggle: isMouse && (native.ctrlKey || native.metaKey),
|
|
135
|
+
extend: isMouse && native.shiftKey,
|
|
136
|
+
},
|
|
137
|
+
selection: row.table.store.state.rowSelection,
|
|
138
|
+
// A checkbox is only ever additive — ticking one has never cleared
|
|
139
|
+
// the others, so `canReplaceSelection` stays false whatever is held.
|
|
140
|
+
canReplaceSelection: false,
|
|
141
|
+
});
|
|
142
|
+
row.table.setRowSelection(resolved.selection);
|
|
143
|
+
ui.actions.setSelectionAnchor(resolved.anchorRowId);
|
|
144
|
+
}}
|
|
64
145
|
// A row can select on click too; the checkbox must not toggle twice.
|
|
65
146
|
onClick={(event) => event.stopPropagation()}
|
|
66
147
|
/>
|
|
@@ -69,32 +150,38 @@ function SelectRowCheckbox<TData extends RowData>({
|
|
|
69
150
|
|
|
70
151
|
/**
|
|
71
152
|
* The generated checkbox column, prepended under
|
|
72
|
-
* `
|
|
153
|
+
* `selectionMode: "checkbox"` (the default) or `"checkboxAndHighlight"`.
|
|
73
154
|
*/
|
|
74
|
-
export function createSelectColumn<TData extends RowData>(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
unknown
|
|
78
|
-
> {
|
|
155
|
+
export function createSelectColumn<TData extends RowData>(
|
|
156
|
+
label = "Checkbox selection",
|
|
157
|
+
): ColumnDef<TMDataGridFeatures, TData, unknown> {
|
|
79
158
|
return {
|
|
80
159
|
id: SELECT_COLUMN_ID,
|
|
81
160
|
meta: {
|
|
82
|
-
label
|
|
161
|
+
label,
|
|
83
162
|
align: "center",
|
|
84
163
|
// Structurally the first column; it also anchors the left pinned lane, so
|
|
85
164
|
// no other column can be moved in front of it.
|
|
86
165
|
enableOrdering: false,
|
|
87
166
|
},
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
167
|
+
// A system lane: as wide as the control it holds and no wider. Fixed at
|
|
168
|
+
// every scale — the control does not grow with the font size, so neither
|
|
169
|
+
// should its track.
|
|
170
|
+
size: 36,
|
|
171
|
+
minSize: 36,
|
|
172
|
+
maxSize: 36,
|
|
91
173
|
enableResizing: false,
|
|
92
174
|
enableSorting: false,
|
|
93
175
|
enableColumnFilter: false,
|
|
94
176
|
enableGlobalFilter: false,
|
|
95
177
|
// Structurally pinned to the left; users shouldn't be able to move it.
|
|
96
178
|
enablePinning: false,
|
|
97
|
-
header: ({ table }) => <
|
|
179
|
+
header: ({ table }) => <SelectAllHeader table={table} />,
|
|
98
180
|
cell: ({ row }) => <SelectRowCheckbox row={row} />,
|
|
181
|
+
// Every cell on a group row that is not the grouped column counts as
|
|
182
|
+
// aggregated, this lane included, and an aggregated cell with nothing
|
|
183
|
+
// declared renders blank. Without this the checkbox would disappear from
|
|
184
|
+
// exactly the rows that select a whole group. See renderCellContent.
|
|
185
|
+
aggregatedCell: ({ row }) => <SelectRowCheckbox row={row} />,
|
|
99
186
|
};
|
|
100
187
|
}
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
grid-template-columns: subgrid;
|
|
28
28
|
position: sticky;
|
|
29
29
|
top: 0;
|
|
30
|
-
z-index:
|
|
30
|
+
z-index: var(--dg-z-header, 6);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
.bodyRow {
|
|
@@ -42,13 +42,39 @@
|
|
|
42
42
|
--row-bg: var(--mantine-color-default-hover);
|
|
43
43
|
}
|
|
44
44
|
|
|
45
|
-
/*
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
45
|
+
/* A group row takes no background of its own. Collapsed, every row on screen is
|
|
46
|
+
a group row, so a tint would grey out the whole grid and read as if
|
|
47
|
+
everything were selected. The bold label and the chevron carry the
|
|
48
|
+
distinction instead — and `--dg-row-group-bg` is there for a consumer who
|
|
49
|
+
wants the tint back. Declared before the selection rules, so a selected or
|
|
50
|
+
highlighted group still reads as one. */
|
|
51
|
+
.bodyRow[data-grouped="true"] {
|
|
52
|
+
--row-bg: var(--dg-row-group-bg);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/* The row an open context menu is about. The pointer has usually left it by
|
|
56
|
+
then, so without this the menu would be the only thing saying which row it
|
|
57
|
+
acts on. Declared before the selection rules, which are the stronger
|
|
58
|
+
statement and win at equal specificity. */
|
|
59
|
+
.bodyRow[data-context-menu="true"] {
|
|
60
|
+
--row-bg: var(--mantine-color-default-hover);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/* Being selected and being painted for it are separate: a row is always
|
|
64
|
+
`data-selected`, but only takes the background when `showSelectedBackground`
|
|
65
|
+
is on — the default under `"row"`, off with checkboxes. */
|
|
66
|
+
.bodyRow[data-selected-bg="true"] {
|
|
49
67
|
--row-bg: var(--dg-row-selected-bg);
|
|
50
68
|
}
|
|
51
69
|
|
|
70
|
+
/* The highlighted row wins over the selected background: under
|
|
71
|
+
`"checkboxAndHighlight"` the two coexist, and the highlighted row is the one
|
|
72
|
+
the detail panel is about, so it must stay distinguishable inside a
|
|
73
|
+
selection. Declared after, so the later rule takes it at equal specificity. */
|
|
74
|
+
.bodyRow[data-highlighted="true"] {
|
|
75
|
+
--row-bg: var(--dg-row-highlight-bg);
|
|
76
|
+
}
|
|
77
|
+
|
|
52
78
|
/* Row selection mode: the row is the control, so it takes focus and must not
|
|
53
79
|
start a text selection on the click that toggles it. */
|
|
54
80
|
.bodyRow[data-selects-on-click="true"] {
|
|
@@ -72,6 +98,83 @@
|
|
|
72
98
|
font-size: var(--dg-font-size);
|
|
73
99
|
}
|
|
74
100
|
|
|
101
|
+
/* A control lane — the checkbox, the details chevron — is a fixed 36px track
|
|
102
|
+
holding a control of a known width, not text that can ellipsize. Cell padding
|
|
103
|
+
is sized for text and grows with the scale, so at `xl` its 18px a side left
|
|
104
|
+
12px for a 16px box and the checkbox was clipped. The lane centres its
|
|
105
|
+
control instead. */
|
|
106
|
+
.bodyCell[data-control-column="true"] {
|
|
107
|
+
padding: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/* A drag is laying down a range. Text selection would otherwise follow the
|
|
111
|
+
pointer across every cell it passes. */
|
|
112
|
+
.grid[data-range-dragging] {
|
|
113
|
+
user-select: none;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* The selected block, under `cellSelection: "range"`.
|
|
117
|
+
|
|
118
|
+
A tint over the row's own background rather than instead of it, so a
|
|
119
|
+
selected cell on a highlighted row still reads as both. `color-mix` keeps
|
|
120
|
+
one declaration for light and dark: it thins the theme's primary colour into
|
|
121
|
+
whatever `--row-bg` the row resolved to. */
|
|
122
|
+
.bodyCell[data-selected="true"] {
|
|
123
|
+
background-color: color-mix(
|
|
124
|
+
in srgb,
|
|
125
|
+
var(--mantine-primary-color-filled) 14%,
|
|
126
|
+
var(--row-bg)
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/* The outline around the block, drawn edge by edge: only the cells on a side
|
|
131
|
+
of the rectangle draw that side, so they add up to one border around the
|
|
132
|
+
whole thing however it is shaped. A single overlay box would have to be
|
|
133
|
+
positioned against a scrolling grid with sticky lanes in it.
|
|
134
|
+
|
|
135
|
+
Four shadows are always laid down and each is transparent until its edge
|
|
136
|
+
says otherwise. `box-shadow` does not accumulate across rules — a second
|
|
137
|
+
declaration replaces the first — so the alternative is one rule per corner
|
|
138
|
+
combination, and a cell can be on any of fifteen of them. */
|
|
139
|
+
.bodyCell[data-selected="true"] {
|
|
140
|
+
--dg-edge-top: transparent;
|
|
141
|
+
--dg-edge-bottom: transparent;
|
|
142
|
+
--dg-edge-left: transparent;
|
|
143
|
+
--dg-edge-right: transparent;
|
|
144
|
+
box-shadow:
|
|
145
|
+
inset 0 1px 0 0 var(--dg-edge-top),
|
|
146
|
+
inset 0 -1px 0 0 var(--dg-edge-bottom),
|
|
147
|
+
inset 1px 0 0 0 var(--dg-edge-left),
|
|
148
|
+
inset -1px 0 0 0 var(--dg-edge-right);
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
.bodyCell[data-edge-top="true"] {
|
|
152
|
+
--dg-edge-top: var(--mantine-primary-color-filled);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
.bodyCell[data-edge-bottom="true"] {
|
|
156
|
+
--dg-edge-bottom: var(--mantine-primary-color-filled);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.bodyCell[data-edge-left="true"] {
|
|
160
|
+
--dg-edge-left: var(--mantine-primary-color-filled);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
.bodyCell[data-edge-right="true"] {
|
|
164
|
+
--dg-edge-right: var(--mantine-primary-color-filled);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/* The cell the keyboard is on, under `cellSelection`.
|
|
168
|
+
|
|
169
|
+
Painted from `data-focused` rather than `:focus-visible`, because the ring
|
|
170
|
+
has to stay while the focus steps into a control inside the cell — that is
|
|
171
|
+
still where the arrow keys resume from. The offset keeps it inside the
|
|
172
|
+
cell's own box, so a pinned neighbour cannot clip it. */
|
|
173
|
+
.bodyCell[data-focused="true"] {
|
|
174
|
+
outline: 2px solid var(--mantine-primary-color-filled);
|
|
175
|
+
outline-offset: -2px;
|
|
176
|
+
}
|
|
177
|
+
|
|
75
178
|
.cellContent {
|
|
76
179
|
min-width: 0;
|
|
77
180
|
overflow: hidden;
|
|
@@ -92,6 +195,23 @@
|
|
|
92
195
|
flex: 1 1 auto;
|
|
93
196
|
}
|
|
94
197
|
|
|
198
|
+
/* The panel an expanded row opens. Its own grid row inside .bodyRow, spanning
|
|
199
|
+
every column track — so it is measured together with the row above it.
|
|
200
|
+
|
|
201
|
+
It takes `--row-bg` rather than a colour of its own: the panel belongs to its
|
|
202
|
+
row, and a selected or highlighted row whose panel stayed white would read as
|
|
203
|
+
two separate things. */
|
|
204
|
+
.detailsCell {
|
|
205
|
+
grid-column: 1 / -1;
|
|
206
|
+
border-bottom: 1px solid var(--mantine-color-default-border);
|
|
207
|
+
background-color: var(--row-bg);
|
|
208
|
+
padding: var(--dg-padding);
|
|
209
|
+
/* The row above may be the selection control, which turns text selection off
|
|
210
|
+
for everything inside it. A panel is content, so it takes both back. */
|
|
211
|
+
user-select: text;
|
|
212
|
+
cursor: auto;
|
|
213
|
+
}
|
|
214
|
+
|
|
95
215
|
.messageRow {
|
|
96
216
|
grid-column: 1 / -1;
|
|
97
217
|
display: flex;
|
|
@@ -101,3 +221,38 @@
|
|
|
101
221
|
gap: var(--mantine-spacing-xs);
|
|
102
222
|
padding: var(--mantine-spacing-xl);
|
|
103
223
|
}
|
|
224
|
+
|
|
225
|
+
/* The summary row — one sticky row of column footers along the bottom edge,
|
|
226
|
+
rendered only while at least one column defines `footer`. Same subgrid
|
|
227
|
+
placement as the header, so its cells sit exactly on the body's tracks. */
|
|
228
|
+
.summaryRow {
|
|
229
|
+
display: grid;
|
|
230
|
+
grid-column: 1 / -1;
|
|
231
|
+
grid-template-columns: subgrid;
|
|
232
|
+
position: sticky;
|
|
233
|
+
bottom: 0;
|
|
234
|
+
z-index: var(--dg-z-summary-row, 4);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
.summaryCell {
|
|
238
|
+
display: flex;
|
|
239
|
+
align-items: center;
|
|
240
|
+
padding: 0 var(--dg-padding);
|
|
241
|
+
border-top: 1px solid var(--mantine-color-default-border);
|
|
242
|
+
/* Opaque: the body scrolls underneath it. */
|
|
243
|
+
background-color: var(--mantine-color-body);
|
|
244
|
+
font-size: var(--dg-font-size);
|
|
245
|
+
font-weight: 600;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
.summaryCell[data-control-column="true"] {
|
|
249
|
+
padding: 0;
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
.summaryCell[data-align="right"] {
|
|
253
|
+
justify-content: flex-end;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
.summaryCell[data-align="center"] {
|
|
257
|
+
justify-content: center;
|
|
258
|
+
}
|