@ngx-stoui/core 21.0.10 → 21.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.
- package/ngx-stoui.css +5 -5
- package/package.json +1 -1
- package/styles/toolbox-grid/_toolbox-grid.scss +460 -39
- package/toolbox-grid.css +596 -80
package/ngx-stoui.css
CHANGED
|
@@ -2414,8 +2414,8 @@ span.sortable {
|
|
|
2414
2414
|
--mat-badge-background-color: var(--primary-highlight);
|
|
2415
2415
|
--mat-badge-container-overlap-offset: -1rem -0.9rem;
|
|
2416
2416
|
--mat-badge-container-padding: 0.3rem;
|
|
2417
|
-
--mat-badge-container-shape:
|
|
2418
|
-
--mat-badge-container-size: 1.
|
|
2417
|
+
--mat-badge-container-shape: 50%;
|
|
2418
|
+
--mat-badge-container-size: 1.5rem;
|
|
2419
2419
|
--mat-badge-text-color: var(--primary-resting);
|
|
2420
2420
|
--mat-button-filled-container-shape: var(--mat-sys-corner-small);
|
|
2421
2421
|
--mat-button-outlined-container-shape: var(--mat-sys-corner-small);
|
|
@@ -3134,7 +3134,7 @@ div.mat-primary {
|
|
|
3134
3134
|
}
|
|
3135
3135
|
|
|
3136
3136
|
.mat-accent {
|
|
3137
|
-
--message-panel-bg: var(--accent-
|
|
3137
|
+
--message-panel-bg: var(--accent-highlight);
|
|
3138
3138
|
--message-panel-color: var(--accent-resting-contrast);
|
|
3139
3139
|
--message-panel-border: var(--accent-resting);
|
|
3140
3140
|
--message-panel-icon: var(--accent-resting);
|
|
@@ -3214,8 +3214,8 @@ h6.mat-accent {
|
|
|
3214
3214
|
}
|
|
3215
3215
|
|
|
3216
3216
|
div.mat-accent {
|
|
3217
|
-
background-color: var(--accent-
|
|
3218
|
-
color: var(--accent-
|
|
3217
|
+
background-color: var(--accent-highlight);
|
|
3218
|
+
color: var(--accent-highlight-contrast);
|
|
3219
3219
|
}
|
|
3220
3220
|
|
|
3221
3221
|
.mat-warn {
|
package/package.json
CHANGED
|
@@ -1,15 +1,43 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* EDS (Equinor Design System) Theme for @toolbox-web/grid
|
|
3
3
|
*
|
|
4
|
-
* Styles the toolbox grid to match Equinor's design system.
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Styles the toolbox grid to match Equinor's design system. Shared by
|
|
5
|
+
* Angular consumers (cargo-tracker-apps via `@ngx-stoui/core/toolbox-grid.css`)
|
|
6
|
+
* and React consumers (planning Roma app).
|
|
7
|
+
*
|
|
8
|
+
* Both `<tbw-grid>` (web component) and `<div data-tbw-grid>` are supported
|
|
9
|
+
* so React apps that don't import the web component can still opt in to the
|
|
10
|
+
* theme by stamping the attribute on a wrapper.
|
|
11
|
+
*
|
|
12
|
+
* Supports light/dark modes via the light-dark() CSS function. Consumers that
|
|
13
|
+
* don't support dark mode (e.g. Roma) can opt out with `color-scheme: light only`
|
|
14
|
+
* on their root.
|
|
15
|
+
*
|
|
16
|
+
* In-cell editor coexistence:
|
|
17
|
+
* - Angular: Material form fields (`.mat-mdc-*`) — chrome is stripped so the
|
|
18
|
+
* surrounding `.tbw-editor-host` paints the visual boundary.
|
|
19
|
+
* - React/EDS: native EDS `<DatePicker>` / `<Autocomplete>` wrapped with
|
|
20
|
+
* `.tbw-eds-date-editor` / `.tbw-eds-autocomplete-editor` marker classes.
|
|
7
21
|
*
|
|
8
22
|
* Reference: https://eds.equinor.com/
|
|
9
23
|
* Grid Theming: https://toolboxjs.com/?path=/docs/grid-theming--docs
|
|
10
24
|
* Requires @toolbox-web/grid v1.3.1+
|
|
11
25
|
*
|
|
12
|
-
* Usage:
|
|
26
|
+
* Usage:
|
|
27
|
+
* Angular: "@ngx-stoui/core/toolbox-grid.css" in project.json styles array
|
|
28
|
+
* React: import the compiled css, or @use this partial in a Sass entry
|
|
29
|
+
*
|
|
30
|
+
* Sections:
|
|
31
|
+
* 1. Theme Variables
|
|
32
|
+
* 2. Grid Styles (cells, editors, Material stripping, anchors, Typography reset)
|
|
33
|
+
* 3. Pinned cells & sticky group rows
|
|
34
|
+
* 4. Filter Panel
|
|
35
|
+
* 5. Context Menu
|
|
36
|
+
* 6. Overlay Panel
|
|
37
|
+
* 7. EDS in-cell editors (DatePicker / Autocomplete)
|
|
38
|
+
* 8. Empty State Overlay
|
|
39
|
+
* 9. Opt-ins (compact mode, thin header)
|
|
40
|
+
* 10. Dark Mode
|
|
13
41
|
*/
|
|
14
42
|
|
|
15
43
|
/* ================================================================
|
|
@@ -22,6 +50,7 @@
|
|
|
22
50
|
* rendered in document.body, so these variables cascade properly.
|
|
23
51
|
* ================================================================ */
|
|
24
52
|
tbw-grid,
|
|
53
|
+
[data-tbw-grid],
|
|
25
54
|
.tbw-filter-panel {
|
|
26
55
|
/* --- EDS Token Aliases (cascade to all children) --- */
|
|
27
56
|
--_bg: var(--eds_ui_background__default, light-dark(#ffffff, #132634));
|
|
@@ -52,6 +81,7 @@ tbw-grid,
|
|
|
52
81
|
--tbw-font-size: var(--sto-base-font-size, 13px);
|
|
53
82
|
--tbw-font-size-header: var(--sto-base-font-size, 13px);
|
|
54
83
|
--tbw-font-weight-header: 700;
|
|
84
|
+
--tbw-aggregation-font-size: 0.9em;
|
|
55
85
|
|
|
56
86
|
/* --- Colors --- */
|
|
57
87
|
--tbw-color-bg: var(--_bg);
|
|
@@ -108,9 +138,16 @@ tbw-grid,
|
|
|
108
138
|
--tbw-cell-padding-header: 0 var(--eds_spacing_medium, 8px);
|
|
109
139
|
--tbw-button-padding: 0.375rem 0.625rem;
|
|
110
140
|
|
|
111
|
-
/* --- Focus ---
|
|
141
|
+
/* --- Focus ---
|
|
142
|
+
`--tbw-focus-outline` paints the focus ring; the grid applies
|
|
143
|
+
`--tbw-focus-background` as the cell tint when a cell has focus. Use an
|
|
144
|
+
alpha-blended accent so the grid's own `.cell-focus` rule produces the
|
|
145
|
+
soft tint we want — no element-targeting needed. Pinned cells need a
|
|
146
|
+
pre-composited override (see section 3) because alpha over a sticky
|
|
147
|
+
opaque panel-bg would bleed scrolling content through. */
|
|
112
148
|
--tbw-focus-outline: 0.5px dotted var(--_focus);
|
|
113
149
|
--tbw-focus-outline-offset: -1px;
|
|
150
|
+
--tbw-focus-background: rgba(from var(--_accent) r g b / 8%);
|
|
114
151
|
|
|
115
152
|
/* --- Resize Handle --- */
|
|
116
153
|
--tbw-resize-handle-color: transparent;
|
|
@@ -134,9 +171,12 @@ tbw-grid,
|
|
|
134
171
|
rgba(0, 0, 0, 0.15),
|
|
135
172
|
rgba(0, 0, 0, 0.4)
|
|
136
173
|
);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
174
|
+
/* Filter inputs: EDS underline style. Strip the grid's default border
|
|
175
|
+
and radius via variables; the underline box-shadow itself (no variable)
|
|
176
|
+
is applied in section 4. */
|
|
177
|
+
--tbw-filter-input-bg: var(--_surface);
|
|
178
|
+
--tbw-filter-input-border: none;
|
|
179
|
+
--tbw-filter-input-radius: 0;
|
|
140
180
|
--tbw-filter-input-focus: var(--_focus);
|
|
141
181
|
--tbw-filter-accent: var(--_accent);
|
|
142
182
|
--tbw-filter-accent-fg: var(--_accent-fg);
|
|
@@ -161,16 +201,13 @@ tbw-grid,
|
|
|
161
201
|
/* ================================================================
|
|
162
202
|
* 2. Grid Styles
|
|
163
203
|
*
|
|
164
|
-
* All
|
|
165
|
-
*
|
|
204
|
+
* All grid-scoped rules: cell styling, editor hosts, anchors,
|
|
205
|
+
* Typography reset, and Angular Material overrides.
|
|
206
|
+
*
|
|
207
|
+
* Compact mode and thin-header opt-ins live in section 9.
|
|
166
208
|
* ================================================================ */
|
|
167
|
-
tbw-grid
|
|
168
|
-
|
|
169
|
-
&.eds-compact {
|
|
170
|
-
--tbw-row-height: calc(var(--sto-base-font-size, 13px) * 1.385);
|
|
171
|
-
--tbw-header-height: calc(var(--sto-base-font-size, 13px) * 1.769);
|
|
172
|
-
}
|
|
173
|
-
|
|
209
|
+
tbw-grid,
|
|
210
|
+
[data-tbw-grid] {
|
|
174
211
|
/* --- Angular Material overrides for in-grid editors --- */
|
|
175
212
|
--mat-checkbox-state-layer-size: 20px;
|
|
176
213
|
--mdc-filled-text-field-container-color: transparent;
|
|
@@ -204,33 +241,78 @@ tbw-grid {
|
|
|
204
241
|
line-height: 1em;
|
|
205
242
|
}
|
|
206
243
|
|
|
244
|
+
/* Anchor tags rendered inside cells (e.g. deep-link cells) should read
|
|
245
|
+
in the same color as plain text cells. Browser UA / EDS `Typography`
|
|
246
|
+
would otherwise paint them blue/teal. Underline is preserved
|
|
247
|
+
(we only override `color`). */
|
|
248
|
+
& .cell a {
|
|
249
|
+
color: var(--_fg);
|
|
250
|
+
}
|
|
251
|
+
|
|
207
252
|
/* --- Numeric alignment --- */
|
|
208
253
|
& .cell[data-type='number'] {
|
|
209
254
|
text-align: right;
|
|
210
255
|
}
|
|
211
256
|
|
|
212
|
-
/* --- Data cell styling & editor host ---
|
|
257
|
+
/* --- Data cell styling & editor host ---
|
|
258
|
+
The grid already paints `height: var(--tbw-row-height)` and
|
|
259
|
+
`background: var(--tbw-focus-background)` on focused cells from its own
|
|
260
|
+
base layer, so we only add what the grid doesn't expose as a variable:
|
|
261
|
+
`font-weight` on cells, the sticky-cell focus override, and editor-host
|
|
262
|
+
chrome (which lives on our `.tbw-editor-host` wrapper, not on a built-in
|
|
263
|
+
grid class). */
|
|
213
264
|
& [part='cell'],
|
|
214
265
|
& .data-grid-row .cell {
|
|
215
266
|
font-weight: 500;
|
|
216
|
-
|
|
267
|
+
|
|
268
|
+
/* Neutralize EDS `<Typography>` when used inside custom cell renderers.
|
|
269
|
+
Typography defaults to its own color, weight, `<p>` margin, and
|
|
270
|
+
a `1.429em` line-height, all of which break the grid's uniform
|
|
271
|
+
row appearance.
|
|
272
|
+
|
|
273
|
+
`!important` is required: EDS ships a global rule with an ID
|
|
274
|
+
selector (specificity 1,1,0) that wins over any class-based
|
|
275
|
+
chain. The third-party rule is itself a hardcoded-ID hack;
|
|
276
|
+
overriding with `!important` is the correct counter and stays
|
|
277
|
+
scoped to elements inside a grid cell. */
|
|
278
|
+
& [class*='Typography__StyledTypography'] {
|
|
279
|
+
color: inherit !important;
|
|
280
|
+
font-family: inherit !important;
|
|
281
|
+
font-size: inherit !important;
|
|
282
|
+
font-weight: inherit !important;
|
|
283
|
+
line-height: inherit !important;
|
|
284
|
+
letter-spacing: inherit !important;
|
|
285
|
+
}
|
|
217
286
|
|
|
218
287
|
&.editing {
|
|
219
288
|
padding: 2px 1px;
|
|
220
289
|
position: relative;
|
|
221
290
|
}
|
|
222
291
|
|
|
223
|
-
|
|
224
|
-
|
|
292
|
+
/* Pinned cell focus tint.
|
|
293
|
+
|
|
294
|
+
The grid's own `.cell-focus` rule already paints
|
|
295
|
+
`--tbw-focus-background` (set in section 1 to an alpha-blended
|
|
296
|
+
accent) on any focused cell. On a sticky cell the rows behind
|
|
297
|
+
would scroll through that translucent tint as the user pans
|
|
298
|
+
horizontally, so we pre-composite the same 8% accent onto the
|
|
299
|
+
pinned-cell `--tbw-color-panel-bg` to keep the result fully opaque.
|
|
300
|
+
This is the only place we still target `.cell-focus` directly
|
|
301
|
+
— `color-mix` needs the panel-bg as a second color, which a
|
|
302
|
+
single variable can't express. */
|
|
303
|
+
&.cell-focus.sticky-left,
|
|
304
|
+
&.cell-focus.sticky-right {
|
|
305
|
+
background: color-mix(
|
|
306
|
+
in srgb,
|
|
307
|
+
var(--_accent) 8%,
|
|
308
|
+
var(--tbw-color-panel-bg)
|
|
309
|
+
);
|
|
225
310
|
}
|
|
226
311
|
|
|
227
312
|
/* Editor host — visual boundary for all editor types */
|
|
228
313
|
& .tbw-editor-host {
|
|
229
314
|
border: 1px solid var(--_border);
|
|
230
|
-
background: var(
|
|
231
|
-
--eds_ui_background__default,
|
|
232
|
-
light-dark(#ffffff, #243746)
|
|
233
|
-
);
|
|
315
|
+
background: var(--tbw-color-bg);
|
|
234
316
|
display: flex;
|
|
235
317
|
align-items: center;
|
|
236
318
|
width: 100%;
|
|
@@ -247,6 +329,14 @@ tbw-grid {
|
|
|
247
329
|
outline: none;
|
|
248
330
|
}
|
|
249
331
|
|
|
332
|
+
/* Editors that bring their own full-bleed input (e.g. EDS DatePicker /
|
|
333
|
+
Autocomplete) opt out of the host's padding so they can stretch
|
|
334
|
+
to fill the cell. See section 7. */
|
|
335
|
+
&:has(.tbw-eds-date-editor),
|
|
336
|
+
&:has(.tbw-eds-autocomplete-editor) {
|
|
337
|
+
padding: 0;
|
|
338
|
+
}
|
|
339
|
+
|
|
250
340
|
/* Framework component hosts: transparent for flex layout.
|
|
251
341
|
:where() for zero specificity so component :host styles can override.
|
|
252
342
|
Excludes form elements and custom editor boxes. */
|
|
@@ -370,8 +460,13 @@ tbw-grid {
|
|
|
370
460
|
}
|
|
371
461
|
|
|
372
462
|
& input.mat-mdc-input-element {
|
|
463
|
+
/* `line-height: normal` is browser/font-dependent (≈ 1.2-1.5) which
|
|
464
|
+
inflates the `1lh + 2 * padding` floor used by `.cell.editing`
|
|
465
|
+
and pushes the editing row past `--tbw-row-height`. Locking it
|
|
466
|
+
to 1 keeps the input the height of its font-size so the cell can
|
|
467
|
+
collapse to `--tbw-row-height` in compact mode. */
|
|
373
468
|
height: auto;
|
|
374
|
-
line-height:
|
|
469
|
+
line-height: 1;
|
|
375
470
|
}
|
|
376
471
|
|
|
377
472
|
& .mat-mdc-select {
|
|
@@ -410,30 +505,132 @@ tbw-grid {
|
|
|
410
505
|
);
|
|
411
506
|
}
|
|
412
507
|
}
|
|
413
|
-
}
|
|
414
508
|
|
|
415
|
-
/*
|
|
416
|
-
.
|
|
417
|
-
|
|
418
|
-
|
|
509
|
+
/* ================================================================
|
|
510
|
+
* 3. Pinned cells & sticky group rows
|
|
511
|
+
* ================================================================ */
|
|
512
|
+
|
|
513
|
+
/* Row hover on pinned cells.
|
|
514
|
+
|
|
515
|
+
Pinned cells (`.sticky-left` / `.sticky-right`) carry an opaque
|
|
516
|
+
`--tbw-color-panel-bg` so non-sticky content scrolling behind
|
|
517
|
+
them can't bleed through. That opaque fill also masks the row's
|
|
518
|
+
`:hover` tint, making pinned columns visually disconnected from
|
|
519
|
+
the rest of the row. Repaint them with the row-hover color to
|
|
520
|
+
restore continuity. Wrapped in `@media (hover: hover)` to mirror
|
|
521
|
+
the grid's own row-hover rule and avoid sticky tap-state flicker
|
|
522
|
+
on touch devices. */
|
|
523
|
+
@media (hover: hover) {
|
|
524
|
+
& .data-grid-row:hover > .cell.sticky-left,
|
|
525
|
+
& .data-grid-row:hover > .cell.sticky-right {
|
|
526
|
+
background: var(--tbw-color-row-hover);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/* Hover + focus on a pinned cell: keep the focus tint visible by
|
|
530
|
+
flattening the same 8% accent over the row-hover color. */
|
|
531
|
+
& .data-grid-row:hover > .cell.cell-focus.sticky-left,
|
|
532
|
+
& .data-grid-row:hover > .cell.cell-focus.sticky-right {
|
|
533
|
+
background: color-mix(
|
|
534
|
+
in srgb,
|
|
535
|
+
var(--tbw-color-accent) 8%,
|
|
536
|
+
var(--tbw-color-row-hover)
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/* Sticky group-row chrome.
|
|
542
|
+
|
|
543
|
+
The grouping-rows feature renders a full-width banner row for each
|
|
544
|
+
group boundary: a `.data-grid-row.group-row` whose only child is a
|
|
545
|
+
single `.cell.group-full` (spanning `grid-column: 1 / -1`) containing
|
|
546
|
+
`.group-toggle`, `.group-label`, `.group-count`, and optional
|
|
547
|
+
`.group-aggregates`. On a horizontally-scrollable grid the cell is
|
|
548
|
+
as wide as the row, so when the user scrolls right the entire chrome
|
|
549
|
+
slides off the left edge.
|
|
550
|
+
|
|
551
|
+
Approach: shrink the cell to its content width and pin it to the left
|
|
552
|
+
with `position: sticky; left: 0`. The chrome children keep their
|
|
553
|
+
inline flow — we never touch them individually, so new chrome
|
|
554
|
+
elements in a future grid version "just work".
|
|
555
|
+
|
|
556
|
+
Two things move from the cell up to the row:
|
|
557
|
+
1. Background — the cell no longer spans the row, so the row paints
|
|
558
|
+
the banner tint.
|
|
559
|
+
2. Full-row span override — the cell still has `grid-column: 1 / -1`
|
|
560
|
+
from the grid runtime; `width: max-content !important` shrinks
|
|
561
|
+
the rendered box while leaving the grid-track placement intact.
|
|
562
|
+
|
|
563
|
+
Why we override `overflow: hidden` on the cell:
|
|
564
|
+
@toolbox-web/grid sets `overflow: hidden` on every `.cell` to clip
|
|
565
|
+
content. Per the CSS Position spec, that establishes a scroll
|
|
566
|
+
container, which traps the cell's own sticky positioning inside the
|
|
567
|
+
(non-scrolling) cell box. `overflow: visible` lets the sticky context
|
|
568
|
+
bubble up past the row, past `.rows-viewport` (`overflow: clip` —
|
|
569
|
+
non-scrollable), all the way to `.tbw-scroll-area` (the actual
|
|
570
|
+
horizontal scroller) where sticky engages. */
|
|
571
|
+
& .data-grid-row.group-row {
|
|
572
|
+
background: var(
|
|
573
|
+
--tbw-color-header-bg,
|
|
574
|
+
var(--tbw-color-panel-bg, transparent)
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
& > .cell.group-full {
|
|
578
|
+
overflow: visible;
|
|
579
|
+
position: sticky;
|
|
580
|
+
left: 0;
|
|
581
|
+
z-index: 2;
|
|
582
|
+
width: max-content !important;
|
|
583
|
+
max-width: 100%;
|
|
584
|
+
background: transparent;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
& .group-count {
|
|
588
|
+
padding: 0 0.5rem;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
/* Sticky aggregation (footer) row.
|
|
593
|
+
|
|
594
|
+
The bottom aggregation row (`.tbw-footer > .tbw-aggregation-rows >
|
|
595
|
+
.tbw-aggregation-row > .tbw-aggregation-cell.tbw-aggregation-cell-full`)
|
|
596
|
+
has the same shape as a group row: a full-width cell that spans the
|
|
597
|
+
entire scrollable area (`grid-column: 1 / -1`, width = scrollWidth).
|
|
598
|
+
When the user scrolls horizontally the totals/label slide off the
|
|
599
|
+
left edge.
|
|
600
|
+
|
|
601
|
+
Same fix as `.group-row > .cell.group-full`: shrink the cell to its
|
|
602
|
+
content width, pin it to the left with `position: sticky; left: 0`,
|
|
603
|
+
and override the grid's `overflow: hidden` so the sticky context can
|
|
604
|
+
bubble up past the row to the scroll container.
|
|
605
|
+
|
|
606
|
+
`.tbw-footer` itself is already `position: sticky; bottom: 0` from
|
|
607
|
+
the grid runtime — we only need to handle horizontal stickiness. */
|
|
608
|
+
& .tbw-aggregation-row > .tbw-aggregation-cell-full {
|
|
609
|
+
overflow: visible;
|
|
610
|
+
position: sticky;
|
|
611
|
+
left: 0;
|
|
612
|
+
z-index: 2;
|
|
613
|
+
width: max-content !important;
|
|
614
|
+
max-width: 100%;
|
|
615
|
+
background: transparent;
|
|
616
|
+
}
|
|
419
617
|
}
|
|
420
618
|
|
|
421
619
|
/* ================================================================
|
|
422
|
-
*
|
|
620
|
+
* 4. Filter Panel Styles
|
|
423
621
|
* ================================================================ */
|
|
424
622
|
.tbw-filter-panel {
|
|
425
623
|
max-width: none;
|
|
426
624
|
max-height: none;
|
|
427
625
|
|
|
428
|
-
/* EDS underline inputs
|
|
626
|
+
/* EDS underline inputs — the bg/border/radius are stripped via
|
|
627
|
+
`--tbw-filter-input-*` variables in section 1. The underline
|
|
628
|
+
`box-shadow` and height have no variable equivalent. */
|
|
429
629
|
& .tbw-filter-search-input,
|
|
430
630
|
& .tbw-filter-range-input,
|
|
431
631
|
& .tbw-filter-date-input {
|
|
432
632
|
height: var(--tbw-row-height);
|
|
433
|
-
border: none;
|
|
434
|
-
border-radius: 0;
|
|
435
633
|
box-shadow: inset 0px -1px 0px 0px var(--_fg-muted);
|
|
436
|
-
background: var(--_surface);
|
|
437
634
|
outline: 1px solid transparent;
|
|
438
635
|
outline-offset: 0px;
|
|
439
636
|
}
|
|
@@ -520,7 +717,7 @@ tbw-grid {
|
|
|
520
717
|
}
|
|
521
718
|
|
|
522
719
|
/* ================================================================
|
|
523
|
-
*
|
|
720
|
+
* 5. Context Menu
|
|
524
721
|
*
|
|
525
722
|
* Appended to document.body (outside tbw-grid).
|
|
526
723
|
* CSS variables are copied from tbw-grid at render time.
|
|
@@ -579,7 +776,7 @@ tbw-grid {
|
|
|
579
776
|
}
|
|
580
777
|
|
|
581
778
|
/* ================================================================
|
|
582
|
-
*
|
|
779
|
+
* 6. Overlay Panel (BaseOverlayEditor)
|
|
583
780
|
* ================================================================ */
|
|
584
781
|
.tbw-overlay-panel {
|
|
585
782
|
--tbw-overlay-bg: var(
|
|
@@ -596,10 +793,234 @@ tbw-grid {
|
|
|
596
793
|
}
|
|
597
794
|
|
|
598
795
|
/* ================================================================
|
|
599
|
-
*
|
|
796
|
+
* 7. EDS in-cell editors — DatePicker and Autocomplete
|
|
797
|
+
*
|
|
798
|
+
* Marker classes:
|
|
799
|
+
* `.tbw-eds-date-editor` — wrapper around EDS <DatePicker>
|
|
800
|
+
* `.tbw-eds-autocomplete-editor` — wrapper around EDS <Autocomplete>
|
|
801
|
+
*
|
|
802
|
+
* Used by React consumers that render EDS form components inside grid
|
|
803
|
+
* cell editors (typically inside `<EdsProvider density="compact">`).
|
|
804
|
+
* EDS wraps each field in an InputWrapper with a label and helper
|
|
805
|
+
* area — none of which we want inside a row-height cell. We strip the
|
|
806
|
+
* chrome, hide the label/helper for sighted users (kept for screen
|
|
807
|
+
* readers), and stretch the inner field stack to fill the cell.
|
|
808
|
+
*
|
|
809
|
+
* Popover positioning fix (applies to both):
|
|
810
|
+
* EDS uses the native popover API (`popover="manual"`) + floating-ui
|
|
811
|
+
* to place the calendar / options dropdown. Inline EDS sets
|
|
812
|
+
* `position: absolute` with viewport-anchored top/left from the
|
|
813
|
+
* trigger's getBoundingClientRect. That works in plain DOM, but
|
|
814
|
+
* `tbw-grid` virtualises rows with `transform` which creates a
|
|
815
|
+
* containing block. Once the popover enters the browser top-layer
|
|
816
|
+
* (`.showPopover()`), the spec says its containing block is the
|
|
817
|
+
* viewport — but floating-ui's inset values assume the regular
|
|
818
|
+
* containing-block cascade. The two coordinate systems mismatch and
|
|
819
|
+
* the popover renders off-screen.
|
|
820
|
+
*
|
|
821
|
+
* Forcing `position: fixed` aligns the popover's containing block
|
|
822
|
+
* with floating-ui's viewport math. The inset reset overrides the
|
|
823
|
+
* browser's default `[popover]:popover-open { inset: 0 }` rule that
|
|
824
|
+
* would otherwise stretch the popover full-viewport.
|
|
825
|
+
*
|
|
826
|
+
* Harmless when EDS is absent (Angular consumers don't ship these
|
|
827
|
+
* markers), so safe to include in the shared theme.
|
|
828
|
+
* ================================================================ */
|
|
829
|
+
|
|
830
|
+
/* Shared chrome-stripping + popover-positioning rules. Applied to both
|
|
831
|
+
editor wrappers via @extend so the rules stay co-located with their
|
|
832
|
+
shared docstring above. */
|
|
833
|
+
%tbw-eds-cell-editor {
|
|
834
|
+
width: 100%;
|
|
835
|
+
height: 100%;
|
|
836
|
+
display: flex;
|
|
837
|
+
align-items: stretch;
|
|
838
|
+
|
|
839
|
+
/* Hide the visually-rendered EDS label/helper, keep them for a11y. */
|
|
840
|
+
label,
|
|
841
|
+
[class*='HelperText'] {
|
|
842
|
+
position: absolute;
|
|
843
|
+
width: 1px;
|
|
844
|
+
height: 1px;
|
|
845
|
+
padding: 0;
|
|
846
|
+
margin: -1px;
|
|
847
|
+
overflow: hidden;
|
|
848
|
+
clip: rect(0, 0, 0, 0);
|
|
849
|
+
white-space: nowrap;
|
|
850
|
+
border: 0;
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
/* Calendar / options dropdown popover — see header for rationale. */
|
|
854
|
+
[popover] {
|
|
855
|
+
position: fixed !important;
|
|
856
|
+
right: auto !important;
|
|
857
|
+
bottom: auto !important;
|
|
858
|
+
width: max-content !important;
|
|
859
|
+
margin: 0 !important;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
|
|
863
|
+
.tbw-eds-date-editor {
|
|
864
|
+
@extend %tbw-eds-cell-editor;
|
|
865
|
+
|
|
866
|
+
/* Stretch the EDS field stack to fill the cell vertically and strip
|
|
867
|
+
its own background/box-shadow underline since the surrounding
|
|
868
|
+
`.tbw-editor-host:focus-within` already provides the focus indicator.
|
|
869
|
+
`!important` beats EDS's ID-scoped rule (specificity 1,1,0).
|
|
870
|
+
NOTE: do not use `> div` — the calendar popover is also a direct
|
|
871
|
+
child once `popover="manual"` opens it, and forcing it to 100%
|
|
872
|
+
height stretches it to the full viewport and breaks auto-flip. */
|
|
873
|
+
[class*='InputWrapper__Container'],
|
|
874
|
+
[class*='FieldWrapper'] {
|
|
875
|
+
width: 100% !important;
|
|
876
|
+
height: 100% !important;
|
|
877
|
+
}
|
|
878
|
+
|
|
879
|
+
[class*='FieldWrapper'] {
|
|
880
|
+
background: transparent !important;
|
|
881
|
+
box-shadow: none !important;
|
|
882
|
+
border: none !important;
|
|
883
|
+
display: flex;
|
|
884
|
+
align-items: center;
|
|
885
|
+
}
|
|
886
|
+
}
|
|
887
|
+
|
|
888
|
+
.tbw-eds-autocomplete-editor {
|
|
889
|
+
@extend %tbw-eds-cell-editor;
|
|
890
|
+
|
|
891
|
+
/* Stretch EDS field stack to fill the cell vertically and strip its
|
|
892
|
+
own background/underline since the editor host owns the focus ring. */
|
|
893
|
+
[class*='InputWrapper__Container'],
|
|
894
|
+
[class*='Container'] {
|
|
895
|
+
width: 100% !important;
|
|
896
|
+
height: 100% !important;
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
[class*='Container'] {
|
|
900
|
+
background: transparent !important;
|
|
901
|
+
box-shadow: none !important;
|
|
902
|
+
border: none !important;
|
|
903
|
+
}
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
/* ================================================================
|
|
907
|
+
* 8. Empty State Overlay
|
|
908
|
+
*
|
|
909
|
+
* The grid's empty overlay (.tbw-empty-overlay) is absolutely
|
|
910
|
+
* positioned inside .rows-container. When the grid host is sized
|
|
911
|
+
* by content (no explicit height) and there are zero rows, the
|
|
912
|
+
* rows-container collapses to height 0 — leaving the overlay
|
|
913
|
+
* with no space and stacking the column header directly on top
|
|
914
|
+
* of the pinned/aggregation footer.
|
|
915
|
+
*
|
|
916
|
+
* Reserve a sensible minimum height for the rows area whenever
|
|
917
|
+
* the empty overlay is present, so the message has room to render
|
|
918
|
+
* and the header / footer separate visually.
|
|
919
|
+
* ================================================================ */
|
|
920
|
+
tbw-grid,
|
|
921
|
+
[data-tbw-grid] {
|
|
922
|
+
& .rows-container:has(> .tbw-empty-overlay) {
|
|
923
|
+
min-height: var(--tbw-empty-min-height, 120px);
|
|
924
|
+
}
|
|
925
|
+
|
|
926
|
+
& .tbw-empty-overlay {
|
|
927
|
+
min-height: var(--tbw-empty-min-height, 120px);
|
|
928
|
+
color: var(--_fg-muted);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
|
|
932
|
+
/* ================================================================
|
|
933
|
+
* 9. Opt-ins (compact mode, thin header)
|
|
934
|
+
* ================================================================ */
|
|
935
|
+
|
|
936
|
+
/* Compact mode — triggers when `.eds-compact` is on the grid itself
|
|
937
|
+
(`<tbw-grid class="eds-compact">`) or on any ancestor (e.g. a wrapping
|
|
938
|
+
section that toggles density for everything inside). */
|
|
939
|
+
tbw-grid.eds-compact,
|
|
940
|
+
[data-tbw-grid].eds-compact,
|
|
941
|
+
.eds-compact tbw-grid,
|
|
942
|
+
.eds-compact [data-tbw-grid] {
|
|
943
|
+
/* Multipliers are tuned against the 13px EDS base:
|
|
944
|
+
row 13 * 1.111 ≈ 14.4px (works once in-cell mat-icons and chip
|
|
945
|
+
padding are constrained — see section 2)
|
|
946
|
+
header 13 * 1.4 ≈ 18.2px
|
|
947
|
+
Apps with a larger base (e.g. 18px) get proportionally bigger:
|
|
948
|
+
18 * 1.111 ≈ 20px / 18 * 1.4 ≈ 25px. */
|
|
949
|
+
--tbw-row-height: calc(var(--sto-base-font-size, 13px) * 1.111);
|
|
950
|
+
--tbw-header-height: calc(var(--sto-base-font-size, 13px) * 1.4);
|
|
951
|
+
|
|
952
|
+
/* In-cell Material icons.
|
|
953
|
+
Angular Material renders `<mat-icon>` as `<span class="mat-icon">` at a
|
|
954
|
+
hardcoded 24x24. Since `.data-grid-row` is `display: grid` and the row
|
|
955
|
+
track grows to fit the tallest cell content, a 24px icon would inflate
|
|
956
|
+
every row past `--tbw-row-height`. Constrain in-cell icons to the cell
|
|
957
|
+
font-size so they fit the compact row track.
|
|
958
|
+
|
|
959
|
+
Sizing trick: `font-size: 1em` keeps the glyph at the cell font-size
|
|
960
|
+
(13px default), then `width/height: 1em` resolves against the icon's
|
|
961
|
+
own font-size — producing a 13x13 box. Only applied under `.eds-compact`
|
|
962
|
+
so non-compact grids keep Material's standard 24px icons. */
|
|
963
|
+
& .cell .mat-icon,
|
|
964
|
+
& .cell mat-icon {
|
|
965
|
+
font-size: 1em;
|
|
966
|
+
width: 1em;
|
|
967
|
+
height: 1em;
|
|
968
|
+
line-height: 1em;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
/* In-cell editor density.
|
|
972
|
+
Active editors (`.cell.editing > .tbw-editor-host`) host Angular
|
|
973
|
+
Material form-fields. Even with all chrome stripped (see section 2),
|
|
974
|
+
a Material input renders at ~35px tall because of its intrinsic
|
|
975
|
+
padding/min-height — which then ratchets the grid's row-height
|
|
976
|
+
measurement upward and shrinks the visible-row count for every
|
|
977
|
+
other row.
|
|
978
|
+
|
|
979
|
+
In compact mode we constrain the editor to the compact row height
|
|
980
|
+
so editing a row no longer changes the row's painted height. */
|
|
981
|
+
& .cell.editing {
|
|
982
|
+
/* Eliminate the `1lh + 2 * padding` floor inherited from the base
|
|
983
|
+
`.cell.editing` rule — the active cell follows row-height only. */
|
|
984
|
+
min-height: var(--tbw-row-height);
|
|
985
|
+
|
|
986
|
+
& .tbw-editor-host,
|
|
987
|
+
& .tbw-editor-host .mat-mdc-form-field,
|
|
988
|
+
& .tbw-editor-host .mat-mdc-text-field-wrapper,
|
|
989
|
+
& .tbw-editor-host .mat-mdc-form-field-flex,
|
|
990
|
+
& .tbw-editor-host .mat-mdc-form-field-infix {
|
|
991
|
+
min-height: 0;
|
|
992
|
+
height: 100%;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
& .tbw-editor-host input.mat-mdc-input-element,
|
|
996
|
+
& .tbw-editor-host .mat-mdc-select-trigger {
|
|
997
|
+
height: var(--tbw-row-height);
|
|
998
|
+
min-height: 0;
|
|
999
|
+
padding-top: 0;
|
|
1000
|
+
padding-bottom: 0;
|
|
1001
|
+
line-height: 1;
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
|
|
1006
|
+
/* Thin header — for grids that are sub-sections inside a larger page
|
|
1007
|
+
(e.g. a field-split table) where a full-height header competes
|
|
1008
|
+
visually with surrounding form headings.
|
|
1009
|
+
|
|
1010
|
+
Apply with: <div class="tbw-thin-header"><tbw-grid ... /></div> */
|
|
1011
|
+
.tbw-thin-header tbw-grid,
|
|
1012
|
+
.tbw-thin-header [data-tbw-grid] {
|
|
1013
|
+
--tbw-header-height: 28px;
|
|
1014
|
+
--tbw-font-weight-header: 500;
|
|
1015
|
+
--tbw-font-size-header: 0.75rem;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
1018
|
+
/* ================================================================
|
|
1019
|
+
* 10. Dark Mode
|
|
600
1020
|
* ================================================================ */
|
|
601
1021
|
body.sto-dark-theme {
|
|
602
1022
|
tbw-grid,
|
|
1023
|
+
[data-tbw-grid],
|
|
603
1024
|
.tbw-filter-panel,
|
|
604
1025
|
.tbw-context-menu,
|
|
605
1026
|
.tbw-overlay-panel {
|