|
| 1 | +import { state, getNumCols } from '../state'; |
| 2 | + |
| 3 | +/** |
| 4 | + * Column color mode. A toolbar toggle that gives every data column a distinct, |
| 5 | + * theme-adaptive background tint (header stronger, body fainter) so columns are |
| 6 | + * easy to tell apart, similar to Rainbow CSV but readable on any VS Code theme. |
| 7 | + * |
| 8 | + * How the colors work (see also media/webview.css → "Column Color Mode"): |
| 9 | + * - Each column gets one hue via golden-angle rotation (137.5°), which keeps |
| 10 | + * adjacent columns far apart on the wheel for any column count, even after a |
| 11 | + * column is inserted or deleted. Only the per-column hue is injected here as |
| 12 | + * a CSS variable (--cm-h) on that column's cells via their stable AG Grid |
| 13 | + * `col-id`; the lightness, chroma and alpha live in CSS and adapt to the |
| 14 | + * active theme (light / dark / high-contrast). |
| 15 | + * - The tint is a translucent overlay (color-mix in OKLCH) painted over the |
| 16 | + * real row background, so the theme's own foreground text keeps its contrast |
| 17 | + * and frozen rows, selection, find matches and duplicate highlights — all of |
| 18 | + * which are !important and higher in the cascade — keep painting clearly on |
| 19 | + * top. The row-number gutter (col-id "row-index") is never tinted. |
| 20 | + * |
| 21 | + * The toggle is persisted globally (VS Code globalState) exactly like zoom, so |
| 22 | + * it is remembered across every CSV file and every session. |
| 23 | + */ |
| 24 | + |
| 25 | +const HUE_STYLE_ID = 'cm-col-hues'; |
| 26 | +// 360 * (1 - 1/phi). Irrational vs 360°, so successive hues land in the largest |
| 27 | +// remaining gap and never visibly repeat. |
| 28 | +const GOLDEN_ANGLE = 137.50776405003785; |
| 29 | +// Start offset so column 0 isn't pure red. |
| 30 | +const START_HUE = 25; |
| 31 | + |
| 32 | +function persistColorMode(): void { |
| 33 | + vscodeApi.postMessage({ type: 'colorModeChanged', colorMode: state.colorMode }); |
| 34 | +} |
| 35 | + |
| 36 | +function updateButton(): void { |
| 37 | + document.getElementById('btn-colormode')?.classList.toggle('btn-active', state.colorMode); |
| 38 | +} |
| 39 | + |
| 40 | +// Toggles the `cm-on` class on the grid container (which gates all tint CSS) and, |
| 41 | +// when on, (re)generates the per-column hue rules for the current column count. |
| 42 | +// Safe to call before the grid has data (numCols 0 → empty rule set, class only). |
| 43 | +// Called on setup, on toggle, and at the end of every buildGrid (column add/delete, |
| 44 | +// delimiter change, paging) so freshly built columns pick up their hue. |
| 45 | +export function applyColorMode(): void { |
| 46 | + const container = document.getElementById('grid-container'); |
| 47 | + if (!container) return; |
| 48 | + container.classList.toggle('cm-on', state.colorMode); |
| 49 | + |
| 50 | + let styleEl = document.getElementById(HUE_STYLE_ID) as HTMLStyleElement | null; |
| 51 | + if (!state.colorMode) { |
| 52 | + styleEl?.remove(); |
| 53 | + return; |
| 54 | + } |
| 55 | + if (!styleEl) { |
| 56 | + styleEl = document.createElement('style'); |
| 57 | + styleEl.id = HUE_STYLE_ID; |
| 58 | + document.head.appendChild(styleEl); |
| 59 | + } |
| 60 | + const numCols = getNumCols(state.data); |
| 61 | + let css = ''; |
| 62 | + for (let c = 0; c < numCols; c++) { |
| 63 | + const hue = ((START_HUE + c * GOLDEN_ANGLE) % 360).toFixed(2); |
| 64 | + css += `#grid-container.cm-on [col-id="col_${c}"]{--cm-h:${hue};}`; |
| 65 | + } |
| 66 | + styleEl.textContent = css; |
| 67 | +} |
| 68 | + |
| 69 | +function toggleColorMode(): void { |
| 70 | + state.colorMode = !state.colorMode; |
| 71 | + updateButton(); |
| 72 | + applyColorMode(); |
| 73 | + persistColorMode(); |
| 74 | +} |
| 75 | + |
| 76 | +export function setupColorMode(): void { |
| 77 | + state.colorMode = !!INITIAL_COLOR_MODE; |
| 78 | + updateButton(); |
| 79 | + applyColorMode(); |
| 80 | + document.getElementById('btn-colormode')?.addEventListener('click', toggleColorMode); |
| 81 | +} |
0 commit comments