Dark Mode & Theming
Relevant source files
The following files were used as context for generating this wiki page:
The vitepress-plugin-chartjs provides integrated support for theme switching, ensuring that charts remain readable and visually consistent when users toggle between light and dark modes. The theming system operates through a combination of build-time color application and client-side reactive updates.
The plugin handles theming at two levels: global configuration via the VitePress config file and dynamic updates within the Vue component based on the active VitePress theme state.
Theme Architecture & Data Flow
The theming architecture follows a "Data-First" approach where default color palettes are injected during the markdown parsing phase, while reactive visual adjustments (like grid line and text colors) occur in the browser.
Build-Time Color Injection
During the build process, the markdown plugin applies default colors to datasets if specific colors are not provided by the user. This ensures that every chart has a professional look out of the box.
The diagram shows the progression from raw markdown to a processed Vue component with themed defaults applied at build time.
Sources: src/markdown/index.ts:167-175, src/markdown/index.ts:246-248
Client-Side Reactive Updates
On the client side, the VpChart.vue component utilizes the isDark state from VitePress's useData composable. When the theme changes, the component triggers an internal update mechanism to adjust Chart.js canvas elements that do not automatically respond to CSS, such as ticks, grid lines, and labels.
This sequence illustrates how the plugin intercepts VitePress theme changes to re-render chart canvas elements.
Sources: src/VpChart.vue:46-75, src/VpChart.vue:137-139
Configuration Options
The plugin allows developers to define custom palettes for both light and dark modes through the chartjs property in config.mts.
| Option | Type | Default | Description |
|---|---|---|---|
colorPalette | string[] | Built-in RGBA set | Global color palette used for datasets in light mode. |
darkColorPalette | string[] | Built-in Light RGBA set | Color palette applied specifically for dark mode environments. |
autoDarkMode | boolean | undefined | Enables automatic detection of the dark mode state. |
Sources: src/config.ts:176-179, example/api.md:44-53
Built-in Palettes
The plugin includes predefined color sets designed for accessibility and contrast in both modes.
- Light Mode Defaults: Primarily uses
rgba(..., 0.8)values with distinct colors like Blue, Red, Teal, and Yellow. - Dark Mode Defaults: Uses lighter versions of the base colors (e.g., Light Blue, Light Red) to maintain visibility against dark backgrounds.
Sources: src/config.ts:240-264
Implementation Details
Theme Update Logic
The updateTheme function in the Vue component specifically targets three main areas of the Chart.js configuration:
- Scales: Updates
ticks.color,grid.color, andscale.title.color. - Legend: Updates
plugins.legend.labels.color. - Title: Updates
plugins.title.color.
const updateTheme = () => {
if (!chartInstance) return;
const dark = isDark.value;
const textColor = dark ? '#e5e7eb' : '#374151';
const gridColor = dark ? 'rgba(255, 255, 255, 0.1)' : 'rgba(0, 0, 0, 0.1)';
const options = chartInstance.options;
// ... iteration over scales and plugins to apply colors
chartInstance.update('none');
};
Sources: src/VpChart.vue:46-75
CSS Theming
Beyond the canvas-based colors, the plugin uses standard CSS variables and scoped styles to theme the chart container. The container uses var(--vp-c-bg-soft) for its background and var(--vp-c-text-2) for the loading placeholder text.
Sources: src/VpChart.vue:143-167, example/api.md:27-31
Summary
Dark mode and theming in vitepress-plugin-chartjs are handled through a hybrid system. Visual data (dataset colors) is determined at build time using configurable palettes, while the UI context (axes, grids, and labels) is managed dynamically at runtime by watching the VitePress isDark state. This ensures that charts are always optimized for the user's current viewing environment without requiring manual configuration for every chart block.