generated from tpl/obsidian-sample-plugin
Add svelte modal helper
This commit is contained in:
parent
8ebed95fda
commit
6ffad2b5d1
|
@ -1,8 +1,8 @@
|
||||||
import GoodreadsSearch from "@components/GoodreadsSearch.svelte";
|
import GoodreadsSearch from "@components/GoodreadsSearch.svelte";
|
||||||
import { type SearchResult } from "@data-sources/goodreads";
|
import { type SearchResult } from "@data-sources/goodreads";
|
||||||
import { Event, EventEmitter } from "@utils/event";
|
import { Event, EventEmitter } from "@utils/event";
|
||||||
import { App, Modal, Notice } from "obsidian";
|
import { App } from "obsidian";
|
||||||
import { mount, unmount } from "svelte";
|
import { SvelteModal } from "./svelte-modal";
|
||||||
|
|
||||||
export class SearchEvent extends Event {
|
export class SearchEvent extends Event {
|
||||||
constructor(
|
constructor(
|
||||||
|
@ -26,13 +26,10 @@ interface GoodreadsSearchModalEventMap {
|
||||||
|
|
||||||
export class GoodreadsSearchModal extends EventEmitter<
|
export class GoodreadsSearchModal extends EventEmitter<
|
||||||
GoodreadsSearchModalEventMap,
|
GoodreadsSearchModalEventMap,
|
||||||
typeof Modal
|
typeof SvelteModal<typeof GoodreadsSearch>
|
||||||
>(Modal) {
|
>(SvelteModal) {
|
||||||
private component: ReturnType<typeof GoodreadsSearch> | undefined;
|
constructor(app: App) {
|
||||||
|
super(app, GoodreadsSearch, {
|
||||||
onOpen() {
|
|
||||||
this.component = mount(GoodreadsSearch, {
|
|
||||||
target: this.contentEl,
|
|
||||||
props: {
|
props: {
|
||||||
onError: (error: Error) => {
|
onError: (error: Error) => {
|
||||||
this.emit("error", new ErrorEvent(error));
|
this.emit("error", new ErrorEvent(error));
|
||||||
|
@ -44,13 +41,6 @@ export class GoodreadsSearchModal extends EventEmitter<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose() {
|
|
||||||
if (this.component) {
|
|
||||||
unmount(this.component);
|
|
||||||
this.component = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static createAndOpen(app: App): Promise<SearchResult[]> {
|
static createAndOpen(app: App): Promise<SearchResult[]> {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const modal = new GoodreadsSearchModal(app);
|
const modal = new GoodreadsSearchModal(app);
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import Rating from "@components/Rating.svelte";
|
import Rating from "@components/Rating.svelte";
|
||||||
import { Event, EventEmitter } from "@utils/event";
|
import { Event, EventEmitter } from "@utils/event";
|
||||||
import { App, Modal } from "obsidian";
|
import { App } from "obsidian";
|
||||||
import { mount, unmount } from "svelte";
|
import { SvelteModal } from "./svelte-modal";
|
||||||
|
|
||||||
class SubmitEvent extends Event {
|
class SubmitEvent extends Event {
|
||||||
constructor(public readonly rating: number) {
|
constructor(public readonly rating: number) {
|
||||||
|
@ -15,13 +15,10 @@ interface RatingModalEventMap {
|
||||||
|
|
||||||
export class RatingModal extends EventEmitter<
|
export class RatingModal extends EventEmitter<
|
||||||
RatingModalEventMap,
|
RatingModalEventMap,
|
||||||
typeof Modal
|
typeof SvelteModal<typeof Rating>
|
||||||
>(Modal) {
|
>(SvelteModal) {
|
||||||
private component: ReturnType<typeof Rating> | undefined;
|
constructor(app: App) {
|
||||||
|
super(app, Rating, {
|
||||||
onOpen(): void {
|
|
||||||
this.component = mount(Rating, {
|
|
||||||
target: this.contentEl,
|
|
||||||
props: {
|
props: {
|
||||||
onSubmit: (rating: number) =>
|
onSubmit: (rating: number) =>
|
||||||
this.emit("submit", new SubmitEvent(rating)),
|
this.emit("submit", new SubmitEvent(rating)),
|
||||||
|
@ -29,13 +26,6 @@ export class RatingModal extends EventEmitter<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(): void {
|
|
||||||
if (this.component) {
|
|
||||||
unmount(this.component);
|
|
||||||
this.component = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static createAndOpen(app: App): Promise<number> {
|
static createAndOpen(app: App): Promise<number> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const modal = new RatingModal(app);
|
const modal = new RatingModal(app);
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import ReadingLogEntryEditor from "@components/ReadingLogEntryEditor.svelte";
|
import ReadingLogEntryEditor from "@components/ReadingLogEntryEditor.svelte";
|
||||||
import type { ReadingLogEntry } from "@src/types";
|
import type { ReadingLogEntry } from "@src/types";
|
||||||
import { Event, EventEmitter } from "@utils/event";
|
import { Event, EventEmitter } from "@utils/event";
|
||||||
import { App, Modal } from "obsidian";
|
import { App } from "obsidian";
|
||||||
import { mount, unmount } from "svelte";
|
import { SvelteModal } from "./svelte-modal";
|
||||||
|
|
||||||
class SubmitEvent extends Event {
|
export class SubmitEvent extends Event {
|
||||||
constructor(public readonly entry: ReadingLogEntry) {
|
constructor(public readonly entry: ReadingLogEntry) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -16,29 +16,15 @@ interface ReadingLogEntryEditModalEventMap {
|
||||||
|
|
||||||
export class ReadingLogEntryEditModal extends EventEmitter<
|
export class ReadingLogEntryEditModal extends EventEmitter<
|
||||||
ReadingLogEntryEditModalEventMap,
|
ReadingLogEntryEditModalEventMap,
|
||||||
typeof Modal
|
typeof SvelteModal<typeof ReadingLogEntryEditor>
|
||||||
>(Modal) {
|
>(SvelteModal) {
|
||||||
private component: ReturnType<typeof ReadingLogEntryEditor> | undefined;
|
constructor(app: App, entry: ReadingLogEntry) {
|
||||||
|
super(app, ReadingLogEntryEditor, {
|
||||||
constructor(app: App, private readonly entry: ReadingLogEntry) {
|
|
||||||
super(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpen(): void {
|
|
||||||
this.component = mount(ReadingLogEntryEditor, {
|
|
||||||
target: this.contentEl,
|
|
||||||
props: {
|
props: {
|
||||||
entry: this.entry,
|
entry,
|
||||||
onSubmit: (entry: ReadingLogEntry) =>
|
onSubmit: (entry: ReadingLogEntry) =>
|
||||||
this.emit("submit", new SubmitEvent(entry)),
|
this.emit("submit", new SubmitEvent(entry)),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(): void {
|
|
||||||
if (this.component) {
|
|
||||||
unmount(this.component);
|
|
||||||
this.component = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import ReadingProgress from "@components/ReadingProgress.svelte";
|
import ReadingProgress from "@components/ReadingProgress.svelte";
|
||||||
import { Event, EventEmitter } from "@utils/event";
|
import { Event, EventEmitter } from "@utils/event";
|
||||||
import { App, Modal } from "obsidian";
|
import { App } from "obsidian";
|
||||||
import { mount, unmount } from "svelte";
|
import { SvelteModal } from "./svelte-modal";
|
||||||
|
|
||||||
class SubmitEvent extends Event {
|
export class SubmitEvent extends Event {
|
||||||
constructor(public readonly pageNumber: number) {
|
constructor(public readonly pageNumber: number) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
@ -15,19 +15,12 @@ interface ReadingProgressModalEventMap {
|
||||||
|
|
||||||
export class ReadingProgressModal extends EventEmitter<
|
export class ReadingProgressModal extends EventEmitter<
|
||||||
ReadingProgressModalEventMap,
|
ReadingProgressModalEventMap,
|
||||||
typeof Modal
|
typeof SvelteModal<typeof ReadingProgress>
|
||||||
>(Modal) {
|
>(SvelteModal) {
|
||||||
private component: ReturnType<typeof ReadingProgress> | undefined;
|
constructor(app: App, pageLength: number) {
|
||||||
|
super(app, ReadingProgress, {
|
||||||
constructor(app: App, private readonly pageLength: number) {
|
|
||||||
super(app);
|
|
||||||
}
|
|
||||||
|
|
||||||
onOpen(): void {
|
|
||||||
this.component = mount(ReadingProgress, {
|
|
||||||
target: this.contentEl,
|
|
||||||
props: {
|
props: {
|
||||||
pageLength: this.pageLength,
|
pageLength,
|
||||||
onSubmit: (pageNumber: number) => {
|
onSubmit: (pageNumber: number) => {
|
||||||
this.emit("submit", new SubmitEvent(pageNumber));
|
this.emit("submit", new SubmitEvent(pageNumber));
|
||||||
},
|
},
|
||||||
|
@ -35,13 +28,6 @@ export class ReadingProgressModal extends EventEmitter<
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(): void {
|
|
||||||
if (this.component) {
|
|
||||||
unmount(this.component);
|
|
||||||
this.component = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static createAndOpen(app: App, pageLength: number): Promise<number> {
|
static createAndOpen(app: App, pageLength: number): Promise<number> {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const modal = new ReadingProgressModal(app, pageLength);
|
const modal = new ReadingProgressModal(app, pageLength);
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
import { App, Modal } from "obsidian";
|
||||||
|
import { mount, unmount, type Component, type MountOptions } from "svelte";
|
||||||
|
|
||||||
|
export class SvelteModal<
|
||||||
|
TComponent extends Component<TProps, TExports, TBindings>,
|
||||||
|
TProps extends Record<string, any> = {},
|
||||||
|
TExports extends Record<string, any> = {},
|
||||||
|
TBindings extends keyof TProps | "" = string
|
||||||
|
> extends Modal {
|
||||||
|
protected component: TExports | undefined;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
app: App,
|
||||||
|
private readonly componentCtor: TComponent,
|
||||||
|
private readonly mountOpts: Omit<MountOptions<TProps>, "target">
|
||||||
|
) {
|
||||||
|
super(app);
|
||||||
|
}
|
||||||
|
|
||||||
|
onOpen(): void {
|
||||||
|
this.component = mount(this.componentCtor, {
|
||||||
|
...this.mountOpts,
|
||||||
|
target: this.contentEl,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
onClose(): void {
|
||||||
|
if (this.component) {
|
||||||
|
unmount(this.component);
|
||||||
|
this.component = undefined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue