From 51499602768ca8021d5ee304f710190bfe233ba6 Mon Sep 17 00:00:00 2001 From: Nolann Biron Date: Wed, 26 Mar 2025 16:04:36 +0100 Subject: [PATCH] Revert "Improve codeblock highlight style" --- .changeset/fast-pigs-itch.md | 5 --- .../CodeBlock/ClientCodeBlock.tsx | 6 ++-- .../DocumentView/CodeBlock/CodeBlock.tsx | 9 +---- .../CodeBlock/CodeBlockRenderer.tsx | 1 + .../DocumentView/CodeBlock/highlight.ts | 34 +++++++------------ .../DocumentView/CodeBlock/theme.css | 31 +++++++++++++++++ 6 files changed, 48 insertions(+), 38 deletions(-) delete mode 100644 .changeset/fast-pigs-itch.md create mode 100644 packages/gitbook/src/components/DocumentView/CodeBlock/theme.css diff --git a/.changeset/fast-pigs-itch.md b/.changeset/fast-pigs-itch.md deleted file mode 100644 index cb8281fc7..000000000 --- a/.changeset/fast-pigs-itch.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'gitbook': patch ---- - -Improve codeblock highlight style diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx b/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx index 7b08fb5c1..77d9b33c5 100644 --- a/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/ClientCodeBlock.tsx @@ -5,7 +5,6 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { useInViewportListener } from '@/components/hooks/useInViewportListener'; import { useScrollListener } from '@/components/hooks/useScrollListener'; -import { useTheme } from 'next-themes'; import { useDebounceCallback } from 'usehooks-ts'; import type { BlockProps } from '../Block'; import { CodeBlockRenderer } from './CodeBlockRenderer'; @@ -27,7 +26,6 @@ export function ClientCodeBlock(props: ClientBlockProps) { const [isInViewport, setIsInViewport] = useState(false); const plainLines = useMemo(() => plainHighlight(block, []), [block]); const [lines, setLines] = useState(null); - const { resolvedTheme } = useTheme(); // Preload the highlighter when the block is mounted. useEffect(() => { @@ -80,7 +78,7 @@ export function ClientCodeBlock(props: ClientBlockProps) { if (typeof window !== 'undefined') { import('./highlight').then(({ highlight }) => { - highlight(block, inlines, resolvedTheme).then((lines) => { + highlight(block, inlines).then((lines) => { if (cancelled) { return; } @@ -97,7 +95,7 @@ export function ClientCodeBlock(props: ClientBlockProps) { // Otherwise if the block is not in viewport, we reset to the plain lines setLines(null); - }, [isInViewport, block, inlines, resolvedTheme]); + }, [isInViewport, block, inlines]); return ( diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlock.tsx b/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlock.tsx index 46f2bd9b0..2516c8d4f 100644 --- a/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlock.tsx +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlock.tsx @@ -3,8 +3,6 @@ import type { DocumentBlockCode } from '@gitbook/api'; import { getNodeFragmentByType } from '@/lib/document'; import { isV2 } from '@/lib/v2'; -import { MiddlewareHeaders } from '@v2/lib/middleware'; -import { headers } from 'next/headers'; import type { BlockProps } from '../Block'; import { Blocks } from '../Blocks'; import { ClientCodeBlock } from './ClientCodeBlock'; @@ -40,14 +38,9 @@ export async function CodeBlock(props: BlockProps) { if (isV2() && !isEstimatedOffscreen) { // In v2, we render the code block server-side - const theme = getTheme(); - const lines = await highlight(block, richInlines, theme); + const lines = await highlight(block, richInlines); return ; } return ; } - -function getTheme() { - return headers().get(MiddlewareHeaders.Theme) || 'light'; -} diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlockRenderer.tsx b/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlockRenderer.tsx index fdb73fb7f..e2279f744 100644 --- a/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlockRenderer.tsx +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/CodeBlockRenderer.tsx @@ -9,6 +9,7 @@ import type { BlockProps } from '../Block'; import { CopyCodeButton } from './CopyCodeButton'; import type { HighlightLine, HighlightToken } from './highlight'; +import './theme.css'; import './CodeBlockRenderer.css'; type CodeBlockRendererProps = Pick, 'block' | 'style'> & { diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/highlight.ts b/packages/gitbook/src/components/DocumentView/CodeBlock/highlight.ts index 19532ecab..eb02b5b92 100644 --- a/packages/gitbook/src/components/DocumentView/CodeBlock/highlight.ts +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/highlight.ts @@ -3,11 +3,15 @@ import type { DocumentBlockCodeLine, DocumentInlineAnnotation, } from '@gitbook/api'; -import { type ThemedToken, createSingletonShorthands, createdBundledHighlighter } from 'shiki/core'; +import { + type ThemedToken, + createCssVariablesTheme, + createSingletonShorthands, + createdBundledHighlighter, +} from 'shiki/core'; import { createJavaScriptRegexEngine } from 'shiki/engine/javascript'; import { type BundledLanguage, bundledLanguages } from 'shiki/langs'; -import githubDarkDefault from 'shiki/themes/github-dark-default.mjs'; -import minLight from 'shiki/themes/min-light.mjs'; + import { plainHighlight } from './plain-highlight'; export type HighlightLine = { @@ -29,15 +33,12 @@ export type RenderedInline = { body: React.ReactNode; }; -const themes = { - light: minLight, - dark: githubDarkDefault, -}; +const theme = createCssVariablesTheme(); const { getSingletonHighlighter } = createSingletonShorthands( createdBundledHighlighter({ langs: bundledLanguages, - themes: themes, + themes: {}, engine: () => createJavaScriptRegexEngine({ forgiving: true, target: 'ES2018' }), }) ); @@ -50,7 +51,7 @@ export async function preloadHighlight(block: DocumentBlockCode) { if (langName) { await getSingletonHighlighter({ langs: [langName], - themes: Object.values(themes), + themes: [theme], }); } } @@ -60,11 +61,9 @@ export async function preloadHighlight(block: DocumentBlockCode) { */ export async function highlight( block: DocumentBlockCode, - inlines: RenderedInline[], - theme?: string + inlines: RenderedInline[] ): Promise { const langName = getBlockLang(block); - if (!langName) { // Language not found, fallback to plain highlighting return plainHighlight(block, inlines); @@ -74,19 +73,12 @@ export async function highlight( const highlighter = await getSingletonHighlighter({ langs: [langName], - themes: Object.values(themes), + themes: [theme], }); - const selectedTheme = (() => { - if (theme === 'dark') { - return themes.dark; - } - return themes.light; - })(); - const lines = highlighter.codeToTokensBase(code, { lang: langName, - theme: selectedTheme, + theme, tokenizeMaxLineLength: 400, }); diff --git a/packages/gitbook/src/components/DocumentView/CodeBlock/theme.css b/packages/gitbook/src/components/DocumentView/CodeBlock/theme.css new file mode 100644 index 000000000..22ce3b60e --- /dev/null +++ b/packages/gitbook/src/components/DocumentView/CodeBlock/theme.css @@ -0,0 +1,31 @@ +:root { + --shiki-color-text: theme("colors.tint.11"); + --shiki-token-constant: #0a6355; + --shiki-token-string: #8b6d32; + --shiki-token-comment: theme("colors.teal.700/.64"); + --shiki-token-keyword: theme("colors.pomegranate.600"); + --shiki-token-parameter: #0a3069; + --shiki-token-function: #8250df; + --shiki-token-string-expression: #6a4906; + --shiki-token-punctuation: theme("colors.pomegranate.700/.92"); + --shiki-token-link: theme("colors.tint.12"); + --shiki-token-inserted: #22863a; + --shiki-token-deleted: #b31d28; + --shiki-token-changed: #8250df; +} + +html.dark { + --shiki-color-text: theme("colors.tint.11"); + --shiki-token-constant: #d19a66; + --shiki-token-string: theme("colors.pomegranate.300"); + --shiki-token-comment: theme("colors.teal.300/.64"); + --shiki-token-keyword: theme("colors.pomegranate.400"); + --shiki-token-parameter: theme("colors.yellow.500"); + --shiki-token-function: #56b6c2; + --shiki-token-string-expression: theme("colors.tint.11"); + --shiki-token-punctuation: #acc6ee; + --shiki-token-link: theme("colors.pomegranate.400"); + --shiki-token-inserted: #85e89d; + --shiki-token-deleted: #fdaeb7; + --shiki-token-changed: #56b6c2; +}