diff --git a/ui/src/views/Forecast.jsx b/ui/src/views/Forecast.jsx index 7caa0c5..d59b030 100644 --- a/ui/src/views/Forecast.jsx +++ b/ui/src/views/Forecast.jsx @@ -1007,7 +1007,23 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio // survives adding measures or rearranging the pivot, unlike hiding by position. // The rule has to live inside the plugin's shadow root; a document stylesheet // cannot reach it. - const HIDE_SPLIT_TOTAL_CSS = ` + const GRID_CSS = ` + /* Let headers and row labels size their own column. + * + * Auto-fit measures cells with getBoundingClientRect() and sets each column's + * min-width from the result — but the datagrid's own CSS wraps and clips + * header text, so a clipped th measures at the width it was *allotted*, not + * the width of its content. The column can therefore never grow to fit its + * own heading, which is why the values fit and the headings did not. Row + * labels are th elements in tbody and clip for the same reason. + * + * nowrap alone: no width or overflow is touched, so the measurement sees the + * full text and the existing sizing logic does the rest. */ + thead th, + tbody th { + white-space: nowrap !important; + } + th.psp-split-total:not(.psp-split-subtotal), td.psp-split-total:not(.psp-split-subtotal) { visibility: hidden !important; @@ -1045,10 +1061,10 @@ export default function Forecast({ sources = [], sourceId, versions = [], versio // Retried from the config-update handler, and once on a short delay. if (!grid) return false const root = grid.getRootNode() - if (!root || root.querySelector?.('#pf-hide-split-total')) return true + if (!root || root.querySelector?.('#pf-grid-css')) return true const style = document.createElement('style') - style.id = 'pf-hide-split-total' - style.textContent = HIDE_SPLIT_TOTAL_CSS + style.id = 'pf-grid-css' + style.textContent = GRID_CSS ;(root.appendChild ? root : document.head).appendChild(style) return true }