feat(react/settings): port heading style

This commit is contained in:
Elian Doran 2025-08-18 09:47:18 +03:00
parent 701855344e
commit 3ba0bcea4e
No known key found for this signature in database
3 changed files with 37 additions and 58 deletions

View File

@ -738,6 +738,18 @@ function isLaunchBarConfig(noteId: string) {
return ["_lbRoot", "_lbAvailableLaunchers", "_lbVisibleLaunchers", "_lbMobileRoot", "_lbMobileAvailableLaunchers", "_lbMobileVisibleLaunchers"].includes(noteId);
}
export function toggleBodyClass(prefix: string, value: string) {
const $body = $("body");
for (const clazz of Array.from($body[0].classList)) {
// create copy to safely iterate over while removing classes
if (clazz.startsWith(prefix)) {
$body.removeClass(clazz);
}
}
$body.addClass(prefix + value);
}
export default {
reloadFrontendApp,
restartDesktopApp,

View File

@ -1,14 +1,17 @@
import { useEffect } from "preact/hooks";
import { t } from "../../../services/i18n";
import FormCheckbox from "../../react/FormCheckbox";
import FormRadioGroup from "../../react/FormRadioGroup";
import { useTriliumOption, useTriliumOptionBool } from "../../react/hooks";
import OptionsSection from "./components/OptionsSection";
import { toggleBodyClass } from "../../../services/utils";
export default function TextNoteSettings() {
return (
<>
<FormattingToolbar />
<EditorFeatures />
<HeadingStyle />
</>
)
}
@ -66,3 +69,25 @@ function EditorFeatures() {
</OptionsSection>
);
}
function HeadingStyle() {
const [ headingStyle, setHeadingStyle ] = useTriliumOption("headingStyle");
useEffect(() => {
toggleBodyClass("heading-style-", headingStyle);
}, [ headingStyle ]);
return (
<OptionsSection title={t("heading_style.title")}>
<FormRadioGroup
name="heading-style"
currentValue={headingStyle} onChange={setHeadingStyle}
values={[
{ value: "plain", label: t("heading_style.plain") },
{ value: "underline", label: t("heading_style.underline") },
{ value: "markdown", label: t("heading_style.markdown") }
]}
/>
</OptionsSection>
);
}

View File

@ -1,58 +0,0 @@
import OptionsWidget from "../options_widget.js";
import { t } from "../../../../services/i18n.js";
import type { OptionMap } from "@triliumnext/commons";
const TPL = /*html*/`
<div class="options-section">
<h4>${t("heading_style.title")}</h4>
<div role="group">
<label class="tn-radio">
<input name="heading-style" type="radio" value="plain" />
${t("heading_style.plain")}
</label>
<label class="tn-radio">
<input name="heading-style" type="radio" value="underline" />
${t("heading_style.underline")}
</label>
<label class="tn-radio">
<input name="heading-style" type="radio" value="markdown" />
${t("heading_style.markdown")}
</label>
</div>
</div>`;
export default class HeadingStyleOptions extends OptionsWidget {
private $body!: JQuery<HTMLElement>;
doRender() {
this.$widget = $(TPL);
this.$body = $("body");
this.$widget.find(`input[name="heading-style"]`).on("change", () => {
const newHeadingStyle = String(this.$widget.find(`input[name="heading-style"]:checked`).val());
this.toggleBodyClass("heading-style-", newHeadingStyle);
this.updateOption("headingStyle", newHeadingStyle);
});
}
async optionsLoaded(options: OptionMap) {
this.$widget.find(`input[name="heading-style"][value="${options.headingStyle}"]`)
.prop("checked", "true");
}
toggleBodyClass(prefix: string, value: string) {
for (const clazz of Array.from(this.$body[0].classList)) {
// create copy to safely iterate over while removing classes
if (clazz.startsWith(prefix)) {
this.$body.removeClass(clazz);
}
}
this.$body.addClass(prefix + value);
}
}