From 6434a5acc0e26936821a8a9ea02cf55948fcb105 Mon Sep 17 00:00:00 2001 From: ydliu2 Date: Tue, 2 Jun 2026 06:26:18 +0800 Subject: [PATCH] fix(docs): restore component page code highlighting --- .../app/components/components-page-client.tsx | 57 +++++++++++-------- apps/docs/app/site.css | 18 +++++- apps/docs/scripts/check-code-blocks.mjs | 44 ++++++++++++++ 3 files changed, 93 insertions(+), 26 deletions(-) diff --git a/apps/docs/app/components/components-page-client.tsx b/apps/docs/app/components/components-page-client.tsx index 35cf771..83520fe 100644 --- a/apps/docs/app/components/components-page-client.tsx +++ b/apps/docs/app/components/components-page-client.tsx @@ -220,10 +220,39 @@ function CommandBlock({ children }: { children: string }) { ) } +function HighlightedTsxBlock({ code, filename, variant = "source" }: { code: string; filename: string; variant?: "source" | "usage" }) { + const lines = code.split("\n") + + return ( +
+      
+        {lines.map((line, index) => (
+          
+            
+            
+              {tokenizeTsxLine(line).map((token, tokenIndex) =>
+                token.kind ? (
+                  
+                    {token.text}
+                  
+                ) : (
+                  {token.text}
+                )
+              )}
+            
+          
+        ))}
+      
+    
+ ) +} + function SourceCodeBlock({ code, filename }: { code: string; filename: string }) { const [copyLabel, setCopyLabel] = useState("Copy") const [collapsed, setCollapsed] = useState(false) - const lines = code.split("\n") function copyCode() { setCopyLabel("Copied") @@ -273,29 +302,7 @@ function SourceCodeBlock({ code, filename }: { code: string; filename: string }) -
-        
-          {lines.map((line, index) => (
-            
-              
-              
-                {tokenizeTsxLine(line).map((token, tokenIndex) =>
-                  token.kind ? (
-                    
-                      {token.text}
-                    
-                  ) : (
-                    {token.text}
-                  )
-                )}
-              
-            
-          ))}
-        
-      
+ ) } @@ -766,7 +773,7 @@ function ComponentPanel({ {available ? (

Usage

- {usageSnippet(component)} +
) : null} diff --git a/apps/docs/app/site.css b/apps/docs/app/site.css index 92e51b9..76446fc 100644 --- a/apps/docs/app/site.css +++ b/apps/docs/app/site.css @@ -1429,6 +1429,11 @@ line-height: 1.85; } +.vekui-source-card__body[data-variant="usage"] { + border: 1px solid var(--vk-code-border); + margin-top: 18px; +} + .vekui-source-card[data-collapsed="true"] .vekui-source-card__body { max-height: 220px; } @@ -2713,7 +2718,8 @@ border: 0; border-radius: 0; max-height: calc(100svh - 100px); - padding: 0; + overflow-y: auto; + padding: 0 4px 0 0; } .vekui-components-nav-group + .vekui-components-nav-group { @@ -2726,6 +2732,16 @@ background: var(--vk-surface); } +.vekui-components-nav-group[aria-label="Components"] { + overflow: visible; + padding-right: 0; +} + +.vekui-components-nav-group[aria-label="Components"] p { + position: static; + z-index: auto; +} + .vekui-components-nav-item { border-radius: 0; min-height: 31px; diff --git a/apps/docs/scripts/check-code-blocks.mjs b/apps/docs/scripts/check-code-blocks.mjs index 742bd5c..33e4e67 100644 --- a/apps/docs/scripts/check-code-blocks.mjs +++ b/apps/docs/scripts/check-code-blocks.mjs @@ -16,6 +16,17 @@ function assertIncludes(source, expected, message) { } } +function assertRuleIncludes(source, selector, expected, message) { + const escapedSelector = selector.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + const blocks = [...source.matchAll(new RegExp(`${escapedSelector}\\s*\\{([\\s\\S]*?)\\n\\}`, "g"))].map( + (match) => match[1] + ) + + if (!blocks.some((block) => block.includes(expected))) { + throw new Error(message) + } +} + assertIncludes( componentPage, "tokenizeTsxLine", @@ -26,6 +37,21 @@ assertIncludes( 'className={`vekui-source-token vekui-source-token--${token.kind}`}', "Component source blocks should render semantic syntax token classes." ) +assertIncludes( + componentPage, + 'function HighlightedTsxBlock({ code, filename, variant = "source" }', + "Component docs should share one highlighted TSX block for source and usage snippets." +) +assertIncludes( + componentPage, + '', + "Component usage snippets should render through syntax-highlighted TSX blocks." +) +assertIncludes( + siteCss, + '.vekui-source-card__body[data-variant="usage"]', + "Usage code blocks should have a dedicated visual treatment when rendered outside source cards." +) assertIncludes( siteCss, "--vk-code-surface", @@ -36,6 +62,24 @@ assertIncludes( ".vekui-source-token--keyword", "Code block syntax token classes should be styled." ) +assertRuleIncludes( + siteCss, + ".vekui-components-sidebar", + "overflow-y: auto;", + "Components sidebar should own scrolling instead of clipping an inner floating section." +) +assertRuleIncludes( + siteCss, + '.vekui-components-nav-group[aria-label="Components"]', + "overflow: visible;", + "Components nav group should not create a nested scroll area that masks list items." +) +assertRuleIncludes( + siteCss, + '.vekui-components-nav-group[aria-label="Components"] p', + "position: static;", + "Components nav heading should not float over the component list." +) assertIncludes( siteCss, ".vekui-components-command {\n background: var(--vk-code-surface);",