sync form work
This commit is contained in:
188
lib/ui/popup.js
188
lib/ui/popup.js
@ -1,45 +1,161 @@
|
||||
import "../../css/popup.scss";
|
||||
import { createElement } from "../functions";
|
||||
import { r } from "../utility";
|
||||
import { createIcon } from "./icon";
|
||||
|
||||
function createPopup(title, content, ...buttons) {
|
||||
const mask = createElement('div', 'popup-mask');
|
||||
const container = createElement('div', 'popup-container');
|
||||
const close = () => {
|
||||
mask.classList.add('popup-active');
|
||||
mask.style.opacity = 0;
|
||||
setTimeout(() => mask.remove(), 120);
|
||||
};
|
||||
container.append(
|
||||
createElement('div', header => {
|
||||
header.className = 'popup-header';
|
||||
if (title instanceof HTMLElement) {
|
||||
class Popup {
|
||||
#mask;
|
||||
#option;
|
||||
|
||||
constructor(opts = {}) {
|
||||
this.#option = opts;
|
||||
}
|
||||
|
||||
get container() { return this.#mask.querySelector('.popup-container') }
|
||||
|
||||
create() {
|
||||
const mask = createElement('div', 'popup-mask');
|
||||
const container = createElement('div', 'popup-container');
|
||||
const close = () => {
|
||||
mask.classList.add('popup-active');
|
||||
mask.style.opacity = 0;
|
||||
setTimeout(() => mask.remove(), 120);
|
||||
};
|
||||
let content = this.#option.content;
|
||||
if (!(content instanceof HTMLElement)) {
|
||||
content = createElement('div', d => d.innerText = content);
|
||||
}
|
||||
container.append(
|
||||
createElement('div', header => {
|
||||
header.className = 'popup-header';
|
||||
let title = this.#option.title;
|
||||
if (!(title instanceof HTMLElement)) {
|
||||
title = createElement('div', t => t.innerText = title);
|
||||
}
|
||||
header.appendChild(title);
|
||||
} else {
|
||||
header.appendChild(createElement('div', t => t.innerText = title));
|
||||
}
|
||||
const cancel = createIcon('fa-regular', 'times');
|
||||
cancel.addEventListener('click', () => close());
|
||||
header.appendChild(cancel);
|
||||
}),
|
||||
createElement('div', 'popup-body', content),
|
||||
createElement('div', 'popup-footer', ...buttons.map(b => {
|
||||
const button = createElement('div', 'popup-button');
|
||||
button.innerText = b.text;
|
||||
if (typeof b.trigger === 'function') {
|
||||
button.addEventListener('click', () => {
|
||||
if (b.trigger(container) === false) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
const move = title.querySelector('.popup-move') ?? title;
|
||||
move.addEventListener('mousedown', e => {
|
||||
const x = e.clientX - container.offsetLeft;
|
||||
const y = e.clientY - container.offsetTop;
|
||||
const move = e => {
|
||||
container.style.left = `${e.clientX - x}px`;
|
||||
container.style.top = `${e.clientY - y}px`;
|
||||
};
|
||||
mask.addEventListener('mousemove', move, { passive: false });
|
||||
mask.addEventListener('mouseup', () => {
|
||||
mask.removeEventListener('mousemove', move, { passive: false });
|
||||
});
|
||||
});
|
||||
}
|
||||
}))
|
||||
);
|
||||
mask.appendChild(container);
|
||||
return mask;
|
||||
const cancel = createIcon('fa-regular', 'times');
|
||||
cancel.addEventListener('click', () => close());
|
||||
header.appendChild(cancel);
|
||||
}),
|
||||
createElement('div', 'popup-body', content, createElement('div', 'popup-loading',
|
||||
createElement('div', null, createIcon('fa-regular', 'spinner-third'))
|
||||
))
|
||||
);
|
||||
if (Array.isArray(this.#option.buttons)) {
|
||||
container.appendChild(
|
||||
createElement('div', 'popup-footer', ...this.#option.buttons.map(b => {
|
||||
const button = createElement('div', 'popup-button');
|
||||
button.innerText = b.text;
|
||||
button.addEventListener('click', () => {
|
||||
if (typeof b.trigger === 'function' && b.trigger(this) === false) {
|
||||
return;
|
||||
}
|
||||
close();
|
||||
});
|
||||
return button;
|
||||
}))
|
||||
);
|
||||
}
|
||||
mask.appendChild(container);
|
||||
this.#mask = mask;
|
||||
return mask;
|
||||
}
|
||||
|
||||
show(parent = document.body) {
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
let mask = this.#mask ?? this.create();
|
||||
parent.appendChild(mask);
|
||||
return new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
mask.style.opacity = 1
|
||||
resolve();
|
||||
}, 0);
|
||||
});
|
||||
}
|
||||
|
||||
get loading() { return this.#mask?.querySelector('.popup-body>.popup-loading')?.style?.visibility === 'visible' }
|
||||
set loading(flag) {
|
||||
let loading = this.#mask?.querySelector('.popup-body>.popup-loading');
|
||||
if (loading == null) {
|
||||
return;
|
||||
}
|
||||
if (flag === false) {
|
||||
loading.style.visibility = 'hidden';
|
||||
loading.style.opacity = 0;
|
||||
} else {
|
||||
loading.style.visibility = 'visible';
|
||||
loading.style.opacity = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {
|
||||
createPopup
|
||||
export default Popup;
|
||||
|
||||
export function createPopup(title, content, ...buttons) {
|
||||
const popup = new Popup({
|
||||
title,
|
||||
content,
|
||||
buttons
|
||||
});
|
||||
return popup;
|
||||
}
|
||||
|
||||
const iconTypes = {
|
||||
'info': 'info-circle',
|
||||
'information': 'info-circle',
|
||||
'warn': 'exclamation-triangle',
|
||||
'warning': 'exclamation-triangle',
|
||||
'question': 'question-circle',
|
||||
'error': 'times-circle'
|
||||
}
|
||||
|
||||
export function showAlert(title, message, iconType = 'info', parent = document.body) {
|
||||
return new Promise(resolve => {
|
||||
const popup = new Popup({
|
||||
title,
|
||||
content: createElement('div', 'message-wrapper',
|
||||
createIcon('fa-solid', iconTypes[iconType] ?? 'info-circle'),
|
||||
createElement('span', span => span.innerText = message)
|
||||
),
|
||||
buttons: [
|
||||
{ text: r('ok', 'OK'), trigger: resolve }
|
||||
]
|
||||
});
|
||||
popup.show(parent);
|
||||
});
|
||||
}
|
||||
|
||||
export function showConfirm(title, message, buttons, iconType = 'question', parent = document.body) {
|
||||
return new Promise(resolve => {
|
||||
const popup = new Popup({
|
||||
title,
|
||||
content: createElement('div', 'message-wrapper',
|
||||
createIcon('fa-solid', iconTypes[iconType] ?? 'question-circle'),
|
||||
createElement('span', span => span.innerText = message)
|
||||
),
|
||||
buttons: buttons?.map(b => {
|
||||
return { text: b.text, trigger: p => resolve(b.key, p) }
|
||||
}) ??
|
||||
[
|
||||
{ text: r('yes', 'Yes'), trigger: p => resolve('yes', p) },
|
||||
{ text: r('no', 'No'), trigger: p => resolve('no', p) }
|
||||
]
|
||||
});
|
||||
popup.show(parent);
|
||||
});
|
||||
}
|
Reference in New Issue
Block a user