obsidian#TextComponent TypeScript Examples

The following examples show how to use obsidian#TextComponent. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: settings.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
static setValidationError(textInput: TextComponent, message?: string) {
        textInput.inputEl.addClass("is-invalid");
        if (message) {
            textInput.inputEl.parentElement.addClasses([
                "has-invalid-message",
                "unset-align-items"
            ]);
            textInput.inputEl.parentElement.parentElement.addClass(
                ".unset-align-items"
            );
            let mDiv = textInput.inputEl.parentElement.querySelector(
                ".invalid-feedback"
            ) as HTMLDivElement;

            if (!mDiv) {
                mDiv = createDiv({ cls: "invalid-feedback" });
            }
            mDiv.innerText = message;
            mDiv.insertAfter(textInput.inputEl);
        }
    }
Example #2
Source File: path.ts    From obsidian-fantasy-calendar with MIT License 6 votes vote down vote up
constructor(app: App, input: TextComponent, items: TFile[]) {
        super(app, input.inputEl, items);
        this.files = [...items];
        this.text = input;

        this.createPrompts();

        this.inputEl.addEventListener("input", this.getFile.bind(this));
    }
Example #3
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 6 votes vote down vote up
/* utils functions */

    static setValidationError(textInput: TextComponent, insertAfter: Element, message?: string) {
        textInput.inputEl.addClass("is-invalid");
        if (message) {

            let mDiv = textInput.inputEl.parentElement.querySelector(
                ".invalid-feedback"
            ) as HTMLDivElement;

            if (!mDiv) {
                mDiv = createDiv({ cls: "invalid-feedback" });
            }
            mDiv.innerText = message;
            mDiv.insertAfter(insertAfter);
        }
    }
Example #4
Source File: functions.ts    From obsidian-rss with GNU General Public License v3.0 6 votes vote down vote up
export async function createNewNote(plugin: RssReaderPlugin, item: RssFeedItem): Promise<void> {
    const activeFile = plugin.app.workspace.getActiveFile();
    let dir = plugin.app.fileManager.getNewFileParent(activeFile ? activeFile.path : "").path;

    if (plugin.settings.saveLocation === "custom") {
        dir = plugin.settings.saveLocationFolder;
    }

    let filename = applyTemplate(plugin, item, plugin.settings.defaultFilename);
    //make sure there are no slashes in the title.
    filename = filename.replace(/[\/\\:]/g, ' ');

    if (plugin.settings.askForFilename) {
        const inputPrompt = new TextInputPrompt(plugin.app, t("specify_name"), t("cannot_contain") + " * \" \\ / < > : | ?", filename, filename);
        await inputPrompt
            .openAndGetValue(async (text: TextComponent) => {
                const value = text.getValue();
                if (value.match(FILE_NAME_REGEX)) {
                    inputPrompt.setValidationError(text, t("invalid_filename"));
                    return;
                }
                const filePath = normalizePath([dir, `${value}.md`].join('/'));

                if (isInVault(plugin.app, filePath, '')) {
                    inputPrompt.setValidationError(text, t("note_exists"));
                    return;
                }
                inputPrompt.close();
                await createNewFile(plugin, item, filePath, value);
            });
    } else {
        const replacedTitle = filename.replace(FILE_NAME_REGEX, '');
        const filePath = normalizePath([dir, `${replacedTitle}.md`].join('/'));
        await createNewFile(plugin, item, filePath, item.title);
    }


}
Example #5
Source File: ICSSettingsTab.ts    From obsidian-ics with MIT License 6 votes vote down vote up
static setValidationError(textInput: TextComponent, message ? : string) {
		textInput.inputEl.addClass("is-invalid");
		if (message) {
			textInput.inputEl.parentElement.addClasses([
				"has-invalid-message",
				"unset-align-items"
			]);
			textInput.inputEl.parentElement.parentElement.addClass(
				".unset-align-items"
			);
			let mDiv = textInput.inputEl.parentElement.querySelector(
				".invalid-feedback"
			) as HTMLDivElement;

			if (!mDiv) {
				mDiv = createDiv({
					cls: "invalid-feedback"
				});
			}
			mDiv.innerText = message;
			mDiv.insertAfter(textInput.inputEl);
		}
	}
Example #6
Source File: settings.ts    From remotely-save with Apache License 2.0 6 votes vote down vote up
wrapTextWithPasswordHide = (text: TextComponent) => {
  const { eye, eyeOff } = getEyesElements();
  const hider = text.inputEl.insertAdjacentElement("afterend", createSpan());
  // the init type of hider is "hidden" === eyeOff === password
  hider.innerHTML = eyeOff;
  hider.addEventListener("click", (e) => {
    const isText = text.inputEl.getAttribute("type") === "text";
    hider.innerHTML = isText ? eyeOff : eye;
    text.inputEl.setAttribute("type", isText ? "password" : "text");
    text.inputEl.focus();
  });

  // the init type of text el is password
  text.inputEl.setAttribute("type", "password");
  return text;
}
Example #7
Source File: index.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
constructor(public plugin: ObsidianAdmonition, input: TextComponent) {
        super(
            plugin.app,
            input.inputEl,
            plugin.iconManager.iconDefinitions
        );
        this.icons = plugin.iconManager.iconDefinitions;
        this.text = input;

        this.createPrompts();

        this.inputEl.addEventListener("input", this.getItem.bind(this));
    }
Example #8
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 6 votes vote down vote up
createListNoteContainer(parentNode: HTMLDivElement): TextComponent {
        const listNoteContainerLabel = parentNode.createDiv()
        listNoteContainerLabel.setText(`Path of the note containing the values:`)
        const input = new TextComponent(parentNode)
        const listNotePath = this.property.valuesListNotePath
        input.setValue(listNotePath)
        input.setPlaceholder("Path/of/the/note.md")
        input.onChange(value => this.property.valuesListNotePath = value)
        return input
    }
Example #9
Source File: index.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
constructor(
        public plugin: ObsidianAdmonition,
        input: TextComponent,
        items: Admonition[]
    ) {
        super(plugin.app, input.inputEl, items);
        this.admonitions = [...items];
        this.text = input;

        this.createPrompts();

        this.inputEl.addEventListener("input", this.getItem.bind(this));
    }
Example #10
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 6 votes vote down vote up
createnameInputContainer(parentNode: HTMLDivElement): TextComponent {
        const propertyNameContainerLabel = parentNode.createDiv()
        propertyNameContainerLabel.setText(`Property Name:`)
        const input = new TextComponent(parentNode)
        const name = this.property.name
        input.setValue(name)
        input.setPlaceholder("Name of the property")
        input.onChange(value => {
            this.property.name = value
            this.titleEl.setText(`Manage predefined values for ${this.property.name}`)
            FieldSettingsModal.removeValidationError(input)
        })
        return input
    }
Example #11
Source File: settings.ts    From obsidian-admonition with MIT License 6 votes vote down vote up
static removeValidationError(textInput: TextComponent) {
        textInput.inputEl.removeClass("is-invalid");
        textInput.inputEl.parentElement.removeClasses([
            "has-invalid-message",
            "unset-align-items"
        ]);
        textInput.inputEl.parentElement.parentElement.removeClass(
            ".unset-align-items"
        );

        if (
            textInput.inputEl.parentElement.querySelector(".invalid-feedback")
        ) {
            textInput.inputEl.parentElement.removeChild(
                textInput.inputEl.parentElement.querySelector(
                    ".invalid-feedback"
                )
            );
        }
    }
Example #12
Source File: UserScriptSettingsModal.ts    From quickadd with MIT License 6 votes vote down vote up
private addFormatInput(name: string, value: string, placeholder?: string) {
        new Setting(this.contentEl).setName(name);

        const formatDisplay = this.contentEl.createEl("span");
        const input = new TextComponent(this.contentEl);
        new FormatSyntaxSuggester(this.app, input.inputEl, QuickAdd.instance);
        const displayFormatter = new FormatDisplayFormatter(this.app, QuickAdd.instance);

        input.setValue(value)
            .onChange(async value => {
                this.command.settings[name] = value
                formatDisplay.innerText = await displayFormatter.format(value);
            })
            .setPlaceholder(placeholder ?? "")

        input.inputEl.style.width = "100%";
        input.inputEl.style.marginBottom = "1em";

        (async () => formatDisplay.innerText = await displayFormatter.format(value))();
    }
Example #13
Source File: valueTextInputModal.ts    From obsidian_supercharged_links with MIT License 6 votes vote down vote up
buildInputEl(inputDiv: HTMLDivElement): void{
        const form = inputDiv.createEl("form")
        form.type = "submit";
        form.onsubmit = (e: Event) => {
            e.preventDefault()
            if(this.lineNumber == -1){
                replaceValues(this.app, this.file, this.name, inputEl.getValue())
            }
            else {
                this.app.vault.read(this.file).then(result => {
                    let newContent: string[] = []
                    if(this.top){
                        newContent.push(`${this.name}${this.inFrontmatter ? ":" : "::"} ${inputEl.getValue()}`)
                        result.split("\n").forEach((line, _lineNumber) => newContent.push(line))
                    } else {
                        result.split("\n").forEach((line, _lineNumber) => {
                            newContent.push(line)
                            if(_lineNumber == this.lineNumber){
                                newContent.push(`${this.name}${this.inFrontmatter ? ":" : "::"} ${inputEl.getValue()}`)
                            }
                        })
                    }
                    this.app.vault.modify(this.file, newContent.join('\n'))
                    this.close()
                })
            }
            this.close()
        }
        const inputEl = new TextComponent(form)
        inputEl.inputEl.focus()
        inputEl.setValue(this.value)
        inputEl.inputEl.addClass("frontmatter-prompt-input")

    }
Example #14
Source File: templateChoiceBuilder.ts    From quickadd with MIT License 6 votes vote down vote up
private addFileNameFormatSetting(): void {
        let textField: TextComponent;
        const enableSetting = new Setting(this.contentEl);
        enableSetting.setName("File Name Format")
            .setDesc("Set the file name format.")
            .addToggle(toggleComponent => {
                toggleComponent.setValue(this.choice.fileNameFormat.enabled)
                    .onChange(value => {
                        this.choice.fileNameFormat.enabled = value;
                        textField.setDisabled(!value);
                    })
            });

        const formatDisplay: HTMLSpanElement = this.contentEl.createEl('span');
        const displayFormatter: FileNameDisplayFormatter = new FileNameDisplayFormatter(this.app);
        (async () => formatDisplay.textContent = await displayFormatter.format(this.choice.fileNameFormat.format))();

        const formatInput = new TextComponent(this.contentEl);
        formatInput.setPlaceholder("File name format");
        textField = formatInput;
        formatInput.inputEl.style.width = "100%";
        formatInput.inputEl.style.marginBottom = "8px";
        formatInput.setValue(this.choice.fileNameFormat.format)
                .setDisabled(!this.choice.fileNameFormat.enabled)
                .onChange(async value => {
                    this.choice.fileNameFormat.format = value;
                    formatDisplay.textContent = await displayFormatter.format(value);
                });

        new FormatSyntaxSuggester(this.app, textField.inputEl, this.plugin, true);
    }
Example #15
Source File: suggester.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 6 votes vote down vote up
constructor(
        public plugin: InitiativeTracker,
        input: TextComponent,
        public party: Party
    ) {
        super(plugin.app, input.inputEl);
        this.text = input;

        this.createPrompts();

        this.inputEl.addEventListener("input", this.getItem.bind(this));
        this.inputEl.addEventListener("focus", this.onInputChanged.bind(this));
    }
Example #16
Source File: addNewFieldModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
onOpen(){
        this.titleEl.setText("Insert new field")
        const addNewFieldContainer = this.contentEl.createDiv()
        const nameInputContainer = addNewFieldContainer.createDiv()
        nameInputContainer.setText("Field Name: ")
        const nameInputEl = new TextComponent(nameInputContainer)
        nameInputEl.setPlaceholder("Field name")
        const valueInputContainer = addNewFieldContainer.createDiv()
        valueInputContainer.setText("Field value: ")
        const valueInputEl = new TextComponent(valueInputContainer)
        valueInputEl.setPlaceholder("Field value")
        const footerButtons = this.contentEl.createDiv({
            cls: 'frontmatter-textarea-buttons'
        })
        const saveButton = new ButtonComponent(footerButtons)
        saveButton.setIcon("checkmark")
        saveButton.onClick(() => {
            this.app.vault.read(this.file).then(result => {
                let newContent: string[] = []
                if(this.top){
                    newContent.push(`${nameInputEl.getValue()}${this.inFrontmatter ? ":" : "::"} ${valueInputEl.getValue()}`)
                    result.split("\n").forEach((line, _lineNumber) => newContent.push(line))
                } else {
                    result.split("\n").forEach((line, _lineNumber) => {
                        newContent.push(line)
                        if(_lineNumber == this.lineNumber){
                            newContent.push(`${nameInputEl.getValue()}${this.inFrontmatter ? ":" : "::"} ${valueInputEl.getValue()}`)
                        }
                    })
                }
                this.app.vault.modify(this.file, newContent.join('\n'))
                this.close()
            })
        })
        const cancelButton = new ExtraButtonComponent(footerButtons)
        cancelButton.setIcon("cross")
        cancelButton.onClick(() => {
            this.close()
        })


    }
Example #17
Source File: TextInputPrompt.ts    From obsidian-rss with GNU General Public License v3.0 5 votes vote down vote up
async openAndGetValue(resolve: (value: TextComponent) => void): Promise<void> {
        this.resolve = resolve;
        await this.open();
    }
Example #18
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
namePromptComponent: TextComponent
Example #19
Source File: ICSSettingsTab.ts    From obsidian-ics with MIT License 5 votes vote down vote up
async display() {
		let {
			contentEl
		} = this;

		contentEl.empty();

		const settingDiv = contentEl.createDiv();

		let calendarPreview = await getCalendarElement(
			this.icsName,
			this.icsUrl,
		);

		contentEl.appendChild(calendarPreview);
		let nameText: TextComponent;
		const nameSetting = new Setting(settingDiv)
			.setName("Calendar Name")

			.addText((text) => {
				nameText = text;
				nameText.setValue(this.icsName).onChange((v) => {
					this.icsName = v;
				});
			});

		let urlText: TextComponent;
		const urlSetting = new Setting(settingDiv)
			.setName("Calendar URL")

			.addText((text) => {
				urlText = text;
				urlText.setValue(this.icsUrl).onChange((v) => {
					this.icsUrl = v;
				});
			});

		let footerEl = contentEl.createDiv();
		let footerButtons = new Setting(footerEl);
		footerButtons.addButton((b) => {
			b.setTooltip("Save")
				.setIcon("checkmark")
				.onClick(async () => {
					this.saved = true;
					this.close();
				});
			return b;
		});
		footerButtons.addExtraButton((b) => {
			b.setIcon("cross")
				.setTooltip("Cancel")
				.onClick(() => {
					this.saved = false;
					this.close();
				});
			return b;
		});
	}
Example #20
Source File: index.ts    From obsidian-admonition with MIT License 5 votes vote down vote up
text: TextComponent;
Example #21
Source File: suggester.ts    From obsidian-initiative-tracker with GNU General Public License v3.0 5 votes vote down vote up
constructor(app: App, input: TextComponent) {
        super(app, input.inputEl);
        this.text = input;

        this.createPrompts();

        this.inputEl.addEventListener("input", this.getItem.bind(this));
    }
Example #22
Source File: captureChoiceBuilder.ts    From quickadd with MIT License 5 votes vote down vote up
private addCapturedToSetting() {
        let textField: TextComponent;
        const captureToSetting: Setting = new Setting(this.contentEl)
            .setName('Capture To')
            .setDesc('File to capture to. Supports some format syntax.');

        const captureToContainer: HTMLDivElement = this.contentEl.createDiv('captureToContainer');

        const captureToActiveFileContainer: HTMLDivElement = captureToContainer.createDiv('captureToActiveFileContainer');
        const captureToActiveFileText: HTMLSpanElement = captureToActiveFileContainer.createEl('span');
        captureToActiveFileText.textContent = "Capture to active file";
        const captureToActiveFileToggle: ToggleComponent = new ToggleComponent(captureToActiveFileContainer);
        captureToActiveFileToggle.setValue(this.choice?.captureToActiveFile);
        captureToActiveFileToggle.onChange(value => {
            this.choice.captureToActiveFile = value;

            this.reload();
        });

        if (!this.choice?.captureToActiveFile) {
            const captureToFileContainer: HTMLDivElement = captureToContainer.createDiv('captureToFileContainer');

            const formatDisplay: HTMLSpanElement = captureToFileContainer.createEl('span');
            const displayFormatter: FileNameDisplayFormatter = new FileNameDisplayFormatter(this.app);
            (async () => formatDisplay.textContent = await displayFormatter.format(this.choice.captureTo))();

            const formatInput = new TextComponent(captureToFileContainer);
            formatInput.setPlaceholder("File name format");
            textField = formatInput;
            formatInput.inputEl.style.width = "100%";
            formatInput.inputEl.style.marginBottom = "8px";
            formatInput.setValue(this.choice.captureTo)
                .setDisabled(this.choice?.captureToActiveFile)
                .onChange(async value => {
                    this.choice.captureTo = value;
                    formatDisplay.textContent = await displayFormatter.format(value);
                });

            const markdownFilesAndFormatSyntax = [...this.app.vault.getMarkdownFiles().map(f => f.path), ...FILE_NAME_FORMAT_SYNTAX];
            new GenericTextSuggester(this.app, textField.inputEl, markdownFilesAndFormatSyntax);
        }
    }
Example #23
Source File: mockSetting.ts    From obsidian-switcher-plus with GNU General Public License v3.0 5 votes vote down vote up
export class MockTextComponent implements TextComponent {
  inputEl: HTMLInputElement;
  disabled: boolean;
  onChangeCB: (value: string) => any;

  constructor(public containerEl: HTMLElement) {
    this.inputEl = mock<HTMLInputElement>();
  }

  getValue(): string {
    return this.inputEl.value;
  }

  setValue(value: string): this {
    this.inputEl.value = value;

    if (this.onChangeCB) {
      this.onChangeCB(value);
    }

    return this;
  }

  setPlaceholder(_placeholder: string): this {
    return this;
  }

  onChange(callback: (value: string) => any): this {
    this.onChangeCB = callback;
    return this;
  }

  setDisabled(_disabled: boolean): this {
    throw new Error('Method not implemented.');
  }
  onChanged(): void {
    throw new Error('Method not implemented.');
  }
  registerOptionListener(
    _listeners: Record<string, (value?: string) => string>,
    _key: string,
  ): this {
    throw new Error('Method not implemented.');
  }
  then(_cb: (component: this) => any): this {
    throw new Error('Method not implemented.');
  }
}
Example #24
Source File: newPresetDialog.ts    From obsidian-map-view with GNU General Public License v3.0 5 votes vote down vote up
onOpen() {
        let statusLabel: HTMLDivElement = null;
        const grid = this.contentEl.createDiv({ cls: 'newPresetDialogGrid' });
        const row1 = grid.createDiv({ cls: 'newPresetDialogLine' });
        const row2 = grid.createDiv({ cls: 'newPresetDialogLine' });
        const row3 = grid.createDiv({ cls: 'newPresetDialogLine' });
        let name = new TextComponent(row1).onChange((value) => {
            if (value == 'Default' || value.length === 0)
                saveButton.disabled = true;
            else saveButton.disabled = false;
            if (this.findPresetByName(value))
                statusLabel.setText(
                    "Clicking 'Save' will overwrite an existing preset."
                );
            else statusLabel.setText('');
        });
        name.inputEl.style.width = '100%';
        name.inputEl.addEventListener('keypress', (ev: KeyboardEvent) => {
            if (ev.key == 'Enter') saveButton.buttonEl.click();
        });
        const includeMapSource = row2.createEl('input', { type: 'checkbox' });
        includeMapSource.id = 'includeMapSource';
        const includeMapSourceLabel = row2.createEl('label');
        includeMapSourceLabel.setAttribute('for', 'includeMapSource');
        includeMapSourceLabel.textContent = 'Include chosen map source';
        let saveButton = new ButtonComponent(row3)
            .setButtonText('Save')
            .onClick(async () => {
                let existingPreset = this.findPresetByName(name.getValue());
                let newState = { ...this.stateToSave, name: name.getValue() };
                if (!(includeMapSource as HTMLInputElement).checked)
                    newState.chosenMapSource = undefined;
                if (existingPreset) {
                    Object.assign(existingPreset, newState);
                    newState = existingPreset;
                } else {
                    this.settings.savedStates.push(newState);
                }
                await this.plugin.saveSettings();
                // Update the presets list
                const presetIndex = this.settings.savedStates.indexOf(newState);
                // Select the new preset in the view's controls
                this.callback((presetIndex + 1).toString());
                this.close();
            });
        new ButtonComponent(row3).setButtonText('Cancel').onClick(() => {
            this.close();
        });
        statusLabel = row3.createDiv();
        name.onChanged();
        name.inputEl.focus();
    }
Example #25
Source File: mockSetting.ts    From obsidian-switcher-plus with GNU General Public License v3.0 5 votes vote down vote up
addText(cb: (component: TextComponent) => any): this {
    cb(new MockTextComponent(this.containerEl));
    return this;
  }
Example #26
Source File: SettingsTab.ts    From obsidian-rss with GNU General Public License v3.0 5 votes vote down vote up
display(): void {
        const {containerEl} = this;

        containerEl.empty();

        containerEl.createEl('h2', {text: t("RSS_Reader") + " " + t("settings")});

        containerEl.createEl('h3', {text: t("file_creation")});

        const templateDesc = new DocumentFragment();
        templateDesc.createDiv().innerHTML = t("template_new_help") + "<br>" + t("available_variables") + `<br>` +
            `<strong>{{title}}</strong> → ${t("article_title")}<br>` +
            `<strong>{{link}}</strong> → ${t("article_link")}<br>` +
            `<strong>{{author}}</strong> → ${t("article_author")}<br>` +
            `<strong>{{published}}</strong> → ${t("article_published")}<br>` +
            `<strong>{{created}}</strong> → ${t("note_created")}<br>` +
            `<strong>{{description}}</strong> → ${t("article_description")}<br>` +
            `<strong>{{content}}</strong> → ${t("article_content")}<br>` +
            `<strong>{{folder}}</strong> → ${t("feed_folder")}<br>` +
            `<strong>{{feed}}</strong> → ${t("feed_title")}<br>` +
            `<strong>{{filename}}</strong> → ${t("filename")}<br>` +
            `<strong>{{tags}}</strong> → ${t("article_tags")}<br>` +
            `<strong>{{media}}</strong> → ${t("article_media")}<br>` +
            `<strong>{{highlights}}</strong> → ${t("highlights")}`;

        new Setting(containerEl)
            .setName(t("template_new"))
            .setDesc(templateDesc)
            .addTextArea((textArea: TextAreaComponent) => {
                textArea
                    .setValue(this.plugin.settings.template)
                    .setPlaceholder(DEFAULT_SETTINGS.template)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => ({
                            template: value
                        }));
                    });
                textArea.inputEl.setAttr("rows", 15);
                textArea.inputEl.setAttr("cols", 50);
            });

        const pasteTemplateDesc = new DocumentFragment();
        pasteTemplateDesc.createDiv().innerHTML = t("template_new_help") + "<br>" + t("available_variables") + `<br>` +
            `<strong>{{title}}</strong> → ${t("article_title")}<br>` +
            `<strong>{{link}}</strong> → ${t("article_link")}<br>` +
            `<strong>{{author}}</strong> → ${t("article_author")}<br>` +
            `<strong>{{published}}</strong> → ${t("article_published")}<br>` +
            `<strong>{{created}}</strong> → ${t("note_created")}<br>` +
            `<strong>{{description}}</strong> → ${t("article_description")}<br>` +
            `<strong>{{content}}</strong> → ${t("article_content")}<br>` +
            `<strong>{{folder}}</strong> → ${t("feed_folder")}<br>` +
            `<strong>{{feed}}</strong> → ${t("feed_title")}<br>` +
            `<strong>{{tags}}</strong> → ${t("article_tags")}<br>` +
            `<strong>{{media}}</strong> → ${t("article_media")}<br>` +
            `<strong>{{highlights}}</strong> → ${t("highlights")}`;

        new Setting(containerEl)
            .setName(t("template_paste"))
            .setDesc(pasteTemplateDesc)
            .addTextArea((textArea: TextAreaComponent) => {
                textArea
                    .setValue(this.plugin.settings.pasteTemplate)
                    .setPlaceholder(DEFAULT_SETTINGS.pasteTemplate)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => ({
                            pasteTemplate: value
                        }));
                    });
                textArea.inputEl.setAttr("rows", 15);
                textArea.inputEl.setAttr("cols", 50);
            });

        new Setting(containerEl)
            .setName(t("file_location"))
            .setDesc(t("file_location_help"))
            .addDropdown(async (dropdown: DropdownComponent) => {
                dropdown
                    .addOption("default", t("file_location_default"))
                    .addOption("custom", t("file_location_custom"))
                    .setValue(this.plugin.settings.saveLocation)
                    .onChange(async (value: string) => {
                        await this.plugin.writeSettings(() => (
                            {saveLocation: value}
                        ));
                        this.display();
                    });
            });

        if (this.plugin.settings.saveLocation == "custom") {
            new Setting(containerEl)
                .setName(t("file_location_folder"))
                .setDesc(t("file_location_folder_help"))
                .addSearch(async (search: SearchComponent) => {
                    new FolderSuggest(this.app, search.inputEl);
                    search
                        .setValue(this.plugin.settings.saveLocationFolder)
                        .setPlaceholder(DEFAULT_SETTINGS.saveLocationFolder)
                        .onChange(async (value: string) => {
                            await this.plugin.writeSettings(() => (
                                {saveLocationFolder: value}
                            ));
                        });
                });
        }

        let dateFormatSampleEl: MomentFormatComponent;
        const dateFormat = new Setting(containerEl)
            .setName(t("date_format"))
            .addMomentFormat((format: MomentFormatComponent) => {
                dateFormatSampleEl = format
                    .setDefaultFormat(DEFAULT_SETTINGS.dateFormat)
                    .setPlaceholder(DEFAULT_SETTINGS.dateFormat)
                    .setValue(this.plugin.settings.dateFormat)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => (
                            {dateFormat: value}
                        ));
                    });
            });
        const referenceLink = dateFormat.descEl.createEl("a");
        referenceLink.setAttr("href", "https://momentjs.com/docs/#/displaying/format/");
        referenceLink.setText(t("syntax_reference"));
        const text = dateFormat.descEl.createDiv("text");
        text.setText(t("syntax_looks"));
        const sampleEl = text.createSpan("sample");
        dateFormatSampleEl.setSampleEl(sampleEl);
        dateFormat.addExtraButton((button) => {
            button
                .setIcon('reset')
                .setTooltip(t("reset"))
                .onClick(async () => {
                    await this.plugin.writeSettings(() => ({
                        dateFormat: DEFAULT_SETTINGS.dateFormat
                    }));
                    this.display();
                });
        });

        new Setting(containerEl)
            .setName(t("ask_filename"))
            .setDesc(t("ask_filename_help"))
            .addToggle((toggle: ToggleComponent) => {
                toggle
                    .setValue(this.plugin.settings.askForFilename)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => ({
                            askForFilename: value
                        }));
                    });
            });

        new Setting(containerEl)
            .setName(t("default_filename"))
            .setDesc(t("default_filename_help"))
            .addText((text) => {
                text
                    .setPlaceholder(DEFAULT_SETTINGS.defaultFilename)
                    .setValue(this.plugin.settings.defaultFilename)
                    .onChange(async (value) => {
                        if (value.length > 0) {
                            await this.plugin.writeSettings(() => ({
                                defaultFilename: value
                            }));
                        } else {
                            new Notice(t("fix_errors"));
                        }
                    });
            });

        containerEl.createEl("hr", {attr: {style: "border-top: 5px solid var(--background-modifier-border);"}});
        containerEl.createEl("h3", {text: "Misc"});

        const refresh = new Setting(containerEl)
            .setName(t("refresh_time"))
            .setDesc(t("refresh_time_help"))
            .addText((text: TextComponent) => {
                text
                    .setPlaceholder(String(DEFAULT_SETTINGS.updateTime))
                    .setValue(String(this.plugin.settings.updateTime))
                    .onChange(async (value) => {
                        if (value.length === 0) {
                            new Notice(t("specify_positive_number"));
                            return;
                        }
                        if (Number(value) < 0) {
                            new Notice(t("specify_positive_number"));
                            return;
                        }

                        await this.plugin.writeSettings(() => (
                            {updateTime: Number(value)}
                        ));
                    });
                text.inputEl.setAttr("type", "number");
                text.inputEl.setAttr("min", "1");
                //we don't want decimal numbers.
                text.inputEl.setAttr("onkeypress", "return event.charCode >= 48 && event.charCode <= 57");
            });
        refresh.addExtraButton((button) => {
            button
                .setIcon('reset')
                .setTooltip('restore default')
                .onClick(async () => {
                    await this.plugin.writeSettings(() => ({
                        updateTime: DEFAULT_SETTINGS.updateTime
                    }));
                    this.display();
                });
        });

        new Setting(containerEl)
            .setName(t("multi_device_usage"))
            .setDesc(t("multi_device_usage_help"))
            .addToggle((toggle: ToggleComponent) => {
                return toggle
                    .setValue(this.plugin.settings.autoSync)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => ({
                            autoSync: value
                        }));
                    });
            });

        new Setting(containerEl)
            .setName(t("display_style"))
            .addDropdown(dropdown => {
                return dropdown
                    .addOption("list", t("list"))
                    .addOption("cards", t("cards"))
                    .setValue(this.plugin.settings.displayStyle)
                    .onChange(async (value) => {
                        await this.plugin.writeSettings(() => ({
                            displayStyle: value
                        }));
                    });
            });

        containerEl.createEl("h2", {text: t("content")});

        const filterContainer = containerEl.createDiv("filter-container");
        displayFilterSettings(this.plugin, filterContainer);

        const feedsContainer = containerEl.createDiv(
            "feed-container"
        );
        displayFeedSettings(this.plugin, feedsContainer);

        containerEl.createEl("hr", {attr: {style: "border-top: 5px solid var(--background-modifier-border);"}});

        const hotkeyContainer = containerEl.createDiv("hotkey-container");
        displayHotkeys(this.plugin, hotkeyContainer);

        containerEl.createEl("hr", {attr: {style: "border-top: 5px solid var(--background-modifier-border);"}});

        const details = containerEl.createEl("details");
        const summary = details.createEl("summary");
        summary.setText(t("advanced"));
        const advanced = details.createDiv("advanced");

        advanced.createEl("h3", {text: t("customize_terms")});
        advanced.createSpan({text: "Change a few selected terms here. You can help translating the plugin "});
        advanced.createEl("a", {text: "here", href: "https://github.com/joethei/obsidian-rss/tree/master/src/l10n"});

        new Setting(advanced)
            .setName(t("folders"))
            .addText(text => {
                text
                    .setPlaceholder(t("folders"))
                    .setValue(this.plugin.settings.renamedText.folders)
                    .onChange(async value => {
                        await this.plugin.writeSettings(() => ({
                            renamedText: {
                                ...this.plugin.settings.renamedText,
                                folders: value
                            }
                        }));
                    });
            });

        new Setting(advanced)
            .setName(t("filtered_folders"))
            .addText(text => {
                text
                    .setPlaceholder(t("filtered_folders"))
                    .setValue(this.plugin.settings.renamedText.filtered_folders)
                    .onChange(async value => {
                        await this.plugin.writeSettings(() => ({
                            renamedText: {
                                ...this.plugin.settings.renamedText,
                                filtered_folders: value
                            }
                        }));
                    });
            });

        new Setting(advanced)
            .setName(t("no_folder"))
            .addText(text => {
                text
                    .setPlaceholder(t("no_folder"))
                    .setValue(this.plugin.settings.renamedText.no_folder)
                    .onChange(async value => {
                        await this.plugin.writeSettings(() => ({
                            renamedText: {
                                ...this.plugin.settings.renamedText,
                                no_folder: value
                            }
                        }));
                    });
            });

        advanced.createEl("hr", {attr: {style: "border-top: 5px solid var(--background-modifier-border);"}});

        new Setting(advanced)
            .setName(t("display_media"))
            .addToggle(toggle => {
               toggle
                   .setValue(this.plugin.settings.displayMedia)
                   .onChange(async value => {
                       await this.plugin.writeSettings(() => ({
                           displayMedia: value
                       }));
                   });
            });
    }
Example #27
Source File: viewControls.ts    From obsidian-map-view with GNU General Public License v3.0 5 votes vote down vote up
createControls() {
        this.controlsDiv = createDiv({
            cls: 'graph-controls',
        });
        let filtersDiv = this.controlsDiv.createDiv({
            cls: 'graph-control-div',
        });
        filtersDiv.innerHTML = `
			<input id="filtersCollapsible" class="controls-toggle" type="checkbox">
			<label for="filtersCollapsible" class="lbl-triangle">▸</label>
			<label for="filtersCollapsible" class="lbl-toggle">Filters</label>
			`;
        const filtersButton = filtersDiv.getElementsByClassName(
            'controls-toggle'
        )[0] as HTMLInputElement;
        filtersButton.checked = this.settings.mapControls.filtersDisplayed;
        filtersButton.onclick = async () => {
            this.settings.mapControls.filtersDisplayed = filtersButton.checked;
            this.plugin.saveSettings();
        };
        let filtersContent = filtersDiv.createDiv({
            cls: 'graph-control-content',
        });
        // Wrapping the query box in a div so we can place a button in the right-middle of it
        const queryDiv = filtersContent.createDiv('search-input-container');
        queryDiv.style.margin = '0';
        this.queryBox = new TextComponent(queryDiv);
        this.queryBox.setPlaceholder('Query');
        this.queryBox.onChange((query: string) => {
            this.setStateByQueryString(query);
        });
        let suggestor: QuerySuggest = null;
        this.queryBox.inputEl.addEventListener('focus', (ev: FocusEvent) => {
            if (!suggestor) {
                suggestor = new QuerySuggest(this.app, this.queryBox);
                suggestor.open();
            }
        });
        this.queryBox.inputEl.addEventListener('focusout', (ev: FocusEvent) => {
            if (suggestor) {
                suggestor.close();
                suggestor = null;
            }
        });
        let clearButton = queryDiv.createDiv('search-input-clear-button');
        clearButton.onClickEvent((ev) => {
            this.queryBox.setValue('');
            this.setStateByQueryString('');
        });

        let viewDiv = this.controlsDiv.createDiv({ cls: 'graph-control-div' });
        viewDiv.innerHTML = `
			<input id="viewCollapsible" class="controls-toggle" type="checkbox">
			<label for="viewCollapsible" class="lbl-triangle">▸</label>
			<label for="viewCollapsible" class="lbl-toggle">View</label>
			`;
        const viewButton = viewDiv.getElementsByClassName(
            'controls-toggle'
        )[0] as HTMLInputElement;
        viewButton.checked = this.settings.mapControls.viewDisplayed;
        viewButton.onclick = async () => {
            this.settings.mapControls.viewDisplayed = viewButton.checked;
            this.plugin.saveSettings();
        };
        let viewDivContent = viewDiv.createDiv({
            cls: 'graph-control-content',
        });
        this.mapSourceBox = new DropdownComponent(viewDivContent);
        for (const [index, source] of this.settings.mapSources.entries()) {
            this.mapSourceBox.addOption(index.toString(), source.name);
        }
        this.mapSourceBox.onChange(async (value: string) => {
            this.setStateByNewMapSource(parseInt(value));
        });
        this.setMapSourceBoxByState();
        this.sourceMode = new DropdownComponent(viewDivContent);
        this.sourceMode
            .addOptions({ auto: 'Auto', light: 'Light', dark: 'Dark' })
            .setValue(this.settings.chosenMapMode ?? 'auto')
            .onChange(async (value) => {
                this.settings.chosenMapMode = value as MapLightDark;
                await this.plugin.saveSettings();
                this.view.refreshMap();
            });
        let goDefault = new ButtonComponent(viewDivContent);
        goDefault
            .setButtonText('Reset')
            .setTooltip('Reset the view to the defined default.')
            .onClick(async () => {
                this.presetsBox.setValue('0');
                await this.choosePresetAndUpdateState(0);
                this.updateControlsToState();
            });
        let fitButton = new ButtonComponent(viewDivContent);
        fitButton
            .setButtonText('Fit')
            .setTooltip(
                'Set the map view to fit all currently-displayed markers.'
            )
            .onClick(() => this.view.autoFitMapToMarkers());
        const followDiv = viewDivContent.createDiv({
            cls: 'graph-control-follow-div',
        });
        this.followActiveNoteToggle = new ToggleComponent(followDiv);
        const followLabel = followDiv.createEl('label');
        followLabel.className = 'graph-control-follow-label';
        followLabel.addEventListener('click', () =>
            this.followActiveNoteToggle.onClick()
        );
        followLabel.innerHTML = 'Follow active note';
        this.followActiveNoteToggle.onChange((value) => {
            this.setStateByFollowActiveNote(value);
        });

        this.presetsDiv = this.controlsDiv.createDiv({
            cls: 'graph-control-div',
        });
        this.presetsDiv.innerHTML = `
			<input id="presetsCollapsible" class="controls-toggle" type="checkbox">
			<label for="presetsCollapsible" class="lbl-triangle">▸</label>
			<label for="presetsCollapsible" class="lbl-toggle">Presets</label>
			`;
        const presetsButton = this.presetsDiv.getElementsByClassName(
            'controls-toggle'
        )[0] as HTMLInputElement;
        presetsButton.checked = this.settings.mapControls.presetsDisplayed;
        presetsButton.onclick = async () => {
            this.settings.mapControls.presetsDisplayed = presetsButton.checked;
            this.plugin.saveSettings();
        };
        this.refreshPresets();

        this.parentElement.append(this.controlsDiv);
    }
Example #28
Source File: event.ts    From obsidian-fantasy-calendar with MIT License 5 votes vote down vote up
buildDateFields(el: HTMLElement, field = this.event.date) {
        el.empty();
        const dayEl = el.createDiv("fantasy-calendar-date-field");
        dayEl.createEl("label", { text: "Day" });
        const day = new TextComponent(dayEl)
            .setPlaceholder("Day")
            .setValue(`${field.day}`)
            .onChange((v) => {
                field.day = Number(v);
                this.buildDateString();
            });
        day.inputEl.setAttr("type", "number");

        const monthEl = el.createDiv("fantasy-calendar-date-field");
        monthEl.createEl("label", { text: "Month" });
        new DropdownComponent(monthEl)
            .addOptions(
                Object.fromEntries([
                    ["select", "Select Month"],
                    ...this.calendar.static.months.map((month) => [
                        month.name,
                        month.name
                    ])
                ])
            )
            .setValue(
                field.month != undefined
                    ? this.calendar.static.months[field.month].name
                    : "select"
            )
            .onChange((v) => {
                if (v === "select") field.month = null;
                const index = this.calendar.static.months.find(
                    (m) => m.name == v
                );
                field.month = this.calendar.static.months.indexOf(index);
                this.buildDateString();
            });

        const yearEl = el.createDiv("fantasy-calendar-date-field");
        yearEl.createEl("label", { text: "Year" });
        const year = new TextComponent(yearEl)
            .setPlaceholder("Year")
            .setValue(`${field.year}`)
            .onChange((v) => {
                if (!v || v == undefined) {
                    field.year = undefined;
                } else {
                    field.year = Number(v);
                }
                this.buildDateString();
            });
        year.inputEl.setAttr("type", "number");
    }
Example #29
Source File: GenericInputPrompt.ts    From quickadd with MIT License 5 votes vote down vote up
private inputComponent: TextComponent;