refactor: simplify DocDialog and move documentation to markdown body
Simplify the `DocDialog` component by removing hardcoded property tables and syntax blocks. Instead, rely on the raw markdown body provided in the `DocEntry` to render documentation content. This shifts the responsibility of formatting (syntax, props, etc.) from the component to the individual markdown files, allowing for more flexible and detailed documentation.
This commit is contained in:
@@ -162,73 +162,12 @@ const DocContent: Component<{ entry: AnyEntry }> = (props) => {
|
||||
|
||||
return (
|
||||
<div class="max-w-none">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-2">
|
||||
<h2 class="text-2xl font-bold text-gray-900 mb-6">
|
||||
{e.icon} {e.title}
|
||||
<code class="ml-3 text-base font-mono bg-gray-100 px-2 py-0.5 rounded text-blue-700">
|
||||
:{e.tag}
|
||||
</code>
|
||||
</h2>
|
||||
|
||||
<p class="text-gray-600 mb-6">{e.description}</p>
|
||||
|
||||
<div class="mb-6">
|
||||
<h3 class="text-sm font-semibold text-gray-500 uppercase mb-2">
|
||||
基本语法
|
||||
</h3>
|
||||
<pre class="bg-gray-900 text-gray-100 px-4 py-3 rounded-lg text-sm overflow-x-auto">
|
||||
<code>{e.syntax}</code>
|
||||
</pre>
|
||||
</div>
|
||||
|
||||
<Show when={e.props.length > 0}>
|
||||
<div class="mb-6">
|
||||
<h3 class="text-sm font-semibold text-gray-500 uppercase mb-2">
|
||||
属性
|
||||
</h3>
|
||||
<table class="w-full text-sm border-collapse">
|
||||
<thead>
|
||||
<tr class="border-b border-gray-200">
|
||||
<th class="text-left py-2 pr-4 font-medium text-gray-600">
|
||||
属性
|
||||
</th>
|
||||
<th class="text-left py-2 pr-4 font-medium text-gray-600">
|
||||
类型
|
||||
</th>
|
||||
<th class="text-left py-2 pr-4 font-medium text-gray-600">
|
||||
默认值
|
||||
</th>
|
||||
<th class="text-left py-2 font-medium text-gray-600">说明</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<For each={e.props}>
|
||||
{(prop) => (
|
||||
<tr class="border-b border-gray-100">
|
||||
<td class="py-2 pr-4">
|
||||
<code class="bg-gray-100 px-1.5 py-0.5 rounded text-xs text-pink-700">
|
||||
{prop.name}
|
||||
</code>
|
||||
</td>
|
||||
<td class="py-2 pr-4">
|
||||
<code class="text-xs text-gray-600">{prop.type}</code>
|
||||
</td>
|
||||
<td class="py-2 pr-4 text-xs text-gray-400">
|
||||
{prop.default ?? "—"}
|
||||
</td>
|
||||
<td class="py-2 text-sm text-gray-600">{prop.desc}</td>
|
||||
</tr>
|
||||
)}
|
||||
</For>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
<div class="prose-sm max-w-none">
|
||||
<h3 class="text-sm font-semibold text-gray-500 uppercase mb-2">示例</h3>
|
||||
<div class="bg-gray-50 border border-gray-200 rounded-lg p-4 text-sm leading-relaxed whitespace-pre-wrap font-mono text-gray-800">
|
||||
{e.body}
|
||||
</div>
|
||||
<div class="text-sm leading-relaxed whitespace-pre-wrap text-gray-800">
|
||||
{e.body}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -4,16 +4,12 @@ export interface DocEntry {
|
||||
tag: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
syntax: string;
|
||||
props: { name: string; type: string; default?: string; desc: string }[];
|
||||
/** Markdown body (everything after frontmatter ---) */
|
||||
/** Full markdown body (everything after frontmatter ---) */
|
||||
body: string;
|
||||
}
|
||||
|
||||
/** Splits frontmatter and markdown body from a raw .md string. */
|
||||
function parseFrontmatter(raw: string): Record<string, unknown> | null {
|
||||
// Handle CRLF line endings by normalizing to LF first
|
||||
const normalized = raw.replace(/\r\n/g, "\n");
|
||||
const match = normalized.match(/^---\n([\s\S]*?)\n---\n?([\s\S]*)$/);
|
||||
if (!match) return null;
|
||||
@@ -27,7 +23,7 @@ function parseFrontmatter(raw: string): Record<string, unknown> | null {
|
||||
function getBody(raw: string): string {
|
||||
const normalized = raw.replace(/\r\n/g, "\n");
|
||||
const match = normalized.match(/^---\n[\s\S]*?\n---\n?([\s\S]*)$/);
|
||||
return match ? match[1] : raw;
|
||||
return (match ? match[1] : raw).trim();
|
||||
}
|
||||
|
||||
function parseEntry(raw: string): DocEntry | null {
|
||||
@@ -37,9 +33,6 @@ function parseEntry(raw: string): DocEntry | null {
|
||||
tag: fm.tag as string,
|
||||
icon: fm.icon as string,
|
||||
title: fm.title as string,
|
||||
description: fm.description as string,
|
||||
syntax: fm.syntax as string,
|
||||
props: (fm.props as DocEntry["props"]) ?? [],
|
||||
body: getBody(raw),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -4,9 +4,7 @@ export interface JournalDocEntry {
|
||||
tag: string;
|
||||
icon: string;
|
||||
title: string;
|
||||
description: string;
|
||||
syntax: string;
|
||||
props: { name: string; type: string; default?: string; desc: string }[];
|
||||
/** Full markdown body (everything after frontmatter ---) */
|
||||
body: string;
|
||||
}
|
||||
|
||||
@@ -24,7 +22,7 @@ function parseFrontmatter(raw: string): Record<string, unknown> | null {
|
||||
function getBody(raw: string): string {
|
||||
const normalized = raw.replace(/\r\n/g, "\n");
|
||||
const match = normalized.match(/^---\n[\s\S]*?\n---\n?([\s\S]*)$/);
|
||||
return match ? match[1] : raw;
|
||||
return (match ? match[1] : raw).trim();
|
||||
}
|
||||
|
||||
function parseEntry(raw: string): JournalDocEntry | null {
|
||||
@@ -34,9 +32,6 @@ function parseEntry(raw: string): JournalDocEntry | null {
|
||||
tag: fm.tag as string,
|
||||
icon: fm.icon as string,
|
||||
title: fm.title as string,
|
||||
description: fm.description as string,
|
||||
syntax: fm.syntax as string,
|
||||
props: (fm.props as JournalDocEntry["props"]) ?? [],
|
||||
body: getBody(raw),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user