@alaarab/ogrid-react-fluent 2.0.11 → 2.0.13

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