diff --git a/package.json b/package.json index e47247f..fb4e4f8 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/src/app/dashboard/snippets/components/snippet-show-form.tsx b/src/app/dashboard/snippets/components/snippet-show-form.tsx index 749869c..d95b539 100644 --- a/src/app/dashboard/snippets/components/snippet-show-form.tsx +++ b/src/app/dashboard/snippets/components/snippet-show-form.tsx @@ -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 ( -
- (null); + const editorRef = useRef(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, - }} - /> -
+ fontFamily: "Fira Code Variable, monospace", + fontLigatures: true, + automaticLayout: true, + }); + } + } + + initializeEditor(); + + return () => { + if (editorRef.current) { + editorRef.current.dispose(); + editorRef.current = null; + } + }; + }, [snippet]); + + return ( +
); } diff --git a/src/app/dashboard/snippets/page.tsx b/src/app/dashboard/snippets/page.tsx index 1271437..49fb740 100644 --- a/src/app/dashboard/snippets/page.tsx +++ b/src/app/dashboard/snippets/page.tsx @@ -27,7 +27,7 @@ export default async function SnippetsPage() { -
+
{renderedSnippets}