Skip to content

Commit

Permalink
feat: add dialog plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
oeyoews committed Feb 23, 2025
1 parent 9285865 commit d07ef60
Show file tree
Hide file tree
Showing 8 changed files with 209 additions and 2 deletions.
8 changes: 8 additions & 0 deletions docs/plugins/neotw-dialog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# neotw-dialog

> your neotw-dialog description
## 插件在线地址

<TwPlugin name="neotw-dialog" />

16 changes: 16 additions & 0 deletions plugins/oeyoews/neotw-dialog/plugin.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"title": "$:/plugins/oeyoews/neotw-dialog",
"description": "neotw-dialog",
"author": "oeyoews",
"version": "0.0.1",
"core-version": ">=5.3.4",
"type": "application/json",
"plugin-type": "plugin",
"name": "neotw-dialog",
"meat#disabled": "yes",
"qrcode": "yes",
"created": "20250223",
"dependents": [],
"stability": "STABILITY_2_STABLE",
"list": "readme"
}
4 changes: 4 additions & 0 deletions plugins/oeyoews/neotw-dialog/readme.tid
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
title: $:/plugins/oeyoews/neotw-dialog/readme
description: neotw-dialog

[[在线文档|https://neotw.vercel.app/docs/plugins/neotw-dialog]]
117 changes: 117 additions & 0 deletions plugins/oeyoews/neotw-dialog/tiddlers/dialog.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
/*\
title: $:/plugins/oeyoews/neotw-dialog/dialog.js
type: application/javascript
// module-type: library
module-type: global
neotw-dialog
\*/

/**
* 弹出对话框
*
* @param {'confirm' | 'alert'' | 'prompt'} type - 弹窗类型
* @param {string} title - 弹窗标题
* @param {string} message - 弹窗消息
* @returns {Promise} - 弹窗关闭后的值
*/
async function showDialog(type, title, message) {
return new Promise((resolve) => {
// 创建遮罩层
const overlay = document.createElement('div');
overlay.className =
'fixed top-0 left-0 w-full h-full flex items-center justify-center bg-black bg-opacity-50 opacity-0 transition-opacity duration-300 cursor-pointer';

// 创建弹窗
const modal = document.createElement('div');
modal.className =
'bg-white p-3 rounded-lg shadow-lg max-w-sm w-full transform scale-90 opacity-0 transition-all duration-300';

// 创建标题
const titleElement = document.createElement('h2');
titleElement.className = 'text-lg font-semibold mb-4 mt--';
titleElement.textContent = title;

// 创建消息
const messageElement = document.createElement('p');
messageElement.className = 'mb-4';
messageElement.textContent = message || '';

// 创建输入框(仅在prompt类型时需要)
const inputElement =
type === 'prompt' ? document.createElement('input') : null;
if (inputElement) {
inputElement.className = 'w-full p-2 border rounded mb-4 dark:bg-white';
inputElement?.focus();
inputElement.addEventListener('keydown', (event) => {
// enter to close modal
if (event.keyCode === 13) {
event.preventDefault();
closeDialog(inputElement.value);
}
});
}

// 创建按钮容器
const buttonContainer = document.createElement('div');
buttonContainer.className = 'flex justify-end space-x-2';

// 创建确认按钮
const confirmButton = document.createElement('button');
confirmButton.className = 'px-4 py-2 bg-blue-500 text-white rounded';
confirmButton.textContent = type === 'alert' ? '确定' : '确认';

// 创建取消按钮(仅在confirm和prompt类型时需要)
const cancelButton =
type !== 'alert' ? document.createElement('button') : null;
if (cancelButton) {
cancelButton.className = 'px-4 py-2 bg-gray-300 rounded';
cancelButton.textContent = '取消';
}

// 关闭弹窗的函数
const closeDialog = (value) => {
modal.classList.add('scale-90', 'opacity-0'); // 添加隐藏动画
overlay.classList.add('opacity-0'); // 遮罩淡出

// 等待动画完成再移除
modal.addEventListener(
'transitionend',
() => {
document.body.removeChild(overlay);
resolve(value);
},
{ once: true },
);
};

// 按钮事件绑定
confirmButton.onclick = () =>
closeDialog(type === 'prompt' ? inputElement.value : true);
if (cancelButton) cancelButton.onclick = () => closeDialog(false);

// 遮罩层点击关闭弹窗
overlay.onclick = (e) => {
if (e.target === overlay) closeDialog(null);
};

// 组装DOM
modal.appendChild(titleElement);
modal.appendChild(messageElement);
if (inputElement) modal.appendChild(inputElement);
if (cancelButton) buttonContainer.appendChild(cancelButton);
buttonContainer.appendChild(confirmButton);
modal.appendChild(buttonContainer);
overlay.appendChild(modal);
document.body.appendChild(overlay);

// **触发进入动画**
requestAnimationFrame(() => {
overlay.classList.remove('opacity-0');
modal.classList.remove('scale-90', 'opacity-0');
});
});
}

exports.showDialog = showDialog;
17 changes: 17 additions & 0 deletions plugins/oeyoews/neotw-dialog/tiddlers/startup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/*\
title: $:/plugins/oeyoews/neotw-dialog/startup.js
type: application/javascript
module-type: startup
neotw-dialog startup
\*/

exports.name = 'neotw-dialog-startup-hook';
exports.platforms = ['browser'];
exports.after = ['startup'];
exports.synchronous = true;
exports.startup = () => {
// your code here
console.log('neotw-dialog-startup-hook');
};
44 changes: 44 additions & 0 deletions plugins/oeyoews/neotw-dialog/tiddlers/widget.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*\
title: $:/plugins/oeyoews/neotw-dialog/widget.js
type: application/javascript
module-type: widget
neotw-dialog widget
\*/
const { widget: Widget } = require('$:/core/modules/widgets/widget.js');

class NeotwDialogWidget extends Widget {
constructor(parseTreeNode, options) {
super(parseTreeNode, options);
}

render(parent, nextSibling) {
if (!$tw.browser) return;

this.computeAttributes();
this.execute();

const ssr = this.document.isTiddlyWikiFakeDom;
if (ssr) return;

const createElement = $tw.utils.domMaker;

const btn = createElement('button', {
text: 'Click me',
class: 'rounded p-1',
});

const domNode = createElement('div', {
// text: 'example',
// class: 'underline font-bold',
children: [btn],
});

parent.insertBefore(domNode, nextSibling);
this.domNodes.push(domNode);
}
}

/** @description neotw-dialog widget */
exports['widget-4a7vf1nw'] = NeotwDialogWidget;
2 changes: 1 addition & 1 deletion plugins/oeyoews/nprogress/tiddlers/nprogress.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class NprogressGlobal {
static configure(config) {
NprogressGlobal.requireNProgress();
const defaultConfig = {
showSpinner: true
showSpinner: true,
};
NprogressGlobal.NProgress.configure(Object.assign(defaultConfig, config));
}
Expand Down
3 changes: 2 additions & 1 deletion plugins/oeyoews/vue-contextmenu/tiddlers/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,8 +188,9 @@ const app = (target, title, self) => {
{
label: t('menu.rename'),
icon: getIcon('rename'),
onClick: () => {
onClick: async () => {
const to = window.prompt('Rename to:', title);
// const to = await $tw.showDialog('prompt', 'rename', title);
if (to) {
// o('tm-rename-tiddler', title, '99');
$tw.wiki.renameTiddler(title, to);
Expand Down

0 comments on commit d07ef60

Please sign in to comment.