Chart tooltip: app-owned token styling, drop vega-tooltip's default sheet

This commit is contained in:
2026-06-14 01:25:58 +03:00
parent e4d1466ab0
commit 236b1c8a37
2 changed files with 74 additions and 0 deletions
+8
View File
@@ -173,6 +173,14 @@ export async function renderSpec(
actions: false, // Astrolabe owns its own export/copy affordances
renderer,
config,
// Suppress vega-tooltip's bundled light/dark stylesheet so the app owns the
// tooltip's look. With the default style gone, the single `#vg-tooltip-element`
// it appends to <body> is styled entirely from our design tokens in base.css —
// surface, type, and the key/value table — and follows `[data-theme]` for free
// (the element inherits the cascade from <html>). vega-tooltip still positions
// the element (inline top/left) and toggles `.visible`; our CSS supplies the
// structural rules (position/visibility/z-index) the default sheet used to.
tooltip: { disableDefaultStyle: true },
});
return {
+66
View File
@@ -107,6 +107,72 @@ body {
}
}
/*
* Chart tooltip (vega-tooltip). The renderer disables vega-tooltip's bundled
* stylesheet (chart-renderer `disableDefaultStyle`), so the look is ours: an
* elevated surface matching the popover recipe (--layer-01 + border + shadow,
* square corners), in Plex, with the data laid out as a quiet key/value table.
* vega-tooltip appends one `#vg-tooltip-element` to <body> and positions it
* inline; these rules supply everything the default sheet did — position,
* visibility toggle, z-index — plus the visual styling. Tokens cascade from
* <html data-theme>, so the tooltip follows the active theme without a class.
*/
#vg-tooltip-element {
visibility: hidden;
position: fixed;
/* Cursor-following overlay: the topmost ephemeral layer. Must clear the feature
modal (900) that hosts the Chart Builder preview, toasts (1100), and an open
select (2000) — none of which it ever needs to sit beneath. */
z-index: 2100;
padding: var(--space-3) var(--space-4);
background: var(--layer-01);
border: var(--border-width) solid var(--border);
border-radius: var(--radius);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
font-family: var(--font-sans);
font-size: 12px;
line-height: 1.3;
color: var(--text);
}
#vg-tooltip-element.visible {
visibility: visible;
}
/* Title — shown when a tooltip channel resolves to a single labeled value. */
#vg-tooltip-element h2 {
margin: 0 0 var(--space-2);
font-size: 12px;
font-weight: 600;
}
#vg-tooltip-element table {
border-spacing: 0;
}
#vg-tooltip-element td {
padding: var(--space-1) 0;
overflow: hidden;
text-overflow: ellipsis;
}
/* Field name: quiet, right-aligned against its value. */
#vg-tooltip-element td.key {
max-width: 150px;
padding-inline-end: var(--space-3);
text-align: right;
color: var(--text-secondary);
}
/* Value: primary text; tabular figures keep numeric columns aligned. */
#vg-tooltip-element td.value {
display: block;
max-width: 300px;
max-height: 7em;
text-align: left;
font-variant-numeric: tabular-nums;
}
/*
* Visually-hidden but available to assistive tech — the standard sr-only recipe.
* Used for polite `aria-live`/`role="status"` announcements whose visible