diff --git a/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx b/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx index c70ab5895..ad75c46ff 100644 --- a/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx +++ b/docs/tutorialkit.dev/src/content/docs/reference/configuration.mdx @@ -529,3 +529,19 @@ See [Overriding Components](/guides/overriding-components/) for details of all t Controls whether the tutorial routes are automatically added to your project. When set to `true`, it additionally adds a redirect from `/` to the first tutorial. Use `"tutorial-only"` to only add the tutorial routes without the redirect. + +### `expressiveCodeThemes` + +**type**: `[ThemeObjectOrShikiThemeName, ThemeObjectOrShikiThemeName]`
+**default**: `['light-plus', 'dark-plus']` + +Controls which themes are applied to [Expressive Code](https://expressive-code.com/). + +```ts +tutorialkit({ + expressiveCodeThemes: ['catppuccin-latte', 'catppuccin-mocha'], +}); +``` + +Make sure to provide a light and a dark theme if you want support for both light and dark modes. +See the [themes](https://expressive-code.com/guides/themes/) section of Expressive Code to learn more. diff --git a/packages/astro/src/index.ts b/packages/astro/src/index.ts index 2ea81475f..86eb3a5db 100644 --- a/packages/astro/src/index.ts +++ b/packages/astro/src/index.ts @@ -1,6 +1,6 @@ import { fileURLToPath } from 'node:url'; import type { AstroConfig, AstroIntegration } from 'astro'; -import type { ExpressiveCodePlugin } from 'astro-expressive-code'; +import type { ExpressiveCodePlugin, ThemeObjectOrShikiThemeName } from 'astro-expressive-code'; import { extraIntegrations } from './integrations.js'; import { updateMarkdownConfig } from './remark/index.js'; import { tutorialkitCore } from './vite-plugins/core.js'; @@ -67,6 +67,15 @@ export interface Options { * @default [] */ expressiveCodePlugins?: ExpressiveCodePlugin[]; + + /** + * Themes for expressive code. + * Make sure to provide a light and a dark theme if you want support for both light and dark modes. + * Default values are ['light-plus', 'dark-plus'] + * + * @default ['light-plus', 'dark-plus'] + */ + expressiveCodeThemes?: [ThemeObjectOrShikiThemeName, ThemeObjectOrShikiThemeName]; } export default function createPlugin({ @@ -75,6 +84,7 @@ export default function createPlugin({ isolation, enterprise, expressiveCodePlugins = [], + expressiveCodeThemes, }: Options = {}): AstroIntegration { const webcontainerFiles = new WebContainerFiles(); @@ -149,7 +159,7 @@ export default function createPlugin({ config.integrations.splice( selfIndex + 1, 0, - ...extraIntegrations({ root: fileURLToPath(config.root), expressiveCodePlugins }), + ...extraIntegrations({ root: fileURLToPath(config.root), expressiveCodePlugins, expressiveCodeThemes }), ); }, 'astro:config:done'({ config }) { diff --git a/packages/astro/src/integrations.ts b/packages/astro/src/integrations.ts index 74348a2b7..01a95cac6 100644 --- a/packages/astro/src/integrations.ts +++ b/packages/astro/src/integrations.ts @@ -4,21 +4,28 @@ import react from '@astrojs/react'; import { pluginCollapsibleSections } from '@expressive-code/plugin-collapsible-sections'; import { pluginLineNumbers } from '@expressive-code/plugin-line-numbers'; import { getInlineContentForPackage } from '@tutorialkit/theme'; -import expressiveCode, { type ExpressiveCodePlugin } from 'astro-expressive-code'; +import expressiveCode, { type ExpressiveCodePlugin, type ThemeObjectOrShikiThemeName } from 'astro-expressive-code'; import UnoCSS from 'unocss/astro'; export function extraIntegrations({ root, expressiveCodePlugins = [], + expressiveCodeThemes = ['light-plus', 'dark-plus'], }: { root: string; expressiveCodePlugins?: ExpressiveCodePlugin[]; + + /** + * Themes for Expressive Code. + * Takes a tuple of themes, e.g. `[lightTheme, darkTheme]`. + */ + expressiveCodeThemes?: [ThemeObjectOrShikiThemeName, ThemeObjectOrShikiThemeName]; }) { return [ react(), expressiveCode({ plugins: [pluginCollapsibleSections(), pluginLineNumbers(), ...expressiveCodePlugins], - themes: ['dark-plus', 'light-plus'], + themes: expressiveCodeThemes, customizeTheme: (theme) => { const isDark = theme.type === 'dark'; @@ -35,13 +42,7 @@ export function extraIntegrations({ }; }, themeCssSelector: (theme) => { - let customThemeName = 'light'; - - if (theme.name === 'dark-plus') { - customThemeName = 'dark'; - } - - return `[data-theme='${customThemeName}']`; + return `[data-theme='${theme.type}']`; }, defaultProps: { showLineNumbers: false,