client: add an option to center the content

This commit is contained in:
Adorian Doran 2025-11-07 18:17:28 +02:00
parent 2d03dd22e3
commit fa64ca2c93
9 changed files with 32 additions and 8 deletions

View File

@ -1811,6 +1811,8 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu {
.note-split { .note-split {
/* Limits the maximum width of the note */ /* Limits the maximum width of the note */
--max-content-width: var(--preferred-max-content-width); --max-content-width: var(--preferred-max-content-width);
/* Indicates the inline margin of the content. If set to "auto" the content will be centered. */
--content-margin-inline: var(--preferred-content-margin-inline);
margin-inline-start: auto; margin-inline-start: auto;
margin-inline-end: auto; margin-inline-end: auto;

View File

@ -1110,7 +1110,8 @@
"title": "Content Width", "title": "Content Width",
"default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.", "default_description": "Trilium by default limits max content width to improve readability for maximized screens on wide screens.",
"max_width_label": "Max content width", "max_width_label": "Max content width",
"max_width_unit": "pixels" "max_width_unit": "pixels",
"centerContent": "Keep content centered"
}, },
"native_title_bar": { "native_title_bar": {
"title": "Native Title Bar (requires app restart)", "title": "Native Title Bar (requires app restart)",

View File

@ -1,6 +1,11 @@
.note-list-widget { .note-list-widget {
min-height: 0; min-height: 0;
max-width: var(--max-content-width); /* Inherited from .note-split */ /* Inherited from .note-split */
max-width: var(--max-content-width);
/* Inherited from .note-split. If set to "auto" the list widget will be centered horizontally. */
margin-inline: var(--content-margin-inline);
overflow: auto; overflow: auto;
contain: none !important; contain: none !important;
} }

View File

@ -31,7 +31,7 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
window.visualViewport?.addEventListener("resize", () => this.#onMobileResize()); window.visualViewport?.addEventListener("resize", () => this.#onMobileResize());
} }
this.#setMaxContentWidth(options.getInt("maxContentWidth") ?? 0); this.#setMaxContentWidth();
this.#setMotion(options.is("motionEnabled")); this.#setMotion(options.is("motionEnabled"));
this.#setShadows(options.is("shadowsEnabled")); this.#setShadows(options.is("shadowsEnabled"));
this.#setBackdropEffects(options.is("backdropEffectsEnabled")); this.#setBackdropEffects(options.is("backdropEffectsEnabled"));
@ -54,8 +54,8 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
this.#setBackdropEffects(options.is("backdropEffectsEnabled")); this.#setBackdropEffects(options.is("backdropEffectsEnabled"));
} }
if (loadResults.isOptionReloaded("maxContentWidth")) { if (loadResults.isOptionReloaded("maxContentWidth") || loadResults.isOptionReloaded("centerContent")) {
this.#setMaxContentWidth(options.getInt("maxContentWidth") ?? 0); this.#setMaxContentWidth();
} }
} }
@ -66,9 +66,15 @@ export default class RootContainer extends FlexContainer<BasicWidget> {
this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened); this.$widget.toggleClass("virtual-keyboard-opened", isKeyboardOpened);
} }
#setMaxContentWidth(width: number) { #setMaxContentWidth() {
width = Math.max(width, 640); const width = Math.max(options.getInt("maxContentWidth") || 0, 640);
const centerContent = options.is("centerContent");
document.body.style.setProperty("--preferred-max-content-width", `${width}px`); document.body.style.setProperty("--preferred-max-content-width", `${width}px`);
// To center the content, "--preferred-content-margin-inline" should be set to "auto".
document.body.style.setProperty("--preferred-content-margin-inline",
(centerContent) ? "auto" : "unset");
} }
#setMotion(enabled: boolean) { #setMotion(enabled: boolean) {

View File

@ -40,6 +40,8 @@ const TPL = /*html*/`
<style> <style>
.note-detail { .note-detail {
max-width: var(--max-content-width); /* Inherited from .note-split */ max-width: var(--max-content-width); /* Inherited from .note-split */
/* Inherited from .note-split. If set to "auto" the note detail widget will be centered horizontally. */
margin-inline: var(--content-margin-inline);
font-family: var(--detail-font-family); font-family: var(--detail-font-family);
font-size: var(--detail-font-size); font-size: var(--detail-font-size);
} }

View File

@ -284,7 +284,8 @@ function SmoothScrollEnabledOption() {
} }
function MaxContentWidth() { function MaxContentWidth() {
const [ maxContentWidth, setMaxContentWidth ] = useTriliumOption("maxContentWidth"); const [maxContentWidth, setMaxContentWidth] = useTriliumOption("maxContentWidth");
const [centerContent, setCenterContent] = useTriliumOptionBool("centerContent");
return ( return (
<OptionsSection title={t("max_content_width.title")}> <OptionsSection title={t("max_content_width.title")}>
@ -299,6 +300,10 @@ function MaxContentWidth() {
/> />
</FormGroup> </FormGroup>
</Column> </Column>
<FormCheckbox label={t("max_content_width.centerContent")}
currentValue={centerContent}
onChange={setCenterContent} />
</OptionsSection> </OptionsSection>
) )
} }

View File

@ -68,6 +68,7 @@ const ALLOWED_OPTIONS = new Set<OptionNames>([
"smoothScrollEnabled", "smoothScrollEnabled",
"backdropEffectsEnabled", "backdropEffectsEnabled",
"maxContentWidth", "maxContentWidth",
"centerContent",
"compressImages", "compressImages",
"downloadImagesAutomatically", "downloadImagesAutomatically",
"minTocHeadings", "minTocHeadings",

View File

@ -117,6 +117,7 @@ const defaultOptions: DefaultOption[] = [
{ name: "weeklyBackupEnabled", value: "true", isSynced: false }, { name: "weeklyBackupEnabled", value: "true", isSynced: false },
{ name: "monthlyBackupEnabled", value: "true", isSynced: false }, { name: "monthlyBackupEnabled", value: "true", isSynced: false },
{ name: "maxContentWidth", value: "1200", isSynced: false }, { name: "maxContentWidth", value: "1200", isSynced: false },
{ name: "centerContent", value: "false", isSynced: false },
{ name: "compressImages", value: "true", isSynced: true }, { name: "compressImages", value: "true", isSynced: true },
{ name: "downloadImagesAutomatically", value: "true", isSynced: true }, { name: "downloadImagesAutomatically", value: "true", isSynced: true },
{ name: "minTocHeadings", value: "5", isSynced: true }, { name: "minTocHeadings", value: "5", isSynced: true },

View File

@ -82,6 +82,7 @@ export interface OptionDefinitions extends KeyboardShortcutsOptions<KeyboardActi
autoReadonlySizeText: number; autoReadonlySizeText: number;
autoReadonlySizeCode: number; autoReadonlySizeCode: number;
maxContentWidth: number; maxContentWidth: number;
centerContent: boolean;
minTocHeadings: number; minTocHeadings: number;
eraseUnusedAttachmentsAfterSeconds: number; eraseUnusedAttachmentsAfterSeconds: number;
eraseUnusedAttachmentsAfterTimeScale: number; eraseUnusedAttachmentsAfterTimeScale: number;