obsidian#ToggleComponent TypeScript Examples

The following examples show how to use obsidian#ToggleComponent. 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: genericCheckboxPrompt.ts    From quickadd with MIT License 6 votes vote down vote up
private addCheckboxRow(item: string, container: HTMLDivElement) {
        const checkboxRow: HTMLDivElement = container.createDiv('checkboxRow');

        const text: HTMLSpanElement = checkboxRow.createEl('span', {text: item});
        const checkbox: ToggleComponent = new ToggleComponent(checkboxRow);
        checkbox
			.setTooltip(`Toggle ${item}`)
			.setValue(this._selectedItems.contains(item))
			.onChange(value => {
				if (value)
					this._selectedItems.push(item);
				else {
					const index = this._selectedItems.findIndex(value => item === value);
					this._selectedItems.splice(index, 1);
				}
			});
    }
Example #2
Source File: valueMultiSelectModal.ts    From obsidian_supercharged_links with MIT License 6 votes vote down vote up
buildValueToggler(valueGrid: HTMLDivElement,presetValue: string){
        const valueSelectorContainer = valueGrid.createDiv({
            cls: "frontmatter-value-selector-container"
        })
        const valueTogglerContainer = valueSelectorContainer.createDiv({
            cls: "frontmatter-value-selector-toggler"
        })
        const valueToggler = new ToggleComponent(valueTogglerContainer)
        this.values.forEach(value => {
            if (value == presetValue){
                valueToggler.setValue(true)
            }
        })
        valueToggler.onChange(value => {
            if(value && !this.values.includes(presetValue)){
                this.values.push(presetValue)
            }
            if(!value){
                this.values.remove(presetValue)
            }
        })
        const valueLabel = valueSelectorContainer.createDiv({
            cls: "frontmatter-value-selector-label"
        })
        valueLabel.setText(presetValue)
    }
Example #3
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 #4
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
isCycleTogglerComponent: ToggleComponent
Example #5
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
isMultiTogglerComponent: ToggleComponent
Example #6
Source File: FieldSettingsModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
createTogglerContainer(parentNode: HTMLDivElement, label: string): ToggleComponent {
        const propertyContainerLabel = parentNode.createDiv({
            cls: 'frontmatter-checkbox-toggler'
        })
        propertyContainerLabel.setText(label)
        const toggler = new ToggleComponent(parentNode)
        return toggler
    }
Example #7
Source File: valueToggleModal.ts    From obsidian_supercharged_links with MIT License 5 votes vote down vote up
buildInputEl(inputDiv: HTMLDivElement): void{
        const inputEl = new ToggleComponent(inputDiv)
        inputEl.setValue(this.value)
        inputEl.onChange(v => {
            replaceValues(this.app, this.file, this.name, v ? "true" : "false")
        })
    }
Example #8
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 #9
Source File: viewControls.ts    From obsidian-map-view with GNU General Public License v3.0 5 votes vote down vote up
private followActiveNoteToggle: ToggleComponent;
Example #10
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 #11
Source File: mockSetting.ts    From obsidian-switcher-plus with GNU General Public License v3.0 5 votes vote down vote up
export class MockToggleComponent implements ToggleComponent {
  toggleEl: HTMLElement;
  value: boolean;
  onChangeCB: (value: boolean) => any;

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

  getValue(): boolean {
    return this.value;
  }

  setValue(on: boolean): this {
    this.value = on;

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

    return this;
  }

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

  setDisabled(_disabled: boolean): this {
    throw new Error('Method not implemented.');
  }
  setTooltip(_tooltip: string): this {
    throw new Error('Method not implemented.');
  }
  onClick(): void {
    throw new Error('Method not implemented.');
  }
  registerOptionListener(
    _listeners: Record<string, (value?: boolean) => boolean>,
    _key: string,
  ): this {
    throw new Error('Method not implemented.');
  }
  disabled: boolean;
  then(_cb: (component: this) => any): this {
    throw new Error('Method not implemented.');
  }
}
Example #12
Source File: mockSetting.ts    From obsidian-switcher-plus with GNU General Public License v3.0 5 votes vote down vote up
addToggle(cb: (component: ToggleComponent) => any): this {
    cb(new MockToggleComponent(this.containerEl));
    return this;
  }
Example #13
Source File: templateChoiceBuilder.ts    From quickadd with MIT License 5 votes vote down vote up
private addFolderSetting(): void {
        const folderSetting: Setting = new Setting(this.contentEl);
        folderSetting.setName("Create in folder")
            .setDesc("Create the file in the specified folder. If multiple folders are specified, you will be prompted for which folder to create the file in.")
            .addToggle(toggle => {
                toggle.setValue(this.choice.folder.enabled);
                toggle.onChange(value => {
                    this.choice.folder.enabled = value;
                    this.reload();
                });
            });

        if (this.choice.folder.enabled) {
            if (!this.choice.folder?.createInSameFolderAsActiveFile) {
                const chooseFolderWhenCreatingNoteContainer: HTMLDivElement = this.contentEl.createDiv('chooseFolderWhenCreatingNoteContainer');
                chooseFolderWhenCreatingNoteContainer.createEl('span', {text: "Choose folder when creating a new note"});
                const chooseFolderWhenCreatingNote: ToggleComponent = new ToggleComponent(chooseFolderWhenCreatingNoteContainer);
                chooseFolderWhenCreatingNote.setValue(this.choice.folder?.chooseWhenCreatingNote)
                    .onChange(value => {
                        this.choice.folder.chooseWhenCreatingNote = value;
                        this.reload();
                    });

                if (!this.choice.folder?.chooseWhenCreatingNote) {
                    this.addFolderSelector();
                }
            }

            if (!this.choice.folder?.chooseWhenCreatingNote) {
                const createInSameFolderAsActiveFileSetting: Setting = new Setting(this.contentEl);
                createInSameFolderAsActiveFileSetting.setName("Create in same folder as active file")
                    .setDesc("Creates the file in the same folder as the currently active file. Will not create the file if there is no active file.")
                    .addToggle(toggle => toggle
                        .setValue(this.choice.folder?.createInSameFolderAsActiveFile)
                        .onChange(value => {
                            this.choice.folder.createInSameFolderAsActiveFile = value;
                            this.reload();
                        })
                    )
            }
        }
    }
Example #14
Source File: MacrosManager.ts    From quickadd with MIT License 5 votes vote down vote up
private addMacroSetting(macro: IMacro, container: HTMLDivElement) {
        const configureMacroContainer = container.createDiv();

        const macroSetting: Setting = new Setting(configureMacroContainer);
        macroSetting.setName(macro.name);
        macroSetting.infoEl.style.fontWeight = "bold";

        this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => {
            this.addSpanWithText(itemContainerEl, "Run on plugin load");

            const toggle: ToggleComponent = new ToggleComponent(itemContainerEl);
            toggle.setValue(macro.runOnStartup);

            toggle.onChange(value => {
                macro.runOnStartup = value;

                this.updateMacro(macro);
            });
        });

        configureMacroContainer.addClass("configureMacroDiv");
        this.addMacroConfigurationItem(configureMacroContainer, itemContainerEl => {
            const deleteButton: ButtonComponent = new ButtonComponent(itemContainerEl);
            deleteButton.setClass('mod-warning');
            deleteButton.buttonEl.style.marginRight = "0";

            deleteButton.setButtonText("Delete").onClick(evt => {
                this.macros = this.macros.filter(m => m.id !== macro.id);
                const scroll: number = this.macroContainer.scrollTop;

                this.reload();

                this.macroContainer.scrollTop = scroll;
            });

            const configureButton: ButtonComponent = new ButtonComponent(itemContainerEl);
            configureButton.setClass('mod-cta');
            configureButton.buttonEl.style.marginRight = "0";

            configureButton.setButtonText("Configure").onClick(async evt => {
                const getReachableChoices = (choices: IChoice[]) => {
                    let reachableChoices: IChoice[] = [];
                    choices.forEach(choice => {
                        if (choice.type === ChoiceType.Multi)
                            reachableChoices.push(...getReachableChoices((<IMultiChoice>choice).choices));

                        if (choice.type !== ChoiceType.Multi)
                            reachableChoices.push(choice);
                    })
                    return reachableChoices;
                }

                const reachableChoices = getReachableChoices(this.choices);
                const newMacro = await new MacroBuilder(this.app, this.plugin, macro, reachableChoices).waitForClose;

                if (newMacro) {
                    this.updateMacro(newMacro);
                    this.reload();
                }
            });
        });

    }
Example #15
Source File: settings-tab.ts    From better-word-count with MIT License 4 votes vote down vote up
display(): void {
    let { containerEl } = this;

    containerEl.empty();
    containerEl.createEl("h2", { text: "Better Word Count Settings" });

    // General Settings
    containerEl.createEl("h3", { text: "General Settings" });
    new Setting(containerEl)
      .setName("Collect Statistics")
      .setDesc(
        "Reload Required for change to take effect. Turn on to start collecting daily statistics of your writing. Stored in the .vault-stats file in the root of your vault. This is required for counts of the day."
      )
      .addToggle((cb: ToggleComponent) => {
        cb.setValue(this.plugin.settings.collectStats);
        cb.onChange(async (value: boolean) => {
          this.plugin.settings.collectStats = value;
          await this.plugin.saveSettings();
        });
      });
    new Setting(containerEl)
      .setName("Don't Count Comments")
      .setDesc("Turn on if you don't want markdown comments to be counted.")
      .addToggle((cb: ToggleComponent) => {
        cb.setValue(this.plugin.settings.countComments);
        cb.onChange(async (value: boolean) => {
          this.plugin.settings.countComments = value;
          await this.plugin.saveSettings();
        });
      });

    // Status Bar Settings
    containerEl.createEl("h3", { text: "Status Bar Settings" });
    new Setting(containerEl)
      .setName("Select a Preset")
      .setDesc(
        "Presets are premade status bar expressions. Overides status bar settings."
      )
      .addDropdown((cb: DropdownComponent) => {
        PRESETS.forEach((preset: PresetOption) => {
          cb.addOption(preset.name, preset.name);
        });
        cb.setValue(this.plugin.settings.preset.name);

        cb.onChange(async (value: string) => {
          let newPreset = PRESETS.find((preset) => preset.name === value);
          this.plugin.settings.preset = newPreset;
          this.plugin.settings.statusBarQuery = newPreset.statusBarQuery;
          this.plugin.settings.statusBarAltQuery = newPreset.statusBarAltQuery;
          await this.plugin.saveSettings();
        });
      });
    new Setting(containerEl)
      .setName("Status Bar Text")
      .setDesc("Customize the Status Bar text with this.")
      .addTextArea((cb: TextAreaComponent) => {
        cb.setPlaceholder("Enter an expression...");
        cb.setValue(this.plugin.settings.statusBarQuery);
        cb.onChange((value: string) => {
          let newPreset = PRESETS.find((preset) => preset.name === "custom");
          this.plugin.settings.preset = newPreset;
          this.plugin.settings.statusBarQuery = value;
          this.plugin.saveSettings();
        });
      });
    new Setting(containerEl)
      .setName("Alternative Status Bar Text")
      .setDesc("Customize the Alternative Status Bar text with this.")
      .addTextArea((cb: TextAreaComponent) => {
        cb.setPlaceholder("Enter an expression...");
        cb.setValue(this.plugin.settings.statusBarAltQuery);
        cb.onChange((value: string) => {
          let newPreset = PRESETS.find((preset) => preset.name === "custom");
          this.plugin.settings.preset = newPreset;
          this.plugin.settings.statusBarAltQuery = value;
          this.plugin.saveSettings();
        });
      });

    this.containerEl.createEl("h3", {
      text: "Syntax for the status bars works like this: ",
    });

    this.containerEl.createEl("li", {
      text: "To get a stat input the name of the stat in between `{}` eg. `{word_count}`.",
    });

    this.containerEl.createEl("li", {
      text: "All other words remain.",
    });

    this.containerEl.createEl("br");

    this.containerEl.createEl("h4", {
      text: "Available Stats:",
    });

    this.containerEl.createEl("p", {
      text:
        "word_count, " +
        "character_count, " +
        "sentence_count, " +
        "total_word_count, " +
        "total_character_count, " +
        "total_sentence_count, " +
        "file_count, " +
        "words_today, " +
        "characters_today, " +
        "sentences_today, ",
    });
  }
Example #16
Source File: settingsTabSection.test.ts    From obsidian-switcher-plus with GNU General Public License v3.0 4 votes vote down vote up
describe('settingsTabSection', () => {
  let mockApp: MockProxy<App>;
  let mockPluginSettingTab: MockProxy<PluginSettingTab>;
  let mockConfig: MockProxy<SwitcherPlusSettings>;
  let mockContainerEl: MockProxy<HTMLElement>;
  let sut: SUT;

  beforeAll(() => {
    mockApp = mock<App>();
    mockContainerEl = mock<HTMLElement>();
    mockPluginSettingTab = mock<PluginSettingTab>({ containerEl: mockContainerEl });
    mockConfig = mock<SwitcherPlusSettings>();

    sut = sut = new SUT(mockApp, mockPluginSettingTab, mockConfig);
  });

  describe('createSetting', () => {
    it('should create a Setting with name and description', () => {
      const setNameSpy = jest.spyOn(Setting.prototype, 'setName');
      const setDescSpy = jest.spyOn(Setting.prototype, 'setDesc');
      const name = chance.word();
      const desc = chance.word();

      const setting = sut.createSetting(mock<HTMLElement>(), name, desc);

      expect(setting).not.toBeFalsy();
      expect(setNameSpy).toHaveBeenCalledWith(name);
      expect(setDescSpy).toHaveBeenCalledWith(desc);

      setNameSpy.mockRestore();
      setDescSpy.mockRestore();
    });
  });

  describe('addSectionTitle', () => {
    it('should display a header and divider for the section', () => {
      const title = chance.sentence();
      const desc = chance.sentence();
      const mockSetting = mock<Setting>();
      const createSettingSpy = jest.spyOn(SettingsTabSection.prototype, 'createSetting');
      createSettingSpy.mockReturnValue(mockSetting);

      sut.addSectionTitle(mockContainerEl, title, desc);

      expect(createSettingSpy).toHaveBeenCalledWith(mockContainerEl, title, desc);
      expect(mockSetting.setHeading).toHaveBeenCalled();

      createSettingSpy.mockRestore();
    });
  });

  describe('addTextSetting', () => {
    let mockSetting: MockProxy<Setting>;
    let mockTextComp: MockProxy<TextComponent>;
    let createSettingSpy: jest.SpyInstance;

    beforeAll(() => {
      mockSetting = mock<Setting>();
      mockTextComp = mock<TextComponent>();

      mockSetting.addText.mockImplementation((cb) => {
        cb(mockTextComp);
        return mockSetting;
      });

      createSettingSpy = jest.spyOn(SettingsTabSection.prototype, 'createSetting');
      createSettingSpy.mockReturnValue(mockSetting);
    });

    afterAll(() => {
      createSettingSpy.mockRestore();
    });

    it('should show the setting with the initial value', () => {
      const name = chance.sentence();
      const desc = chance.sentence();
      const initValue = 'init value';
      const placeholderValue = 'placeholder text';

      const result = sut.addTextSetting(
        mockContainerEl,
        name,
        desc,
        initValue,
        'editorListCommand',
        placeholderValue,
      );

      expect(result).not.toBeNull();
      expect(createSettingSpy).toHaveBeenCalledWith(mockContainerEl, name, desc);
      expect(mockTextComp.setValue).toHaveBeenCalledWith(initValue);
      expect(mockTextComp.setPlaceholder).toHaveBeenCalledWith(placeholderValue);
    });

    it('should save the modified setting', () => {
      mockConfig.editorListCommand = 'editor command';
      const finalValue = 'final value';

      let onChangeFn: (v: string) => void;
      mockTextComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockTextComp;
      });

      sut.addTextSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.editorListCommand,
        'editorListCommand',
      );

      // trigger the value change here
      onChangeFn(finalValue);

      expect(mockTextComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.editorListCommand).toBe(finalValue);

      mockReset(mockConfig);
    });

    it('should fallback to the initial value when an empty string is set for the value', () => {
      const initValue = 'editor command';
      mockConfig.editorListCommand = initValue;

      let onChangeFn: (v: string) => void;
      mockTextComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockTextComp;
      });

      sut.addTextSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.editorListCommand,
        'editorListCommand',
      );

      // trigger the value change here
      onChangeFn('');

      expect(mockTextComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.editorListCommand).toBe(initValue);

      mockReset(mockConfig);
    });
  });

  describe('addToggleSetting', () => {
    let mockSetting: MockProxy<Setting>;
    let mockToggleComp: MockProxy<ToggleComponent>;
    let createSettingSpy: jest.SpyInstance;

    beforeAll(() => {
      mockSetting = mock<Setting>();
      mockToggleComp = mock<ToggleComponent>();

      mockSetting.addToggle.mockImplementation((cb) => {
        cb(mockToggleComp);
        return mockSetting;
      });

      createSettingSpy = jest.spyOn(SettingsTabSection.prototype, 'createSetting');
      createSettingSpy.mockReturnValue(mockSetting);
    });

    afterAll(() => {
      createSettingSpy.mockRestore();
    });

    it('should show the setting with the initial value', () => {
      const name = chance.sentence();
      const desc = chance.sentence();
      const initValue = true;

      const result = sut.addToggleSetting(
        mockContainerEl,
        name,
        desc,
        initValue,
        'alwaysNewPaneForSymbols',
      );

      expect(result).not.toBeNull();
      expect(createSettingSpy).toHaveBeenCalledWith(mockContainerEl, name, desc);
      expect(mockToggleComp.setValue).toHaveBeenCalledWith(initValue);
    });

    it('should save the modified setting', () => {
      mockConfig.alwaysNewPaneForSymbols = false;
      const finalValue = true;

      let onChangeFn: (v: boolean) => void;
      mockToggleComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockToggleComp;
      });

      sut.addToggleSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.alwaysNewPaneForSymbols,
        'alwaysNewPaneForSymbols',
      );

      // trigger the value change here
      onChangeFn(finalValue);

      expect(mockToggleComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.alwaysNewPaneForSymbols).toBe(finalValue);

      mockReset(mockConfig);
    });
  });

  describe('addTextAreaSetting', () => {
    let mockSetting: MockProxy<Setting>;
    let mockTextComp: MockProxy<TextAreaComponent>;
    let createSettingSpy: jest.SpyInstance;

    beforeAll(() => {
      mockSetting = mock<Setting>();
      mockTextComp = mock<TextAreaComponent>();

      mockSetting.addTextArea.mockImplementation((cb) => {
        cb(mockTextComp);
        return mockSetting;
      });

      createSettingSpy = jest.spyOn(SettingsTabSection.prototype, 'createSetting');
      createSettingSpy.mockReturnValue(mockSetting);
    });

    afterAll(() => {
      createSettingSpy.mockRestore();
    });

    it('should show the setting with the initial value', () => {
      const name = chance.sentence();
      const desc = chance.sentence();
      const initValue = 'init value';
      const placeholderValue = 'placeholder text';

      const result = sut.addTextAreaSetting(
        mockContainerEl,
        name,
        desc,
        initValue,
        'editorListCommand',
        placeholderValue,
      );

      expect(result).not.toBeNull();
      expect(createSettingSpy).toHaveBeenCalledWith(mockContainerEl, name, desc);
      expect(mockTextComp.setValue).toHaveBeenCalledWith(initValue);
      expect(mockTextComp.setPlaceholder).toHaveBeenCalledWith(placeholderValue);
    });

    it('should save the modified setting as string', () => {
      mockConfig.editorListCommand = 'editor command';
      const finalValue = 'final value';

      let onChangeFn: (v: string) => void;
      mockTextComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockTextComp;
      });

      sut.addTextAreaSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.editorListCommand,
        'editorListCommand',
      );

      // trigger the value change here
      onChangeFn(finalValue);

      expect(mockTextComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.editorListCommand).toBe(finalValue);

      mockReset(mockConfig);
    });

    it('should save the modified setting as list', () => {
      mockConfig.includeSidePanelViewTypes = [chance.word()];
      const finalValue = [chance.word(), chance.word(), chance.word()];

      let onChangeFn: (v: string) => void;
      mockTextComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockTextComp;
      });

      sut.addTextAreaSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.includeSidePanelViewTypes.join('\n'),
        'includeSidePanelViewTypes',
      );

      // trigger the value change here
      // Note: the onChange function takes a string and converts it to a list
      // by splitting on the newline '\n\
      onChangeFn(finalValue.join('\n'));

      expect(mockTextComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.includeSidePanelViewTypes).toEqual(finalValue);

      mockReset(mockConfig);
    });

    it('should fallback to the initial value when an empty string is set for the value', () => {
      const initValue = [chance.word()];
      mockConfig.includeSidePanelViewTypes = initValue;

      let onChangeFn: (v: string) => void;
      mockTextComp.onChange.mockImplementationOnce((cb) => {
        onChangeFn = cb;
        return mockTextComp;
      });

      sut.addTextAreaSetting(
        mockContainerEl,
        chance.word(),
        chance.sentence(),
        mockConfig.includeSidePanelViewTypes.join('\n'),
        'includeSidePanelViewTypes',
      );

      // trigger the value change here
      onChangeFn('');

      expect(mockTextComp.onChange).toHaveBeenCalled();
      expect(mockConfig.save).toHaveBeenCalled();
      expect(mockConfig.includeSidePanelViewTypes).toEqual(initValue);

      mockReset(mockConfig);
    });
  });
});
Example #17
Source File: SuperchargedLinksSettingTab.ts    From obsidian_supercharged_links with MIT License 4 votes vote down vote up
display(): void {
		let {containerEl} = this;

		containerEl.empty();

        /* Managing extra attirbutes for a.internal-link */
		new Setting(containerEl)
			.setName('Target Attributes for styling')
			.setDesc('Frontmatter attributes to target, comma separated')
			.addTextArea((text) => {text
				.setPlaceholder('Enter attributes as string, comma separated')
				.setValue(this.plugin.settings.targetAttributes.join(', '))
				.onChange(async (value) => {
					this.plugin.settings.targetAttributes = value.replace(/\s/g,'').split(',');
					if (this.plugin.settings.targetAttributes.length === 1 && !this.plugin.settings.targetAttributes[0]) {
						this.plugin.settings.targetAttributes = [];
					}
					await this.plugin.saveSettings();
				})
				text.inputEl.rows = 6;
				text.inputEl.cols = 25;
			});

		containerEl.createEl('h4', {text: 'Styling'});
		const styleSettingDescription = containerEl.createDiv();
		styleSettingDescription.innerHTML = `
Styling can be done using the Style Settings plugin. 
 <ol>
 <li>Create selectors down below.</li>
 <li>Go to the Style Settings tab and style your links!</li>
</ol>`
		const selectorDiv = containerEl.createDiv();
		this.drawSelectors(selectorDiv);


		containerEl.createEl('h4', {text: 'Settings'});
		new Setting(containerEl)
			.setName('Enable in Editor')
			.setDesc('If true, this will also supercharge internal links in the editor view of a note.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.enableEditor)
				toggle.onChange(value => {
					this.plugin.settings.enableEditor = value
					this.plugin.saveSettings()
				})
			})

		new Setting(containerEl)
			.setName('Enable in File Browser')
			.setDesc('If true, this will also supercharge the file browser.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.enableFileList)
				toggle.onChange(value => {
					this.plugin.settings.enableFileList = value
					this.plugin.saveSettings()
				})
			})

		new Setting(containerEl)
			.setName('Enable in Plugins')
			.setDesc('If true, this will also supercharge plugins like the backlinks and forward links panels.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.enableBacklinks)
				toggle.onChange(value => {
					this.plugin.settings.enableBacklinks = value
					this.plugin.saveSettings()
				});
			});
		new Setting(containerEl)
			.setName('Enable in Quick Switcher')
			.setDesc('If true, this will also supercharge the quick switcher.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.enableQuickSwitcher)
				toggle.onChange(value => {
					this.plugin.settings.enableQuickSwitcher = value
					this.plugin.saveSettings()
				});
			});
		new Setting(containerEl)
			.setName('Enable in Link Autocompleter')
			.setDesc('If true, this will also supercharge the link autocompleter.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.enableSuggestor)
				toggle.onChange(value => {
					this.plugin.settings.enableSuggestor = value
					this.plugin.saveSettings()
				});
			});

		containerEl.createEl('h4', {text: 'Advanced'});
		// Managing choice wether you want to parse tags both from normal tags and in the frontmatter
		new Setting(containerEl)
			.setName('Parse all tags in the file')
			.setDesc('Sets the `data-link-tags`-attribute to look for tags both in the frontmatter and in the file as #tag-name')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.targetTags)
				toggle.onChange(async value => {
					this.plugin.settings.targetTags = value
					await this.plugin.saveSettings();
				})
			})

		// Managing choice wether you get attributes from inline fields and frontmatter or only frontmater
		new Setting(containerEl)
		.setName('Search for attribute in Inline fields like <field::>')
		.setDesc('Sets the `data-link-<field>`-attribute to the value of inline fields')
		.addToggle(toggle => {
			toggle.setValue(this.plugin.settings.getFromInlineField)
				toggle.onChange(async value => {
					this.plugin.settings.getFromInlineField = value
					await this.plugin.saveSettings()
				});
		});

		// Managing choice wether you get attributes from inline fields and frontmatter or only frontmater
		new Setting(containerEl)
			.setName('Automatically activate snippet')
			.setDesc('If true, this will automatically activate the generated CSS snippet "supercharged-links-gen.css". ' +
				'Turn this off if you don\'t want this to happen.')
			.addToggle(toggle => {
				toggle.setValue(this.plugin.settings.activateSnippet)
				toggle.onChange(async value => {
					this.plugin.settings.activateSnippet = value
					await this.plugin.saveSettings()
				});
			});

        /* Managing predefined values for properties */
		/* Manage menu options display*/
		new Setting(containerEl)
			.setName("Display field options in context menu")
			.setDesc("Choose to show or hide fields options in the context menu of a link or a file")
			.addToggle((toggle: ToggleComponent) => {
				toggle.setValue(this.plugin.settings.displayFieldsInContextMenu)
				toggle.onChange(async value => {
					this.plugin.settings.displayFieldsInContextMenu = value
					await this.plugin.saveSettings()
				})
			})
		/* Exclude Fields from context menu*/
		new Setting(containerEl)
			.setName('Ignored fields')
			.setDesc('Fields to be ignored by the plugin when adding options to the context menu')
			.addTextArea((text) => {text
				.setPlaceholder('Enter fields as string, comma separated')
				.setValue(this.plugin.settings.globallyIgnoredFields.join(', '))
				.onChange(async (value) => {
					this.plugin.settings.globallyIgnoredFields = value.replace(/\s/g,'').split(',');
					await this.plugin.saveSettings();
				})
				text.inputEl.rows = 6;
				text.inputEl.cols = 25;
			});

		/* Set classFiles Path*/
		new Setting(containerEl)
		.setName('class Files path')
		.setDesc('Path to the files containing the authorized fields for a type of note')
		.addText((text) => {text
			.setPlaceholder('Path/')
			.setValue(this.plugin.settings.classFilesPath)
			.onChange(async (value) => {
				this.plugin.settings.classFilesPath = value
				await this.plugin.saveSettings();
			})
		});

        /* Add new property for which we want to preset values*/
		new Setting(containerEl)
			.setName("Add New Property Manager")
			.setDesc("Add a new Frontmatter property for which you want preset values.")
			.addButton((button: ButtonComponent): ButtonComponent => {
				return button
					.setTooltip("Add New Property Manager")
					.setButtonText("+")
					.onClick(async () => {
						let modal = new FieldSettingsModal(this.app, this.plugin, containerEl);
						modal.open();
					});
			});

        /* Managed properties that currently have preset values */
		this.plugin.initialProperties.forEach(prop => {
            const property = new Field()
            Object.assign(property, prop)
			new FieldSetting(containerEl, property, this.app, this.plugin)
		})
	}