This commit is contained in:
Chen Lily 2024-02-20 14:31:24 +08:00
parent 3d2c0e7a97
commit 45205cd63d
3 changed files with 454 additions and 110 deletions

95
count.cjs Normal file
View File

@ -0,0 +1,95 @@
/**
* @author HoPGoldy
* @source https://www.jianshu.com/p/333795b9893f
* @date 2020-1-7
*
* 统计指定目录下代码行数及注释率
*
* 用法: node count.js <路径> [后缀名]...
* 后缀名不填的话默认为统计 .js .ts 文件
*
* 示例 [统计 ./src 下的 js 文件]: node count.js ./src
* 示例 [统计 ./dist 下的 java 文件]: node count.js ./src .java
*/
const fs = require('fs')
let path = require('path')
// 获取命令行参数
const parm = process.argv.splice(2)
// 第一个参数是路径
const rootPath = parm[0]
// 后面的所有参数都是文件后缀
let types = parm.splice(1)
if (types.length === 0) types = [ '.js', '.ts' ]
// 需要过滤的文件夹
const filter = [ './node_modules', './.git', './.tscache' ]
// 总计
let total = {
path: 'total',
length: 0,
comment: 0,
commentRatio: 1
}
// 统计结果
let result = []
/**
* 对指定文件进行统计
* 包括获取文件行数注释及计算注释率
*
* @param {string} path 文件路径
*/
async function count(path) {
const rep = await fs.readFileSync(path).toString()
const lines = rep.split('\n')
// 匹配出注释的行数
const commentNum = lines.filter(line => new RegExp('^(//|/\\*|\\*|\\*/)', 'g').test(line.trimStart())).length
result.push({
path,
length: lines.length,
comment: commentNum,
commentRatio: (Math.round(commentNum/lines.length * 10000) / 100) + '%'
})
updateTotal(lines.length, commentNum)
}
/**
* 更新总计信息
*
* @param {number} length 新增行数
* @param {number} comment 新增注释
*/
function updateTotal(length, comment) {
total.length += length
total.comment += comment
total.commentRatio = (Math.round(total.comment/total.length * 10000) / 100) + '%'
}
/**
* 递归所有文件夹统计
*
* @param {string} pt 根目录
*/
async function start(pt) {
fs.readdirSync(pt).map(file => `${pt}/${file}`)
.forEach(file => {
const stat = fs.statSync(file)
// 是文件夹就递归
if (stat.isDirectory()) {
if (filter.indexOf(pt) != -1) return
return start(file)
}
// 是文件并且后缀名符合就执行统计
if (types.indexOf(path.extname(file)) != -1) count(file)
})
}
;(async () => {
await start(rootPath)
result.push(total)
console.table(result)
})()

View File

@ -6,6 +6,36 @@ import { createCheckbox } from "../checkbox";
import { Dropdown } from "../dropdown";
import { convertCssStyle } from "../extension";
import { createDateInput, formatDate, setDateValue, getDateValue } from "../date";
// definition
import { DropdownOptions, GridItemBooleanCallback, GridDropdownSourceCallback, DateFormatterCallback, GridSourceItem, GridItemWrapper, Grid } from "./grid";
/**
* @ignore
* @callback DropExpandedCallback
* @param {Map<string, ValueItem>} item - 行数据对象
* @param {Dropdown} drop - 下拉框对象
* @this GridColumnDefinition
*/
/**
* 列定义接口
* @ignore
* @typedef GridColumnDefinition
* @property {string} key - 列关键字默认以该关键字从行数据中提取单元格值行数据的关键字属性值里包含 DisplayValue 则优先显示此值
* @property {(boolean | string | GridItemBooleanCallback)} [enabled] - 列是否可用可编辑允许以下类型
*
* * `boolean` 则直接使用该值
* * `string` 则以该值为关键字从行数据中取值作为判断条件
* * `GridItemBooleanCallback` 则调用如下回调以返回值作为判断条件
* @property {DropdownOptions} [dropOptions] - 列为下拉列表类型时以该值设置下拉框的参数
* @property {(GridSourceItem[] | Promise<GridSourceItem[]> | GridDropdownSourceCallback)} [source] - 列为下拉列表类型时以该值设置下拉列表数据源支持返回异步对象也支持如下函数返回
* @property {boolean} [sourceCache=false] - 下拉列表数据源是否缓存结果即行数据未发生变化时仅从source属性获取一次值
* @property {("fa-light" | "fa-regular" | "fa-solid")} [iconType=fa-light] - 列为图标类型时以该值设置图标样式
* @property {string} [dateMin] - 列为日期类型时以该值作为最小可选日期值
* @property {string} [dateMax] - 列为日期类型时以该值作为最大可选日期值
* @property {DateFormatterCallback} [dateValueFormatter] - 列为日期类型时自定义日期格式化函数
* @property {DropExpandedCallback} [onDropExpanded] - 列为下拉框类型时在下拉列表展开时触发的事件
*/
/**
* 列定义基类
@ -14,6 +44,7 @@ import { createDateInput, formatDate, setDateValue, getDateValue } from "../date
* <img src="./assets/column-refresh.jpg" alt="Column Refresh"/>
* @class
* @static
* @hideconstructor
*/
export class GridColumn {
/**
@ -49,7 +80,7 @@ export class GridColumn {
* @param {Function} trigger - 编辑事件回调函数`e` 参数会传递给 [getValue]{@linkcode GridColumn.getValue} 方法
* @param {GridColumnDefinition} col - 列定义对象
* @param {HTMLElement} container - 父容器元素
* @param {GridItemWrapper} vals - 行包装对象 `values` 属性为行数据对象
* @param {GridItemWrapper} wrapper - 行包装对象 `values` 属性为行数据对象
* @returns {HTMLElement} 返回创建的编辑状态的单元格元素
* @virtual
*/
@ -67,7 +98,7 @@ export class GridColumn {
* 获取编辑状态单元格值时调用的方法
* @method
* @name GridColumn.getValue
* @param {any} `e` [createEdit]{@linkcode GridColumn.createEdit} 方法中 `trigger` 函数传递来的对象
* @param {any} e - [createEdit]{@linkcode GridColumn.createEdit} 方法中 `trigger` 函数传递来的对象
* @param {GridColumnDefinition} col - 列定义对象
* @returns {(string | boolean | number)} 返回单元格的值
* @virtual
@ -77,7 +108,7 @@ export class GridColumn {
* 设置单元格值时调用的方法
* @param {HTMLElement} element - 单元格元素
* @param {(string | boolean | number)} val - 待设置的单元格值
* @param {GridItemWrapper} vals - 行包装对象
* @param {GridItemWrapper} wrapper - 行包装对象
* @param {GridColumnDefinition} col - 列定义对象
* @param {Grid} grid - Grid 对象
* @virtual
@ -132,8 +163,7 @@ export class GridColumn {
*/
/**
* 复写 [toString]{@linkcode String#toString} 方法
* @private
* @ignore
*/
static toString() { return '[object Column]' }
}
@ -141,29 +171,44 @@ export class GridColumn {
/**
* 单行文本输入列
* @class
* @static
* @extends GridColumn
* @hideconstructor
*/
export class GridInputColumn extends GridColumn {
static get editing() { return true };
static createEdit(trigger, col, _wrapper, vals) {
/**
* @ignore
* @param {Function} trigger
* @param {GridColumnDefinition} col
* @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper
* @returns {HTMLElement}
*/
static createEdit(trigger, col, _container, wrapper) {
const input = createElement('input');
input.setAttribute('type', 'text');
if (typeof trigger === 'function') {
input.addEventListener('change', trigger);
}
input.addEventListener('input', () => {
if (vals.__editing == null) {
vals.__editing = {
if (wrapper.__editing == null) {
wrapper.__editing = {
[col.key]: true
}
} else {
vals.__editing[col.key] = true;
wrapper.__editing[col.key] = true;
}
});
return input;
}
/**
* @ignore
* @param {HTMLElement} element
* @param {string} val
*/
static setValue(element, val) {
if (element.tagName !== 'INPUT') {
super.setValue(element, val);
@ -172,33 +217,67 @@ export class GridInputColumn extends GridColumn {
}
}
/**
* @ignore
* @param {Event} e
* @returns {string}
*/
static getValue(e) { return e.target.value }
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} enabled
*/
static setEnabled(element, enabled) {
super.setEnabled(element, enabled);
element.disabled = enabled === false;
}
}
/**
* 多行文本输入列
* @class
* @static
* @extends GridInputColumn
* @hideconstructor
* @ignore
*/
export class GridTextColumn extends GridInputColumn {
static createEdit(trigger, col, _wrapper, vals) {
/**
* @ignore
* @param {Function} trigger
* @param {GridColumnDefinition} col
* @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper
* @returns {HTMLElement}
*/
static createEdit(trigger, col, _container, wrapper) {
const input = createElement('textarea');
if (typeof trigger === 'function') {
input.addEventListener('change', trigger);
}
input.addEventListener('input', () => {
if (vals.__editing == null) {
vals.__editing = {
if (wrapper.__editing == null) {
wrapper.__editing = {
[col.key]: true
}
} else {
vals.__editing[col.key] = true;
wrapper.__editing[col.key] = true;
}
});
return input;
}
static setValue(element, val, _item, _col, grid) {
/**
* @ignore
* @param {HTMLElement} element
* @param {string} val
* @param {GridItemWrapper} _wrapper
* @param {GridColumnDefinition} _col
* @param {Grid} grid
*/
static setValue(element, val, _wrapper, _col, grid) {
if (element.tagName !== 'TEXTAREA') {
super.setValue(element, val);
} else {
@ -217,31 +296,49 @@ const SymbolDropdown = Symbol.for('ui-dropdown');
/**
* 下拉选择列
* @class
* @static
* @extends GridColumn
* @hideconstructor
*/
export class GridDropdownColumn extends GridColumn {
static createEdit(trigger, col, container, it) {
/**
* @ignore
* @param {Function} trigger
* @param {GridColumnDefinition} col
* @param {HTMLElement} container
* @param {GridItemWrapper} wrapper
* @returns {HTMLElement}
*/
static createEdit(trigger, col, container, wrapper) {
const drop = new Dropdown({
...col.dropOptions,
wrapper: container.parentElement
});
drop.onSelected = trigger;
drop.onExpanded = () => {
if (it.__editing == null) {
it.__editing = {
if (wrapper.__editing == null) {
wrapper.__editing = {
[col.key]: true
}
} else {
it.__editing[col.key] = true;
wrapper.__editing[col.key] = true;
}
if (typeof col.onDropExpanded === 'function') {
col.onDropExpanded.call(col, it.values, drop);
col.onDropExpanded.call(col, wrapper.values, drop);
}
};
return drop.create();
}
/**
* @private
* @param {HTMLElement} element
* @returns {Dropdown}
*/
static _getDrop(element) {
/**
* @type {Map<string, Dropdown>}
*/
const dropGlobal = global[SymbolDropdown];
if (dropGlobal == null) {
return null;
@ -256,32 +353,39 @@ export class GridDropdownColumn extends GridColumn {
/**
* @private
* @param {Map<string, ValueItem>} item
* @param {GridItemWrapper} wrapper
* @param {GridColumnDefinition} col
* @returns {GridSourceItem[]}
*/
static _getSource(item, col) {
static _getSource(wrapper, col) {
let source;
if (col.sourceCache !== false) {
source = item.source?.[col.key];
source = wrapper.source?.[col.key];
if (source != null) {
return source;
}
}
source = col.source;
if (typeof source === 'function') {
source = source(item.values);
source = source(wrapper.values);
}
if (col.sourceCache !== false) {
if (item.source == null) {
item.source = { [col.key]: source };
if (wrapper.source == null) {
wrapper.source = { [col.key]: source };
} else {
item.source[col.key] = source;
wrapper.source[col.key] = source;
}
}
return source;
}
/**
* @private
* @param {GridSourceItem[]} source
* @param {HTMLElement} element
* @param {any} val
* @param {DropdownOptions} opts
*/
static _setValue(source, element, val, opts) {
const data = source?.find(v => v[opts?.valueKey ?? 'value'] === val);
if (data != null) {
@ -290,9 +394,16 @@ export class GridDropdownColumn extends GridColumn {
super.setValue(element, val);
}
static setValue(element, val, item, col) {
/**
* @ignore
* @param {HTMLElement} element
* @param {any} val
* @param {GridItemWrapper} wrapper
* @param {GridColumnDefinition} col
*/
static setValue(element, val, wrapper, col) {
if (element.tagName !== 'DIV') {
let source = this._getSource(item, col);
let source = this._getSource(wrapper, col);
if (source instanceof Promise) {
source.then(s => this._setValue(s, element, val, col.dropOptions));
} else {
@ -305,7 +416,7 @@ export class GridDropdownColumn extends GridColumn {
return;
}
if (drop.source == null || drop.source.length === 0) {
let source = this._getSource(item, col);
let source = this._getSource(wrapper, col);
if (source instanceof Promise) {
source.then(s => {
drop.source = s;
@ -319,10 +430,21 @@ export class GridDropdownColumn extends GridColumn {
drop.select(val, true);
}
/**
* @ignore
* @param {GridSourceItem} e
* @param {GridColumnDefinition} col
* @returns {any}
*/
static getValue(e, col) {
return e[col.dropOptions?.valueKey ?? 'value'];
}
/**
* @ignore
* @param {HTMLElement} element
* @param {string} name
*/
static setClass(element, name) {
if (element.tagName === 'DIV') {
element.className = `ui-drop-wrapper ${name ?? ''}`;
@ -331,6 +453,11 @@ export class GridDropdownColumn extends GridColumn {
}
}
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} enabled
*/
static setEnabled(element, enabled) {
super.setEnabled(element, enabled);
const drop = this._getDrop(element);
@ -340,6 +467,11 @@ export class GridDropdownColumn extends GridColumn {
drop.disabled = enabled === false;
}
/**
* @ignore
* @param {HTMLElement} element
* @param {HTMLElement} container
*/
static leaveEdit(element, container) {
container.parentElement.querySelectorAll('.ui-drop-box.active').forEach(e => {
if (e != null) {
@ -356,7 +488,20 @@ export class GridDropdownColumn extends GridColumn {
}
}
/**
* 复选框列
* @class
* @static
* @extends GridColumn
* @hideconstructor
* @ignore
*/
export class GridCheckboxColumn extends GridColumn {
/**
* @ignore
* @param {Function} trigger
* @returns {HTMLElement}
*/
static createEdit(trigger) {
const check = createCheckbox({
onchange: typeof trigger === 'function' ? trigger : null
@ -364,12 +509,27 @@ export class GridCheckboxColumn extends GridColumn {
return check;
}
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} val
*/
static setValue(element, val) {
element.querySelector('input').checked = val;
}
/**
* @ignore
* @param {Event} e
* @returns {boolean}
*/
static getValue(e) { return e.target.checked }
/**
* @ignore
* @param {HTMLElement} element
* @param {string} name
*/
static setClass(element, name) {
if (element.tagName === 'LABEL') {
element.className = `ui-check-wrapper ${name ?? ''}`;
@ -378,19 +538,43 @@ export class GridCheckboxColumn extends GridColumn {
}
}
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} enabled
*/
static setEnabled(element, enabled) {
super.setEnabled(element, enabled);
element.querySelector('input').disabled = enabled === false;
}
}
/**
* 图标列
* @class
* @static
* @extends GridColumn
* @hideconstructor
* @ignore
*/
export class GridIconColumn extends GridColumn {
/**
* @ignore
* @returns {HTMLElement}
*/
static create() { return createElement('span', 'col-icon') }
static setValue(element, val, item, col) {
/**
* @ignore
* @param {HTMLElement} element
* @param {string} val
* @param {GridItemWrapper} wrapper
* @param {GridColumnDefinition} col
*/
static setValue(element, val, wrapper, col) {
// let className = col.iconClassName;
// if (typeof className === 'function') {
// className = className.call(col, item.values);
// className = className.call(col, wrapper.values);
// }
// if (className == null) {
// element.className = 'col-icon';
@ -399,7 +583,7 @@ export class GridIconColumn extends GridColumn {
// }
let type = col.iconType;
if (typeof type === 'function') {
type = type.call(col, item.values);
type = type.call(col, wrapper.values);
}
type ??= 'fa-light';
if (element.dataset.type !== type || element.dataset.icon !== val) {
@ -412,10 +596,20 @@ export class GridIconColumn extends GridColumn {
}
}
/**
* @ignore
* @param {HTMLElement} element
* @param {string} name
*/
static setClass(element, name) {
element.className = `col-icon ${name ?? ''}`;
}
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} enabled
*/
static setEnabled(element, enabled) {
super.setEnabled(element, enabled);
if (enabled === false) {
@ -426,41 +620,72 @@ export class GridIconColumn extends GridColumn {
}
}
/**
* 日期选择列
* @class
* @static
* @extends GridColumn
* @hideconstructor
*/
export class GridDateColumn extends GridColumn {
static get editing() { return true };
static createEdit(trigger, col, _container, vals) {
/**
* @ignore
* @param {Function} trigger
* @param {GridColumnDefinition} col
* @param {HTMLElement} _container
* @param {GridItemWrapper} wrapper
* @returns {HTMLElement}
*/
static createEdit(trigger, col, _container, wrapper) {
let enabled = col.enabled;
if (typeof enabled === 'string') {
enabled = vals.values[enabled];
enabled = wrapper.values[enabled];
} else if (typeof enabled === 'function') {
enabled = col.enabled(vals.values);
enabled = col.enabled(wrapper.values);
}
if (enabled === false) {
return super.create();
}
const date = createDateInput(col.dateMin, col.dateMax);
date.addEventListener('change', () => {
if (vals.__editing == null) {
vals.__editing = {
if (wrapper.__editing == null) {
wrapper.__editing = {
[col.key]: true
}
} else {
vals.__editing[col.key] = true;
wrapper.__editing[col.key] = true;
}
});
date.addEventListener('blur', trigger);
return date;
}
/**
* @ignore
* @param {HTMLElement} element
* @param {(string | number | Date)} val
*/
static setValue(element, val) {
setDateValue(element, val);
}
/**
* @ignore
* @param {Event} e
* @param {GridColumnDefinition} col
* @returns {string}
*/
static getValue(e, col) {
return getDateValue(e.target, col.dateValueFormatter);
}
/**
* @ignore
* @param {HTMLElement} element
* @param {string} name
*/
static setClass(element, name) {
if (element.tagName === 'INPUT') {
element.className = `ui-date-cell ${name ?? ''}`;
@ -469,10 +694,26 @@ export class GridDateColumn extends GridColumn {
}
}
/**
* @ignore
* @param {HTMLElement} element
* @param {boolean} enabled
*/
static setEnabled(element, enabled) {
element.disabled = enabled === false;
}
/**
* 格式化日期字符串
* @param {(string | number | Date)} date - 要格式化的日期值
*
* 支持以下几种数据类型
* * `"2024-01-26"`
* * `"1/26/2024"`
* * `"638418240000000000"`
* * `new Date('2024-01-26')`
* @returns {string} 格式化为 M/d/yyyy 的日期字符串
*/
static formatDate(date) {
return formatDate(date);
}

View File

@ -339,39 +339,39 @@ class GridColumnDefinition {
/**
* 列关键字默认以该关键字从行数据中提取单元格值行数据的关键字属性值里包含 DisplayValue 则优先显示此值
* @type {string}
* @private
* @ignore
*/
key;
/**
* 列的类型可以为 {@linkcode GridColumn} 的子类或者内置类型 {@linkcode Grid.ColumnTypes}
* @type {(GridColumnTypeEnum | GridColumn)}
* @default Grid.ColumnTypes.Common
* @private
* @ignore
*/
type;
/**
* 列标题文本
* @type {string}
* @private
* @ignore
*/
caption;
/**
* 列标题的元素样式
* @type {any}
* @private
* @ignore
*/
captionStyle;
/**
* 大于 0 则设置为该宽度否则根据列内容自动调整列宽
* @type {number}
* @private
* @ignore
*/
width;
/**
* 列对齐方式
* @type {("left" |"center" | "right")}
* @default "left"
* @private
* @ignore
*/
align;
/**
@ -381,199 +381,199 @@ class GridColumnDefinition {
* * `string` 则以该值为关键字从行数据中取值作为判断条件
* * `GridItemBooleanCallback` 则调用如下回调以返回值作为判断条件
* @type {(boolean | string | GridItemBooleanCallback)}
* @private
* @ignore
*/
enabled;
/**
* 单元格取值采用该函数返回的值
* @type {GridItemFilterCallback}
* @private
* @ignore
*/
filter;
/**
* 单元格以该值填充内容忽略filter与关键字属性
* @type {string}
* @private
* @ignore
*/
text;
/**
* 列是否可见
* @type {boolean}
* @default true
* @private
* @ignore
*/
visible;
/**
* 列是否允许调整宽度
* @type {boolean}
* @default true
* @private
* @ignore
*/
resizable;
/**
* 列是否允许排序
* @type {boolean}
* @default true
* @private
* @ignore
*/
sortable;
/**
* 列是否允许重排顺序
* @type {boolean}
* @default true
* @private
* @ignore
*/
orderable;
/**
* 列为复选框类型时是否在列头增加全选复选框
* @type {boolean}
* @default false
* @private
* @ignore
*/
allcheck;
/**
* 列为收缩列禁用自动调整大小
* @type {boolean}
* @default false
* @private
* @ignore
*/
shrink;
/**
* 单元格元素的额外样式类型字符串仅在重建行元素时读取
* @type {string}
* @private
* @ignore
*/
class;
/**
* 单元格css样式对象仅在重建行元素时读取
* @type {any}
* @private
* @ignore
*/
css;
/**
* 合计行样式仅在重建合计行元素时读取
* @type {any}
* @private
* @ignore
*/
totalCss;
/**
* 单元格样式填充行列数据时读取支持直接返回样式对象或调用函数返回若赋值则忽略 [styleFilter]{@linkcode GridColumnDefinition#styleFilter}
* @type {(any | GridItemObjectCallback)}
* @private
* @ignore
*/
style;
/**
* **已过时**<br/>_根据返回值填充单元格样式填充行列数据时读取_
* @type {GridItemObjectCallback}
* @private
* @ignore
* @deprecated
*/
styleFilter;
/**
* 设置单元格背景色填充行列数据时读取支持直接设置颜色字符串或调用函数返回若赋值则忽略 [bgFilter]{@linkcode GridColumnDefinition#bgFilter}
* @type {(string | GridItemStringCallback)}
* @private
* @ignore
*/
background;
/**
* **已过时**<br/>_根据返回值设置单元格背景色_
* @type {GridItemStringCallback}
* @private
* @ignore
* @deprecated
*/
bgFilter;
/**
* 给单元格元素附加事件事件函数上下文为数据行对象
* @type {Map<string, Function>}
* @private
* @ignore
*/
events;
/**
* 根据返回值设置单元格元素的附加属性允许直接设置对象也支持调用如下函数返回对象
* @type {(any | GridItemObjectCallback)}
* @private
* @ignore
*/
attrs;
/**
* 是否允许进行列头过滤
* @type {boolean}
* @default false
* @private
* @ignore
*/
allowFilter;
/**
* 过滤值的数组
* @type {any[]}
* @private
* @ignore
*/
filterValues;
/**
* 是否区分 `null` 与空字符串
* @type {boolean}
* @default false
* @private
* @ignore
*/
filterAllowNull;
/**
* 自定义列过滤器的数据源允许调用如下函数
* @type {(ValueItem[] | GridColumnFilterSourceCallback)}
* @private
* @ignore
*/
filterSource;
/**
* 自定义列排序函数
* @type {GridItemSortCallback}
* @private
* @ignore
*/
sortFilter;
/**
* 列为下拉列表类型时以该值设置下拉框的参数
* @type {DropdownOptions}
* @private
* @ignore
*/
dropOptions;
/**
* 列为下拉列表类型时以该值设置下拉列表数据源支持返回异步对象也支持如下函数返回
* @type {(GridSourceItem[] | Promise<GridSourceItem[]> | GridDropdownSourceCallback)}
* @private
* @ignore
*/
source;
/**
* 下拉列表数据源是否缓存结果即行数据未发生变化时仅从source属性获取一次值
* @type {boolean}
* @default false
* @private
* @ignore
*/
sourceCache;
/**
* 列为图标类型时以该值设置图标样式
* @type {("fa-light" | "fa-regular" | "fa-solid")}
* @default "fa-light"
* @private
* @ignore
*/
iconType;
/**
* 列为日期类型时以该值作为最小可选日期值
* @type {string}
* @private
* @ignore
*/
dateMin;
/**
* 列为日期类型时以该值作为最大可选日期值
* @type {string}
* @private
* @ignore
*/
dateMax;
/**
* 列为日期类型时自定义日期格式化函数
* @type {DateFormatterCallback}
* @private
* @ignore
*/
dateValueFormatter;
/**
* 额外设置单元格的 tooltip支持直接使用字符串或者调用如下函数
* @type {(string | GridItemStringCallback)}
* @private
* @ignore
*/
tooltip;
/**
@ -622,7 +622,7 @@ class GridColumnDefinition {
* 列为下拉框类型时在下拉列表展开时触发的事件
* @event
* @param {Map<string, ValueItem>} item - 行数据对象
* @param {Dropdown} drop - 拉框对象
* @param {Dropdown} drop - 拉框对象
* @this GridColumnDefinition
*/
onDropExpanded;
@ -736,6 +736,7 @@ const GridColumnDirection = {
* @property {string} [langs.duplicatePrompt={column} is being sorted more than once...]
* @property {number} [virtualCount=100] - 行数大于等于该值则启用虚模式
* @property {number} [rowHeight=36] - 表格行高
* @property {number} [lineHeight=24] - 文本行高多行文本列计算高度时使用
* @property {string} [filterIcon=filter] - 列头过滤图标旧版本样式横着三个点需修改为 `"ellipsis-h"`
* @property {number} [extraRows=0] - 列表底部留出额外的空白行
* @property {number} [filterRowHeight=30] - 过滤条件列表的行高
@ -1023,108 +1024,108 @@ export class Grid {
/**
* 列定义的数组
* @type {GridColumnDefinition[]}
* @private
* @ignore
*/
columns = [];
/**
* 合计行数据
* @type {Map<string, ValueItem>}
* @private
* @ignore
*/
total = null;
/**
* 多语言资源对象
* @private
* @ignore
*/
langs = {
/**
* @type {string}
* @default "( All )"
* @private
* @ignore
*/
all: null,
/**
* @type {string}
* @default "OK"
* @private
* @ignore
*/
ok: null,
/**
* @type {string}
* @default "Reset"
* @private
* @ignore
*/
reset: null,
/**
* @type {string}
* @default "Cancel"
* @private
* @ignore
*/
cancel: null,
/**
* @type {string}
* @default "( Null )"
* @private
* @ignore
*/
null: null,
/**
* @type {string}
* @default "Add Level"
* @private
* @ignore
*/
addLevel: null,
/**
* @type {string}
* @default "Delete Level"
* @private
* @ignore
*/
deleteLevel: null,
/**
* @type {string}
* @default "Copy Level"
* @private
* @ignore
*/
copyLevel: null,
/**
* @type {string}
* @default "Ascending"
* @private
* @ignore
*/
asc: null,
/**
* @type {string}
* @default "Descending"
* @private
* @ignore
*/
desc: null,
/**
* @type {string}
* @default "Column"
* @private
* @ignore
*/
column: null,
/**
* @type {string}
* @default "Order"
* @private
* @ignore
*/
order: null,
/**
* @type {string}
* @default "Sort"
* @private
* @ignore
*/
sort: null,
/**
* @type {string}
* @default "All sort criteria must have a column specified. Check the selected sort criteria and try again."
* @private
* @ignore
*/
requirePrompt: null,
/**
* @type {string}
* @default "{column} is being sorted more than once. Delete the duplicate sort criteria and try again."
* @private
* @ignore
*/
duplicatePrompt: null
};
@ -1132,110 +1133,117 @@ export class Grid {
* 行数大于等于该值则启用虚模式
* @type {number}
* @default 100
* @private
* @ignore
*/
virtualCount = 100;
/**
* 表格行高
* @type {number}
* @default 36
* @private
* @ignore
*/
rowHeight = 36;
/**
* 文本行高多行文本列计算高度时使用
* @type {number}
* @default 24
* @ignore
*/
lineHeight = 24;
/**
* 列头过滤图标旧版本样式横着三个点需修改为 `ellipsis-h`
* @type {string}
* @default "filter"
* @private
* @ignore
*/
filterIcon = 'filter';
/**
* 列表底部留出额外的空白行
* @type {number}
* @default 0
* @private
* @ignore
*/
extraRows = 0;
/**
* 过滤条件列表的行高
* @type {number}
* @default 30
* @private
* @ignore
*/
filterRowHeight = 30;
/**
* 列表高度值 0 时列表始终显示全部内容自增高为非数字或者小于 0 则根据容器高度来确定虚模式的渲染行数
* @type {number | null}
* @private
* @ignore
*/
height;
/**
* 是否允许多选
* @type {boolean}
* @default false
* @private
* @ignore
*/
multiSelect = false;
/**
* `false` 时只有点击在单元格内才会选中行
* @type {boolean}
* @default true
* @private
* @ignore
*/
fullrowClick = true;
/**
* 单元格 tooltip 是否禁用
* @type {boolean}
* @default false
* @private
* @ignore
*/
tooltipDisabled = false;
/**
* 列头是否显示
* @type {boolean}
* @default true
* @private
* @ignore
*/
headerVisible = true;
/**
* 监听事件的窗口载体
* @type {(Window | HTMLElement)}
* @default window
* @private
* @ignore
*/
window;
/**
* 排序列的索引
* @type {number}
* @default -1
* @private
* @ignore
*/
sortIndex = -1;
/**
* 排序方式正数升序负数倒序
* @type {GridColumnDirection}
* @default GridColumnDirection.Ascending
* @private
* @ignore
*/
sortDirection = GridColumnDirection.Ascending;
/**
* 排序列数组
* @type {GridColumnSortDefinition[]}
* @default null
* @private
* @ignore
*/
sortArray = null;
/**
* 是否支持点击扩展
* @type {boolean}
* @default false
* @private
* @ignore
*/
expandable;
/**
* 扩展行生成器
* @type {GridExpandableObjectCallback}
* @private
* @ignore
*/
expandableGenerator;