diff --git a/src/settings.ts b/src/settings.ts index 956e4f2..ced445a 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -10,24 +10,93 @@ export const DEFAULT_SETTINGS: MyPluginSettings = { mySetting: 'default' } +// Inspired by https://stackoverflow.com/a/50851710/13613783 +export type KeysOfType = NonNullable<{ [k in keyof Obj]: Obj[k] extends Type ? k : never }[keyof Obj]>; + export class SampleSettingTab extends PluginSettingTab { constructor(public plugin: MyPlugin) { super(plugin.app, plugin); } + addHeading(heading: string) { + return new Setting(this.containerEl).setName(heading).setHeading(); + } + + addTextSetting(settingName: KeysOfType) { + return new Setting(this.containerEl) + .addText((text) => { + text.setValue(this.plugin.settings[settingName]) + .setPlaceholder(DEFAULT_SETTINGS[settingName]) + .onChange(async (value) => { + // @ts-ignore + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + }); + }); + } + + addNumberSetting(settingName: KeysOfType) { + return new Setting(this.containerEl) + .addText((text) => { + text.setValue('' + this.plugin.settings[settingName]) + .setPlaceholder('' + DEFAULT_SETTINGS[settingName]) + .then((text) => text.inputEl.type = "number") + .onChange(async (value) => { + this.plugin.settings[settingName] = value === '' ? DEFAULT_SETTINGS[settingName] : +value; + await this.plugin.saveSettings(); + }); + }); + } + + addToggleSetting(settingName: KeysOfType, extraOnChange?: (value: boolean) => void) { + return new Setting(this.containerEl) + .addToggle((toggle) => { + toggle.setValue(this.plugin.settings[settingName]) + .onChange(async (value) => { + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + extraOnChange?.(value); + }); + }); + } + + addDropdowenSetting(settingName: KeysOfType, options: readonly string[], display?: (option: string) => string, extraOnChange?: (value: string) => void) { + return new Setting(this.containerEl) + .addDropdown((dropdown) => { + const displayNames = new Set(); + for (const option of options) { + const displayName = display?.(option) ?? option; + if (!displayNames.has(displayName)) { + dropdown.addOption(option, displayName); + displayNames.add(displayName); + } + }; + dropdown.setValue(this.plugin.settings[settingName]) + .onChange(async (value) => { + // @ts-ignore + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + extraOnChange?.(value); + }); + }); + } + + addSliderSetting(settingName: KeysOfType, min: number, max: number, step: number) { + return new Setting(this.containerEl) + .addSlider((slider) => { + slider.setLimits(min, max, step) + .setValue(this.plugin.settings[settingName]) + .setDynamicTooltip() + .onChange(async (value) => { + // @ts-ignore + this.plugin.settings[settingName] = value; + await this.plugin.saveSettings(); + }); + }); + } + display(): void { const {containerEl} = this; containerEl.empty(); - - new Setting(containerEl) - .setName('Setting #1') - .setDesc('It\'s a secret') - .addText(text => text - .setPlaceholder('Enter your secret') - .setValue(this.plugin.settings.mySetting) - .onChange(async (value) => { - this.plugin.settings.mySetting = value; - await this.plugin.saveSettings(); - })); } }