Merge pull request #488 from TROY665/fix/chart-text-color-dark-theme

Fix: chart scenes unreadable on dark themes
This commit is contained in:
Calesthio
2026-08-22 11:22:17 -07:00
committed by GitHub
2 changed files with 46 additions and 0 deletions

View File

@@ -233,6 +233,7 @@ interface Cut {
heroSubtitle?: string;
// Styling overrides
backgroundColor?: string;
cardBackgroundColor?: string; // Inner card surface (comparison); defaults to theme.surfaceColor
backgroundImage?: string; // AI-generated or stock image rendered behind the component
backgroundVideo?: string; // Video clip rendered behind the component (takes priority over backgroundImage)
backgroundVideoStart?: number; // Seek position in seconds for background video (default 0)
@@ -615,6 +616,7 @@ const SceneRenderer: React.FC<{ cut: Cut; theme: ThemeConfig }> = ({ cut, theme
leftLabel={cut.leftLabel} rightLabel={cut.rightLabel}
leftValue={cut.leftValue} rightValue={cut.rightValue}
title={cut.title} backgroundColor={bgColor} textColor={textColor}
cardBackgroundColor={cut.cardBackgroundColor || theme.surfaceColor}
/>
);
}
@@ -660,6 +662,7 @@ const SceneRenderer: React.FC<{ cut: Cut; theme: ThemeConfig }> = ({ cut, theme
data={cut.chartData} title={cut.title} colors={cut.chartColors || theme.chartColors}
animationStyle={(cut.chartAnimation as any) || "grow-up"}
showGrid={cut.showGrid} showValues={cut.showValues} backgroundColor={bgColor}
textColor={textColor}
/>
);
}
@@ -670,6 +673,7 @@ const SceneRenderer: React.FC<{ cut: Cut; theme: ThemeConfig }> = ({ cut, theme
animationStyle={(cut.chartAnimation as any) || "draw"}
showGrid={cut.showGrid} showMarkers={cut.showMarkers} showLegend={cut.showLegend}
xLabel={cut.xLabel} yLabel={cut.yLabel} backgroundColor={bgColor}
textColor={textColor}
/>
);
}
@@ -680,6 +684,7 @@ const SceneRenderer: React.FC<{ cut: Cut; theme: ThemeConfig }> = ({ cut, theme
animationStyle={(cut.chartAnimation as any) || "expand"}
donut={cut.donut} centerLabel={cut.centerLabel} centerValue={cut.centerValue}
showLegend={cut.showLegend} backgroundColor={bgColor}
textColor={textColor}
/>
);
}
@@ -689,6 +694,7 @@ const SceneRenderer: React.FC<{ cut: Cut; theme: ThemeConfig }> = ({ cut, theme
metrics={cut.chartData} title={cut.title} columns={cut.columns}
colors={cut.chartColors || theme.chartColors} animationStyle={(cut.chartAnimation as any) || "count-up"}
backgroundColor={bgColor}
textColor={textColor}
/>
);
}

View File

@@ -26,3 +26,43 @@ def test_cinematic_fades_are_bounded_by_each_scene_duration() -> None:
assert "Math.round(scene.durationSeconds * fps)" in source
assert "durationInFrames - fadeOutFrames" in source
def _jsx_block(source: str, component: str) -> str:
"""Return the JSX element text for <Component ... /> in the source."""
start = source.index(f"<{component}")
end = source.index("/>", start)
return source[start:end]
def test_chart_scenes_receive_the_theme_text_color() -> None:
"""Charts default textColor to near-black (#1F2937).
If Explainer does not forward the theme's textColor, every chart title,
axis label, category label and value renders dark-on-dark and is invisible
on any dark theme.
"""
source = (REPO_ROOT / "remotion-composer/src/Explainer.tsx").read_text(
encoding="utf-8"
)
for component in ("BarChart", "LineChart", "PieChart", "KPIGrid"):
assert "textColor={textColor}" in _jsx_block(source, component), (
f"{component} must receive the theme textColor, "
f"or its labels are invisible on dark themes"
)
def test_comparison_card_surface_follows_the_theme() -> None:
"""ComparisonCard hardcodes cardBackgroundColor to a light grey (#F3F4F6).
On a dark theme it receives the theme's light textColor, so without a
themed card surface the labels are light-on-light.
"""
source = (REPO_ROOT / "remotion-composer/src/Explainer.tsx").read_text(
encoding="utf-8"
)
block = _jsx_block(source, "ComparisonCard")
assert "textColor={textColor}" in block
assert "cardBackgroundColor={cut.cardBackgroundColor || theme.surfaceColor}" in block