diff --git a/src/components/SyntaxHighlight.tsx b/src/components/SyntaxHighlight.tsx index e89316e..2cbe4a4 100644 --- a/src/components/SyntaxHighlight.tsx +++ b/src/components/SyntaxHighlight.tsx @@ -29,42 +29,39 @@ export function SyntaxHighlight({ }: SyntaxHighlightProps) { const { html, loading, error } = useHighlightedCode(code, language); + // Use consistent wrapper structure for all states to avoid size jumps + const wrapperClasses = cn( + "shiki-container overflow-x-auto max-w-full [&_pre]:!bg-transparent [&_pre]:!m-0 [&_code]:text-xs [&_code]:font-mono", + showLineNumbers && "line-numbers", + className, + ); + // Loading state - show code without highlighting if (loading) { return ( -
-        {code}
-      
+
+
+          {code}
+        
+
); } // Error state - fallback to plain code if (error || !html) { return ( -
-        {code}
-      
+
+
+          {code}
+        
+
); } // Render highlighted HTML return (
); diff --git a/src/components/nostr/kinds/RepositoryFilesSection.tsx b/src/components/nostr/kinds/RepositoryFilesSection.tsx index af934af..01130b9 100644 --- a/src/components/nostr/kinds/RepositoryFilesSection.tsx +++ b/src/components/nostr/kinds/RepositoryFilesSection.tsx @@ -97,23 +97,9 @@ export function RepositoryFilesSection({ ); } - // Error state + // Error state - silently hide section if (treeError) { - return ( -
-

- - Files -

-
- -
-

Unable to load repository files

-

{treeError.message}

-
-
-
- ); + return null; } // No tree available @@ -147,8 +133,22 @@ export function RepositoryFilesSection({
{selectedFile ? ( contentLoading ? ( -
- +
+
+ + {selectedFile.path} + +
+
+ + + + + + + + +
) : contentError ? (
diff --git a/src/components/ui/FileTreeView.tsx b/src/components/ui/FileTreeView.tsx index 748a43a..46a0615 100644 --- a/src/components/ui/FileTreeView.tsx +++ b/src/components/ui/FileTreeView.tsx @@ -153,7 +153,7 @@ function TreeNode({ selectedPath, depth, }: TreeNodeProps) { - const [isOpen, setIsOpen] = useState(depth === 0); + const [isOpen, setIsOpen] = useState(false); const isSelected = selectedPath === path; const handleClick = () => { diff --git a/src/lib/shiki.ts b/src/lib/shiki.ts index bc6c955..78ac8ce 100644 --- a/src/lib/shiki.ts +++ b/src/lib/shiki.ts @@ -11,8 +11,8 @@ let highlighterPromise: Promise | null = null; const loadedLanguages = new Set(); /** - * Grimoire dark theme matching current minimalistic Prism styles - * Uses muted colors with primary accent for keywords/functions + * Grimoire dark theme - minimalistic grayscale with semantic colors + * Uses muted grays for syntax with color only for diff semantics */ const grimoireTheme: ThemeRegistration = { name: "grimoire-dark", @@ -32,7 +32,7 @@ const grimoireTheme: ThemeRegistration = { scope: ["string", "string.quoted"], settings: { foreground: "#9ca3af" }, }, - // Keywords, operators - primary color + // Keywords, operators - emphasized gray { scope: [ "keyword", @@ -42,14 +42,14 @@ const grimoireTheme: ThemeRegistration = { "keyword.operator", "keyword.control", ], - settings: { foreground: "#a855f7" }, + settings: { foreground: "#d4d4d4" }, }, - // Functions, methods - primary bold + // Functions, methods - foreground bold { scope: ["entity.name.function", "support.function", "meta.function-call"], - settings: { foreground: "#a855f7", fontStyle: "bold" }, + settings: { foreground: "#e5e5e5", fontStyle: "bold" }, }, - // Classes, types - primary bold + // Classes, types - foreground bold { scope: [ "entity.name.class", @@ -57,9 +57,9 @@ const grimoireTheme: ThemeRegistration = { "support.class", "support.type", ], - settings: { foreground: "#a855f7", fontStyle: "bold" }, + settings: { foreground: "#e5e5e5", fontStyle: "bold" }, }, - // Numbers, constants - primary + // Numbers, constants - emphasized gray { scope: [ "constant", @@ -67,7 +67,7 @@ const grimoireTheme: ThemeRegistration = { "constant.language", "constant.character", ], - settings: { foreground: "#a855f7" }, + settings: { foreground: "#d4d4d4" }, }, // Variables, parameters - foreground { @@ -91,7 +91,7 @@ const grimoireTheme: ThemeRegistration = { // Tags (HTML/JSX) { scope: ["entity.name.tag", "support.class.component"], - settings: { foreground: "#a855f7" }, + settings: { foreground: "#d4d4d4" }, }, // JSON keys { @@ -124,7 +124,7 @@ const grimoireTheme: ThemeRegistration = { // Markdown headings { scope: ["markup.heading", "entity.name.section"], - settings: { foreground: "#a855f7", fontStyle: "bold" }, + settings: { foreground: "#e5e5e5", fontStyle: "bold" }, }, // Markdown bold/italic { @@ -138,7 +138,7 @@ const grimoireTheme: ThemeRegistration = { // Markdown links { scope: ["markup.underline.link"], - settings: { foreground: "#a855f7" }, + settings: { foreground: "#93c5fd" }, }, ], }; @@ -277,6 +277,8 @@ const CORE_LANGUAGES = [ "json", "diff", "bash", + "rust", + "markdown", ] as const; /** @@ -303,6 +305,8 @@ export async function getHighlighter(): Promise { import("shiki/langs/json.mjs"), import("shiki/langs/diff.mjs"), import("shiki/langs/bash.mjs"), + import("shiki/langs/rust.mjs"), + import("shiki/langs/markdown.mjs"), ], engine: createOnigurumaEngine(import("shiki/wasm")), }).then((hl) => {