Full document, spreadsheet, slideshow, and diagram tooling
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request 'fix: sparkline canvas colors now read CSS theme variables' (#270) from fix/sparkline-theme-colors into main

scott f07f77c2 6b535d04

+30 -8
+6
CHANGELOG.md
··· 8 8 ## [0.23.5] — 2026-04-06 9 9 10 10 ### Fixed 11 + - Improve keyboard focus visibility for accessibility (#447) 12 + - CSS polish: replace hardcoded transition durations with CSS variables (#446) 13 + - CSS polish: define missing variables, fix hardcoded colors, focus styles (#445) 11 14 - Frozen column background now survives scrolling: compositing layer + inline !important prevent WebKit paint drops and CSS override (#441) 12 15 - Version badge no longer overlapped by sheet UI elements (z-index 1→50) (#441) 13 16 - Frozen column transparent background in dark mode when scrolling (#440) ··· 15 18 - Sheets: frozen columns/rows now always have an opaque background in dark mode, preventing scrolled content from showing through (#432) 16 19 17 20 ### Added 21 + - Polish: UI/CSS fit-and-finish improvements (#443) 18 22 - Sheets: `RecalcEngine.clearSpillTarget()` method for notifying the engine when a user edits a spill target cell 19 23 - Tests: 7 data integrity tests for spill system to prevent cell data overwrites during recalc 20 24 ··· 250 254 - Fix E2E test flakiness: replace page reload with addInitScript, add waitForURL before waitForSelector (#305) 251 255 252 256 ### Changed 257 + - QA batch 22: tests for cross-sheet, custom-format, permissions, named-ranges (#444) 258 + - QA: batch 21 edge case tests for untested modules (#442) 253 259 - QA batch 20: continued edge case coverage expansion (#439) 254 260 - QA batch 19: theming, automations, range-highlight, export edge cases (#438) 255 261 - QA batch 18: formulas & pivot-table edge cases (#437)
+24 -8
src/sheets/sparkline.ts
··· 50 50 51 51 const VALID_CHART_TYPES: ReadonlySet<string> = new Set(['line', 'bar', 'winloss']); 52 52 53 - const DEFAULT_COLOR = '#3b82f6'; 54 - const DEFAULT_NEG_COLOR = '#ef4444'; 53 + const FALLBACK_COLOR = '#3b82f6'; 54 + const FALLBACK_NEG_COLOR = '#ef4444'; 55 + const FALLBACK_AXIS_COLOR = '#94a3b8'; 55 56 const DEFAULT_LINE_WIDTH = 1.5; 57 + 58 + /** Read resolved CSS variable values from the document for canvas rendering. */ 59 + function getThemeColors(): { color: string; negColor: string; axisColor: string } { 60 + if (typeof document === 'undefined') { 61 + return { color: FALLBACK_COLOR, negColor: FALLBACK_NEG_COLOR, axisColor: FALLBACK_AXIS_COLOR }; 62 + } 63 + const styles = getComputedStyle(document.documentElement); 64 + const read = (prop: string, fallback: string) => styles.getPropertyValue(prop).trim() || fallback; 65 + return { 66 + color: read('--color-teal', FALLBACK_COLOR), 67 + negColor: read('--color-danger', FALLBACK_NEG_COLOR), 68 + axisColor: read('--color-border', FALLBACK_AXIS_COLOR), 69 + }; 70 + } 56 71 57 72 // --- Type guard --- 58 73 ··· 280 295 const w = canvas.width; 281 296 const h = canvas.height; 282 297 const opts = result.options; 283 - const color = opts.color || DEFAULT_COLOR; 284 - const negColor = opts.negColor || DEFAULT_NEG_COLOR; 298 + const theme = getThemeColors(); 299 + const color = opts.color || theme.color; 300 + const negColor = opts.negColor || theme.negColor; 285 301 286 302 ctx.clearRect(0, 0, w, h); 287 303 ··· 298 314 if (range > 0) { 299 315 const axisY = h - ((0 - minVal) / range) * h; 300 316 if (axisY >= 0 && axisY <= h) { 301 - ctx.strokeStyle = '#94a3b8'; 317 + ctx.strokeStyle = theme.axisColor; 302 318 ctx.lineWidth = 0.5; 303 319 ctx.beginPath(); 304 320 ctx.moveTo(0, axisY); ··· 340 356 const range = maxVal - minVal; 341 357 if (range > 0 && minVal < 0) { 342 358 const axisY = (maxVal / range) * h; 343 - ctx.strokeStyle = '#94a3b8'; 359 + ctx.strokeStyle = theme.axisColor; 344 360 ctx.lineWidth = 0.5; 345 361 ctx.beginPath(); 346 362 ctx.moveTo(0, axisY); ··· 361 377 const rects = computeWinLossRects(result.data, w, h, opts); 362 378 363 379 // Draw center line 364 - ctx.strokeStyle = '#94a3b8'; 380 + ctx.strokeStyle = theme.axisColor; 365 381 ctx.lineWidth = 0.5; 366 382 ctx.beginPath(); 367 383 ctx.moveTo(0, h / 2); ··· 377 393 ctx.fillStyle = negColor; 378 394 break; 379 395 case 'zero': 380 - ctx.fillStyle = '#94a3b8'; 396 + ctx.fillStyle = theme.axisColor; 381 397 break; 382 398 } 383 399 ctx.fillRect(rect.x + 0.5, rect.y, rect.width - 1, rect.height);