fet(client/jsx): basic support for JSX render notes

This commit is contained in:
Elian Doran 2025-12-21 11:17:51 +02:00
parent 6e67da7b1f
commit e6b79e83c4
No known key found for this signature in database

View File

@ -1,6 +1,10 @@
import server from "./server.js"; import { h, VNode } from "preact";
import bundleService, { type Bundle } from "./bundle.js";
import type FNote from "../entities/fnote.js"; import type FNote from "../entities/fnote.js";
import { renderReactWidgetAtElement } from "../widgets/react/react_utils.jsx";
import bundleService, { type Bundle } from "./bundle.js";
import froca from "./froca.js";
import server from "./server.js";
async function render(note: FNote, $el: JQuery<HTMLElement>) { async function render(note: FNote, $el: JQuery<HTMLElement>) {
const relations = note.getRelations("renderNote"); const relations = note.getRelations("renderNote");
@ -17,12 +21,34 @@ async function render(note: FNote, $el: JQuery<HTMLElement>) {
$scriptContainer.append(bundle.html); $scriptContainer.append(bundle.html);
// async so that scripts cannot block trilium execution // async so that scripts cannot block trilium execution
bundleService.executeBundle(bundle, note, $scriptContainer); bundleService.executeBundle(bundle, note, $scriptContainer).then(result => {
// Render JSX
if (bundle.html === "") {
renderIfJsx(bundle, result, $el);
}
});
} }
return renderNoteIds.length > 0; return renderNoteIds.length > 0;
} }
async function renderIfJsx(bundle: Bundle, result: unknown, $el: JQuery<HTMLElement>) {
// Ensure the root script note is actually a JSX.
const rootScriptNoteId = await froca.getNote(bundle.noteId);
if (rootScriptNoteId?.mime !== "text/jsx") return;
// Ensure the output is a valid el.
if (typeof result !== "function") return;
// Obtain the parent component.
const closestComponent = glob.getComponentByEl($el.closest(".component")[0]);
if (!closestComponent) return;
// Render the element.
const el = h(result as () => VNode, {});
renderReactWidgetAtElement(closestComponent, el, $el[0]);
}
export default { export default {
render render
}; };