@alaarab/ogrid-react-fluent 2.0.11 → 2.0.12

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 (27) hide show
  1. package/README.md +1 -1
  2. package/dist/esm/ColumnChooser/ColumnChooser.js +10 -128
  3. package/dist/esm/ColumnChooser/ColumnChooser.module.css +45 -10
  4. package/dist/esm/ColumnHeaderFilter/ColumnHeaderFilter.js +16 -36
  5. package/dist/esm/ColumnHeaderMenu/ColumnHeaderMenu.js +9 -3
  6. package/dist/esm/ColumnHeaderMenu/ColumnHeaderMenu.module.css +7 -7
  7. package/dist/esm/DataGridTable/DataGridTable.js +118 -295
  8. package/dist/esm/DataGridTable/DataGridTable.module.css +546 -437
  9. package/dist/esm/DataGridTable/DropIndicator.js +5 -0
  10. package/dist/esm/DataGridTable/EmptyState.js +5 -0
  11. package/dist/esm/DataGridTable/GridContextMenu.js +10 -32
  12. package/dist/esm/DataGridTable/LoadingOverlay.js +6 -0
  13. package/dist/esm/{FluentDataTable/FluentDataTable.js → OGrid/OGrid.js} +0 -2
  14. package/dist/esm/OGrid/index.js +1 -0
  15. package/dist/esm/index.js +1 -1
  16. package/dist/types/ColumnChooser/ColumnChooser.d.ts +2 -8
  17. package/dist/types/ColumnHeaderFilter/ColumnHeaderFilter.d.ts +2 -20
  18. package/dist/types/DataGridTable/DropIndicator.d.ts +7 -0
  19. package/dist/types/DataGridTable/EmptyState.d.ts +11 -0
  20. package/dist/types/DataGridTable/LoadingOverlay.d.ts +6 -0
  21. package/dist/types/{FluentDataTable/FluentDataTable.d.ts → OGrid/OGrid.d.ts} +0 -2
  22. package/dist/types/OGrid/index.d.ts +1 -0
  23. package/dist/types/PaginationControls/PaginationControls.d.ts +2 -10
  24. package/dist/types/index.d.ts +1 -1
  25. package/package.json +3 -3
  26. package/dist/esm/FluentDataTable/index.js +0 -1
  27. package/dist/types/FluentDataTable/index.d.ts +0 -1
@@ -4,315 +4,163 @@
4
4
  flex-direction: column;
5
5
  width: 100%;
6
6
  min-width: 0;
7
- min-height: 100%;
8
- /* Match wrapper so any gap to the right is not transparent (no purple stripe showing through) */
9
- background-color: var(--colorNeutralBackground1, #ffffff);
7
+ background: var(--ogrid-bg, #fff);
10
8
  }
11
9
 
12
10
  .tableWidthAnchor {
13
11
  position: relative;
14
- /* When table fits (data-auto-fit): fill 100% so last column gets space. When overflow: size to content for scroll. */
15
12
  width: max-content;
16
- background-color: var(--colorNeutralBackground1, #ffffff);
17
- }
18
-
19
- /* When table fits in container: fill full width so columns (including Tags) use the space, no dead zone on the right */
20
- .tableWrapper[data-auto-fit=true] .tableWidthAnchor {
21
- width: 100%;
13
+ min-width: var(--data-table-min-width, max-content);
14
+ background: var(--ogrid-bg, #fff);
22
15
  }
23
16
 
24
- /* Always use full container width (matches pagination); columns fill the space */
25
17
  .tableWrapper {
26
18
  position: relative;
27
19
  flex: 1;
28
20
  min-height: 0;
29
- /* Default: no horizontal scroll unless we explicitly allow overflow (wide tables). */
30
21
  overflow-x: hidden;
31
22
  overflow-y: auto;
32
23
  width: 100%;
33
24
  min-width: 0;
34
25
  max-width: 100%;
35
26
  box-sizing: border-box;
36
- /* Border is applied to the grid itself so we don't draw an empty bordered area
37
- when the grid content is narrower than the container. */
38
- border: none;
39
- background-color: var(--colorNeutralBackground1, #ffffff);
40
- -webkit-overflow-scrolling: touch;
27
+ background: var(--ogrid-bg, #fff);
41
28
  will-change: scroll-position;
42
- /* Wide tables: allow horizontal scroll */
43
29
  }
44
30
  .tableWrapper[data-overflow-x=true] {
45
31
  overflow-x: auto;
46
32
  }
47
- .tableWrapper {
48
- /* Empty state: no horizontal scroll – can't scroll right into white space */
49
- }
50
33
  .tableWrapper[data-empty=true] {
51
34
  overflow-x: hidden;
52
35
  }
53
- .tableWrapper {
54
- /* Scoped by data-column-count so our overrides apply; variable is set on this wrapper */
55
- }
56
- .tableWrapper[data-column-count] :global {
57
- /* Let the grid/table size to its content.
58
- This avoids "last column becomes a giant spacer" when the container is wider than the columns,
59
- and keeps header actions (sort/filter) from drifting all the way to the far right.
60
- The wrapper still stays width:100% so pagination aligns. */
61
- }
62
- .tableWrapper[data-column-count] :global .fui-DataGrid {
63
- /* Width behavior is controlled by a CSS var from the React wrapper. */
64
- width: var(--data-table-width, fit-content) !important;
65
- max-width: 100% !important;
66
- min-width: var(--data-table-min-width, max-content) !important;
67
- box-sizing: border-box !important;
68
- overflow: hidden;
69
- }
70
- .tableWrapper[data-column-count] :global {
71
- /* Use auto layout so Fluent sizing/resize works naturally. */
72
- }
73
- .tableWrapper[data-column-count] :global .fui-DataGrid .fui-Table {
74
- width: var(--data-table-width, fit-content) !important;
75
- max-width: 100% !important;
76
- min-width: var(--data-table-min-width, max-content) !important;
77
- table-layout: auto !important;
78
- box-sizing: border-box !important;
79
- border: none !important;
80
- outline: none !important;
81
- }
82
- .tableWrapper[data-column-count] :global {
83
- /* Rows span full table width */
84
- }
85
- .tableWrapper[data-column-count] :global .fui-DataGrid .fui-TableRow,
86
- .tableWrapper[data-column-count] :global .fui-DataGrid .fui-DataGridRow {
87
- width: 100% !important;
88
- min-width: 100% !important;
89
- }
90
- .tableWrapper[data-column-count] :global .fui-DataGridHeader {
91
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
92
- }
93
- .tableWrapper[data-column-count] :global {
94
- /* Let Fluent's column sizing system own widths (resizableColumns + columnSizingOptions).
95
- We only enforce a min-width + sane box sizing. */
96
- }
97
- .tableWrapper[data-column-count] :global .fui-DataGridHeaderCell,
98
- .tableWrapper[data-column-count] :global .fui-DataGridCell {
99
- /* Do NOT use !important here: Fluent sets inline width/min/max during resize. */
100
- min-width: 80px;
101
- box-sizing: border-box !important;
102
- }
103
- .tableWrapper[data-column-count] :global .fui-DataGridHeaderCell {
104
- min-width: var(--data-table-cell-min-width, 80px);
105
- white-space: nowrap !important;
106
- position: sticky; /* Changed from relative - enables vertical sticky for all headers */
107
- top: 0; /* Sticky vertically */
108
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
109
- z-index: 8; /* Stack above body cells */
110
- font-size: 14px;
111
- border-right: 1px solid var(--colorNeutralStroke1, #c4c4c4);
112
- }
113
- .tableWrapper[data-column-count] :global {
114
- /* No extra right border on last column – wrapper provides right edge (row may have trailing <i> so use last-of-type) */
115
- }
116
- .tableWrapper[data-column-count] :global .fui-DataGridHeader .fui-DataGridRow .fui-DataGridHeaderCell:last-of-type,
117
- .tableWrapper[data-column-count] :global .fui-DataGridBody .fui-DataGridRow .fui-DataGridCell:last-of-type {
118
- border-right: none !important;
119
- }
120
- .tableWrapper[data-column-count] :global .fui-DataGridCell {
121
- min-width: var(--data-table-cell-min-width, 80px);
122
- overflow: hidden !important;
123
- text-overflow: ellipsis !important;
124
- white-space: nowrap !important;
125
- font-size: 12px;
126
- padding: 0 !important;
127
- height: 1px;
128
- border-right: 1px solid var(--colorNeutralStroke1, #c4c4c4);
129
- /* Prevent long unbroken content from forcing intrinsic widths / overlap */
130
- }
131
- .tableWrapper[data-column-count] :global .fui-DataGridCell > * {
132
- min-width: 0;
133
- }
134
- .tableWrapper[data-column-count] :global .fui-DataGridCell .fui-TableCellLayout {
135
- font-size: 12px;
136
- }
137
- .tableWrapper[data-column-count] :global {
138
- /* Resize handle: contained so focus ring doesn't create a purple stripe to the right */
139
- }
140
- .tableWrapper[data-column-count] :global .fui-DataGridHeaderCell__aside {
141
- display: flex !important;
142
- cursor: col-resize !important;
143
- position: absolute !important;
144
- right: 0 !important;
145
- top: 0 !important;
146
- bottom: 0 !important;
147
- width: 16px !important;
148
- z-index: 1 !important;
149
- outline: none !important;
150
- border-radius: 0 !important;
151
- }
152
- .tableWrapper[data-column-count] :global {
153
- /* Fix: Fluent renders a resize handle on the last header cell.
154
- The handle has negative horizontal margins (hit target), which bleeds past the table edge
155
- and makes the last header look like it has extra space vs the body cells.
156
- Hide the resize affordance on the last column header. */
157
- }
158
- .tableWrapper[data-column-count] :global .fui-DataGridHeader .fui-DataGridRow .fui-DataGridHeaderCell:last-of-type .fui-DataGridHeaderCell__aside,
159
- .tableWrapper[data-column-count] :global .fui-DataGridHeader .fui-DataGridRow .fui-DataGridHeaderCell:last-of-type .fui-TableResizeHandle {
160
- display: none !important;
161
- }
162
- .tableWrapper[data-column-count] :global {
163
- /* No extra bottom border: last row (row + cells) – wrapper provides bottom edge so no double line */
164
- }
165
- .tableWrapper[data-column-count] :global .fui-DataGridBody .fui-DataGridRow:last-child {
166
- border-bottom: none !important;
167
- }
168
- .tableWrapper[data-column-count] :global .fui-DataGridBody .fui-DataGridRow:last-child .fui-DataGridCell {
169
- border-bottom: none !important;
170
- }
171
- .tableWrapper[data-column-count] :global .fui-Link {
172
- color: var(--colorBrandForeground1, #0f6cbd) !important;
173
- font-weight: 600 !important;
174
- text-decoration: none !important;
175
- }
176
- .tableWrapper[data-column-count] :global .fui-Link:hover {
177
- text-decoration: underline !important;
178
- color: var(--colorBrandForeground1Hover, #115ea3) !important;
179
- }
180
- .tableWrapper[data-column-count] :global .fui-Link:active {
181
- color: var(--colorBrandForeground1Pressed, #0c3b5e) !important;
182
- }
183
- .tableWrapper {
184
- /* When table fits: fill 100% and distribute column width evenly so last column (e.g. Tags) isn't tiny */
185
- }
186
- .tableWrapper[data-auto-fit=true][data-column-count] :global .fui-DataGrid {
187
- width: 100% !important;
188
- }
189
- .tableWrapper[data-auto-fit=true][data-column-count] :global .fui-DataGrid .fui-Table {
190
- width: 100% !important;
191
- }
192
- .tableWrapper[data-auto-fit=true][data-column-count] :global {
193
- /* Equal base width for all columns — override Fluent's inline width/min-width/max-width */
194
- }
195
- .tableWrapper[data-auto-fit=true][data-column-count] :global .fui-DataGridHeaderCell,
196
- .tableWrapper[data-auto-fit=true][data-column-count] :global .fui-DataGridCell {
197
- width: calc(100% / var(--data-table-column-count, 1)) !important;
198
- min-width: 0 !important;
199
- max-width: none !important;
200
- }
201
- .tableWrapper {
202
- /* Selection column must stay 48px even in auto-fit mode (needs same specificity depth to win) */
203
- }
204
- .tableWrapper[data-auto-fit=true][data-column-count] .selectionHeaderCellWrapper, .tableWrapper[data-auto-fit=true][data-column-count] .selectionCellWrapper {
205
- width: 48px !important;
206
- min-width: 48px !important;
207
- max-width: 48px !important;
208
- }
209
- .tableWrapper {
210
- /* Row numbers column must stay 50px even in auto-fit mode */
211
- }
212
- .tableWrapper[data-auto-fit=true][data-column-count] .rowNumberHeaderCellWrapper, .tableWrapper[data-auto-fit=true][data-column-count] .rowNumberCellWrapper {
213
- width: 50px !important;
214
- min-width: 50px !important;
215
- max-width: 50px !important;
216
- }
217
- .tableWrapper {
218
- /* Hide resize handle on last column only when table fits (autoFitColumns); when overflow/scroll, last column can resize (Fluent docs) */
219
- }
220
- .tableWrapper[data-column-count][data-auto-fit=true] :global(.fui-DataGridHeader .fui-DataGridRow .fui-DataGridHeaderCell:last-of-type .fui-DataGridHeaderCell__aside) {
221
- display: none !important;
222
- }
223
36
 
224
- .dataGrid {
225
- min-width: 0;
226
- }
227
-
228
- .groupHeaderRow th {
229
- background: var(--ogrid-header-bg, #f5f5f5);
37
+ .dataTable {
38
+ width: var(--data-table-width, fit-content);
39
+ max-width: 100%;
40
+ min-width: var(--data-table-min-width, max-content);
41
+ border-collapse: separate;
42
+ border-spacing: 0;
43
+ box-sizing: border-box;
44
+ table-layout: auto;
45
+ background-color: var(--ogrid-bg, #fff);
46
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
230
47
  }
231
48
 
232
49
  .groupHeaderCell {
233
50
  text-align: center;
234
51
  font-weight: 600;
235
- border-bottom: 2px solid var(--ogrid-border, #e0e0e0);
236
- padding: 6px 10px;
237
- }
238
-
239
- .leafHeaderCellSpan {
240
- font-weight: 600;
52
+ border-bottom: 2px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
241
53
  padding: 6px 10px;
242
54
  background: var(--ogrid-header-bg, #f5f5f5);
243
55
  }
244
56
 
245
- .selectionHeaderCellWrapper {
246
- width: 48px !important;
247
- min-width: 48px !important;
248
- max-width: 48px !important;
249
- padding: 0 !important;
250
- }
251
-
252
- .selectionCellWrapper {
253
- width: 48px !important;
254
- min-width: 48px !important;
255
- max-width: 48px !important;
256
- padding: 0 !important;
257
- }
258
-
259
- .rowNumberHeaderCellWrapper {
260
- width: 50px !important;
261
- min-width: 50px !important;
262
- max-width: 50px !important;
263
- padding: 0 !important;
264
- }
265
-
266
- .rowNumberCellWrapper {
267
- width: 50px !important;
268
- min-width: 50px !important;
269
- max-width: 50px !important;
270
- padding: 0 !important;
271
- }
272
-
273
- .selectionHeaderCell {
57
+ .headerCellContent {
274
58
  display: flex;
275
59
  align-items: center;
276
- justify-content: center;
277
- width: 100%;
278
- height: 100%;
60
+ gap: 4px;
279
61
  }
280
62
 
281
- .selectionCell {
63
+ .headerMenuTrigger {
64
+ background: transparent;
65
+ border: none;
66
+ cursor: pointer;
67
+ padding: 2px 4px;
68
+ font-size: 16px;
69
+ line-height: 1;
70
+ color: var(--ogrid-fg-secondary, rgba(0, 0, 0, 0.6));
71
+ opacity: 1;
72
+ transition: background-color 0.15s;
73
+ border-radius: 3px;
282
74
  display: flex;
283
75
  align-items: center;
284
76
  justify-content: center;
285
- width: 100%;
286
- height: 100%;
77
+ min-width: 20px;
78
+ height: 20px;
79
+ }
80
+ .headerMenuTrigger:hover {
81
+ background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04));
82
+ }
83
+ .headerMenuTrigger:active {
84
+ background: var(--ogrid-active-bg, rgba(0, 0, 0, 0.08));
85
+ }
86
+ .headerMenuTrigger:focus-visible {
87
+ outline: 2px solid var(--ogrid-accent, #0078d4);
88
+ outline-offset: 2px;
287
89
  }
288
90
 
289
- .rowNumberHeaderCell,
290
- .rowNumberCell {
291
- display: flex;
292
- align-items: center;
293
- justify-content: center;
294
- width: 100%;
295
- height: 100%;
296
- font-weight: 600;
297
- font-variant-numeric: tabular-nums;
298
- color: var(--colorNeutralForeground3, #666);
299
- background: var(--colorNeutralBackground3, #f5f5f5);
91
+ .dropIndicator {
92
+ position: absolute;
93
+ top: 0;
94
+ bottom: 0;
95
+ width: 3px;
96
+ background: var(--ogrid-selection-color, #217346);
97
+ pointer-events: none;
98
+ z-index: 100;
99
+ transition: left 0.05s;
300
100
  }
301
101
 
302
- .selectedRow :global .fui-DataGridCell {
303
- background-color: var(--colorNeutralBackground1Selected, #e6f0fb) !important;
102
+ .resizeHandle {
103
+ position: absolute;
104
+ top: 0;
105
+ right: -3px;
106
+ bottom: 0;
107
+ width: 8px;
108
+ cursor: col-resize;
109
+ user-select: none;
110
+ z-index: 1;
111
+ }
112
+ .resizeHandle::after {
113
+ content: "";
114
+ position: absolute;
115
+ top: 0;
116
+ right: 3px;
117
+ bottom: 0;
118
+ width: 2px;
119
+ }
120
+ .resizeHandle:hover::after {
121
+ background-color: var(--ogrid-accent, #0078d4);
122
+ }
123
+ .resizeHandle:active::after {
124
+ background-color: var(--ogrid-accent-dark, #005a9e);
304
125
  }
305
126
 
306
- .selectableGrid :global .fui-DataGridBody .fui-DataGridRow:hover .fui-DataGridCell {
307
- background-color: var(--colorSubtleBackgroundHover, #f5f5f5);
308
- cursor: pointer;
127
+ .pinnedColLeft {
128
+ position: sticky;
129
+ z-index: 6;
130
+ background: var(--ogrid-bg, #ffffff);
309
131
  }
310
- .selectableGrid :global .fui-DataGridBody .fui-DataGridRow:hover.selectedRow .fui-DataGridCell {
311
- background-color: var(--colorNeutralBackground1Hover, #dae8f8) !important;
132
+ .pinnedColLeft::after {
133
+ content: "";
134
+ position: absolute;
135
+ top: -1px;
136
+ right: -4px;
137
+ bottom: -1px;
138
+ width: 4px;
139
+ background: linear-gradient(to right, var(--ogrid-pinned-shadow, rgba(0, 0, 0, 0.12)), transparent);
140
+ pointer-events: none;
312
141
  }
313
142
 
314
- .selectableGrid :global(.fui-DataGridBody .fui-DataGridRow) {
315
- cursor: pointer;
143
+ .pinnedColRight {
144
+ position: sticky;
145
+ z-index: 6;
146
+ background: var(--ogrid-bg, #ffffff);
147
+ }
148
+ .pinnedColRight::before {
149
+ content: "";
150
+ position: absolute;
151
+ top: -1px;
152
+ left: -4px;
153
+ bottom: -1px;
154
+ width: 4px;
155
+ background: linear-gradient(to left, var(--ogrid-pinned-shadow, rgba(0, 0, 0, 0.12)), transparent);
156
+ pointer-events: none;
157
+ }
158
+
159
+ .freezeColFirst {
160
+ position: sticky;
161
+ left: 0;
162
+ z-index: 6;
163
+ background: var(--ogrid-bg, #ffffff);
316
164
  }
317
165
 
318
166
  .cellContent {
@@ -320,7 +168,7 @@
320
168
  height: 100%;
321
169
  display: flex;
322
170
  align-items: center;
323
- padding: 4px 8px;
171
+ min-width: 0;
324
172
  box-sizing: border-box;
325
173
  overflow: hidden;
326
174
  text-overflow: ellipsis;
@@ -328,29 +176,33 @@
328
176
  user-select: none;
329
177
  outline: none;
330
178
  }
179
+ .cellContent:focus-visible {
180
+ outline: none;
181
+ }
331
182
 
332
183
  .activeCellContent {
333
- outline: 2px solid var(--ogrid-selection, #217346) !important;
184
+ outline: 2px solid var(--ogrid-selection-color, #217346);
334
185
  outline-offset: -1px;
335
186
  z-index: 2;
336
187
  position: relative;
337
188
  overflow: visible;
189
+ background: var(--ogrid-active-cell-bg, rgba(0, 0, 0, 0.02));
338
190
  }
339
191
 
340
192
  .cellInRange {
341
- background-color: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
193
+ background: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important;
342
194
  }
343
195
 
344
196
  :global([data-drag-range]) {
345
- background-color: var(--ogrid-bg-range, rgba(33, 115, 70, 0.12)) !important;
197
+ background: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important;
346
198
  }
347
199
 
348
200
  :global([data-drag-anchor]) {
349
- background-color: var(--colorNeutralBackground1, #fff) !important;
201
+ background: var(--ogrid-bg, #fff) !important;
350
202
  }
351
203
 
352
204
  .cellCut {
353
- background-color: var(--colorNeutralBackground1Hover, rgba(0, 0, 0, 0.04)) !important;
205
+ background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)) !important;
354
206
  opacity: 0.7;
355
207
  }
356
208
 
@@ -360,7 +212,7 @@
360
212
  bottom: -3px;
361
213
  width: 7px;
362
214
  height: 7px;
363
- background: var(--ogrid-selection, #217346);
215
+ background: var(--ogrid-selection-color, #217346);
364
216
  border: 1px solid var(--ogrid-bg, #fff);
365
217
  border-radius: 1px;
366
218
  cursor: crosshair;
@@ -368,74 +220,21 @@
368
220
  z-index: 3;
369
221
  }
370
222
 
371
- /* Freeze panes: sticky header when freezeRows >= 1 */
372
- .stickyHeader {
373
- /* Removed position: sticky; top: 0; - breaks horizontal sticky on pinned columns.
374
- Instead, apply sticky to individual header cells (.fui-DataGridHeaderCell). */
375
- z-index: 8;
376
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
377
- }
378
-
379
- /* Freeze panes: sticky first column(s) when freezeCols >= 1; only first column gets left: 0 (multi-column needs width measurement) */
380
- .freezeColFirst {
381
- position: sticky;
382
- left: 0;
383
- z-index: 6;
384
- background-color: var(--colorNeutralBackground1, #ffffff);
385
- will-change: transform;
386
- }
387
-
388
- :global(.fui-DataGridHeader) .freezeColFirst {
389
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
390
- }
391
-
392
- /* Freeze/pinned header cells need top: 0 + highest z-index so they stick in BOTH
393
- directions — left/right (from .freezeCol/.pinnedCell) AND top (from .stickyHeader).
394
- Without explicit top, the child's own position: sticky overrides the parent's. */
395
- .stickyHeader .freezeColFirst,
396
- .stickyHeader .pinnedLeft,
397
- .stickyHeader .pinnedRight {
398
- top: 0;
399
- z-index: 10; /* Increased from 9 to stack above base header cells (z-index: 8) */
400
- }
401
-
402
- .activeRow :global .fui-DataGridCell:not(:has(.activeCellContent)) {
403
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
404
- }
405
-
406
- .pinnedCell {
407
- position: sticky;
408
- z-index: 6;
409
- background-color: inherit;
410
- will-change: transform;
411
- }
412
-
413
- .pinnedLeft {
414
- left: 0;
415
- }
416
- .pinnedLeft::after {
417
- content: "";
418
- position: absolute;
419
- top: 0;
420
- right: -4px;
421
- bottom: 0;
422
- width: 4px;
423
- background: linear-gradient(to right, var(--ogrid-pinned-shadow, rgba(0, 0, 0, 0.12)), transparent);
424
- pointer-events: none;
223
+ .selectionHeaderCellInner,
224
+ .selectionCellInner {
225
+ display: flex;
226
+ align-items: center;
227
+ justify-content: center;
228
+ width: 100%;
425
229
  }
426
230
 
427
- .pinnedRight {
428
- right: 0;
429
- }
430
- .pinnedRight::before {
431
- content: "";
432
- position: absolute;
433
- top: 0;
434
- left: -4px;
435
- bottom: 0;
436
- width: 4px;
437
- background: linear-gradient(to left, var(--ogrid-pinned-shadow, rgba(0, 0, 0, 0.12)), transparent);
438
- pointer-events: none;
231
+ .rowNumberHeaderCellInner,
232
+ .rowNumberCellInner {
233
+ display: flex;
234
+ align-items: center;
235
+ justify-content: center;
236
+ width: 100%;
237
+ font-variant-numeric: tabular-nums;
439
238
  }
440
239
 
441
240
  .statusBar {
@@ -443,15 +242,13 @@
443
242
  align-items: center;
444
243
  gap: 16px;
445
244
  width: 100%;
446
- min-width: 0;
447
- box-sizing: border-box;
448
245
  padding: 6px 12px;
246
+ box-sizing: border-box;
449
247
  font-size: 12px;
450
- color: var(--colorNeutralForeground2, #616161);
451
- background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
452
- border-top: 1px solid var(--colorNeutralStroke2, #e0e0e0);
248
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
249
+ background: var(--ogrid-header-bg, #f5f5f5);
250
+ border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
453
251
  min-height: 28px;
454
- user-select: none;
455
252
  }
456
253
 
457
254
  .statusBarItem {
@@ -461,20 +258,18 @@
461
258
  }
462
259
  .statusBarItem:not(:last-child)::after {
463
260
  content: "";
464
- display: inline-block;
465
261
  width: 1px;
466
262
  height: 14px;
467
- background-color: var(--colorNeutralStroke1, #c4c4c4);
263
+ background: var(--ogrid-border, rgba(0, 0, 0, 0.12));
468
264
  margin-left: 12px;
469
265
  }
470
266
 
471
267
  .statusBarLabel {
472
- color: var(--colorNeutralForeground3, #707070);
473
- font-weight: 400;
268
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
474
269
  }
475
270
 
476
271
  .statusBarValue {
477
- color: var(--colorNeutralForeground1, #242424);
272
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
478
273
  font-weight: 600;
479
274
  }
480
275
 
@@ -483,11 +278,10 @@
483
278
  z-index: 10000;
484
279
  min-width: 160px;
485
280
  padding: 4px 0;
486
- background: var(--colorNeutralBackground1, #fff);
487
- border: 1px solid var(--colorNeutralStroke1, #e0e0e0);
488
- border-radius: var(--borderRadiusMedium, 4px);
489
- box-shadow: var(--shadow16, 0 4px 16px rgba(0, 0, 0, 0.12));
490
- outline: none;
281
+ background: var(--ogrid-bg, #fff);
282
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
283
+ border-radius: 6px;
284
+ box-shadow: var(--ogrid-shadow, 0 4px 16px rgba(0, 0, 0, 0.12));
491
285
  }
492
286
 
493
287
  .contextMenuItem {
@@ -502,10 +296,10 @@
502
296
  font-size: 13px;
503
297
  text-align: left;
504
298
  cursor: pointer;
505
- color: var(--colorNeutralForeground1, #242424);
299
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
506
300
  }
507
301
  .contextMenuItem:hover:not(:disabled) {
508
- background-color: var(--colorSubtleBackgroundHover, #f5f5f5);
302
+ background: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04));
509
303
  }
510
304
  .contextMenuItem:disabled {
511
305
  opacity: 0.5;
@@ -517,14 +311,14 @@
517
311
  }
518
312
 
519
313
  .contextMenuItemShortcut {
520
- color: var(--colorNeutralForeground3, rgba(0, 0, 0, 0.4));
314
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
521
315
  font-size: 0.85em;
522
316
  }
523
317
 
524
318
  .contextMenuDivider {
525
319
  height: 1px;
526
320
  margin: 4px 0;
527
- background-color: var(--colorNeutralStroke2, #e0e0e0);
321
+ background: var(--ogrid-border, rgba(0, 0, 0, 0.12));
528
322
  }
529
323
 
530
324
  .loadingOverlay {
@@ -534,7 +328,7 @@
534
328
  display: flex;
535
329
  align-items: center;
536
330
  justify-content: center;
537
- background: var(--ogrid-loading-bg, rgba(255, 255, 255, 0.7));
331
+ background: var(--ogrid-loading-overlay, rgba(255, 255, 255, 0.7));
538
332
  backdrop-filter: blur(1px);
539
333
  pointer-events: all;
540
334
  }
@@ -545,22 +339,21 @@
545
339
  align-items: center;
546
340
  gap: 8px;
547
341
  padding: 16px 24px;
548
- background: var(--colorNeutralBackground1, #ffffff);
549
- border: 1px solid var(--colorNeutralStroke1, #c4c4c4);
550
- border-radius: var(--borderRadiusMedium, 4px);
551
- box-shadow: var(--shadow4, 0 2px 4px rgba(0, 0, 0, 0.14));
342
+ background: var(--ogrid-bg, #fff);
343
+ border: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
344
+ border-radius: 6px;
345
+ box-shadow: var(--ogrid-shadow-sm, 0 2px 4px rgba(0, 0, 0, 0.08));
552
346
  }
553
347
 
554
348
  .loadingOverlayText {
555
349
  font-size: 13px;
556
350
  font-weight: 500;
557
- color: var(--colorNeutralForeground2, #616161);
351
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
558
352
  }
559
353
 
560
354
  .loadingDimmed {
561
355
  opacity: 0.6;
562
356
  pointer-events: none;
563
- transition: opacity 0.15s ease;
564
357
  }
565
358
 
566
359
  .emptyStateInGrid {
@@ -571,47 +364,29 @@
571
364
  text-align: center;
572
365
  padding: 20px 16px;
573
366
  min-height: 88px;
574
- min-width: 0;
575
367
  width: 100%;
576
368
  box-sizing: border-box;
577
- border-top: 1px solid var(--colorNeutralStroke2, #e0e0e0);
578
- background-color: var(--colorNeutralBackground2, #fafafa);
579
- }
580
-
581
- .emptyStateInGridMessageSticky {
582
- position: sticky;
583
- left: 50%;
584
- transform: translateX(-50%);
585
- display: inline-flex;
586
- flex-direction: column;
587
- align-items: center;
588
- text-align: center;
589
- }
590
-
591
- .emptyStateInGridIcon {
592
- font-size: 24px;
593
- margin-bottom: 8px;
594
- opacity: 0.6;
369
+ border-top: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
370
+ background: var(--ogrid-header-bg, #f5f5f5);
595
371
  }
596
372
 
597
373
  .emptyStateInGridTitle {
598
374
  font-size: 14px;
599
375
  font-weight: 600;
600
- color: var(--colorNeutralForeground1, #242424);
376
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
601
377
  margin-bottom: 4px;
602
378
  }
603
379
 
604
380
  .emptyStateInGridMessage {
605
381
  font-size: 13px;
606
- color: var(--colorNeutralForeground2, #616161);
607
- max-width: 100%;
382
+ color: var(--ogrid-fg-muted, rgba(0, 0, 0, 0.5));
608
383
  line-height: 1.5;
609
384
  }
610
385
 
611
386
  .emptyStateInGridLink {
612
387
  background: none;
613
388
  border: none;
614
- color: var(--colorBrandForeground1, #0f6cbd);
389
+ color: var(--ogrid-accent, #0078d4);
615
390
  text-decoration: underline;
616
391
  cursor: pointer;
617
392
  padding: 0;
@@ -619,53 +394,288 @@
619
394
  font-family: inherit;
620
395
  }
621
396
  .emptyStateInGridLink:hover {
622
- color: var(--colorBrandForeground1Hover, #115ea3);
397
+ color: var(--ogrid-accent-dark, #005a9e);
398
+ }
399
+
400
+ .spinner {
401
+ width: 24px;
402
+ height: 24px;
403
+ border: 2px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
404
+ border-top-color: var(--ogrid-accent, #0078d4);
405
+ border-radius: 50%;
406
+ animation: ogrid-spin 0.8s linear infinite;
407
+ }
408
+
409
+ @keyframes ogrid-spin {
410
+ to {
411
+ transform: rotate(360deg);
412
+ }
413
+ }
414
+ /* ─── OGrid Theme Variables ─── */
415
+ /* Bridge Fluent UI tokens -> ogrid CSS variables so headless components (SideBar, etc.)
416
+ automatically follow the active FluentProvider theme (light or dark). */
417
+ :global(:root) {
418
+ --ogrid-bg: #ffffff;
419
+ --ogrid-fg: rgba(0, 0, 0, 0.87);
420
+ --ogrid-fg-secondary: rgba(0, 0, 0, 0.6);
421
+ --ogrid-fg-muted: rgba(0, 0, 0, 0.5);
422
+ --ogrid-border: rgba(0, 0, 0, 0.12);
423
+ --ogrid-header-bg: #f3f2f1;
424
+ --ogrid-hover-bg: rgba(0, 0, 0, 0.04);
425
+ --ogrid-selected-row-bg: #e6f0fb;
426
+ --ogrid-active-cell-bg: rgba(0, 0, 0, 0.02);
427
+ --ogrid-range-bg: rgba(33, 115, 70, 0.12);
428
+ --ogrid-accent: #0078d4;
429
+ --ogrid-selection-color: #217346;
430
+ --ogrid-loading-overlay: rgba(255, 255, 255, 0.7);
431
+ }
432
+
433
+ /* Page-level dark mode (for body background, non-FluentProvider elements) */
434
+ :global([data-theme="dark"]) {
435
+ --ogrid-bg: #1b1b1f;
436
+ --ogrid-fg: rgba(255, 255, 255, 0.87);
437
+ --ogrid-fg-secondary: rgba(255, 255, 255, 0.6);
438
+ --ogrid-fg-muted: rgba(255, 255, 255, 0.5);
439
+ --ogrid-border: rgba(255, 255, 255, 0.12);
440
+ --ogrid-header-bg: #2c2c2c;
441
+ --ogrid-hover-bg: rgba(255, 255, 255, 0.06);
442
+ --ogrid-selected-row-bg: #1a3a5c;
443
+ --ogrid-active-cell-bg: rgba(255, 255, 255, 0.04);
444
+ --ogrid-range-bg: rgba(33, 115, 70, 0.2);
445
+ --ogrid-accent: #4da6ff;
446
+ --ogrid-selection-color: #217346;
447
+ --ogrid-loading-overlay: rgba(0, 0, 0, 0.5);
448
+ }
449
+
450
+ /* Inside FluentProvider: derive --ogrid-* from Fluent tokens so light/dark follows automatically */
451
+ :global(.fui-FluentProvider) {
452
+ --ogrid-bg: var(--colorNeutralBackground1, #ffffff);
453
+ --ogrid-fg: var(--colorNeutralForeground1, rgba(0, 0, 0, 0.87));
454
+ --ogrid-fg-secondary: var(--colorNeutralForeground2, rgba(0, 0, 0, 0.6));
455
+ --ogrid-fg-muted: var(--colorNeutralForeground3, rgba(0, 0, 0, 0.5));
456
+ --ogrid-border: var(--colorNeutralStroke2, rgba(0, 0, 0, 0.12));
457
+ --ogrid-header-bg: var(--colorSubtleBackgroundSelected, #f3f2f1);
458
+ --ogrid-hover-bg: var(--colorSubtleBackgroundHover, rgba(0, 0, 0, 0.04));
459
+ --ogrid-selected-row-bg: var(--colorNeutralBackground1Selected, #e6f0fb);
460
+ --ogrid-active-cell-bg: rgba(0, 0, 0, 0.02);
461
+ --ogrid-range-bg: rgba(33, 115, 70, 0.12);
462
+ --ogrid-accent: var(--colorBrandForeground1, #0078d4);
463
+ --ogrid-selection-color: #217346;
464
+ --ogrid-loading-overlay: rgba(255, 255, 255, 0.7);
623
465
  }
624
466
 
625
- /* Column reorder drop indicator */
626
- .dropIndicator {
627
- position: absolute;
467
+ .tableScrollContent {
468
+ min-height: 100%;
469
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
470
+ }
471
+
472
+ .tableWidthAnchor {
473
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
474
+ }
475
+
476
+ .tableWrapper {
477
+ border: none;
478
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
479
+ -webkit-overflow-scrolling: touch;
480
+ outline: none;
481
+ }
482
+
483
+ .dataTable {
484
+ table-layout: auto !important;
485
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
486
+ }
487
+
488
+ .dataTable :global(.fui-TableHeaderCell),
489
+ .dataTable :global(.fui-TableCell) {
490
+ min-width: 80px;
491
+ box-sizing: border-box;
492
+ border-right: 1px solid var(--colorNeutralStroke1, #c4c4c4);
493
+ font-size: 13px;
494
+ vertical-align: middle;
495
+ }
496
+
497
+ .dataTable :global(.fui-TableHeaderCell) {
498
+ padding: 6px 10px;
499
+ font-weight: 600;
500
+ font-size: 14px;
501
+ color: var(--ogrid-fg, rgba(0, 0, 0, 0.87));
502
+ white-space: nowrap;
503
+ position: sticky;
628
504
  top: 0;
629
- bottom: 0;
630
- width: 3px;
631
- background: var(--ogrid-primary, #217346);
632
- pointer-events: none;
633
- z-index: 100;
634
- transition: left 0.05s;
505
+ background-color: var(--colorSubtleBackgroundSelected, var(--ogrid-header-bg, #f3f2f1));
506
+ z-index: 8;
507
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
508
+ }
509
+ .dataTable :global(.fui-TableHeaderCell) > :global(.fui-TableHeaderCell__button) {
510
+ position: static !important;
511
+ }
512
+ .dataTable :global(.fui-TableHeaderCell):focus-visible {
513
+ outline: 2px solid var(--colorBrandStroke1, var(--ogrid-accent, #0078d4));
514
+ outline-offset: -2px;
515
+ z-index: 11;
635
516
  }
636
517
 
637
- /* Empty state: hide body, keep header and empty message */
638
- .tableWrapper[data-empty=true] :global(.fui-DataGrid) tbody {
639
- display: none;
518
+ .dataTable :global(.fui-TableCell) {
519
+ padding: 0;
520
+ overflow: hidden;
521
+ text-overflow: ellipsis;
522
+ white-space: nowrap;
523
+ font-size: 12px;
524
+ height: 1px;
525
+ border-right: 1px solid var(--colorNeutralStroke1, #c4c4c4);
526
+ position: relative;
527
+ border-bottom: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
528
+ /* Prevent long unbroken content from forcing intrinsic widths / overlap */
529
+ }
530
+ .dataTable :global(.fui-TableCell) > * {
531
+ min-width: 0;
532
+ }
533
+ .dataTable :global(.fui-TableCell):focus-visible {
534
+ outline: none;
640
535
  }
641
536
 
642
- /* Empty state: no extra bottom border (header row is last row, remove its border-bottom) */
643
- .tableWrapper[data-empty=true] :global(.fui-DataGridHeader .fui-DataGridRow) {
644
- border-bottom: none !important;
537
+ /* No extra right border on last column */
538
+ .dataTable :global(.fui-TableHeaderCell:last-of-type),
539
+ .dataTable :global(.fui-TableCell:last-of-type) {
540
+ border-right: none;
645
541
  }
646
542
 
647
- .headerCellContent {
648
- display: flex;
649
- align-items: center;
650
- gap: 4px;
543
+ /* No extra bottom border on last row */
544
+ .dataTable :global(.fui-TableBody .fui-TableRow:last-child .fui-TableCell) {
545
+ border-bottom: none;
651
546
  }
652
547
 
653
- .headerMenuTrigger {
654
- background: transparent;
655
- border: none;
548
+ /* Row hover */
549
+ .dataTable :global(.fui-TableBody .fui-TableRow:hover .fui-TableCell) {
550
+ background-color: var(--colorSubtleBackgroundHover, var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)));
551
+ }
552
+
553
+ .leafHeaderCellSpan {
554
+ font-weight: 600;
555
+ padding: 6px 10px;
556
+ background: var(--ogrid-header-bg, #f3f2f1);
557
+ }
558
+
559
+ .selectionHeaderCellWrapper {
560
+ width: 48px;
561
+ min-width: 48px;
562
+ max-width: 48px;
563
+ padding: 4px !important;
564
+ text-align: center;
565
+ }
566
+
567
+ .selectionCellWrapper {
568
+ width: 48px;
569
+ min-width: 48px;
570
+ max-width: 48px;
571
+ padding: 4px !important;
572
+ text-align: center;
573
+ }
574
+
575
+ .rowNumberHeaderCellWrapper {
576
+ width: 50px;
577
+ min-width: 50px;
578
+ max-width: 50px;
579
+ padding: 4px 8px !important;
580
+ text-align: center;
581
+ background: var(--ogrid-header-bg, #f5f5f5);
582
+ font-weight: 600;
583
+ color: var(--colorNeutralForeground3, #666);
584
+ border-right: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
585
+ }
586
+
587
+ .rowNumberCellWrapper {
588
+ width: 50px;
589
+ min-width: 50px;
590
+ max-width: 50px;
591
+ padding: 4px 8px !important;
592
+ text-align: center;
593
+ background: var(--colorNeutralBackground3, #f5f5f5);
594
+ font-weight: 600;
595
+ color: var(--colorNeutralForeground3, #666);
596
+ border-right: 1px solid var(--ogrid-border, rgba(0, 0, 0, 0.12));
597
+ }
598
+
599
+ .dataTable :global(.fui-TableBody) .selectedRow :global(.fui-TableCell) {
600
+ background-color: var(--colorNeutralBackground1Selected, var(--ogrid-selected-row-bg, #e6f0fb));
601
+ }
602
+
603
+ .selectableGrid .dataTable :global(.fui-TableBody .fui-TableRow:hover .fui-TableCell) {
604
+ background-color: var(--colorSubtleBackgroundHover, #f5f5f5);
656
605
  cursor: pointer;
657
- padding: 2px 4px;
658
- font-size: 16px;
659
- line-height: 1;
606
+ }
607
+
608
+ .selectableGrid .dataTable :global(.fui-TableBody) .selectedRow:hover :global(.fui-TableCell) {
609
+ background-color: var(--colorNeutralBackground1Hover, #dae8f8);
610
+ }
611
+
612
+ .selectableGrid .dataTable :global(.fui-TableBody .fui-TableRow) {
613
+ cursor: pointer;
614
+ }
615
+
616
+ .cellContent {
617
+ padding: 4px 8px;
618
+ }
619
+
620
+ .activeCellContent {
621
+ outline: 2px solid var(--ogrid-selection-color, #217346) !important;
622
+ background-color: var(--ogrid-active-cell-bg, rgba(0, 0, 0, 0.02)) !important;
623
+ }
624
+
625
+ .cellInRange {
626
+ background-color: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important;
627
+ }
628
+
629
+ :global([data-drag-range]) {
630
+ background-color: var(--ogrid-range-bg, rgba(33, 115, 70, 0.12)) !important;
631
+ }
632
+
633
+ :global([data-drag-anchor]) {
634
+ background-color: var(--ogrid-bg, #ffffff) !important;
635
+ }
636
+
637
+ .cellCut {
638
+ background-color: var(--ogrid-hover-bg, rgba(0, 0, 0, 0.04)) !important;
639
+ }
640
+
641
+ .stickyHeader {
642
+ z-index: 8;
643
+ background-color: var(--colorSubtleBackgroundSelected, var(--ogrid-header-bg, #f3f2f1));
644
+ }
645
+
646
+ .freezeColFirst {
647
+ background-color: var(--colorNeutralBackground1, #ffffff);
648
+ }
649
+
650
+ .dataTable :global(.fui-TableHeader) .freezeColFirst {
651
+ background-color: var(--colorSubtleBackgroundSelected, var(--ogrid-header-bg, #f3f2f1));
652
+ }
653
+
654
+ .stickyHeader .freezeColFirst,
655
+ .stickyHeader .pinnedColLeft,
656
+ .stickyHeader .pinnedColRight {
657
+ top: 0;
658
+ z-index: 10;
659
+ }
660
+
661
+ .dataTable .pinnedColLeft {
662
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
663
+ }
664
+
665
+ .dataTable :global(.fui-TableHeader) .pinnedColLeft {
666
+ background-color: var(--colorSubtleBackgroundSelected, var(--ogrid-header-bg, #f3f2f1));
667
+ }
668
+
669
+ .dataTable .pinnedColRight {
670
+ background-color: var(--colorNeutralBackground1, var(--ogrid-bg, #ffffff));
671
+ }
672
+
673
+ .dataTable :global(.fui-TableHeader) .pinnedColRight {
674
+ background-color: var(--colorSubtleBackgroundSelected, var(--ogrid-header-bg, #f3f2f1));
675
+ }
676
+
677
+ .headerMenuTrigger {
660
678
  color: var(--colorNeutralForeground3, #666);
661
- opacity: 1;
662
- transition: background-color 0.15s;
663
- border-radius: 3px;
664
- display: flex;
665
- align-items: center;
666
- justify-content: center;
667
- min-width: 20px;
668
- height: 20px;
669
679
  }
670
680
  .headerMenuTrigger:hover {
671
681
  background: var(--colorNeutralBackground1Hover, #f3f2f1);
@@ -673,27 +683,138 @@
673
683
  .headerMenuTrigger:active {
674
684
  background: var(--colorNeutralBackground1Pressed, #e1dfdd);
675
685
  }
686
+ .headerMenuTrigger:focus-visible {
687
+ outline: 2px solid var(--colorBrandStroke1, var(--ogrid-accent, #0078d4));
688
+ }
676
689
 
677
- .tableWrapper :global(.fui-DataGridHeaderCell.pinnedColLeft),
678
- .tableWrapper :global(.fui-DataGridCell.pinnedColLeft) {
679
- border-left: 2px solid var(--colorBrandForeground1, #0078d4) !important;
690
+ /* Column resize handle -- Fluent token override */
691
+ .resizeHandle:hover::after {
692
+ background-color: var(--colorBrandForeground1, var(--ogrid-accent, #0078d4));
693
+ }
694
+ .resizeHandle:active::after {
695
+ background-color: var(--colorBrandForeground1Pressed, #005a9e);
680
696
  }
681
697
 
682
- .tableWrapper :global(.fui-DataGridHeaderCell.pinnedColRight),
683
- .tableWrapper :global(.fui-DataGridCell.pinnedColRight) {
684
- border-right: 2px solid var(--colorBrandForeground1, #0078d4) !important;
698
+ .statusBar {
699
+ min-width: 0;
700
+ color: var(--colorNeutralForeground2, #616161);
701
+ background-color: var(--colorSubtleBackgroundSelected, #f3f2f1);
702
+ border-top: 1px solid var(--colorNeutralStroke2, #e0e0e0);
703
+ user-select: none;
685
704
  }
686
705
 
687
- .density-compact :global(.fui-DataGridHeaderCell),
688
- .density-compact :global(.fui-DataGridCell) {
706
+ .statusBarItem:not(:last-child)::after {
707
+ display: inline-block;
708
+ background-color: var(--colorNeutralStroke1, #c4c4c4);
709
+ }
710
+
711
+ .statusBarLabel {
712
+ color: var(--colorNeutralForeground3, #707070);
713
+ font-weight: 400;
714
+ }
715
+
716
+ .statusBarValue {
717
+ color: var(--colorNeutralForeground1, #242424);
718
+ }
719
+
720
+ .contextMenu {
721
+ background: var(--colorNeutralBackground1, #fff);
722
+ border: 1px solid var(--colorNeutralStroke1, #e0e0e0);
723
+ border-radius: var(--borderRadiusMedium, 4px);
724
+ box-shadow: var(--shadow16, 0 4px 16px rgba(0, 0, 0, 0.12));
725
+ outline: none;
726
+ }
727
+
728
+ .contextMenuItem {
729
+ color: var(--colorNeutralForeground1, #242424);
730
+ }
731
+ .contextMenuItem:hover:not(:disabled) {
732
+ background-color: var(--colorSubtleBackgroundHover, #f5f5f5);
733
+ }
734
+
735
+ .contextMenuItemShortcut {
736
+ color: var(--colorNeutralForeground3, rgba(0, 0, 0, 0.4));
737
+ }
738
+
739
+ .contextMenuDivider {
740
+ background-color: var(--colorNeutralStroke2, #e0e0e0);
741
+ }
742
+
743
+ .loadingOverlayContent {
744
+ background: var(--colorNeutralBackground1, #ffffff);
745
+ border: 1px solid var(--colorNeutralStroke1, #c4c4c4);
746
+ border-radius: var(--borderRadiusMedium, 4px);
747
+ box-shadow: var(--shadow4, 0 2px 4px rgba(0, 0, 0, 0.14));
748
+ }
749
+
750
+ .loadingOverlayText {
751
+ color: var(--colorNeutralForeground2, #616161);
752
+ }
753
+
754
+ .loadingDimmed {
755
+ transition: opacity 0.15s ease;
756
+ }
757
+
758
+ .emptyStateInGrid {
759
+ min-width: 0;
760
+ border-top: 1px solid var(--colorNeutralStroke2, #e0e0e0);
761
+ background-color: var(--colorNeutralBackground2, #fafafa);
762
+ }
763
+
764
+ .emptyStateInGridMessageSticky {
765
+ position: sticky;
766
+ left: 50%;
767
+ transform: translateX(-50%);
768
+ display: inline-flex;
769
+ flex-direction: column;
770
+ align-items: center;
771
+ text-align: center;
772
+ }
773
+
774
+ .emptyStateInGridIcon {
775
+ font-size: 24px;
776
+ margin-bottom: 8px;
777
+ opacity: 0.6;
778
+ }
779
+
780
+ .emptyStateInGridTitle {
781
+ color: var(--colorNeutralForeground1, #242424);
782
+ }
783
+
784
+ .emptyStateInGridMessage {
785
+ color: var(--colorNeutralForeground2, #616161);
786
+ max-width: 100%;
787
+ }
788
+
789
+ .emptyStateInGridLink {
790
+ color: var(--colorBrandForeground1, #0f6cbd);
791
+ }
792
+ .emptyStateInGridLink:hover {
793
+ color: var(--colorBrandForeground1Hover, #115ea3);
794
+ }
795
+
796
+ /* Fluent Link styling within grid */
797
+ .dataTable :global(.fui-Link) {
798
+ color: var(--colorBrandForeground1, #0f6cbd);
799
+ font-weight: 600;
800
+ text-decoration: none;
801
+ }
802
+ .dataTable :global(.fui-Link):hover {
803
+ text-decoration: underline;
804
+ color: var(--colorBrandForeground1Hover, #115ea3);
805
+ }
806
+ .dataTable :global(.fui-Link):active {
807
+ color: var(--colorBrandForeground1Pressed, #0c3b5e);
808
+ }
809
+
810
+ .density-compact .dataTable :global(.fui-TableHeaderCell) {
689
811
  padding: 4px 8px;
690
812
  }
691
813
  .density-compact .cellContent {
692
814
  padding: 4px 8px;
693
815
  }
694
816
 
695
- .density-comfortable :global(.fui-DataGridHeaderCell),
696
- .density-comfortable :global(.fui-DataGridCell) {
817
+ .density-comfortable .dataTable :global(.fui-TableHeaderCell) {
697
818
  padding: 12px 16px;
698
819
  }
699
820
  .density-comfortable .cellContent {
@@ -701,12 +822,6 @@
701
822
  }
702
823
 
703
824
  /* ─── Accessibility: Focus Visible Styles ─────────────────────── */
704
- .tableWrapper :global .fui-DataGridHeaderCell:focus-visible,
705
- .tableWrapper :global .fui-DataGridCell:focus-visible {
706
- outline: 2px solid var(--colorBrandStroke1, #0078d4);
707
- outline-offset: -2px;
708
- z-index: 11;
709
- }
710
825
  .tableWrapper :global .fui-Button:focus-visible,
711
826
  .tableWrapper :global .fui-MenuButton:focus-visible {
712
827
  outline: 2px solid var(--colorBrandStroke1, #0078d4);
@@ -715,10 +830,4 @@
715
830
  .tableWrapper :global .fui-Checkbox:focus-visible {
716
831
  outline: 2px solid var(--colorBrandStroke1, #0078d4);
717
832
  outline-offset: 2px;
718
- }
719
-
720
- .cellContent:focus-visible {
721
- outline: 2px solid var(--colorBrandStroke1, #0078d4);
722
- outline-offset: -2px;
723
- z-index: 3;
724
833
  }