mirror of
https://github.com/zadam/trilium.git
synced 2025-11-10 15:25:51 +01:00
chore(react/type_widget): prepare structure for split editor
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
6
apps/client/src/widgets/type_widgets/Mermaid.tsx
Normal file
6
apps/client/src/widgets/type_widgets/Mermaid.tsx
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import SvgSplitEditor from "./helpers/SvgSplitEditor";
|
||||||
|
import { TypeWidgetProps } from "./type_widget";
|
||||||
|
|
||||||
|
export default function Mermaid(props: TypeWidgetProps) {
|
||||||
|
return <SvgSplitEditor {...props} />;
|
||||||
|
}
|
||||||
80
apps/client/src/widgets/type_widgets/helpers/SplitEditor.css
Normal file
80
apps/client/src/widgets/type_widgets/helpers/SplitEditor.css
Normal 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%;
|
||||||
|
}
|
||||||
26
apps/client/src/widgets/type_widgets/helpers/SplitEditor.tsx
Normal file
26
apps/client/src/widgets/type_widgets/helpers/SplitEditor.tsx
Normal 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>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
import { TypeWidgetProps } from "../type_widget";
|
||||||
|
import SplitEditor from "./SplitEditor";
|
||||||
|
|
||||||
|
export default function SvgSplitEditor(props: TypeWidgetProps) {
|
||||||
|
return (
|
||||||
|
<SplitEditor {...props} />
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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";
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user