This commit is contained in:
2024-06-07 16:15:42 +08:00
parent ea7f4f538a
commit 614a983aa8
15 changed files with 834 additions and 464 deletions

View File

@ -51,7 +51,6 @@
}
.ui-switch {
position: relative;
line-height: 1rem;
user-select: none;
cursor: pointer;
@ -59,6 +58,7 @@
>span:first-of-type {
display: inline-flex;
align-items: center;
position: relative;
&::before {
content: '';
@ -76,6 +76,7 @@
content: '';
position: absolute;
left: 1px;
top: calc(50% - 7px);
width: 14px;
height: 14px;
background-color: white;

View File

@ -38,11 +38,14 @@
--border-radius: 2px;
--text-indent: 4px;
--line-height: 18px;
--settings-line-height: 28px;
--font-size: .8125rem; // 13px
--font-smaller-size: .75rem; // 12px
--font-larger-size: .875rem; // 14px
--font-header-size: 1.5rem; // 24px
--font-family: "Franklin Gothic Book", "San Francisco", "Segoe UI", "Open Sans", "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei UI", sans-serif;
--header-font-family: Arial, sans-serif;
}
/*@media (prefers-color-scheme: dark) {

View File

@ -1,5 +1,5 @@
import './css/dropdown.scss';
import { r } from "../utility/lgres";
import { r as lang } from "../utility/lgres";
import { contains, nullOrEmpty } from "../utility/strings";
import { global, isPositive, throttle } from "../utility";
import { createElement } from "../functions";
@ -9,6 +9,7 @@ import { createIcon } from "./icon"
const SymbolDropdown = Symbol.for('ui-dropdown');
const DropdownItemHeight = 30;
let r = lang;
let dropdownGlobal = global[SymbolDropdown];
if (dropdownGlobal == null) {
@ -51,8 +52,13 @@ if (dropdownGlobal == null) {
});
}
function selectItems(label, itemlist, htmlkey, textkey) {
const htmls = itemlist.map(it => it[htmlkey]);
function selectItems(label, itemlist, template, htmlkey, textkey) {
let htmls;
if (typeof template === 'function') {
htmls = itemlist.map(it => template.call(this, it));
} else {
htmls = itemlist.map(it => it[htmlkey]);
}
if (htmls.some(it => it instanceof HTMLElement)) {
label.replaceChildren(...htmls.filter(it => it != null).map(it => it.cloneNode(true)));
} else {
@ -87,6 +93,7 @@ function filterSource(searchkeys, textkey, key, source) {
* @property {string} [textKey=text] - 文本关键字
* @property {string} [valueKey=value] - 值关键字
* @property {string} [htmlKey=html] - 源码显示的关键字
* @property {Function} [htmlTemplate] - 模板创建函数
* @property {number} [maxLength=500] - 最大输入长度
* @property {boolean} [multiSelect] - 是否允许多选
* @property {string} [selected] - 选中值
@ -129,6 +136,10 @@ export class Dropdown {
options.htmlKey ??= 'html';
options.maxLength ??= 500;
this._var.options = options;
const getText = options.getText;
if (typeof getText === 'function') {
r = getText;
}
}
create() {
@ -300,6 +311,7 @@ export class Dropdown {
this._var.lastSelected = selected;
const valuekey = this._var.options.valueKey;
const textkey = this._var.options.textKey;
const template = this._var.options.htmlTemplate;
const htmlkey = this._var.options.htmlKey;
let item = this.source.find(it => (ignoreCase ? String(it[valuekey]).toLowerCase() : String(it[valuekey])) === selected);
if (this._var.options.input) {
@ -317,7 +329,12 @@ export class Dropdown {
this._var.label.innerText = ' ';
return false;
}
const html = item[htmlkey];
let html;
if (typeof template === 'function') {
html = template.call(this, item);
} else {
html = item[htmlkey];
}
if (html instanceof HTMLElement) {
this._var.label.replaceChildren(html.cloneNode(true));
} else if (typeof html === 'string') {
@ -354,6 +371,7 @@ export class Dropdown {
const source = this.source;
const valuekey = this._var.options.valueKey;
const textkey = this._var.options.textKey;
const template = this._var.options.htmlTemplate;
const htmlkey = this._var.options.htmlKey;
const itemlist = selectedlist.map(a => {
const v = typeof a === 'string' ? a : String(a);
@ -371,7 +389,7 @@ export class Dropdown {
this._var.label.innerText = r('none', '( None )');
return false;
}
selectItems(this._var.label, itemlist, htmlkey, textkey);
selectItems(this._var.label, itemlist, template, htmlkey, textkey);
this._var.selectedList = itemlist;
if (!silence && typeof this.onSelectedList === 'function') {
this.onSelectedList(itemlist);
@ -563,6 +581,7 @@ export class Dropdown {
const multiselect = this.multiSelect;
const valuekey = this._var.options.valueKey;
const textkey = this._var.options.textKey;
const template = this._var.options.htmlTemplate;
const htmlkey = this._var.options.htmlKey;
const selected = this.selected;
let scrolled;
@ -575,7 +594,12 @@ export class Dropdown {
li.dataset.value = val;
li.title = item[textkey];
let label;
const html = item[htmlkey];
let html;
if (typeof template === 'function') {
html = template.call(this, item);
} else {
html = item[htmlkey];
}
if (html instanceof HTMLElement) {
label = html;
} else if (typeof html === 'string') {
@ -617,6 +641,7 @@ export class Dropdown {
let list;
const valuekey = this._var.options.valueKey;
const textkey = this._var.options.textKey;
const template = this._var.options.htmlTemplate;
const htmlkey = this._var.options.htmlKey;
if (checkbox.getAttribute('isall') === '1') {
const allchecked = this._var.allChecked = checkbox.checked;
@ -653,7 +678,7 @@ export class Dropdown {
if (this._var.allChecked) {
this._var.label.innerText = r('allItem', '( All )');
} else {
selectItems(this._var.label, list, htmlkey, textkey);
selectItems(this._var.label, list, template, htmlkey, textkey);
}
this._var.selectedList = list;
if (typeof this.onSelectedList === 'function') {

View File

@ -71,13 +71,13 @@ let r = lang;
/**
* 键值字典
* @template T
* @typedef {{[key: string]: T}} KeyMap
* @typedef {Map<string, T>} KeyMap
*/
/**
* 索引字典
* @template T
* @typedef {{[index: number]: T}} IndexMap
* @typedef {Map<number, T>} IndexMap
*/
/**
@ -1077,7 +1077,7 @@ export class Grid {
/**
* 行发生变化时触发的事件
* @event
* @param {("update" | "add" | "remove")} action - 变动类型
* @param {("update" | "add" | "remove" | "drag")} action - 变动类型
* @param {GridRowItem[]} items - 发生变动的行对象
* @param {(number | number[])} indexes - 变动的索引集合
* @this Grid
@ -1244,7 +1244,7 @@ export class Grid {
* 获取已过滤的数据数组,或者设置数据并刷新列表
* @type {GridRowItem[]}
*/
get source() { return this._var.currentSource?.map(s => s.values) }
get source() { return this._var.currentSource?.map(s => s.values) ?? [] }
set source(list) {
if (!Array.isArray(list)) {
throw new Error('source is not an Array.')
@ -1463,6 +1463,9 @@ export class Grid {
this.removeItem(src);
this.addItem(row, target);
this.selectedIndexes = [e.ctrlKey ? target : target - 1];
if (typeof this.onRowChanged === 'function') {
this.onRowChanged('drag', [row], target);
}
});
}
container.replaceChildren(grid);
@ -2862,6 +2865,9 @@ export class Grid {
this.removeItem(src);
this.addItem(row, target);
this.selectedIndexes = [target];
if (typeof this.onRowChanged === 'function') {
this.onRowChanged('drag', [row], target);
}
});
}
const virtualRow = { cells: {} };
@ -3648,6 +3654,8 @@ export class Grid {
}
]).then(result => {
if (result?.key === 'yes') {
const sortCol = this.sortArray.find(c => c.column === col.key);
this.sortDirection = sortCol?.order === 'asc' ? -1 : 1;
this._onDoHeaderSort(col);
}
});

View File

@ -1,5 +1,6 @@
import './css/tooltip.scss';
import { createElement } from "../functions";
import { global } from '../utility';
const pointerHeight = 12;
@ -98,7 +99,7 @@ export function setTooltip(container, content, flag = false, parent = null) {
let lastWidth = p.clientWidth;
let lastHeight = p.clientHeight;
while (p != null) {
const overflow = window.getComputedStyle(p).overflow;
const overflow = global.getComputedStyle(p).overflow;
if (overflow !== 'visible') {
break;
}