Skip to content

Commit 8d4914f

Browse files
committed
highlight the json content of the api requests
1 parent 774d312 commit 8d4914f

4 files changed

Lines changed: 127 additions & 3 deletions

File tree

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
"react": "^19.2.0",
6565
"react-dom": "^19.2.0",
6666
"react-resizable-panels": "^3.0.6",
67+
"shiki": "^3.21.0",
6768
"sonner": "^2.0.7",
6869
"tailwind-merge": "^3.4.0",
6970
"tailwindcss": "^4.1.17",

pnpm-lock.yaml

Lines changed: 66 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/components/ApiRequestsPanel.tsx

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { userPreferencesCollection } from "@/collections/UserPreferences";
1515
import { cn } from "@/lib/utils";
1616
import { HighlightWrapper } from "@/utils/highlight-collection-related-info";
1717
import { USER_PLACEHOLDER } from "@/utils/USER_PLACEHOLDER_CONSTANT";
18+
import { CodeHighlighter } from "./CodeHighlighter";
1819
import { Badge } from "./ui/badge";
1920
import { Button } from "./ui/button";
2021
import {
@@ -58,6 +59,9 @@ function JsonViewer({
5859
return null;
5960
}
6061

62+
const jsonString =
63+
typeof data === "string" ? data : JSON.stringify(data, null, 2);
64+
6165
return (
6266
<Collapsible open={isOpen} onOpenChange={setIsOpen}>
6367
<CollapsibleTrigger className="flex items-center gap-1 text-xs text-muted-foreground hover:text-foreground transition-colors">
@@ -69,9 +73,7 @@ function JsonViewer({
6973
{label}
7074
</CollapsibleTrigger>
7175
<CollapsibleContent>
72-
<pre className="mt-1 whitespace-pre-wrap p-2 bg-muted/50 rounded text-xs overflow-x-auto max-h-40 overflow-y-auto">
73-
{typeof data === "string" ? data : JSON.stringify(data, null, 2)}
74-
</pre>
76+
<CodeHighlighter code={jsonString} language="json" />
7577
</CollapsibleContent>
7678
</Collapsible>
7779
);

src/components/CodeHighlighter.tsx

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import { useEffect, useState } from "react";
2+
import { type BundledLanguage, codeToHtml } from "shiki";
3+
4+
type CodeHighlighterProps = {
5+
code: string;
6+
language?: BundledLanguage;
7+
};
8+
9+
const className =
10+
"mt-1 rounded-md text-xs overflow-x-auto max-h-40 overflow-y-auto [&_.shiki]:p-3! [&_.shiki]:m-0! [&_.shiki]:bg-muted/50 [&_.shiki]:border [&_.shiki]:border-border/50 [&_.shiki]:rounded-md! [&_.shiki]:[--shiki-light-bg:transparent] [&_.shiki]:[--shiki-dark-bg:transparent] [&_.shiki_span]:[--shiki-light-bg:transparent] [&_.shiki_span]:[--shiki-dark-bg:transparent]";
11+
12+
export function CodeHighlighter({
13+
code,
14+
language = "json",
15+
}: CodeHighlighterProps) {
16+
const [html, setHtml] = useState<string | null>(null);
17+
18+
useEffect(() => {
19+
let cancelled = false;
20+
21+
codeToHtml(code, {
22+
lang: language,
23+
themes: {
24+
light: "material-theme-lighter",
25+
dark: "material-theme-darker",
26+
},
27+
defaultColor: false,
28+
}).then((result) => {
29+
if (!cancelled) {
30+
setHtml(result);
31+
}
32+
});
33+
34+
return () => {
35+
cancelled = true;
36+
};
37+
}, [code, language]);
38+
39+
if (html === null) {
40+
// Show plain text while loading
41+
return (
42+
<pre className={className}>
43+
<code>{code}</code>
44+
</pre>
45+
);
46+
}
47+
48+
return (
49+
<div
50+
className={className}
51+
// biome-ignore lint/security/noDangerouslySetInnerHtml: Shiki output is safe
52+
dangerouslySetInnerHTML={{ __html: html }}
53+
/>
54+
);
55+
}

0 commit comments

Comments
 (0)