chore(react/type_widget): prepare structure for split editor

This commit is contained in:
Elian Doran
2025-09-20 12:25:11 +03:00
parent 256d1863d2
commit bed3c2dc67
7 changed files with 122 additions and 108 deletions

View File

@@ -16,6 +16,7 @@ import "./NoteDetail.css";
import File from "./type_widgets/File"; import File from "./type_widgets/File";
import Image from "./type_widgets/Image"; import Image from "./type_widgets/Image";
import { ReadOnlyCode, EditableCode } from "./type_widgets/code/Code"; import { ReadOnlyCode, EditableCode } from "./type_widgets/code/Code";
import Mermaid from "./type_widgets/Mermaid";
/** /**
* A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one, * A `NoteType` altered by the note detail widget, taking into consideration whether the note is editable or not and adding special note types such as an empty one,
@@ -94,6 +95,7 @@ function getCorrespondingWidget(noteType: ExtendedNoteType | undefined, props: T
case "image": return <Image {...props} /> case "image": return <Image {...props} />
case "readOnlyCode": return <ReadOnlyCode {...props} /> case "readOnlyCode": return <ReadOnlyCode {...props} />
case "editableCode": return <EditableCode {...props} /> case "editableCode": return <EditableCode {...props} />
case "mermaid": return <Mermaid {...props} />
default: break; default: break;
} }
} }

View File

@@ -0,0 +1,6 @@
import SvgSplitEditor from "./helpers/SvgSplitEditor";
import { TypeWidgetProps } from "./type_widget";
export default function Mermaid(props: TypeWidgetProps) {
return <SvgSplitEditor {...props} />;
}

View File

@@ -0,0 +1,80 @@
.note-detail-split {
display: flex;
height: 100%;
}
.note-detail-split-editor-col {
display: flex;
flex-direction: column;
}
.note-detail-split-preview-col {
position: relative;
}
.note-detail-split .note-detail-split-editor {
width: 100%;
flex-grow: 1;
}
.note-detail-split .note-detail-split-editor .note-detail-code {
contain: size !important;
}
.note-detail-split .note-detail-error-container {
font-family: var(--monospace-font-family);
margin: 5px;
white-space: pre-wrap;
font-size: 0.85em;
}
.note-detail-split .note-detail-split-preview {
transition: opacity 250ms ease-in-out;
height: 100%;
}
.note-detail-split .note-detail-split-preview.on-error {
opacity: 0.5;
}
/* Horizontal layout */
.note-detail-split.split-horizontal > .note-detail-split-preview-col {
border-left: 1px solid var(--main-border-color);
}
.note-detail-split.split-horizontal > .note-detail-split-editor-col,
.note-detail-split.split-horizontal > .note-detail-split-preview-col {
height: 100%;
width: 50%;
}
.note-detail-split.split-horizontal .note-detail-split-preview {
height: 100%;
}
/* Vertical layout */
.note-detail-split.split-vertical {
flex-direction: column;
}
.note-detail-split.split-vertical > .note-detail-split-editor-col,
.note-detail-split.split-vertical > .note-detail-split-preview-col {
width: 100%;
height: 50%;
}
.note-detail-split.split-vertical > .note-detail-split-editor-col {
border-top: 1px solid var(--main-border-color);
}
.note-detail-split.split-vertical .note-detail-split-preview-col {
order: -1;
}
/* Read-only view */
.note-detail-split.split-read-only .note-detail-split-preview-col {
width: 100%;
}

View File

@@ -0,0 +1,26 @@
import { TypeWidgetProps } from "../type_widget";
import "./SplitEditor.css";
/**
* Abstract `TypeWidget` which contains a preview and editor pane, each displayed on half of the available screen.
*
* Features:
*
* - The two panes are resizeable via a split, on desktop. The split can be optionally customized via {@link buildSplitExtraOptions}.
* - Can display errors to the user via {@link setError}.
* - Horizontal or vertical orientation for the editor/preview split, adjustable via the switch split orientation button floating button.
*/
export default function SplitEditor({ }: TypeWidgetProps) {
return (
<div className="note-detail-split note-detail-printable">
<div className="note-detail-split-editor-col">
<div className="note-detail-split-editor"></div>
<div className="admonition caution note-detail-error-container hidden-ext"></div>
</div>
<div className="note-detail-split-preview-col">
<div className="note-detail-split-preview"></div>
<div className="btn-group btn-group-sm map-type-switcher content-floating-buttons preview-buttons bottom-right" role="group"></div>
</div>
</div>
)
}

View File

@@ -0,0 +1,8 @@
import { TypeWidgetProps } from "../type_widget";
import SplitEditor from "./SplitEditor";
export default function SvgSplitEditor(props: TypeWidgetProps) {
return (
<SplitEditor {...props} />
)
}

View File

@@ -9,111 +9,6 @@ import type { EventData } from "../../components/app_context.js";
import type OnClickButtonWidget from "../buttons/onclick_button.js"; import type OnClickButtonWidget from "../buttons/onclick_button.js";
import type { EditorConfig } from "@triliumnext/codemirror"; import type { EditorConfig } from "@triliumnext/codemirror";
const TPL = /*html*/`\
<div class="note-detail-split note-detail-printable">
<div class="note-detail-split-editor-col">
<div class="note-detail-split-editor"></div>
<div class="admonition caution note-detail-error-container hidden-ext"></div>
</div>
<div class="note-detail-split-preview-col">
<div class="note-detail-split-preview"></div>
<div class="btn-group btn-group-sm map-type-switcher content-floating-buttons preview-buttons bottom-right" role="group"></div>
</div>
<style>
.note-detail-split {
display: flex;
height: 100%;
}
.note-detail-split-editor-col {
display: flex;
flex-direction: column;
}
.note-detail-split-preview-col {
position: relative;
}
.note-detail-split .note-detail-split-editor {
width: 100%;
flex-grow: 1;
}
.note-detail-split .note-detail-split-editor .note-detail-code {
contain: size !important;
}
.note-detail-split .note-detail-error-container {
font-family: var(--monospace-font-family);
margin: 5px;
white-space: pre-wrap;
font-size: 0.85em;
}
.note-detail-split .note-detail-split-preview {
transition: opacity 250ms ease-in-out;
height: 100%;
}
.note-detail-split .note-detail-split-preview.on-error {
opacity: 0.5;
}
/* Horizontal layout */
.note-detail-split.split-horizontal > .note-detail-split-preview-col {
border-left: 1px solid var(--main-border-color);
}
.note-detail-split.split-horizontal > .note-detail-split-editor-col,
.note-detail-split.split-horizontal > .note-detail-split-preview-col {
height: 100%;
width: 50%;
}
.note-detail-split.split-horizontal .note-detail-split-preview {
height: 100%;
}
/* Vertical layout */
.note-detail-split.split-vertical {
flex-direction: column;
}
.note-detail-split.split-vertical > .note-detail-split-editor-col,
.note-detail-split.split-vertical > .note-detail-split-preview-col {
width: 100%;
height: 50%;
}
.note-detail-split.split-vertical > .note-detail-split-editor-col {
border-top: 1px solid var(--main-border-color);
}
.note-detail-split.split-vertical .note-detail-split-preview-col {
order: -1;
}
/* Read-only view */
.note-detail-split.split-read-only .note-detail-split-preview-col {
width: 100%;
}
</style>
</div>
`;
/**
* Abstract `TypeWidget` which contains a preview and editor pane, each displayed on half of the available screen.
*
* Features:
*
* - The two panes are resizeable via a split, on desktop. The split can be optionally customized via {@link buildSplitExtraOptions}.
* - Can display errors to the user via {@link setError}.
* - Horizontal or vertical orientation for the editor/preview split, adjustable via the switch split orientation button floating button.
*/
export default abstract class AbstractSplitTypeWidget extends TypeWidget { export default abstract class AbstractSplitTypeWidget extends TypeWidget {
private splitInstance?: Split.Instance; private splitInstance?: Split.Instance;
@@ -144,8 +39,6 @@ export default abstract class AbstractSplitTypeWidget extends TypeWidget {
} }
doRender(): void { doRender(): void {
this.$widget = $(TPL);
this.spacedUpdate.setUpdateInterval(750); this.spacedUpdate.setUpdateInterval(750);
// Preview pane // Preview pane

View File

@@ -4,7 +4,6 @@ import { t } from "../../services/i18n.js";
import server from "../../services/server.js"; import server from "../../services/server.js";
import toast from "../../services/toast.js"; import toast from "../../services/toast.js";
import utils from "../../services/utils.js"; import utils from "../../services/utils.js";
import ws from "../../services/ws.js";
import OnClickButtonWidget from "../buttons/onclick_button.js"; import OnClickButtonWidget from "../buttons/onclick_button.js";
import AbstractSplitTypeWidget from "./abstract_split_type_widget.js"; import AbstractSplitTypeWidget from "./abstract_split_type_widget.js";