Skip to main content

Modals

Modals display information and accept input from the user. To create a modal, create a class that extends Modal:

modal.ts
import { App, Modal } from "obsidian";
export class ExampleModal extends Modal {  constructor(app: App) {    super(app);  }
  onOpen() {    let { contentEl } = this;    contentEl.setText("Look at me, I'm a modal! 👀");  }
  onClose() {    let { contentEl } = this;    contentEl.empty();  }}
  • onOpen() is called when the modal is opened and is responsible for building the content of your modal. For more information, refer to HTML elements.
  • onClose() is called when the modal is closed and is responsible for cleaning up any resources used by the modal.

To open a modal, create a new instance of ExampleModal and call open() on it:

main.ts
import { Plugin } from "obsidian";import { ExampleModal } from "./modal";
export default class ExamplePlugin extends Plugin {  async onload() {    this.addCommand({      id: "display-modal",      name: "Display modal",      callback: () => {        new ExampleModal(this.app).open();      },    });  }}

Accept user input#

The modal in the previous example only displayed some text. Let's look at a little more complex example that handles input from the user.

Modal with user input

modal.ts
import { App, Modal, Setting } from "obsidian";
export class ExampleModal extends Modal {  result: string;  onSubmit: (result: string) => void;
  constructor(app: App, onSubmit: (result: string) => void) {    super(app);    this.onSubmit = onSubmit;  }
  onOpen() {    const { contentEl } = this;
    contentEl.createEl("h1", { text: "What's your name?" });
    new Setting(contentEl)      .setName("Name")      .addText((text) =>        text.onChange((value) => {          this.result = value        }));
    new Setting(contentEl)      .addButton((btn) =>        btn          .setButtonText("Submit")          .setCta()          .onClick(() => {            this.close();            this.onSubmit(this.result);          }));  }
  onClose() {    let { contentEl } = this;    contentEl.empty();  }}

The result is stored in this.result and returned in the onSubmit callback when the user clicks Submit:

new ExampleModal(this.app, (result) => {  new Notice(`Hello, ${result}!`);}).open();

Select from list of suggestions#

SuggestModal is a special modal that lets you display a list of suggestions to the user.

Modal with suggestions

modal.ts
import { App, Notice, SuggestModal } from "obsidian";
interface Book {  title: string;  author: string;}
const ALL_BOOKS = [  {    title: "How to Take Smart Notes",    author: "Sönke Ahrens",  },  {    title: "Thinking, Fast and Slow",    author: "Daniel Kahneman",  },  {    title: "Deep Work",    author: "Cal Newport",  },];
export class ExampleModal extends SuggestModal<Book> {  // Returns all available suggestions.  getSuggestions(query: string): Book[] {    return ALL_BOOKS.filter((book) =>      book.title.toLowerCase().includes(query.toLowerCase())    );  }
  // Renders each suggestion item.  renderSuggestion(book: Book, el: HTMLElement) {    el.createEl("div", { text: book.title });    el.createEl("small", { text: book.author });  }
  // Perform action on the selected suggestion.  onChooseSuggestion(book: Book, evt: MouseEvent | KeyboardEvent) {    new Notice(`Selected ${book.title}`);  }}

In addition to SuggestModal, the Obsidian API provides an even more specialized type of modal for suggestions: the FuzzySuggestModal. While it doesn't give you the same control of how each item is rendered, you get fuzzy string search out-of-the-box.

Fuzzy string search

export class ExampleModal extends FuzzySuggestModal<Book> {  getItems(): Book[] {    return ALL_BOOKS;  }
  getItemText(book: Book): string {    return book.title;  }
  onChooseItem(book: Book, evt: MouseEvent | KeyboardEvent) {    new Notice(`Selected ${book.title}`);  }}