feat: add Fira Code Variable font and enhance snippet editor with Shiki highlighter

This commit is contained in:
ngc2207 2024-11-23 00:58:07 +08:00
parent 8d90b08925
commit 83b8380f04
3 changed files with 59 additions and 18 deletions

View File

@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@fontsource-variable/fira-code": "^5.1.0",
"@monaco-editor/react": "^4.6.0",
"@radix-ui/react-avatar": "^1.1.1",
"@radix-ui/react-collapsible": "^1.1.1",
@ -23,6 +24,7 @@
"clsx": "^2.1.1",
"devicons-react": "^1.3.0",
"lucide-react": "^0.460.0",
"monaco-editor-core": "^0.52.0",
"next": "15.0.3",
"next-themes": "^0.4.3",
"prisma": "^5.22.0",

View File

@ -1,38 +1,77 @@
"use client";
import "@fontsource-variable/fira-code";
import { Snippet } from "@prisma/client";
import { Editor } from "@monaco-editor/react";
import { createHighlighter } from "shiki";
import { useEffect, useRef } from "react";
import * as monaco from "monaco-editor-core";
import { shikiToMonaco } from "@shikijs/monaco";
interface SnippetShowFormProps {
snippet: Snippet;
}
export function SnippetShowForm({ snippet }: SnippetShowFormProps) {
return (
<div className="flex-grow">
<Editor
height="100vh"
theme="vs-light"
language={snippet.language}
defaultValue={snippet.code}
options={{
const editorContainerRef = useRef<HTMLDivElement>(null);
const editorRef = useRef<monaco.editor.IStandaloneCodeEditor | null>(null);
useEffect(() => {
async function initializeEditor() {
const highlighter = await createHighlighter({
themes: ["one-dark-pro"],
langs: [snippet.language],
});
monaco.languages.register({ id: snippet.language });
shikiToMonaco(highlighter, monaco);
const editorContainer = editorContainerRef.current;
if (!editorContainer) {
throw new Error("Editor container not found");
}
if (!editorRef.current) {
editorRef.current = monaco.editor.create(editorContainer, {
value: snippet.code,
language: snippet.language,
theme: "vitesse-light",
readOnly: true,
minimap: { enabled: false },
scrollbar: {
vertical: "hidden",
horizontal: "hidden",
verticalScrollbarSize: 0,
horizontalScrollbarSize: 0,
vertical: "auto",
horizontal: "auto",
// verticalScrollbarSize: 0,
// horizontalScrollbarSize: 0,
},
scrollBeyondLastLine: false,
// scrollBeyondLastLine: false,
guides: {
bracketPairs: true,
indentation: true,
},
showFoldingControls: "always",
fontSize: 14,
}}
/>
</div>
fontFamily: "Fira Code Variable, monospace",
fontLigatures: true,
automaticLayout: true,
});
}
}
initializeEditor();
return () => {
if (editorRef.current) {
editorRef.current.dispose();
editorRef.current = null;
}
};
}, [snippet]);
return (
<div
ref={editorContainerRef}
style={{ height: "100vh" }}
></div>
);
}

View File

@ -27,7 +27,7 @@ export default async function SnippetsPage() {
</div>
</div>
<Separator className="my-4" />
<div className="grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
<div className="grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-4">
{renderedSnippets}
</div>
</div>