fix(client/rtl): tooltips not inverted

This commit is contained in:
Elian Doran 2025-10-08 19:06:19 +03:00
parent 9d1e89268f
commit b5f73874cb
No known key found for this signature in database
6 changed files with 29 additions and 14 deletions

View File

@ -869,6 +869,18 @@ export function getErrorMessage(e: unknown) {
}
}
/**
* Handles left or right placement of e.g. tooltips in case of right-to-left languages. If the current language is a RTL one, then left and right are swapped. Other directions are unaffected.
* @param placement a string optionally containing a "left" or "right" value.
* @returns a left/right value swapped if needed, or the same as input otherwise.
*/
export function handleRightToLeftPlacement<T extends string>(placement: T) {
if (!glob.isRtl) return placement;
if (placement === "left") return "right";
if (placement === "right") return "left";
return placement;
}
export default {
reloadFrontendApp,
restartDesktopApp,

View File

@ -1,5 +1,6 @@
import { Tooltip } from "bootstrap";
import NoteContextAwareWidget from "../note_context_aware_widget.js";
import { handleRightToLeftPlacement } from "../../services/utils.js";
const TPL = /*html*/`<button class="button-widget bx"
data-bs-toggle="tooltip"
@ -26,13 +27,14 @@ export default class AbstractButtonWidget<SettingsT extends AbstractButtonWidget
doRender() {
this.$widget = $(TPL);
this.tooltip = new Tooltip(this.$widget[0], {
html: true,
// in case getTitle() returns null -> use empty string as fallback
title: () => this.getTitle() || "",
trigger: "hover",
placement: this.settings.titlePlacement,
fallbackPlacements: [this.settings.titlePlacement]
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
});
if (this.settings.onContextMenu) {

View File

@ -1,3 +1,4 @@
import { handleRightToLeftPlacement } from "../../services/utils.js";
import BasicWidget from "../basic_widget.js";
import { Tooltip, Dropdown } from "bootstrap";
type PopoverPlacement = Tooltip.PopoverPlacement;
@ -48,8 +49,8 @@ export default class RightDropdownButtonWidget extends BasicWidget {
this.$tooltip = this.$widget.find(".tooltip-trigger").attr("title", this.title);
this.tooltip = new Tooltip(this.$tooltip[0], {
placement: this.settings.titlePlacement,
fallbackPlacements: [this.settings.titlePlacement]
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
});
this.$widget

View File

@ -2,7 +2,7 @@ import BasicWidget from "./basic_widget.js";
import server from "../services/server.js";
import linkService from "../services/link.js";
import froca from "../services/froca.js";
import utils from "../services/utils.js";
import utils, { handleRightToLeftPlacement } from "../services/utils.js";
import appContext from "../components/app_context.js";
import shortcutService, { isIMEComposing } from "../services/shortcuts.js";
import { t } from "../services/i18n.js";
@ -248,7 +248,7 @@ export default class QuickSearchWidget extends BasicWidget {
let tooltip = new Tooltip(this.$searchString[0], {
trigger: "manual",
title: `Search error: ${error}`,
placement: "right"
placement: handleRightToLeftPlacement("right")
});
tooltip.show();

View File

@ -5,7 +5,7 @@ import { useEffect, useMemo, useRef, useState, type CSSProperties } from "preact
import "./FormList.css";
import { CommandNames } from "../../components/app_context";
import { useStaticTooltip } from "./hooks";
import { isMobile } from "../../services/utils";
import { handleRightToLeftPlacement, isMobile } from "../../services/utils";
interface FormListOpts {
children: ComponentChildren;
@ -93,8 +93,8 @@ interface FormListItemOpts {
}
const TOOLTIP_CONFIG: Partial<Tooltip.Options> = {
placement: "right",
fallbackPlacements: [ "right" ]
placement: handleRightToLeftPlacement("right"),
fallbackPlacements: [ handleRightToLeftPlacement("right") ]
}
export function FormListItem({ className, icon, value, title, active, disabled, checked, container, onClick, selected, rtl, triggerCommand, description, ...contentProps }: FormListItemOpts) {

View File

@ -3,7 +3,7 @@ import BasicWidget from "./basic_widget.js";
import ws from "../services/ws.js";
import options from "../services/options.js";
import syncService from "../services/sync.js";
import { escapeQuotes } from "../services/utils.js";
import { escapeQuotes, handleRightToLeftPlacement } from "../services/utils.js";
import { Tooltip } from "bootstrap";
import { WebSocketMessage } from "@triliumnext/commons";
@ -109,8 +109,8 @@ export default class SyncStatusWidget extends BasicWidget {
Tooltip.getOrCreateInstance(this.$widget.find(`.sync-status-${className}`)[0], {
html: true,
placement: this.settings.titlePlacement,
fallbackPlacements: [this.settings.titlePlacement]
placement: handleRightToLeftPlacement(this.settings.titlePlacement),
fallbackPlacements: [ handleRightToLeftPlacement(this.settings.titlePlacement) ]
});
this.$widget.show();