-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 3f7d752
Showing
5 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
发布于 [Obsidian 中文论坛 t34933](https://forum-zh.obsidian.md/t/topic/34933/1),里面有一些前置的说明。 | ||
|
||
作者本人不是计算机专业的,一定要充分测试之后再使用,更好更安全的方式是参考示例自己写。 | ||
|
||
每个 modal 都有一些套路部分,如图红框所示,剩下部分就和定义一个普通函数没区别了,如图绿框所示,整个 modal 可看作一个异步函数 `rgx_form_modal = async (su)=>`。这样,就很好理解在其他文件引用时应该如何书写。 | ||
|
||
<image width="700" src="https://github.com/PlayerMiller109/obsidian-ample-modal-example/assets/145541890/56dfd86d-85f0-4643-a543-05e9900d8227"> | ||
|
||
例如,图示的 modal 只有 resolve,且 `this.close()` 后的 `this.r()` 中间没有参数,所以没有返回值,在其他文件使用时,格式就是: | ||
|
||
```js | ||
// Suppose you have introduced the modals.js in your plugin and name it "mySimpleApi" | ||
const su = { rgx: '', f: '' } | ||
// other possible expressions... | ||
await this.mySimpleApi.rgx_form_modal(su) | ||
// if no resolve, function stops here. | ||
// other possible expressions... | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
const ob = require('obsidian') | ||
module.exports = class extends ob.Plugin { | ||
mySimpleApi = require(`${app.vault.adapter.basePath}/${app.plugins.manifests['ample-modals'].dir}/src/modals.js`)(app, ob) | ||
// 假设 JS 路径如上, 希望的 Api 名为 mySimpleApi | ||
onload() { | ||
// 这里注册命令以展示 modals | ||
this.addCommand({ | ||
id: 'test-suggester', name: 'Test suggester', | ||
callback: async ()=> { | ||
const r1 = await this.mySimpleApi.suggester(['你能看到的'], ['你能得到的'], '预填值, 可不填') | ||
if (!r1) return; console.log(r1) | ||
const r2 = await this.mySimpleApi.suggester(p=> '选项'+p, [1, 2]); if (!r2) return | ||
console.log(r2) | ||
} | ||
}) | ||
this.addCommand({ | ||
id: 'test-rgx_form_modal', name: 'Test rgx_form_modal', | ||
callback: async ()=> { | ||
const su = { rgx: '/(.*?_)(\\d{4})(\\d{2})(\\d{2})/', f: '`$1$2-$3-$4`' } | ||
await this.mySimpleApi.rgx_form_modal(su) | ||
console.log(su) | ||
} | ||
}) | ||
this.addCommand({ | ||
id: 'test-inputPrompt', name: 'Test inputPrompt', | ||
callback: async ()=> { | ||
const r = await this.mySimpleApi.inputPrompt('我是标题: 请输入', '我是占位符, 可不填', '我是预填值, 可不填') | ||
if (!r) return; console.log(r) | ||
} | ||
}) | ||
this.addCommand({ | ||
id: 'test-yesNoPrompt', name: 'Test yesNoPrompt', | ||
callback: async ()=> { | ||
await this.mySimpleApi.yesNoPrompt('我是标题: 你好吗', '我是描述, 可不填') | ||
? console.log('你好呀') : console.log('还没好') | ||
} | ||
}) | ||
this.addCommand({ | ||
id: 'test-checkboxPrompt', name: 'Test checkboxPrompt', | ||
callback: async ()=> { | ||
const items = ['选项1', '选项2', '选项3'] | ||
const chosenItems = await this.mySimpleApi.checkboxPrompt(items, ['选项1', '选项2']) | ||
// 第 2 个参数为预勾选选项, 可不填 | ||
console.log(chosenItems) | ||
} | ||
}) | ||
} | ||
onunload() {} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"id": "ample-modals", | ||
"name": "Ample Modals", | ||
"version": "0.0.1", | ||
"minAppVersion": "1.4.4", | ||
"description": "Plugin modals.", | ||
"author": "PlayerMiller109", | ||
"authorUrl": "https://github.com/PlayerMiller109/obsidian-ample-modals", | ||
"isDesktopOnly": false | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
module.exports = (app, ob)=> new class { | ||
suggester = async (display, items, value = '')=> await new class extends ob.FuzzySuggestModal { | ||
constructor(app) { | ||
super(app); this.promise = new Promise(r=> this.r = r) | ||
this.open(); Object.assign(this.inputEl, {value}) | ||
} | ||
getItemText = (item)=> Array.isArray(display) ? display[items.indexOf(item)] : display(item) | ||
getItems = ()=> items | ||
onChooseItem = (item, evt)=> this.r(item) | ||
}(app).promise | ||
|
||
rgx_form_modal = async (su)=> await new class extends ob.Modal { | ||
constructor(app) { | ||
super(app); this.Setting = ob.Setting | ||
this.promise = new Promise(r=> this.r = r) | ||
this.modalEl.addClass('ample'); this.open() | ||
} | ||
get base() { return new this.Setting(this.contentEl).setClass('full-line-input') } | ||
onOpen() { | ||
this.base | ||
.setName('Rgx').addText(inpu=> inpu.setValue(su.rgx).onChange(value=> su.rgx = value)) | ||
.addButton(btn=> btn.setButtonText('Submit').onClick(()=> { this.close(); this.r() })) | ||
this.base.setName('Form').addText(inpu=> inpu.setValue(su.f).onChange(value=> su.f = value)) | ||
} | ||
onClose() { this.contentEl.empty() } | ||
}(app).promise | ||
|
||
inputPrompt = async (header, placeholder = '', value = '')=> await new class extends ob.Modal { | ||
constructor(app) { | ||
super(app); this.Setting = ob.Setting | ||
this.promise = new Promise((resolve, reject)=> (this.ok = resolve, this.fail = reject)).catch(e=> e) | ||
this.modalEl.addClass('ample'); this.open() | ||
} | ||
onOpen() { | ||
this.setTitle(header) | ||
const area = this.contentEl.createEl('textarea', { cls: 'full-line-input' }) | ||
Object.assign(area, { | ||
placeholder, value, style: 'height: 30px;', | ||
oninput: ()=> { area.style.height = '32px'; area.style.height = `${area.scrollHeight}px` }, | ||
onkeydown: evt=> { | ||
if (evt.key != 'Enter' || evt.shiftKey || evt.ctrlKey) return; evt.preventDefault() | ||
this.close(); this.ok(area.value) | ||
} | ||
}); area.focus(); area.select() | ||
new this.Setting(this.contentEl) | ||
.addButton(btn=> btn.setButtonText('Cancel').onClick(()=> { this.close(); this.fail() })) | ||
.addButton(btn=> btn.setClass('ok-btn').setButtonText('Ok').onClick(()=> { this.close(); this.ok(area.value) })) | ||
} | ||
onClose() { this.contentEl.empty() } | ||
}(app).promise | ||
|
||
yesNoPrompt = async (header, detail)=> await new class extends ob.Modal { | ||
constructor(app) { | ||
super(app); this.Setting = ob.Setting | ||
this.promise = new Promise((resolve, reject)=> (this.ok = resolve, this.fail = reject)).catch(e=> e) | ||
this.modalEl.addClass('ample'); this.open() | ||
} | ||
onOpen() { | ||
this.setTitle(header); this.contentEl.createEl('div', { text: detail }) | ||
new this.Setting(this.contentEl) | ||
.addButton(btn=> btn.setButtonText('No').onClick(()=> { this.close(); this.fail(!1) })) | ||
.addButton(btn=> btn.setWarning().setButtonText('Yes').onClick(()=> { this.close(); this.ok(!0) })) | ||
} | ||
onClose() { this.contentEl.empty() } | ||
}(app).promise | ||
|
||
checkboxPrompt = async (items, chosenItems)=> await new class extends ob.Modal { | ||
constructor(app) { | ||
super(app); this.Setting = ob.Setting | ||
this.promise = new Promise(r=> this.r = r) | ||
this.modalEl.addClass('ample'); this.open() | ||
} | ||
onOpen() { | ||
items.map(item=> new this.Setting(this.contentEl) | ||
.setClass('toggle-box').setName(item) | ||
.addToggle(box=> box | ||
.setValue(chosenItems.includes(item)) | ||
.onChange(flag=> | ||
flag ? chosenItems.push(item) : chosenItems.splice(chosenItems.findIndex(chosen=> chosen == item), 1) | ||
) | ||
) | ||
) | ||
new this.Setting(this.contentEl).addButton(btn=> btn | ||
.setButtonText('Submit').onClick(()=> { this.close(); this.r(chosenItems) }) | ||
) | ||
} | ||
onClose() { this.contentEl.empty() } | ||
}(app).promise | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
@charset "UTF-8"; | ||
|
||
.ample.modal { | ||
& .setting-item {border-top: none;} | ||
|
||
& .full-line-input > .setting-item-info {display: none;} | ||
& .full-line-input > .setting-item-control > input, | ||
textarea.full-line-input { | ||
flex-grow: 1; width: 100%; resize: none; overflow: hidden; | ||
} | ||
|
||
& .ok-btn { | ||
--interactive-normal: var(--interactive-accent); | ||
--interactive-hover: var(--interactive-accent-hover); | ||
} | ||
|
||
& .toggle-box {padding-block: var(--size-4-1);} | ||
& .toggle-box+ .setting-item {padding-bottom: 0;} | ||
} |