feat(react): render raw react components

This commit is contained in:
Elian Doran
2025-08-20 21:50:06 +03:00
parent 8abd3ed3f1
commit afe3904ea3
13 changed files with 92 additions and 54 deletions

View File

@@ -3,7 +3,7 @@ import { t } from "../../services/i18n";
import { ComponentChildren } from "preact";
import type { CSSProperties, RefObject } from "preact/compat";
import { openDialog } from "../../services/dialog";
import { ParentComponent } from "./ReactBasicWidget";
import { ParentComponent } from "./react_utils";
import { Modal as BootstrapModal } from "bootstrap";
import { memo } from "preact/compat";

View File

@@ -1,9 +1,6 @@
import { createContext, JSX, render } from "preact";
import { JSX } from "preact";
import BasicWidget from "../basic_widget.js";
import Component from "../../components/component.js";
export const ParentComponent = createContext<Component | null>(null);
import { renderReactWidget } from "./react_utils.jsx";
export default abstract class ReactBasicWidget extends BasicWidget {
abstract get component(): JSX.Element;
@@ -13,27 +10,3 @@ export default abstract class ReactBasicWidget extends BasicWidget {
}
}
/**
* Renders a React component and returns the corresponding DOM element wrapped in JQuery.
*
* @param parentComponent the parent Trilium component for the component to be able to handle events.
* @param el the JSX element to render.
* @returns the rendered wrapped DOM element.
*/
export function renderReactWidget(parentComponent: Component, el: JSX.Element) {
return renderReactWidgetAtElement(parentComponent, el, new DocumentFragment()).children();
}
export function renderReactWidgetAtElement(parentComponent: Component, el: JSX.Element, container: Element | DocumentFragment) {
render((
<ParentComponent.Provider value={parentComponent}>
{el}
</ParentComponent.Provider>
), container);
return $(container) as JQuery<HTMLElement>;
}
export function disposeReactWidget(container: Element) {
render(null, container);
}

View File

@@ -1,6 +1,6 @@
import { useCallback, useContext, useEffect, useMemo, useRef, useState } from "preact/hooks";
import { EventData, EventNames } from "../../components/app_context";
import { ParentComponent } from "./ReactBasicWidget";
import { ParentComponent } from "./react_utils";
import SpacedUpdate from "../../services/spaced_update";
import { OptionNames } from "@triliumnext/commons";
import options, { type OptionValue } from "../../services/options";

View File

@@ -1,15 +0,0 @@
import type { RefObject } from "preact";
/**
* Takes in a React ref and returns a corresponding JQuery selector.
*
* @param ref the React ref from which to obtain the jQuery selector.
* @returns the corresponding jQuery selector.
*/
export function refToJQuerySelector<T extends HTMLElement>(ref: RefObject<T> | null): JQuery<T> {
if (ref?.current) {
return $(ref.current);
} else {
return $();
}
}

View File

@@ -0,0 +1,42 @@
import { createContext, render, type JSX, type RefObject } from "preact";
import Component from "../../components/component";
export const ParentComponent = createContext<Component | null>(null);
/**
* Takes in a React ref and returns a corresponding JQuery selector.
*
* @param ref the React ref from which to obtain the jQuery selector.
* @returns the corresponding jQuery selector.
*/
export function refToJQuerySelector<T extends HTMLElement>(ref: RefObject<T> | null): JQuery<T> {
if (ref?.current) {
return $(ref.current);
} else {
return $();
}
}
/**
* Renders a React component and returns the corresponding DOM element wrapped in JQuery.
*
* @param parentComponent the parent Trilium component for the component to be able to handle events.
* @param el the JSX element to render.
* @returns the rendered wrapped DOM element.
*/
export function renderReactWidget(parentComponent: Component, el: JSX.Element) {
return renderReactWidgetAtElement(parentComponent, el, new DocumentFragment()).children();
}
export function renderReactWidgetAtElement(parentComponent: Component, el: JSX.Element, container: Element | DocumentFragment) {
render((
<ParentComponent.Provider value={parentComponent}>
{el}
</ParentComponent.Provider>
), container);
return $(container) as JQuery<HTMLElement>;
}
export function disposeReactWidget(container: Element) {
render(null, container);
}