From 034ac59c9aa5a213d0748716862d513301c13df7 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 8 Oct 2025 11:51:14 +0300 Subject: [PATCH 01/52] feat(i18n/rtl): add an English with RTL enabled for testing --- apps/client/src/widgets/collections/calendar/index.tsx | 3 ++- apps/server/src/services/i18n.ts | 1 + packages/commons/src/lib/i18n.ts | 7 +++++++ 3 files changed, 10 insertions(+), 1 deletion(-) diff --git a/apps/client/src/widgets/collections/calendar/index.tsx b/apps/client/src/widgets/collections/calendar/index.tsx index 3aa9fc1d6..c22155585 100644 --- a/apps/client/src/widgets/collections/calendar/index.tsx +++ b/apps/client/src/widgets/collections/calendar/index.tsx @@ -74,7 +74,8 @@ export const LOCALE_MAPPINGS: Record Promise<{ default: Local pt: () => import("@fullcalendar/core/locales/pt"), "pt_br": () => import("@fullcalendar/core/locales/pt-br"), uk: () => import("@fullcalendar/core/locales/uk"), - en: null + en: null, + "en_rtl": null, }; export default function CalendarView({ note, noteIds }: ViewModeProps) { diff --git a/apps/server/src/services/i18n.ts b/apps/server/src/services/i18n.ts index 1f1db1ac6..1199bd796 100644 --- a/apps/server/src/services/i18n.ts +++ b/apps/server/src/services/i18n.ts @@ -12,6 +12,7 @@ export const DAYJS_LOADER: Record Promise import("dayjs/locale/zh-cn.js"), "de": () => import("dayjs/locale/de.js"), "en": () => import("dayjs/locale/en.js"), + "en_rtl": () => import("dayjs/locale/en.js"), "es": () => import("dayjs/locale/es.js"), "fa": () => import("dayjs/locale/fa.js"), "fr": () => import("dayjs/locale/fr.js"), diff --git a/packages/commons/src/lib/i18n.ts b/packages/commons/src/lib/i18n.ts index 5970d2ab8..a6679f542 100644 --- a/packages/commons/src/lib/i18n.ts +++ b/packages/commons/src/lib/i18n.ts @@ -23,6 +23,13 @@ const UNSORTED_LOCALES: Locale[] = [ { id: "tw", name: "繁體中文", electronLocale: "zh_TW" }, { id: "uk", name: "Українська", electronLocale: "uk" }, + /** + * Development-only languages. + * + * These are only displayed while in dev mode, to test some language particularities (such as RTL) more easily. + */ + { id: "en_rtl", name: "English (right-to-left) [dev]", electronLocale: "en", rtl: true }, + /* * Right to left languages * From adff36cf2214e5130c65c81bd2381eae788d9efc Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 8 Oct 2025 12:08:39 +0300 Subject: [PATCH 02/52] feat(i18n/rtl): apply right to left direction at root level --- apps/client/src/widgets/containers/root_container.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/client/src/widgets/containers/root_container.ts b/apps/client/src/widgets/containers/root_container.ts index 6c2d87521..511a98b14 100644 --- a/apps/client/src/widgets/containers/root_container.ts +++ b/apps/client/src/widgets/containers/root_container.ts @@ -3,6 +3,7 @@ import FlexContainer from "./flex_container.js"; import options from "../../services/options.js"; import type BasicWidget from "../basic_widget.js"; import utils from "../../services/utils.js"; +import { LOCALES } from "@triliumnext/commons"; /** * The root container is the top-most widget/container, from which the entire layout derives. @@ -32,6 +33,7 @@ export default class RootContainer extends FlexContainer { this.#setMotion(options.is("motionEnabled")); this.#setShadows(options.is("shadowsEnabled")); this.#setBackdropEffects(options.is("backdropEffectsEnabled")); + this.#setRightToLeft(options.get("locale")); return super.render(); } @@ -68,6 +70,11 @@ export default class RootContainer extends FlexContainer { #setBackdropEffects(enabled: boolean) { document.body.classList.toggle("backdrop-effects-disabled", !enabled); } + + #setRightToLeft(locale: string) { + const correspondingLocale = LOCALES.find(l => l.id === locale); + document.body.dir = correspondingLocale?.rtl ? "rtl" : "ltr"; + } } function getViewportHeight() { From 247ab1aec3dd565fbfc0682b27d66209beb509a2 Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 8 Oct 2025 17:44:17 +0300 Subject: [PATCH 03/52] feat(client/rtl): handle margin-left --- apps/client/src/layouts/mobile_layout.tsx | 2 +- apps/client/src/stylesheets/style.css | 20 ++++++++-------- apps/client/src/stylesheets/table.css | 2 +- .../src/stylesheets/theme-next/base.css | 2 +- .../src/stylesheets/theme-next/dialogs.css | 4 ++-- .../src/stylesheets/theme-next/forms.css | 4 ++-- .../src/stylesheets/theme-next/llm-chat.css | 2 +- .../src/stylesheets/theme-next/notes/text.css | 2 +- .../src/stylesheets/theme-next/pages.css | 4 ++-- .../src/stylesheets/theme-next/ribbon.css | 4 ++-- .../src/stylesheets/theme-next/shell.css | 12 +++++----- apps/client/src/stylesheets/tree.css | 8 +++---- apps/client/src/widgets/FloatingButtons.css | 4 ++-- apps/client/src/widgets/attachment_detail.ts | 2 +- .../src/widgets/bulk_actions/BulkAction.tsx | 6 ++--- .../src/widgets/buttons/global_menu.css | 6 ++--- .../src/widgets/collections/board/index.css | 2 +- apps/client/src/widgets/dialogs/revisions.tsx | 24 +++++++++---------- apps/client/src/widgets/note_map.ts | 2 +- .../client/src/widgets/promoted_attributes.ts | 2 +- apps/client/src/widgets/react/FormToggle.css | 4 ++-- .../src/widgets/ribbon/BasicPropertiesTab.tsx | 2 +- .../ribbon/SearchDefinitionOptions.tsx | 2 +- apps/client/src/widgets/ribbon/style.css | 8 +++---- apps/client/src/widgets/tab_row.ts | 6 ++--- apps/client/src/widgets/toc.ts | 4 ++-- .../type_widgets/options/text_notes.tsx | 2 +- 27 files changed, 71 insertions(+), 71 deletions(-) diff --git a/apps/client/src/layouts/mobile_layout.tsx b/apps/client/src/layouts/mobile_layout.tsx index 1bc944418..8d8dae6c2 100644 --- a/apps/client/src/layouts/mobile_layout.tsx +++ b/apps/client/src/layouts/mobile_layout.tsx @@ -68,7 +68,7 @@ const FANCYTREE_CSS = ` .fancytree-title { font-size: 1.5em; - margin-left: 0.6em !important; + margin-inline-start: 0.6em !important; } .fancytree-node { diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index eb9449aef..574c0684b 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -174,7 +174,7 @@ textarea, /* Add a gap between consecutive radios / check boxes */ label.tn-radio + label.tn-radio, label.tn-checkbox + label.tn-checkbox { - margin-left: 12px; + margin-inline-start: 12px; } label.tn-radio input[type="radio"], @@ -226,7 +226,7 @@ samp { .badge { --bs-badge-color: var(--muted-text-color); - margin-left: 8px; + margin-inline-start: 8px; background: var(--accented-background-color); } @@ -338,7 +338,7 @@ button kbd { } .ui-menu kbd { - margin-left: 30px; + margin-inline-start: 30px; float: right; } @@ -392,7 +392,7 @@ body.desktop .tabulator-popup-container { } .dropend .dropdown-toggle::after { - margin-left: 0.5em; + margin-inline-start: 0.5em; color: var(--muted-text-color); } @@ -403,7 +403,7 @@ body.desktop .tabulator-popup-container { .dropdown-menu .disabled .disabled-tooltip { pointer-events: all; - margin-left: 8px; + margin-inline-start: 8px; font-size: 0.5em; color: var(--disabled-tooltip-icon-color); cursor: help; @@ -1033,7 +1033,7 @@ svg.ck-icon .note-icon { counter-increment: footnote-counter; display: flex; list-style: none; - margin-left: 0.5em; + margin-inline-start: 0.5em; } .ck-content .footnote-item > * { @@ -1414,7 +1414,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { .ck.ck-slash-command-button__text-part, .ck.ck-template-form__text-part { - margin-left: 0.5em; + margin-inline-start: 0.5em; line-height: 1.2em !important; } @@ -1748,7 +1748,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { display: flex; flex-shrink: 0; flex-direction: column; - margin-left: 10px; + margin-inline-start: 10px; margin-right: 5px; } @@ -1800,7 +1800,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { } .note-split { - margin-left: auto; + margin-inline-start: auto; margin-right: auto; } @@ -1858,7 +1858,7 @@ textarea { .attachment-help-button { display: inline-block; - margin-left: 10px; + margin-inline-start: 10px; vertical-align: middle; font-size: 1em; } diff --git a/apps/client/src/stylesheets/table.css b/apps/client/src/stylesheets/table.css index 211f5d7c6..8f187dd88 100644 --- a/apps/client/src/stylesheets/table.css +++ b/apps/client/src/stylesheets/table.css @@ -67,7 +67,7 @@ } .tabulator div.tabulator-header .tabulator-frozen.tabulator-frozen-left { - margin-left: var(--cell-editing-border-width); + margin-inline-start: var(--cell-editing-border-width); } .tabulator div.tabulator-header .tabulator-col, diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index 7bf49a02d..1549c9f86 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -211,7 +211,7 @@ html body .dropdown-item[disabled] { .dropdown-item span.keyboard-shortcut { color: var(--menu-item-keyboard-shortcut-color) !important; - margin-left: 16px; + margin-inline-start: 16px; } .dropdown-divider { diff --git a/apps/client/src/stylesheets/theme-next/dialogs.css b/apps/client/src/stylesheets/theme-next/dialogs.css index 357a541ff..967689599 100644 --- a/apps/client/src/stylesheets/theme-next/dialogs.css +++ b/apps/client/src/stylesheets/theme-next/dialogs.css @@ -29,7 +29,7 @@ display: flex; justify-content: center; align-items: center; - margin-left: 8px; + margin-inline-start: 8px; border: 0; border-radius: 50%; padding: 0; @@ -374,7 +374,7 @@ div.tn-tool-dialog { } .help-dialog .help-cards kbd:first-child { - margin-left: 0; + margin-inline-start: 0; } /* Inline code - used for Markdown samples */ diff --git a/apps/client/src/stylesheets/theme-next/forms.css b/apps/client/src/stylesheets/theme-next/forms.css index b5cf73428..b548e97d1 100644 --- a/apps/client/src/stylesheets/theme-next/forms.css +++ b/apps/client/src/stylesheets/theme-next/forms.css @@ -71,7 +71,7 @@ button.btn.btn-primary kbd, button.btn.btn-secondary kbd, button.btn.btn-sm kbd, button.btn.btn-success kbd { - margin-left: 0.5em; + margin-inline-start: 0.5em; background: var(--cmd-button-keyboard-shortcut-background); color: var(--cmd-button-keyboard-shortcut-color); font-size: 0.6em; @@ -102,7 +102,7 @@ button.btn.btn-success kbd { } .btn-group .tn-tool-button + .tn-tool-button { - margin-left: 4px !important; + margin-inline-start: 4px !important; } /* The "x" icon button */ diff --git a/apps/client/src/stylesheets/theme-next/llm-chat.css b/apps/client/src/stylesheets/theme-next/llm-chat.css index dc3342485..a56ad217e 100644 --- a/apps/client/src/stylesheets/theme-next/llm-chat.css +++ b/apps/client/src/stylesheets/theme-next/llm-chat.css @@ -19,7 +19,7 @@ } .chat-message.user-message { - margin-left: auto; + margin-inline-start: auto; } .chat-message.assistant-message { diff --git a/apps/client/src/stylesheets/theme-next/notes/text.css b/apps/client/src/stylesheets/theme-next/notes/text.css index 6499fa0b4..4c4e6cec2 100644 --- a/apps/client/src/stylesheets/theme-next/notes/text.css +++ b/apps/client/src/stylesheets/theme-next/notes/text.css @@ -210,7 +210,7 @@ /* Separator */ :root .ck .ck-list__separator { margin: .5em 0; - margin-left: calc(0px - var(--ck-editor-popup-padding)); + margin-inline-start: calc(0px - var(--ck-editor-popup-padding)); width: calc(100% + (var(--ck-editor-popup-padding) * 2)); background: var(--menu-item-delimiter-color); } diff --git a/apps/client/src/stylesheets/theme-next/pages.css b/apps/client/src/stylesheets/theme-next/pages.css index b15801f71..7efc741f5 100644 --- a/apps/client/src/stylesheets/theme-next/pages.css +++ b/apps/client/src/stylesheets/theme-next/pages.css @@ -199,7 +199,7 @@ body.desktop .option-section:not(.tn-no-card) { color: var(--launcher-pane-text-color); margin-top: calc(-1 * var(--options-card-padding) - var(--options-title-font-size) - var(--options-title-offset)) !important; margin-bottom: calc(var(--options-title-offset) + var(--options-card-padding)) !important; - margin-left: calc(-1 * var(--options-card-padding)); + margin-inline-start: calc(-1 * var(--options-card-padding)); } .options-section:not(.tn-no-card) h5 { @@ -216,7 +216,7 @@ body.desktop .option-section:not(.tn-no-card) { .options-section hr { --bs-border-width: 2px; - margin-left: calc(var(--options-card-padding) * -1); + margin-inline-start: calc(var(--options-card-padding) * -1); margin-right: calc(var(--options-card-padding) * -1); opacity: 1; color: var(--root-background); diff --git a/apps/client/src/stylesheets/theme-next/ribbon.css b/apps/client/src/stylesheets/theme-next/ribbon.css index c20ecb488..3957bb1e2 100644 --- a/apps/client/src/stylesheets/theme-next/ribbon.css +++ b/apps/client/src/stylesheets/theme-next/ribbon.css @@ -105,7 +105,7 @@ ul.note-type-dropdown li.dropdown-item { /* Editability dropdown */ ul.editability-dropdown li.dropdown-item > div { - margin-left: 4px; + margin-inline-start: 4px; } .editability-dropdown .dropdown-item .description { @@ -147,7 +147,7 @@ ul.editability-dropdown li.dropdown-item > div { /* Note path in attribute detail dialog */ .attr-detail .note-path { - margin-left: 8px; + margin-inline-start: 8px; } /* diff --git a/apps/client/src/stylesheets/theme-next/shell.css b/apps/client/src/stylesheets/theme-next/shell.css index 28679abc7..ce4a3e4eb 100644 --- a/apps/client/src/stylesheets/theme-next/shell.css +++ b/apps/client/src/stylesheets/theme-next/shell.css @@ -1101,7 +1101,7 @@ body.layout-vertical .tab-row-widget-is-sorting .note-tab.note-tab-is-dragging . .tab-row-widget .note-new-tab { position: relative; - margin-left: 3px; + margin-inline-start: 3px; color: transparent; /* Prevent the original "+" from being displayed */ } @@ -1225,7 +1225,7 @@ body.mobile .note-title { } .title-row > *:nth-child(2) { - margin-left: 0; + margin-inline-start: 0; } .title-row { @@ -1407,7 +1407,7 @@ div.promoted-attribute-cell.promoted-attribute-label-boolean > div:first-of-type div.promoted-attribute-cell .multiplicity:has(span) { --icon-button-size: 24px; - margin-left: 8px; + margin-inline-start: 8px; margin-right: calc(var(--pa-card-padding-left) - var(--pa-card-padding-right)); font-size: 0; /* Prevent whitespaces creating a gap between buttons */ display: flex; @@ -1547,7 +1547,7 @@ div.floating-buttons-children .close-floating-buttons { } div.floating-buttons-children .close-floating-buttons { - margin-left: 0 !important; + margin-inline-start: 0 !important; background: var(--floating-button-hide-button-background); color: var(--floating-button-hide-button-color); } @@ -1642,7 +1642,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span { } .find-replace-widget .form-check .form-check-input { - margin-left: 0; + margin-inline-start: 0; } /* Narrow version */ @@ -1806,7 +1806,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span { } .excalidraw .dropdown-menu .dropdown-menu-container > div:not([class]):not(:last-child) { - margin-left: calc(var(--padding) * var(--space-factor) * -1) !important; + margin-inline-start: calc(var(--padding) * var(--space-factor) * -1) !important; margin-right: calc(var(--padding) * var(--space-factor) * -1) !important; } diff --git a/apps/client/src/stylesheets/tree.css b/apps/client/src/stylesheets/tree.css index 385e596dd..29854e861 100644 --- a/apps/client/src/stylesheets/tree.css +++ b/apps/client/src/stylesheets/tree.css @@ -15,7 +15,7 @@ span.fancytree-node.fancytree-hide { flex-shrink: 1; flex-grow: 1; overflow: hidden; - margin-left: 7px; + margin-inline-start: 7px; outline: none; position: relative; top: 2px; @@ -80,7 +80,7 @@ span.fancytree-node.fancytree-hide { width: 12px; height: 12px; margin-top: 2px; - margin-left: 1px; + margin-inline-start: 1px; border-width: 1px; border-style: solid; } @@ -229,14 +229,14 @@ span.fancytree-node.archived { display: none; font-size: 120%; cursor: pointer; - margin-left: 8px; + margin-inline-start: 8px; padding: 1px; border: 1px solid transparent; border-radius: 5px; } .unhoist-button.bx.tree-item-button { - margin-left: 0; /* unhoist button is on the left and doesn't need more margin */ + margin-inline-start: 0; /* unhoist button is on the left and doesn't need more margin */ display: block; /* keep always visible */ } diff --git a/apps/client/src/widgets/FloatingButtons.css b/apps/client/src/widgets/FloatingButtons.css index f4fc8a092..56a6c20b0 100644 --- a/apps/client/src/widgets/FloatingButtons.css +++ b/apps/client/src/widgets/FloatingButtons.css @@ -74,7 +74,7 @@ .show-floating-buttons { /* display: none;*/ - margin-left: 5px !important; + margin-inline-start: 5px !important; } .show-floating-buttons-button { @@ -97,7 +97,7 @@ /* #region Close floating buttons */ .close-floating-buttons { - margin-left: 5px !important; + margin-inline-start: 5px !important; } .close-floating-buttons:first-child { diff --git a/apps/client/src/widgets/attachment_detail.ts b/apps/client/src/widgets/attachment_detail.ts index 1d2eab902..31be61536 100644 --- a/apps/client/src/widgets/attachment_detail.ts +++ b/apps/client/src/widgets/attachment_detail.ts @@ -30,7 +30,7 @@ const TPL = /*html*/` } .attachment-details { - margin-left: 10px; + margin-inline-start: 10px; } .attachment-content-wrapper { diff --git a/apps/client/src/widgets/bulk_actions/BulkAction.tsx b/apps/client/src/widgets/bulk_actions/BulkAction.tsx index 8b562d0f0..0f629b4bc 100644 --- a/apps/client/src/widgets/bulk_actions/BulkAction.tsx +++ b/apps/client/src/widgets/bulk_actions/BulkAction.tsx @@ -4,7 +4,7 @@ import AbstractBulkAction from "./abstract_bulk_action"; import HelpRemoveButtons from "../react/HelpRemoveButtons"; interface BulkActionProps { - label: string | ComponentChildren; + label: string | ComponentChildren; children?: ComponentChildren; helpText?: ComponentChildren; bulkAction: AbstractBulkAction; @@ -13,7 +13,7 @@ interface BulkActionProps { // Define styles as constants to prevent recreation const flexContainerStyle = { display: "flex", alignItems: "center" } as const; const labelStyle = { marginRight: "10px" } as const; -const textStyle = { marginRight: "10px", marginLeft: "10px" } as const; +const textStyle = { marginRight: "10px", marginInlineStart: "10px" } as const; const BulkAction = memo(({ label, children, helpText, bulkAction }: BulkActionProps) => { return ( @@ -44,4 +44,4 @@ export const BulkActionText = memo(({ text }: { text: string }) => { {text} ); -}); \ No newline at end of file +}); diff --git a/apps/client/src/widgets/buttons/global_menu.css b/apps/client/src/widgets/buttons/global_menu.css index 2145b76f9..0fd1c6988 100644 --- a/apps/client/src/widgets/buttons/global_menu.css +++ b/apps/client/src/widgets/buttons/global_menu.css @@ -69,7 +69,7 @@ button.global-menu-button { } .global-menu .zoom-buttons { - margin-left: 2em; + margin-inline-start: 2em; } .global-menu .zoom-buttons a { @@ -79,7 +79,7 @@ button.global-menu-button { color: var(--button-text-color); background-color: var(--button-background-color); padding: 3px; - margin-left: 3px; + margin-inline-start: 3px; text-decoration: none; } @@ -88,7 +88,7 @@ button.global-menu-button { } .global-menu .zoom-state { - margin-left: 5px; + margin-inline-start: 5px; margin-right: 5px; } diff --git a/apps/client/src/widgets/collections/board/index.css b/apps/client/src/widgets/collections/board/index.css index cf5906930..9f16b4557 100644 --- a/apps/client/src/widgets/collections/board/index.css +++ b/apps/client/src/widgets/collections/board/index.css @@ -93,7 +93,7 @@ .board-view-container .board-column .edit-icon { opacity: 0; - margin-left: 0.5em; + margin-inline-start: 0.5em; transition: opacity 0.2s ease; color: var(--muted-text-color); cursor: pointer; diff --git a/apps/client/src/widgets/dialogs/revisions.tsx b/apps/client/src/widgets/dialogs/revisions.tsx index 65c7dfd2c..b21a36faf 100644 --- a/apps/client/src/widgets/dialogs/revisions.tsx +++ b/apps/client/src/widgets/dialogs/revisions.tsx @@ -91,7 +91,7 @@ export default function RevisionsDialog() { ) } - footer={} + footer={} footerStyle={{ paddingTop: 0, paddingBottom: 0 }} onHidden={() => { setShown(false); @@ -115,16 +115,16 @@ export default function RevisionsDialog() {
- { setRefreshCounter(c => c + 1); @@ -138,7 +138,7 @@ export default function RevisionsDialog() { function RevisionsList({ revisions, onSelect, currentRevision }: { revisions: RevisionItem[], onSelect: (val: string) => void, currentRevision?: RevisionItem }) { return ( - {revisions.map((item) => + {revisions.map((item) => >, onRevisionDeleted?: () => void @@ -163,7 +163,7 @@ function RevisionPreview({noteContent, revisionItem, showDiff, setShown, onRevis if (revisionItem) { server.get(`revisions/${revisionItem.revisionId}`).then(setFullRevision); } else { - setFullRevision(undefined); + setFullRevision(undefined); } }, [revisionItem]); @@ -242,11 +242,11 @@ function RevisionContent({ noteContent, revisionItem, fullRevision, showDiff }: return case "code": return
{content}
; - case "image": + case "image": switch (revisionItem.mime) { case "image/svg+xml": { //Base64 of other format images may be embedded in svg - const encodedSVG = encodeURIComponent(content as string); + const encodedSVG = encodeURIComponent(content as string); return ; @@ -355,7 +355,7 @@ function RevisionFooter({ note }: { note?: FNote }) { if (revisionsNumberLimit === -1) { revisionsNumberLimit = "∞"; } - + return <> {t("revisions.snapshot_interval", { seconds: options.getInt("revisionSnapshotTimeInterval") })} @@ -376,4 +376,4 @@ async function getNote(noteId?: string | null) { } else { return appContext.tabManager.getActiveContextNote(); } -} \ No newline at end of file +} diff --git a/apps/client/src/widgets/note_map.ts b/apps/client/src/widgets/note_map.ts index d0274fc86..ef36d7b7e 100644 --- a/apps/client/src/widgets/note_map.ts +++ b/apps/client/src/widgets/note_map.ts @@ -38,7 +38,7 @@ const TPL = /*html*/`
/* removing default appearance */ -webkit-appearance: none; appearance: none; - margin-left: 15px; + margin-inline-start: 15px; width: 150px; } diff --git a/apps/client/src/widgets/promoted_attributes.ts b/apps/client/src/widgets/promoted_attributes.ts index 1b67ecec1..db1937264 100644 --- a/apps/client/src/widgets/promoted_attributes.ts +++ b/apps/client/src/widgets/promoted_attributes.ts @@ -45,7 +45,7 @@ const TPL = /*html*/` } .promoted-attribute-cell div.input-group { - margin-left: 10px; + margin-inline-start: 10px; display: flex; min-height: 40px; } diff --git a/apps/client/src/widgets/react/FormToggle.css b/apps/client/src/widgets/react/FormToggle.css index f727bc5ff..f012f8056 100644 --- a/apps/client/src/widgets/react/FormToggle.css +++ b/apps/client/src/widgets/react/FormToggle.css @@ -18,7 +18,7 @@ .switch-widget .switch-button { display: block; position: relative; - margin-left: 8px; + margin-inline-start: 8px; width: var(--switch-track-width); height: var(--switch-track-height); border-radius: 24px; @@ -86,7 +86,7 @@ .switch-widget .switch-help-button { border: 0; - margin-left: 4px; + margin-inline-start: 4px; background: none; cursor: pointer; font-size: 1.1em; diff --git a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx index 6039053b5..b7ef4fa0e 100644 --- a/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx +++ b/apps/client/src/widgets/ribbon/BasicPropertiesTab.tsx @@ -353,7 +353,7 @@ function NoteLanguageSwitch({ note }: { note?: FNote | null }) { >{t("note_language.configure-languages")} - + -
{t("ancestor.depth_label")}:
+
{t("ancestor.depth_label")}:
* { position: relative; top: -3px; - margin-left: 10px; + margin-inline-start: 10px; } .ribbon-body { border-bottom: 1px solid var(--main-border-color); - margin-left: 10px; + margin-inline-start: 10px; margin-right: 5px; /* needs to have this value so that the bottom border is the same width as the top one */ } @@ -308,7 +308,7 @@ /* #region Owned Attributes */ .attribute-list { - margin-left: 7px; + margin-inline-start: 7px; margin-right: 7px; margin-top: 5px; margin-bottom: 2px; diff --git a/apps/client/src/widgets/tab_row.ts b/apps/client/src/widgets/tab_row.ts index c13aa4969..0d248fa5a 100644 --- a/apps/client/src/widgets/tab_row.ts +++ b/apps/client/src/widgets/tab_row.ts @@ -172,7 +172,7 @@ const TAB_ROW_TPL = ` } .tab-row-widget .note-tab[is-small] .note-tab-title { - margin-left: 0; + margin-inline-start: 0; } .tab-row-widget .note-tab .note-tab-drag-handle { @@ -240,13 +240,13 @@ const TAB_ROW_TPL = ` } .tab-row-widget .note-tab[is-smaller] .note-tab-close { - margin-left: auto; + margin-inline-start: auto; } .tab-row-widget .note-tab[is-mini]:not([active]) .note-tab-close { display: none; } .tab-row-widget .note-tab[is-mini][active] .note-tab-close { - margin-left: auto; + margin-inline-start: auto; margin-right: auto; } @-moz-keyframes note-tab-was-just-added { diff --git a/apps/client/src/widgets/toc.ts b/apps/client/src/widgets/toc.ts index e49368283..b2858cf71 100644 --- a/apps/client/src/widgets/toc.ts +++ b/apps/client/src/widgets/toc.ts @@ -103,12 +103,12 @@ const TPL = /*html*/`
} .toc li .item-content { - margin-left: 25px; + margin-inline-start: 25px; flex: 1; } .toc li .collapse-button + .item-content { - margin-left: 4px; + margin-inline-start: 4px; } .toc li:hover { diff --git a/apps/client/src/widgets/type_widgets/options/text_notes.tsx b/apps/client/src/widgets/type_widgets/options/text_notes.tsx index 5c8ed90af..4e2475922 100644 --- a/apps/client/src/widgets/type_widgets/options/text_notes.tsx +++ b/apps/client/src/widgets/type_widgets/options/text_notes.tsx @@ -62,7 +62,7 @@ function FormattingToolbar() { name="multiline-toolbar" label={t("editing.editor_type.multiline-toolbar")} currentValue={textNoteEditorMultilineToolbar} onChange={setTextNoteEditorMultilineToolbar} - containerStyle={{ marginLeft: "1em" }} + containerStyle={{ marginInlineStart: "1em" }} /> ) From 6b930136747764e5459b16cdc478f7e8c7baf03a Mon Sep 17 00:00:00 2001 From: Elian Doran Date: Wed, 8 Oct 2025 17:45:31 +0300 Subject: [PATCH 04/52] feat(client/rtl): handle margin-right --- apps/client/src/layouts/mobile_layout.tsx | 4 ++-- apps/client/src/stylesheets/style.css | 16 ++++++++-------- apps/client/src/stylesheets/table.css | 2 +- apps/client/src/stylesheets/theme-next/base.css | 4 ++-- .../src/stylesheets/theme-next/dialogs.css | 6 +++--- .../src/stylesheets/theme-next/llm-chat.css | 4 ++-- apps/client/src/stylesheets/theme-next/pages.css | 4 ++-- .../client/src/stylesheets/theme-next/ribbon.css | 2 +- apps/client/src/stylesheets/theme-next/shell.css | 16 ++++++++-------- apps/client/src/stylesheets/tree.css | 2 +- .../attribute_widgets/attribute_detail.ts | 2 +- .../src/widgets/bulk_actions/BulkAction.tsx | 4 ++-- .../src/widgets/buttons/attachments_actions.ts | 2 +- apps/client/src/widgets/buttons/global_menu.css | 4 ++-- .../src/widgets/collections/board/index.css | 6 +++--- apps/client/src/widgets/dialogs/bulk_actions.css | 2 +- apps/client/src/widgets/find.ts | 4 ++-- apps/client/src/widgets/note_icon.css | 2 +- .../widgets/ribbon/SearchDefinitionOptions.tsx | 2 +- apps/client/src/widgets/ribbon/style.css | 12 ++++++------ apps/client/src/widgets/tab_row.ts | 2 +- 21 files changed, 51 insertions(+), 51 deletions(-) diff --git a/apps/client/src/layouts/mobile_layout.tsx b/apps/client/src/layouts/mobile_layout.tsx index 8d8dae6c2..91953b1a3 100644 --- a/apps/client/src/layouts/mobile_layout.tsx +++ b/apps/client/src/layouts/mobile_layout.tsx @@ -81,7 +81,7 @@ const FANCYTREE_CSS = ` span.fancytree-expander { width: 24px !important; - margin-right: 5px; + margin-inline-end: 5px; } .fancytree-loading span.fancytree-expander { @@ -101,7 +101,7 @@ span.fancytree-expander { .tree-wrapper .scroll-to-active-note-button, .tree-wrapper .tree-settings-button { position: fixed; - margin-right: 16px; + margin-inline-end: 16px; display: none; } diff --git a/apps/client/src/stylesheets/style.css b/apps/client/src/stylesheets/style.css index 574c0684b..5e9b3daf3 100644 --- a/apps/client/src/stylesheets/style.css +++ b/apps/client/src/stylesheets/style.css @@ -179,7 +179,7 @@ label.tn-checkbox + label.tn-checkbox { label.tn-radio input[type="radio"], label.tn-checkbox input[type="checkbox"] { - margin-right: .5em; + margin-inline-end: .5em; } #left-pane input, @@ -1041,13 +1041,13 @@ svg.ck-icon .note-icon { } .ck-content .footnote-back-link { - margin-right: 0.1em; + margin-inline-end: 0.1em; position: relative; top: -0.2em; } .ck-content .footnotes .footnote-back-link > sup { - margin-right: 0; + margin-inline-end: 0; } .ck-content .footnote-item:before { @@ -1749,7 +1749,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { flex-shrink: 0; flex-direction: column; margin-inline-start: 10px; - margin-right: 5px; + margin-inline-end: 5px; } #right-pane .card-header { @@ -1801,7 +1801,7 @@ body:not(.mobile) #launcher-pane.horizontal .dropdown-submenu > .dropdown-menu { .note-split { margin-inline-start: auto; - margin-right: auto; + margin-inline-end: auto; } .note-split.full-content-width { @@ -1820,7 +1820,7 @@ button.close:hover { .reference-link .bx { position: relative; top: 1px; - margin-right: 3px; + margin-inline-end: 3px; } .options-section:first-of-type h4 { @@ -2319,12 +2319,12 @@ footer.webview-footer button { display: flex; align-items: center; font-size: 0.9em; - margin-right: 15px; + margin-inline-end: 15px; cursor: pointer; } .chat-option input[type="checkbox"] { - margin-right: 5px; + margin-inline-end: 5px; } /* Style for thinking process in chat responses */ diff --git a/apps/client/src/stylesheets/table.css b/apps/client/src/stylesheets/table.css index 8f187dd88..1579a6853 100644 --- a/apps/client/src/stylesheets/table.css +++ b/apps/client/src/stylesheets/table.css @@ -117,7 +117,7 @@ /* Cell */ .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left { - margin-right: var(--cell-editing-border-width); + margin-inline-end: var(--cell-editing-border-width); } .tabulator-row .tabulator-cell.tabulator-frozen.tabulator-frozen-left, diff --git a/apps/client/src/stylesheets/theme-next/base.css b/apps/client/src/stylesheets/theme-next/base.css index 1549c9f86..bcadc3517 100644 --- a/apps/client/src/stylesheets/theme-next/base.css +++ b/apps/client/src/stylesheets/theme-next/base.css @@ -357,13 +357,13 @@ li.dropdown-item a.dropdown-item-button:focus-visible { } #toast-container .toast:not(.no-title) .bx { - margin-right: 0.5em; + margin-inline-end: 0.5em; font-size: 1.1em; opacity: 0.85; } #toast-container .toast.no-title .bx { - margin-right: 0; + margin-inline-end: 0; font-size: 1.3em; } diff --git a/apps/client/src/stylesheets/theme-next/dialogs.css b/apps/client/src/stylesheets/theme-next/dialogs.css index 967689599..882e0b942 100644 --- a/apps/client/src/stylesheets/theme-next/dialogs.css +++ b/apps/client/src/stylesheets/theme-next/dialogs.css @@ -56,7 +56,7 @@ } .modal .modal-header .help-button { - margin-right: 0; + margin-inline-end: 0; font-size: calc(var(--modal-control-button-size) * .75); font-family: unset; font-weight: bold; @@ -141,7 +141,7 @@ div.tn-tool-dialog { /* Search box wrapper */ .jump-to-note-dialog .input-group { - margin-right: 16px; + margin-inline-end: 16px; } .jump-to-note-dialog .input-group:hover { @@ -419,5 +419,5 @@ div.tn-tool-dialog { } .note-type-chooser-dialog div.note-type-dropdown .dropdown-item span.bx { - margin-right: .25em; + margin-inline-end: .25em; } \ No newline at end of file diff --git a/apps/client/src/stylesheets/theme-next/llm-chat.css b/apps/client/src/stylesheets/theme-next/llm-chat.css index a56ad217e..da5b47895 100644 --- a/apps/client/src/stylesheets/theme-next/llm-chat.css +++ b/apps/client/src/stylesheets/theme-next/llm-chat.css @@ -23,7 +23,7 @@ } .chat-message.assistant-message { - margin-right: auto; + margin-inline-end: auto; } .message-avatar { @@ -33,7 +33,7 @@ display: flex; align-items: center; justify-content: center; - margin-right: 8px; + margin-inline-end: 8px; } .user-message .message-avatar { diff --git a/apps/client/src/stylesheets/theme-next/pages.css b/apps/client/src/stylesheets/theme-next/pages.css index 7efc741f5..d0c092321 100644 --- a/apps/client/src/stylesheets/theme-next/pages.css +++ b/apps/client/src/stylesheets/theme-next/pages.css @@ -52,7 +52,7 @@ background-color: #f5f5f5; } .google-login-btn img { - margin-right: 10px; + margin-inline-end: 10px; width: 18px; height: 18px; } @@ -217,7 +217,7 @@ body.desktop .option-section:not(.tn-no-card) { --bs-border-width: 2px; margin-inline-start: calc(var(--options-card-padding) * -1); - margin-right: calc(var(--options-card-padding) * -1); + margin-inline-end: calc(var(--options-card-padding) * -1); opacity: 1; color: var(--root-background); } diff --git a/apps/client/src/stylesheets/theme-next/ribbon.css b/apps/client/src/stylesheets/theme-next/ribbon.css index 3957bb1e2..e9af8df88 100644 --- a/apps/client/src/stylesheets/theme-next/ribbon.css +++ b/apps/client/src/stylesheets/theme-next/ribbon.css @@ -95,7 +95,7 @@ div.promoted-attributes-container { /* Note type dropdown */ ul.note-type-dropdown .check { - margin-right: 6px; + margin-inline-end: 6px; } ul.note-type-dropdown li.dropdown-item { diff --git a/apps/client/src/stylesheets/theme-next/shell.css b/apps/client/src/stylesheets/theme-next/shell.css index ce4a3e4eb..cdb9bae09 100644 --- a/apps/client/src/stylesheets/theme-next/shell.css +++ b/apps/client/src/stylesheets/theme-next/shell.css @@ -539,7 +539,7 @@ div.quick-search .search-button { justify-content: center; width: 25px; height: 25px; - margin-right: 8px; + margin-inline-end: 8px; border-radius: 50%; padding: 0; color: var(--quick-search-color) !important; @@ -734,7 +734,7 @@ body.mobile .fancytree-node > span { } #left-pane .tree-item-button { - margin-right: 6px; + margin-inline-end: 6px; border: unset; border-radius: 50%; background: var(--left-pane-item-action-button-background); @@ -1221,7 +1221,7 @@ body.mobile .note-title { } .title-row > *:first-child { - margin-right: 0; + margin-inline-end: 0; } .title-row > *:nth-child(2) { @@ -1312,7 +1312,7 @@ body.mobile .note-title { /* The promoted attributes section */ div.promoted-attributes-container { display: flex; - margin-right: 10%; + margin-inline-end: 10%; padding: 6px 0; gap: 8px; align-items: stretch; @@ -1400,7 +1400,7 @@ div.promoted-attribute-cell .tn-checkbox { /* Relocate the checkbox before the label */ div.promoted-attribute-cell.promoted-attribute-label-boolean > div:first-of-type { order: -1; - margin-right: 1.5em; + margin-inline-end: 1.5em; } /* The element containing the "new attribute" and "remove this attribute button" */ @@ -1408,7 +1408,7 @@ div.promoted-attribute-cell .multiplicity:has(span) { --icon-button-size: 24px; margin-inline-start: 8px; - margin-right: calc(var(--pa-card-padding-left) - var(--pa-card-padding-right)); + margin-inline-end: calc(var(--pa-card-padding-left) - var(--pa-card-padding-right)); font-size: 0; /* Prevent whitespaces creating a gap between buttons */ display: flex; } @@ -1700,7 +1700,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span { } .replace-widget-box > * { - margin-right: unset !important; + margin-inline-end: unset !important; } div.replace-widget-box button.btn.btn-sm { @@ -1807,7 +1807,7 @@ div.find-replace-widget div.find-widget-found-wrapper > span { .excalidraw .dropdown-menu .dropdown-menu-container > div:not([class]):not(:last-child) { margin-inline-start: calc(var(--padding) * var(--space-factor) * -1) !important; - margin-right: calc(var(--padding) * var(--space-factor) * -1) !important; + margin-inline-end: calc(var(--padding) * var(--space-factor) * -1) !important; } .excalidraw .dropdown-menu:before { diff --git a/apps/client/src/stylesheets/tree.css b/apps/client/src/stylesheets/tree.css index 29854e861..00e131936 100644 --- a/apps/client/src/stylesheets/tree.css +++ b/apps/client/src/stylesheets/tree.css @@ -59,7 +59,7 @@ span.fancytree-node.fancytree-hide { line-height: 1; position: relative; top: 2px; - margin-right: 5px; + margin-inline-end: 5px; } .fancytree-loading span.fancytree-expander { diff --git a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts index cdb7c7b43..7ce3372b9 100644 --- a/apps/client/src/widgets/attribute_widgets/attribute_detail.ts +++ b/apps/client/src/widgets/attribute_widgets/attribute_detail.ts @@ -176,7 +176,7 @@ const TPL = /*html*/`