Register Prism's common languages in twui CodeBlock

- Load refractor's ~36 common languages plus docker, nginx, toml,
  powershell, jsx and tsx (was 6)
- Expand TWUIPrismLanguages to 54 names/aliases for autocomplete;
  `language` now also accepts any registered refractor name
- RemoteCodeBlock re-exports the list instead of keeping a stale copy

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
2026-10-16 06:46:19 +01:00
co-authored by Claude Opus 5.5
parent 548a934008
commit 1462067e72
3 changed files with 84 additions and 21 deletions
@@ -1,18 +1,19 @@
import { refractor } from "refractor/core"; // `refractor` (not `refractor/core`) preloads Prism's ~36 common languages
import bash from "refractor/bash"; import { refractor } from "refractor";
import ini from "refractor/ini"; import docker from "refractor/docker";
import javascript from "refractor/javascript"; import jsx from "refractor/jsx";
import json from "refractor/json"; import nginx from "refractor/nginx";
import typescript from "refractor/typescript"; import powershell from "refractor/powershell";
import yaml from "refractor/yaml"; import toml from "refractor/toml";
import tsx from "refractor/tsx";
import type { Root } from "hast"; import type { Root } from "hast";
refractor.register(bash); refractor.register(docker);
refractor.register(ini); refractor.register(jsx);
refractor.register(javascript); refractor.register(nginx);
refractor.register(json); refractor.register(powershell);
refractor.register(typescript); refractor.register(toml);
refractor.register(yaml); refractor.register(tsx);
type Params = { type Params = {
code: string; code: string;
@@ -23,7 +24,9 @@ type Params = {
* # Highlight a code string with Prism (via refractor) * # Highlight a code string with Prism (via refractor)
* *
* Returns a hast tree of `.token` spans, or `null` when the * Returns a hast tree of `.token` spans, or `null` when the
* language is missing or not registered. * language is missing or not registered. More languages can be added
* app-side with `refractor.register(lang)` from `refractor/core`
* (same instance).
*/ */
export default function highlightCode({ code, language }: Params): Root | null { export default function highlightCode({ code, language }: Params): Root | null {
if (!language || !refractor.registered(language)) { if (!language || !refractor.registered(language)) {
+66 -6
View File
@@ -12,16 +12,74 @@ import Divider from "../layout/Divider";
import highlightCode from "../(functions)/code-block/highlight-code"; import highlightCode from "../(functions)/code-block/highlight-code";
import CodeBlockHastNode from "../(partials)/CodeBlockHastNode"; import CodeBlockHastNode from "../(partials)/CodeBlockHastNode";
/**
* Languages (and aliases) registered in `highlight-code.ts`, listed for
* autocomplete. Any other name refractor knows also works; unknown names
* render as plain text.
*/
export const TWUIPrismLanguages = [ export const TWUIPrismLanguages = [
"shell", // Shell & config
"bash", "bash",
"sh",
"shell",
"powershell",
"ini", "ini",
"javascript", "toml",
"typescript",
"json",
"yaml", "yaml",
"yml",
"json",
"docker",
"dockerfile",
"nginx",
"makefile",
"diff",
// Web
"markup",
"html",
"xml",
"svg",
"css",
"scss",
"sass",
"less",
"javascript",
"js",
"jsx",
"typescript",
"ts",
"tsx",
"php",
// General purpose
"c",
"cpp",
"csharp",
"cs",
"go",
"java",
"kotlin",
"lua",
"perl",
"python",
"py",
"r",
"ruby",
"rb",
"rust",
"swift",
"objectivec",
"objc",
"basic",
"vbnet",
"arduino",
// Data & docs
"sql",
"markdown",
"md",
"regex",
] as const; ] as const;
export type TWUIPrismLanguage = (typeof TWUIPrismLanguages)[number];
/** `auto` follows the `.dark` class on `<html>`; `light`/`dark` pin the palette */ /** `auto` follows the `.dark` class on `<html>`; `light`/`dark` pin the palette */
export const TWUICodeBlockThemes = ["auto", "light", "dark"] as const; export const TWUICodeBlockThemes = ["auto", "light", "dark"] as const;
@@ -36,7 +94,7 @@ type Props = PropsWithChildren &
"data-title"?: string; "data-title"?: string;
backgroundColor?: string; backgroundColor?: string;
singleBlock?: boolean; singleBlock?: boolean;
language?: (typeof TWUIPrismLanguages)[number]; language?: TWUIPrismLanguage | (string & {});
/** Colour palette. Defaults to `auto` (follows the page theme) */ /** Colour palette. Defaults to `auto` (follows the page theme) */
theme?: TWUICodeBlockTheme; theme?: TWUICodeBlockTheme;
}; };
@@ -92,7 +150,9 @@ export default function CodeBlock({
? "0 0 10px 10px rgba(18, 139, 99, 0.2)" ? "0 0 10px 10px rgba(18, 139, 99, 0.2)"
: undefined, : undefined,
...(backgroundColor ...(backgroundColor
? ({ "--twui-code-bg": backgroundColor } as React.CSSProperties) ? ({
"--twui-code-bg": backgroundColor,
} as React.CSSProperties)
: {}), : {}),
...wrapperProps?.style, ...wrapperProps?.style,
}} }}
@@ -5,7 +5,7 @@ import rehypePrismPlus from "rehype-prism-plus";
import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote"; import { MDXRemote, type MDXRemoteSerializeResult } from "next-mdx-remote";
import { useMDXComponents } from "../mdx/mdx-components"; import { useMDXComponents } from "../mdx/mdx-components";
export const TWUIPrismLanguages = ["shell", "javascript"] as const; export { TWUIPrismLanguages } from "./CodeBlock";
type Props = { type Props = {
content: string; content: string;