From 1143bd99c146cf91ed167d17a817b4bf58e5dc79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Valverd=C3=A9?= Date: Mon, 31 Aug 2026 02:02:04 +0200 Subject: [PATCH] Fix code block design --- packages/docs/docusaurus.config.ts | 6 +- packages/docs/src/css/custom.css | 75 ++++++++++++++++++++++++ packages/docs/src/pages/index.module.css | 7 ++- packages/docs/src/prism/github-dark.ts | 58 ++++++++++++++++++ packages/docs/src/remark/line-numbers.ts | 38 ++++++++++++ 5 files changed, 180 insertions(+), 4 deletions(-) create mode 100644 packages/docs/src/prism/github-dark.ts create mode 100644 packages/docs/src/remark/line-numbers.ts diff --git a/packages/docs/docusaurus.config.ts b/packages/docs/docusaurus.config.ts index 299ace4..73bce93 100644 --- a/packages/docs/docusaurus.config.ts +++ b/packages/docs/docusaurus.config.ts @@ -2,6 +2,9 @@ import type * as Preset from "@docusaurus/preset-classic" import type { Config } from "@docusaurus/types" import { themes as prismThemes } from "prism-react-renderer" +import githubDark from "./src/prism/github-dark" +import remarkLineNumbers from "./src/remark/line-numbers" + // This runs in Node.js - Don't use client-side code here (browser APIs, JSX...) const config: Config = { @@ -43,6 +46,7 @@ const config: Config = { sidebarPath: "./sidebars.ts", editUrl: "https://github.com/Thiladev/effect-view/tree/main/packages/docs/", + remarkPlugins: [remarkLineNumbers], lastVersion: "current", versions: { current: { @@ -140,7 +144,7 @@ const config: Config = { }, prism: { theme: prismThemes.github, - darkTheme: prismThemes.oneDark, + darkTheme: githubDark, }, } satisfies Preset.ThemeConfig, } diff --git a/packages/docs/src/css/custom.css b/packages/docs/src/css/custom.css index f8081da..f35ae65 100644 --- a/packages/docs/src/css/custom.css +++ b/packages/docs/src/css/custom.css @@ -131,3 +131,78 @@ samp { background: var(--ev-zinc-900); border: 1px solid var(--ev-zinc-800); } + +/* ---------- Code blocks ---------- */ +/* One quiet, low-contrast surface - matches effect.website: a subtle step + off the page background, not a loud bordered card. */ + +.theme-code-block { + --ifm-pre-padding: 1.25rem; + background: var(--ev-zinc-50); + border: 1px solid var(--ev-zinc-200); + border-radius: 0.5rem; + box-shadow: 1.5px 1.5px 3px rgba(0, 0, 0, 0.12); +} + +[data-theme="dark"] .theme-code-block { + background: var(--ev-zinc-900); + border-color: var(--ev-zinc-800); +} + +/* The Prism theme sets its own (much louder) background inline - drop it + so the whole frame reads as one surface instead of a title/body seam. */ +.theme-code-block pre.thin-scrollbar { + background: transparent !important; +} + +/* Title renders only when a `title="..."` fence meta is present */ +.theme-code-block:has(> div + div) > div:first-child { + background: transparent; + color: var(--ev-zinc-500); + font-family: var(--ifm-font-family-monospace); + font-size: 0.78rem; + font-weight: 500; + padding: 0.9rem 1.4rem 0; +} + +.theme-code-block pre.thin-scrollbar { + font-size: 0.85rem; + line-height: 1.7; +} + +[class*="buttonGroup_"] button { + background: transparent; + border: none; + border-radius: 0.35rem; + color: var(--ev-zinc-500); +} + +[class*="buttonGroup_"] button:hover { + background: var(--ev-zinc-100); + color: var(--ev-zinc-800); +} + +[data-theme="dark"] [class*="buttonGroup_"] button:hover { + background: var(--ev-zinc-900); + color: var(--ev-zinc-100); +} + +[class*="codeLineNumber_"] { + border: none; + color: var(--ev-zinc-400); + padding-inline: 1.25rem 1rem !important; + text-align: right !important; +} + +[data-theme="dark"] [class*="codeLineNumber_"] { + color: var(--ev-zinc-600); +} + +[class*="codeLineContent_"] { + border-inline-start: 1px solid rgba(113, 113, 122, 0.2); + padding-inline-start: 1.25rem; +} + +[class*="codeLineNumber_"]::before { + opacity: 1 !important; +} diff --git a/packages/docs/src/pages/index.module.css b/packages/docs/src/pages/index.module.css index e0f5bd9..d63ca0a 100644 --- a/packages/docs/src/pages/index.module.css +++ b/packages/docs/src/pages/index.module.css @@ -280,15 +280,16 @@ } .codeWindow :global(.theme-code-block) { + border: 0; border-radius: 0; box-shadow: none; margin: 0; } -.codeWindow :global(.theme-code-block pre) { +.codeWindow :global(.theme-code-block pre.thin-scrollbar) { background: var(--home-terminal-bg) !important; - font-size: 0.8rem; - line-height: 1.62; + font-size: 0.8rem !important; + line-height: 1.62 !important; max-height: none; padding: 1.4rem 1.6rem !important; } diff --git a/packages/docs/src/prism/github-dark.ts b/packages/docs/src/prism/github-dark.ts new file mode 100644 index 0000000..1b5bf44 --- /dev/null +++ b/packages/docs/src/prism/github-dark.ts @@ -0,0 +1,58 @@ +import type { PrismTheme } from "prism-react-renderer" + +/** + * Matches the classic "GitHub Dark" token palette effect.website uses for + * its dark-mode code blocks (extracted from their rendered token styles) - + * prism-react-renderer doesn't ship this one as a preset. + */ +const githubDark: PrismTheme = { + plain: { + color: "#e1e4e8", + backgroundColor: "transparent", + }, + styles: [ + { + types: ["comment", "prolog", "doctype", "cdata"], + style: { color: "#6a737d" }, + }, + { + types: ["punctuation", "operator", "entity", "url", "variable"], + style: { color: "#e1e4e8" }, + }, + { + types: [ + "number", + "boolean", + "constant", + "symbol", + "deleted", + "class-name", + "maybe-class-name", + "builtin", + ], + style: { color: "#79b8ff" }, + }, + { + types: ["selector", "attr-name", "string", "char", "inserted", "attr-value"], + style: { color: "#9ecbff" }, + }, + { + types: ["atrule", "keyword"], + style: { color: "#f97583" }, + }, + { + types: ["function", "method"], + style: { color: "#b392f0" }, + }, + { + types: ["regex", "important"], + style: { color: "#ffab70" }, + }, + { + types: ["tag"], + style: { color: "#85e89d" }, + }, + ], +} + +export default githubDark diff --git a/packages/docs/src/remark/line-numbers.ts b/packages/docs/src/remark/line-numbers.ts new file mode 100644 index 0000000..a9a4b10 --- /dev/null +++ b/packages/docs/src/remark/line-numbers.ts @@ -0,0 +1,38 @@ +const numberedLanguages = new Set(["ts", "tsx", "js", "jsx"]) + +interface MdastNode { + type: string + lang?: string + meta?: string | null + value?: string + children?: MdastNode[] +} + +function visitCodeNodes(node: MdastNode, onCode: (code: MdastNode) => void): void { + if (!node.children) return + for (const child of node.children) { + if (child.type === "code") onCode(child) + visitCodeNodes(child, onCode) + } +} + +/** + * Turns on line numbers for multi-line ts/tsx/js/jsx fences that don't + * already opt in or out, matching Effect's docs code block presentation. + */ +export default function remarkLineNumbers() { + return (tree: MdastNode) => { + visitCodeNodes(tree, (code) => { + const lang = (code.lang ?? "").toLowerCase() + if (!numberedLanguages.has(lang)) return + + const meta = code.meta ?? "" + if (/showLineNumbers/.test(meta)) return + + const lineCount = (code.value ?? "").split("\n").length + if (lineCount <= 1) return + + code.meta = `${meta} showLineNumbers`.trim() + }) + } +}