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) => (
+
+ {index + 1}
+
+ {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) => (
-
- {index + 1}
-
- {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);",