From 28250550abf6ddd1d857aa414506224667042892 Mon Sep 17 00:00:00 2001 From: Z8MB1E Date: Sun, 6 Sep 2026 17:22:54 -0400 Subject: [PATCH] feat(wiki): add rendered template preview to template dialog Template dialog gains a rendered preview (markdown pipeline + scoped template CSS + HTML templates) alongside the existing source preview, with Rendered/Markdown toggle; editor threads the template maps through. Ultraworked with [Sisyphus](https://github.com/code-yeongju/oh-my-openagent) Co-authored-by: Sisyphus --- src/components/frontend/wiki/WikiEditor.tsx | 2 + .../frontend/wiki/WikiEditorBody.tsx | 6 ++ .../frontend/wiki/WikiTemplateDialog.tsx | 82 +++++++++++++++++-- 3 files changed, 84 insertions(+), 6 deletions(-) diff --git a/src/components/frontend/wiki/WikiEditor.tsx b/src/components/frontend/wiki/WikiEditor.tsx index b93ed0a..75d85f8 100644 --- a/src/components/frontend/wiki/WikiEditor.tsx +++ b/src/components/frontend/wiki/WikiEditor.tsx @@ -215,6 +215,8 @@ export function WikiEditor({ onLinkDialogChange={setLinkDialogOpen} pending={pending} templates={templates} + templateCssMap={templateCssMap} + templateHtmlMap={templateHtmlMap} /> diff --git a/src/components/frontend/wiki/WikiEditorBody.tsx b/src/components/frontend/wiki/WikiEditorBody.tsx index 285e848..5eb34ed 100644 --- a/src/components/frontend/wiki/WikiEditorBody.tsx +++ b/src/components/frontend/wiki/WikiEditorBody.tsx @@ -63,6 +63,8 @@ interface WikiEditorBodyProps { readonly onLinkDialogChange: (open: boolean) => void; readonly pending: boolean; readonly templates: TemplateMap; + readonly templateCssMap?: Record; + readonly templateHtmlMap?: Record; } export function WikiEditorBody({ @@ -74,6 +76,8 @@ export function WikiEditorBody({ onLinkDialogChange, pending, templates, + templateCssMap, + templateHtmlMap, }: WikiEditorBodyProps) { const fileInputRef = useRef(null); const mirrorRef = useRef(null); @@ -429,6 +433,8 @@ export function WikiEditorBody({ onOpenChange={setTemplateDialogOpen} disabled={pending} onInsert={insertTemplateBody} + templateCssMap={templateCssMap} + templateHtmlMap={templateHtmlMap} />
diff --git a/src/components/frontend/wiki/WikiTemplateDialog.tsx b/src/components/frontend/wiki/WikiTemplateDialog.tsx index 7e26ea7..64629c3 100644 --- a/src/components/frontend/wiki/WikiTemplateDialog.tsx +++ b/src/components/frontend/wiki/WikiTemplateDialog.tsx @@ -14,6 +14,9 @@ import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { cn } from "@/lib/utils"; import { extractPlaceholders, type TemplateMap } from "@/lib/wiki/templates"; +import { prepareMarkdown } from "@/lib/wiki/prepare"; +import { buildTemplateStyles } from "@/lib/wiki/templateCss"; +import { WikiPreparedBody } from "@/components/frontend/wiki/WikiContent"; interface WikiTemplateDialogProps { readonly templates: TemplateMap; @@ -21,6 +24,8 @@ interface WikiTemplateDialogProps { readonly onOpenChange: (open: boolean) => void; readonly disabled?: boolean; readonly onInsert: (body: string) => void; + readonly templateCssMap?: Record; + readonly templateHtmlMap?: Record; } function escapeRegExp(text: string): string { @@ -48,9 +53,14 @@ export function WikiTemplateDialog({ onOpenChange, disabled, onInsert, + templateCssMap, + templateHtmlMap, }: WikiTemplateDialogProps) { const [selectedName, setSelectedName] = useState(null); const [values, setValues] = useState>({}); + const [previewMode, setPreviewMode] = useState<"rendered" | "source">( + "rendered", + ); const names = useMemo(() => Object.keys(templates).sort(), [templates]); const selectedBody = selectedName !== null ? (templates[selectedName] ?? "") : ""; @@ -62,11 +72,35 @@ export function WikiTemplateDialog({ () => fillTemplate(selectedBody, values), [selectedBody, values], ); + const preparedPreview = useMemo( + () => + selectedName !== null + ? prepareMarkdown(filled, templates, templateHtmlMap ?? {}) + : "", + [selectedName, filled, templates, templateHtmlMap], + ); + const { css: previewCss, scopeClasses: previewScopeClasses } = useMemo( + () => + buildTemplateStyles( + filled, + selectedName !== null + ? [ + { + name: selectedName, + body: templates[selectedName] ?? "", + css: templateCssMap?.[selectedName] ?? null, + }, + ] + : [], + ), + [filled, selectedName, templates, templateCssMap], + ); function handleOpenChange(next: boolean) { if (!next) { setSelectedName(null); setValues({}); + setPreviewMode("rendered"); } onOpenChange(next); } @@ -143,12 +177,48 @@ export function WikiTemplateDialog({

)}
- - Preview - -
-                {filled}
-              
+
+ + Preview + +
+ + +
+
+ {previewMode === "rendered" ? ( +
+ {previewCss ? ( +