feat: add Journal server documentation to DocDialog
Introduce a new documentation set for Journal server functionality, including a dropdown selector in the DocDialog to switch between "directives" and "journal" documentation modes.
This commit is contained in:
@@ -7,6 +7,10 @@ import {
|
||||
onMount,
|
||||
} from "solid-js";
|
||||
import { docEntries, type DocEntry } from "./doc-data";
|
||||
import { journalDocEntries, type JournalDocEntry } from "./journal-doc-data";
|
||||
|
||||
type DocSet = "directives" | "journal";
|
||||
type AnyEntry = DocEntry | JournalDocEntry;
|
||||
|
||||
export interface DocDialogProps {
|
||||
isOpen: boolean;
|
||||
@@ -14,17 +18,42 @@ export interface DocDialogProps {
|
||||
}
|
||||
|
||||
const DocDialog: Component<DocDialogProps> = (props) => {
|
||||
const [docSet, setDocSet] = createSignal<DocSet>("directives");
|
||||
const [selectedTag, setSelectedTag] = createSignal(docEntries[0]?.tag ?? "");
|
||||
const [dropdownOpen, setDropdownOpen] = createSignal(false);
|
||||
let dropdownRef!: HTMLDivElement;
|
||||
|
||||
const currentEntries = () =>
|
||||
docSet() === "directives"
|
||||
? (docEntries as AnyEntry[])
|
||||
: (journalDocEntries as AnyEntry[]);
|
||||
|
||||
const selectedEntry = () =>
|
||||
docEntries.find((e) => e.tag === selectedTag()) ?? docEntries[0];
|
||||
currentEntries().find((e) => e.tag === selectedTag()) ??
|
||||
currentEntries()[0];
|
||||
|
||||
const docSetLabel = () =>
|
||||
docSet() === "directives" ? "指令组件文档" : "Journal 服务器文档";
|
||||
|
||||
const handleKeyDown = (e: KeyboardEvent) => {
|
||||
if (e.key === "Escape") props.onClose();
|
||||
};
|
||||
|
||||
const switchDocSet = (set: DocSet) => {
|
||||
setDocSet(set);
|
||||
setDropdownOpen(false);
|
||||
const entries = set === "directives" ? docEntries : journalDocEntries;
|
||||
setSelectedTag(entries[0]?.tag ?? "");
|
||||
};
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleKeyDown);
|
||||
// Close dropdown on outside click
|
||||
document.addEventListener("click", (e) => {
|
||||
if (dropdownRef && !dropdownRef.contains(e.target as Node)) {
|
||||
setDropdownOpen(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
onCleanup(() => {
|
||||
@@ -41,7 +70,47 @@ const DocDialog: Component<DocDialogProps> = (props) => {
|
||||
>
|
||||
<div class="bg-white rounded-lg shadow-2xl w-full max-w-4xl max-h-[85vh] flex flex-col overflow-hidden">
|
||||
<div class="flex items-center justify-between px-6 py-4 border-b border-gray-200 shrink-0">
|
||||
<h2 class="text-lg font-bold text-gray-900">指令组件文档</h2>
|
||||
<div ref={dropdownRef} class="relative">
|
||||
<button
|
||||
onClick={() => setDropdownOpen((v) => !v)}
|
||||
class="text-lg font-bold text-gray-900 hover:text-blue-600 flex items-center gap-1"
|
||||
>
|
||||
{docSetLabel()}
|
||||
<span class="text-gray-400 text-sm">▾</span>
|
||||
</button>
|
||||
<Show when={dropdownOpen()}>
|
||||
<div class="absolute top-full left-0 mt-1 w-52 bg-white border border-gray-200 rounded shadow-lg z-50 py-1">
|
||||
<button
|
||||
onClick={() => switchDocSet("directives")}
|
||||
class={`w-full text-left px-3 py-2 text-sm hover:bg-gray-100 flex items-center gap-2 ${
|
||||
docSet() === "directives"
|
||||
? "bg-blue-50 text-blue-700"
|
||||
: "text-gray-700"
|
||||
}`}
|
||||
>
|
||||
<span>📖</span>
|
||||
<span>指令组件文档</span>
|
||||
<Show when={docSet() === "directives"}>
|
||||
<span class="ml-auto text-blue-500">✓</span>
|
||||
</Show>
|
||||
</button>
|
||||
<button
|
||||
onClick={() => switchDocSet("journal")}
|
||||
class={`w-full text-left px-3 py-2 text-sm hover:bg-gray-100 flex items-center gap-2 ${
|
||||
docSet() === "journal"
|
||||
? "bg-blue-50 text-blue-700"
|
||||
: "text-gray-700"
|
||||
}`}
|
||||
>
|
||||
<span>📋</span>
|
||||
<span>Journal 服务器文档</span>
|
||||
<Show when={docSet() === "journal"}>
|
||||
<span class="ml-auto text-blue-500">✓</span>
|
||||
</Show>
|
||||
</button>
|
||||
</div>
|
||||
</Show>
|
||||
</div>
|
||||
<button
|
||||
onClick={props.onClose}
|
||||
class="text-gray-400 hover:text-gray-600 text-xl leading-none p-1"
|
||||
@@ -53,7 +122,7 @@ const DocDialog: Component<DocDialogProps> = (props) => {
|
||||
|
||||
<div class="flex flex-1 min-h-0">
|
||||
<nav class="w-48 shrink-0 border-r border-gray-200 overflow-y-auto p-3 bg-gray-50">
|
||||
<For each={docEntries}>
|
||||
<For each={currentEntries()}>
|
||||
{(entry) => (
|
||||
<button
|
||||
onClick={() => setSelectedTag(entry.tag)}
|
||||
@@ -64,7 +133,12 @@ const DocDialog: Component<DocDialogProps> = (props) => {
|
||||
}`}
|
||||
>
|
||||
<span class="mr-2">{entry.icon}</span>
|
||||
<span class="font-mono text-xs">{`:${entry.tag}`}</span>
|
||||
<Show
|
||||
when={docSet() === "directives"}
|
||||
fallback={<span class="text-xs">{entry.title}</span>}
|
||||
>
|
||||
<span class="font-mono text-xs">{`:${entry.tag}`}</span>
|
||||
</Show>
|
||||
</button>
|
||||
)}
|
||||
</For>
|
||||
@@ -83,7 +157,7 @@ const DocDialog: Component<DocDialogProps> = (props) => {
|
||||
};
|
||||
|
||||
/** Single entry documentation content */
|
||||
const DocContent: Component<{ entry: DocEntry }> = (props) => {
|
||||
const DocContent: Component<{ entry: AnyEntry }> = (props) => {
|
||||
const e = props.entry;
|
||||
|
||||
return (
|
||||
|
||||
Reference in New Issue
Block a user