diff --git a/common/data.ts b/common/data.ts index 8e7d147..07efb6f 100644 --- a/common/data.ts +++ b/common/data.ts @@ -142,6 +142,8 @@ export type HeadingPluginSettings = { sourceHideNumberSigns: boolean; useGutter: boolean; gutterPosition: GutterPosition; + gutterFontSize: GutterFontSize; + enabledGutterSettings: boolean; enabledInOutline: boolean; enabledOutlineSettings: boolean; enabledInQuietOutline: boolean; @@ -164,6 +166,8 @@ export type HeadingPluginData = Omit< | "enabledSourceSettings" | "useGutter" | "gutterPosition" + | "gutterFontSize" + | "enabledGutterSettings" | "enabledInOutline" | "outlineSettings" | "enabledInQuietOutline" @@ -321,6 +325,9 @@ export function defaultSettings(): HeadingPluginSettings { sourceHideNumberSigns: false, useGutter: false, gutterPosition: "before-line-numbers", + gutterFontSize: "ui-small", + enabledGutterSettings: false, + gutterSettings: { ...defaultHeadingDecoratorSettings(), opacity: 100 }, enabledInOutline: false, enabledOutlineSettings: false, outlineSettings: defaultHeadingDecoratorSettings(), diff --git a/components/editor-gutter.ts b/components/editor-gutter.ts index a70cdbd..a28ba82 100644 --- a/components/editor-gutter.ts +++ b/components/editor-gutter.ts @@ -89,12 +89,9 @@ export function createHeadingGutterExtension( } const doc = view.state.doc; - const settings = isLivePreviewMode - ? pluginData.previewSettings - : pluginData.sourceSettings; - - const { opacity } = settings; - const counter = createCounterFromSettings(settings, doc); + const { gutterSettings } = pluginData; + const { opacity } = gutterSettings; + const counter = createCounterFromSettings(gutterSettings, doc); const builder = new RangeSetBuilder(); const heading = new Heading(); diff --git a/components/plugin.ts b/components/plugin.ts index 83299a8..1e61689 100644 --- a/components/plugin.ts +++ b/components/plugin.ts @@ -170,6 +170,7 @@ export class HeadingPlugin extends Plugin { // Register editor extension this.editorExtensions = this.buildEditorExtensions(); this.registerEditorExtension(this.editorExtensions); + this.applyGutterFontSize(); // Register markdown post processor this.registerMarkdownPostProcessor((element, context) => { @@ -317,6 +318,7 @@ export class HeadingPlugin extends Plugin { this.revokes.forEach((revoke) => revoke()); this.revokes = []; + document.body.style.removeProperty("--heading-decorator-gutter-font-size"); } async saveSettings() { @@ -348,7 +350,14 @@ export class HeadingPlugin extends Plugin { } else { this.unloadFileExplorerComponents(); } - } else if (path === "useGutter" || path === "gutterPosition") { + } else if (path === "gutterFontSize") { + this.applyGutterFontSize(); + } else if ( + path === "useGutter" || + path === "gutterPosition" || + path === "enabledGutterSettings" || + path.startsWith("gutterSettings") + ) { this.swapEditorExtensions(); } else if ( path === "enabledOutlineSettings" || @@ -392,6 +401,9 @@ export class HeadingPlugin extends Plugin { if (!this.settings.enabledFileExplorerSettings) { this.debouncedRerenderFileExplorerDecorator(); } + if (this.settings.useGutter && !this.settings.enabledGutterSettings) { + this.swapEditorExtensions(); + } } } @@ -459,6 +471,19 @@ export class HeadingPlugin extends Plugin { this.app.workspace.updateOptions(); } + private applyGutterFontSize(): void { + const cssVarMap: Record = { + "ui-smaller": "var(--font-ui-smaller)", + "ui-small": "var(--font-ui-small)", + "ui-medium": "var(--font-ui-medium)", + "ui-large": "var(--font-ui-large)", + }; + document.body.style.setProperty( + "--heading-decorator-gutter-font-size", + cssVarMap[this.settings.gutterFontSize] ?? "var(--font-ui-small)" + ); + } + private createInlineViewPlugin( getPluginData: () => Promise ) { @@ -871,6 +896,8 @@ export class HeadingPlugin extends Plugin { sourceHideNumberSigns, previewSettings: _previewSettings, sourceSettings: _sourceSettings, + enabledGutterSettings, + gutterSettings: _gutterSettings, } = this.settings; let enabledInPreview = _enabledInPreview; @@ -881,6 +908,9 @@ export class HeadingPlugin extends Plugin { const sourceSettings = enabledSourceSettings ? _sourceSettings : commonSettings; + const gutterSettings = enabledGutterSettings + ? _gutterSettings + : commonSettings; const file = this.getActiveFile(); if (file) { @@ -911,6 +941,7 @@ export class HeadingPlugin extends Plugin { sourceHideNumberSigns, previewSettings, sourceSettings, + gutterSettings, }; } diff --git a/components/setting-tab.ts b/components/setting-tab.ts index dc00ef8..3f2dc2c 100644 --- a/components/setting-tab.ts +++ b/components/setting-tab.ts @@ -113,6 +113,53 @@ export class HeadingSettingTab extends PluginSettingTab { }) ); + //* gutterFontSize + gutterPositionManager.add( + new Setting(containerEl) + .setName(i18n.t("setting.gutterFontSize")) + .setDesc(i18n.t("setting.gutterFontSizeDesc")) + .addDropdown((dropdown) => { + dropdown + .addOptions({ + "ui-smaller": i18n.t("setting.gutterFontSizeSmaller"), + "ui-small": i18n.t("setting.gutterFontSizeSmall"), + "ui-medium": i18n.t("setting.gutterFontSizeMedium"), + "ui-large": i18n.t("setting.gutterFontSizeLarge"), + }) + .setValue(settings.gutterFontSize) + .onChange((value) => { + settings.gutterFontSize = this.isGutterFontSize(value) + ? value + : "ui-small"; + this.plugin.saveSettings(); + }); + }) + ); + + //* enabledGutterSettings + let gutterConfigBtn: ButtonOrUndefined; + gutterPositionManager.add( + new Setting(containerEl) + .setName(i18n.t("setting.enabledInGutterConfig")) + .setDesc(i18n.t("setting.enabledInGutterConfigDesc")) + .addToggle((toggle) => { + toggle.setValue(settings.enabledGutterSettings).onChange((value) => { + settings.enabledGutterSettings = value; + gutterConfigBtn?.setDisabled(!value); + this.plugin.saveSettings(); + }); + }) + .addButton((button) => { + gutterConfigBtn = button; + button + .setButtonText(i18n.t("button.config")) + .onClick(() => { + this.manageHeadingDecoratorSettings("gutterSettings"); + }) + .setDisabled(!settings.enabledGutterSettings); + }) + ); + if (!settings.useGutter) { gutterPositionManager.hide(); } @@ -495,6 +542,10 @@ export class HeadingSettingTab extends PluginSettingTab { return ["before-line-numbers", "after-line-numbers"].includes(value); } + private isGutterFontSize(value: string): value is GutterFontSize { + return ["ui-smaller", "ui-small", "ui-medium", "ui-large"].includes(value); + } + private manageHeadingDecoratorSettings( settingsType: PluginDecoratorSettingsType ) { @@ -528,6 +579,9 @@ export class HeadingSettingTab extends PluginSettingTab { case "fileExplorerSettings": tabName = i18n.t("setting.enabledInFileExplorerConfig"); break; + case "gutterSettings": + tabName = i18n.t("setting.enabledInGutterConfig"); + break; } new Setting(containerEl) diff --git a/locales/en.json b/locales/en.json index e8025d3..7f5a765 100644 --- a/locales/en.json +++ b/locales/en.json @@ -161,6 +161,14 @@ "gutterPositionDesc": "Whether the gutter column appears before or after line numbers.", "beforeLineNumbers": "Before line numbers", "afterLineNumbers": "After line numbers", + "gutterFontSize": "Gutter font size", + "gutterFontSizeDesc": "Set the font size for heading decorations in the gutter column.", + "gutterFontSizeSmaller": "Smaller (12px)", + "gutterFontSizeSmall": "Small (13px)", + "gutterFontSizeMedium": "Medium (15px)", + "gutterFontSizeLarge": "Large (20px)", + "enabledInGutterConfig": "Heading decorator for gutter", + "enabledInGutterConfigDesc": "Ignore the generic heading decorator config and set the heading decorator for the gutter display.", "logic": "Logic", "h1": "H1", "h2": "H2", diff --git a/locales/zh-TW.json b/locales/zh-TW.json index f903e6e..cf03e26 100644 --- a/locales/zh-TW.json +++ b/locales/zh-TW.json @@ -161,6 +161,14 @@ "gutterPositionDesc": "邊欄列顯示在行號之前還是之後。", "beforeLineNumbers": "在行號之前", "afterLineNumbers": "在行號之後", + "gutterFontSize": "邊欄字型大小", + "gutterFontSizeDesc": "設定邊欄中標題裝飾器的字型大小。", + "gutterFontSizeSmaller": "較小 (12px)", + "gutterFontSizeSmall": "小 (13px)", + "gutterFontSizeMedium": "中等 (15px)", + "gutterFontSizeLarge": "大 (20px)", + "enabledInGutterConfig": "邊欄的標題裝飾器", + "enabledInGutterConfigDesc": "忽略通用的標題裝飾器配置,單獨配置邊欄的標題裝飾器。", "logic": "邏輯控制", "h1": "H1 級別", "h2": "H2 級別", diff --git a/locales/zh.json b/locales/zh.json index d789bdd..de9ca5e 100644 --- a/locales/zh.json +++ b/locales/zh.json @@ -161,6 +161,14 @@ "gutterPositionDesc": "边栏列显示在行号之前还是之后。", "beforeLineNumbers": "在行号之前", "afterLineNumbers": "在行号之后", + "gutterFontSize": "边栏字体大小", + "gutterFontSizeDesc": "设置边栏中标题装饰器的字体大小。", + "gutterFontSizeSmaller": "较小 (12px)", + "gutterFontSizeSmall": "小 (13px)", + "gutterFontSizeMedium": "中等 (15px)", + "gutterFontSizeLarge": "大 (20px)", + "enabledInGutterConfig": "边栏的标题装饰器", + "enabledInGutterConfigDesc": "忽略通用的标题装饰器配置,单独配置边栏的标题装饰器。", "logic": "逻辑控制", "h1": "H1 级别", "h2": "H2 级别", diff --git a/styles.css b/styles.css index 965a36a..dbcda08 100644 --- a/styles.css +++ b/styles.css @@ -446,7 +446,7 @@ body { /* gutter start */ .heading-decorator-gutter { - font-size: var(--font-small); + font-size: var(--heading-decorator-gutter-font-size, var(--font-small)); letter-spacing: 0.015em; text-align: end; min-width: 4ch; diff --git a/types.d.ts b/types.d.ts index 9ce4739..cc03e08 100644 --- a/types.d.ts +++ b/types.d.ts @@ -14,6 +14,7 @@ type DecoratorMode = "orderd" | "independent" | "splice" | "unordered"; type OpacityOptions = 10 | 20 | 30 | 40 | 50 | 60 | 70 | 80 | 90 | 100; type PostionOptions = "before" | "before-inside" | "after" | "after-inside"; type GutterPosition = "before-line-numbers" | "after-line-numbers"; +type GutterFontSize = "ui-smaller" | "ui-small" | "ui-medium" | "ui-large"; type RenderPolicy = "partial" | "full"; type PluginDecoratorSettingsType = @@ -23,7 +24,8 @@ type PluginDecoratorSettingsType = | "sourceSettings" | "outlineSettings" | "quietOutlineSettings" - | "fileExplorerSettings"; + | "fileExplorerSettings" + | "gutterSettings"; type HeadingMetadataSettingsType = | "reading"