feat(mermaid): add basic support for vertical layout

This commit is contained in:
Elian Doran 2025-03-22 10:27:42 +02:00
parent 91dca2df35
commit cf874b5ee8
No known key found for this signature in database
6 changed files with 82 additions and 6 deletions

View File

@ -89,6 +89,7 @@ import ContextualHelpButton from "../widgets/floating_buttons/help_button.js";
import CloseZenButton from "../widgets/close_zen_button.js";
import type { AppContext } from "./../components/app_context.js";
import type { WidgetsByParent } from "../services/bundle.js";
import SwitchSplitOrientationButton from "../widgets/floating_buttons/switch_layout_button.js";
export default class DesktopLayout {
@ -202,6 +203,7 @@ export default class DesktopLayout {
.child(new WatchedFileUpdateStatusWidget())
.child(
new FloatingButtons()
.child(new SwitchSplitOrientationButton())
.child(new EditButton())
.child(new ShowTocWidgetButton())
.child(new ShowHighlightsListWidgetButton())

View File

@ -0,0 +1,38 @@
import options from "../../services/options.js";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
const TPL = `
<button type="button"
class="switch-layout-button"
title="Switch layout">
<span class="bx bxs-dock-bottom"></span>
</button>
`;
export default class SwitchSplitOrientationButton extends NoteContextAwareWidget {
isEnabled() {
return super.isEnabled()
&& ["mermaid"].includes(this.note?.type ?? "")
&& this.note?.isContentAvailable()
&& this.noteContext?.viewScope?.viewMode === "default";
}
doRender(): void {
super.doRender();
this.$widget = $(TPL);
this.$widget.on("click", () => {
const currentOrientation = options.get("splitEditorOrientation");
options.save("splitEditorOrientation", toggleOrientation(currentOrientation));
});
this.contentSized();
}
}
function toggleOrientation(orientation: string) {
if (orientation === "horizontal") {
return "vertical";
} else {
return "horizontal";
}
}

View File

@ -4,9 +4,11 @@ import EditableCodeTypeWidget from "./editable_code.js";
import TypeWidget from "./type_widget.js";
import Split from "split.js";
import { DEFAULT_GUTTER_SIZE } from "../../services/resizer.js";
import options from "../../services/options.js";
import type SwitchSplitOrientationButton from "../floating_buttons/switch_layout_button.js";
const TPL = `\
<div class="note-detail-split note-detail-printable split-horizontal">
<div class="note-detail-split note-detail-printable">
<div class="note-detail-split-first-col">
<div class="note-detail-split-editor"></div>
<div class="note-detail-error-container alert alert-warning hidden-ext"></div>
@ -37,6 +39,7 @@ const TPL = `\
.note-detail-split .note-detail-split-preview {
transition: opacity 250ms ease-in-out;
height: 100%;
}
.note-detail-split .note-detail-split-preview.on-error {
@ -58,13 +61,28 @@ const TPL = `\
height: 100%;
}
.note-detail-split-first-col {
.note-detail-split.split-horizontal .note-detail-split-first-col {
flex-direction: column;
}
/* Vertical layout */
.note-detail-split.split-vertical {
flex-direction: column;
}
.note-detail-split.split-vertical > div {
width: 100%;
height: 50%;
}
.note-detail-split.split-vertical > .note-detail-split-first-col {
border-top: 1px solid var(--main-border-color);
}
.note-detail-split.split-vertical .note-detail-split-second-col {
order: -1;
}
</style>
</div>
`;
@ -76,6 +94,7 @@ const TPL = `\
*
* - 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 {@link SwitchSplitOrientationButton}.
*/
export default abstract class AbstractSplitTypeWidget extends TypeWidget {
@ -87,6 +106,7 @@ export default abstract class AbstractSplitTypeWidget extends TypeWidget {
private $editor!: JQuery<HTMLElement>;
private $errorContainer!: JQuery<HTMLElement>;
private editorTypeWidget: EditableCodeTypeWidget;
private layoutOrientation!: "horizontal" | "vertical";
constructor() {
super();
@ -98,6 +118,10 @@ export default abstract class AbstractSplitTypeWidget extends TypeWidget {
doRender(): void {
this.$widget = $(TPL);
const layoutOrientation = options.get("splitEditorOrientation") ?? "horizontal";
this.$widget.addClass(`split-${layoutOrientation}`);
this.layoutOrientation = layoutOrientation as ("horizontal" | "vertical");
this.$firstCol = this.$widget.find(".note-detail-split-first-col");
this.$secondCol = this.$widget.find(".note-detail-split-second-col");
this.$preview = this.$widget.find(".note-detail-split-preview");
@ -132,7 +156,7 @@ export default abstract class AbstractSplitTypeWidget extends TypeWidget {
this.splitInstance?.destroy();
this.splitInstance = Split([ this.$firstCol[0], this.$secondCol[0] ], {
sizes: [ 50, 50 ],
direction: "horizontal",
direction: this.layoutOrientation,
gutterSize: DEFAULT_GUTTER_SIZE,
...this.buildSplitExtraOptions()
});
@ -163,4 +187,5 @@ export default abstract class AbstractSplitTypeWidget extends TypeWidget {
getData() {
return this.editorTypeWidget.getData();
}
}

View File

@ -10,7 +10,7 @@ import { listSyntaxHighlightingThemes } from "../../services/code_block_theme.js
import type { OptionNames } from "../../services/options_interface.js";
// options allowed to be updated directly in the Options dialog
const ALLOWED_OPTIONS = new Set([
const ALLOWED_OPTIONS = new Set<OptionNames>([
"eraseEntitiesAfterTimeInSeconds",
"eraseEntitiesAfterTimeScale",
"protectedSessionTimeout",
@ -78,7 +78,8 @@ const ALLOWED_OPTIONS = new Set([
"backgroundEffects",
"allowedHtmlTags",
"redirectBareDomain",
"showLoginInShareTheme"
"showLoginInShareTheme",
"splitEditorOrientation"
]);
function getOptions() {
@ -163,7 +164,10 @@ function getSupportedLocales() {
}
function isAllowed(name: string) {
return ALLOWED_OPTIONS.has(name) || name.startsWith("keyboardShortcuts") || name.endsWith("Collapsed") || name.startsWith("hideArchivedNotes");
return (ALLOWED_OPTIONS as Set<string>).has(name)
|| name.startsWith("keyboardShortcuts")
|| name.endsWith("Collapsed")
|| name.startsWith("hideArchivedNotes");
}
export default {

View File

@ -132,6 +132,9 @@ const defaultOptions: DefaultOption[] = [
{ name: "promotedAttributesOpenInRibbon", value: "true", isSynced: true },
{ name: "editedNotesOpenInRibbon", value: "true", isSynced: true },
// Appearance
{ name: "splitEditorOrientation", value: "horizontal", isSynced: true },
// Internationalization
{ name: "locale", value: "en", isSynced: true },
{ name: "firstDayOfWeek", value: "1", isSynced: true },

View File

@ -45,6 +45,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
passwordVerificationSalt: string;
passwordDerivedKeySalt: string;
encryptedDataKey: string;
hoistedNoteId: string;
lastSyncedPull: number;
lastSyncedPush: number;
@ -73,6 +74,9 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
firstDayOfWeek: number;
languages: string;
// Appearance
splitEditorOrientation: "horziontal" | "vertical";
initialized: boolean;
isPasswordSet: boolean;
overrideThemeFonts: boolean;