Files
ui-lib/lib/ui.js
T
2025-12-24 10:55:40 +08:00

217 lines
5.3 KiB
JavaScript

import './ui/css/variables/definition.scss';
import './ui/css/common.scss';
import { createElement } from "./functions";
import { createIcon, changeIcon, resolveIcon } from "./ui/icon";
import { createCheckbox, createRadiobox, resolveCheckbox } from "./ui/checkbox";
import { setTooltip, resolveTooltip } from "./ui/tooltip";
import { createTab } from "./ui/tab";
import { Dropdown } from "./ui/dropdown";
import { Grid } from "./ui/grid/grid";
import { GridColumn, GridInputColumn, GridDropdownColumn, GridCheckboxColumn, GridIconColumn, GridTextColumn, GridDateColumn } from './ui/grid/column';
import { Popup, createPopup, resolvePopup, showAlert, showInput, showConfirm } from "./ui/popup";
import { createPicture, createAudio, createVideo, createFile, createVideoList } from './ui/media';
import { validation, convertCssStyle } from './ui/extension';
import { createDateInput, toDateValue, getFormatter, formatDate, setDateValue, getDateValue, DateSelector } from './ui/date';
import * as utility from './utility';
function requestAnimationFrame(callback) {
if (typeof utility.global.requestAnimationFrame === 'function') {
utility.global.requestAnimationFrame(callback);
} else {
setTimeout(callback, 0);
}
}
function scrollLeft() {
const n = document.documentElement;
return (utility.global.scrollX || n.scrollLeft) - (n.clientLeft || 0);
}
function scrollTop() {
const n = document.documentElement;
return (utility.global.scrollY || n.scrollTop) - (n.clientTop || 0);
}
/**
* @private
* @param {HTMLElement} e
*/
function offset(e) {
const rect = e.getBoundingClientRect();
return {
top: rect.top + scrollTop(),
left: rect.left + scrollLeft(),
height: rect.height,
width: rect.width
};
}
class OptionBase {
_option;
r;
constructor(opt) {
this._option = opt;
const getText = opt.getText;
if (typeof getText === 'function') {
this.r = getText;
} else if (typeof GetTextByKey === 'function') {
this.r = GetTextByKey;
} else {
this.r = utility.r;
}
}
}
/**
* 通知选项
* @typedef NotifyOption
* @property {string | HTMLElement} message - 内容,支持自定义元素
* @property {HTMLElement} [parent] - 目标父元素
* @property {string} [title] - 标题
* @property {"success" | "warning" | "error"} [type] - 提示类型
* @property {boolean} [persistent] - 是否持续显示,默认为 `false`,3 秒后自动关闭
* @property {number} [timeout] - 超时时间,默认 3 秒
* @property {(auto: boolean) => void} [onDismissed] - 关闭时触发的函数
*/
/**
* @private
* @param {HTMLDivElement} wrapper
* @param {(auto: boolean) => void} [onDismissed]
* @param {boolean} [auto]
*/
function closeNotify(wrapper, onDismissed, auto) {
wrapper.classList.remove('active');
setTimeout(() => {
wrapper.remove();
if (typeof onDismissed === 'function') {
onDismissed(auto);
}
}, 120);
}
/**
*
* @param {NotifyOption} opts
*/
function notify(opts) {
opts ||= {};
let timer;
const close = createIcon('fa-light', 'times');
close.classList.add('ui-notify-close');
close.addEventListener('click', () => {
timer && clearTimeout(timer);
closeNotify(wrapper, opts.onDismissed);
});
let type;
let typeClass;
opts.type ||= 'success';
switch (opts.type) {
case 'warning':
type = 'exclamation-circle';
typeClass = 'warning';
break;
case 'error':
type = 'times-circle';
typeClass = 'error';
break;
case 'success':
type = 'check-circle';
typeClass = 'success';
break;
default:
type = opts.type;
typeClass = 'success';
break;
}
const icon = createIcon('fa-solid', type);
icon.classList.add('ui-notify-type', typeClass);
const wrapper = createElement('div', 'ui-notify',
utility.nullOrEmpty(opts.title) ?
createElement('div', 'ui-notify-single',
icon,
createElement('span', 'ui-notify-message', opts.message),
close
) :
createElement('div', 'ui-notify-content',
createElement('div', 'ui-notify-header',
icon,
createElement('h2', 'ui-notify-title', opts.title),
close
),
createElement('span', 'ui-notify-message', opts.message)
)
);
if (!opts.persistent) {
timer = setTimeout(() => {
closeNotify(wrapper, opts.onDismissed, true);
}, opts.timeout || 3000);
}
(opts.parent ?? document.body).appendChild(wrapper);
setTimeout(() => wrapper.classList.add('active'), 10);
return wrapper;
}
export {
createElement,
// icon
createIcon,
changeIcon,
resolveIcon,
// checkbox
createCheckbox,
createRadiobox,
resolveCheckbox,
// tooltip
setTooltip,
resolveTooltip,
// tab
createTab,
// dropdown
Dropdown,
// grid
Grid,
GridColumn,
GridInputColumn,
GridDropdownColumn,
GridCheckboxColumn,
GridIconColumn,
GridTextColumn,
GridDateColumn,
// popup
Popup,
createPopup,
resolvePopup,
showAlert,
showInput,
showConfirm,
// dateSelector
createDateInput,
toDateValue,
getFormatter,
formatDate,
setDateValue,
getDateValue,
DateSelector,
// media
createPicture,
createAudio,
createVideo,
createFile,
createVideoList,
// extension
validation,
convertCssStyle,
// utility
utility,
// functions
requestAnimationFrame,
offset,
// base classes
OptionBase,
// notify
notify
}