ivue-material-plus
Version:
A high quality UI components Library with Vue.js
200 lines (169 loc) • 4.67 kB
text/typescript
import { inject } from 'vue';
import {
getFixedColumnsClass,
getFixedColumnOffset,
ensurePosition,
} from '../utils';
// type
import type { TableBodyProps } from './defaults';
import type { TableColumnCtx } from '../table-column/defaults';
import { TableContextKey } from '../table/defaults';
const prefixCls = 'ivue-table';
function useStyles(props: Partial<TableBodyProps>) {
// inject
const IvueTable = inject(TableContextKey);
// 行样式
const getRowStyle = (row: TableColumnCtx, rowIndex: number) => {
const rowStyle = IvueTable?.props.rowStyle;
// function
if (typeof rowStyle === 'function') {
return rowStyle.call(null, {
row,
rowIndex,
});
}
return rowStyle || null;
};
// 行样式
const getRowClass = (row: TableColumnCtx, rowIndex: number) => {
const classes = [
`${prefixCls}-row`,
{
// 斑马纹
[`${prefixCls}-row--stripe`]: props.stripe && rowIndex % 2 === 1,
// 高亮当前行
['highlight-current-row']:
IvueTable?.props.highlightCurrentRow &&
row === props.store?.states.currentRow.value,
},
];
// 行的 className 的回调方法,也可以使用字符串为所有行设置一个固定的 className。
const rowClassName = IvueTable?.props.rowClassName;
// 字符串
if (typeof rowClassName === 'string') {
classes.push(rowClassName);
}
// function
else if (typeof rowClassName === 'function') {
classes.push(
// 执行方法
rowClassName.call(null, {
row,
rowIndex,
})
);
}
return classes;
};
// 获取单元格样式
const getTableSpan = (
row: TableColumnCtx,
column: TableColumnCtx,
rowIndex: number,
columnIndex: number
) => {
// 单元格可横跨的列数
let rowspan = 1;
// 单元格可横跨的列数
let colspan = 1;
const spanMethod = IvueTable?.props.spanMethod;
// 合并行或列的计算方法
if (typeof spanMethod === 'function') {
const result = spanMethod({
// 当前行
row,
// 当前列
column,
// 当前行号
rowIndex,
// 当前列号
columnIndex,
});
// 数组
if (Array.isArray(result)) {
rowspan = result[0];
colspan = result[1];
}
// 对象
else if (typeof result === 'object') {
rowspan = result.rowspan;
colspan = result.colspan;
}
}
return { rowspan, colspan };
};
// 单元格样式
const getCellClass = (
rowIndex: number,
columnIndex: number,
row: TableColumnCtx,
column: TableColumnCtx
) => {
// 是否是嵌套的子列
const fixedClasses = column.isSubColumn
? []
: getFixedColumnsClass(prefixCls, columnIndex, props?.fixed, props.store);
// classes
const classes = [
column.id,
column.align,
column.className,
...fixedClasses,
];
const cellClassName = IvueTable?.props.cellClassName;
// 字符串
if (typeof cellClassName === 'string') {
classes.push(cellClassName);
}
// 方法
else if (typeof cellClassName === 'function') {
classes.push(
cellClassName.call(null, {
rowIndex,
columnIndex,
row,
column,
})
);
}
classes.push('ivue-table-cell');
return classes.filter((className) => Boolean(className)).join(' ');
};
// 单元格样式
const getCellStyle = (
rowIndex: number,
columnIndex: number,
row: TableColumnCtx,
column: TableColumnCtx
) => {
// 单元格的 style 的回调方法
const cellStyle = IvueTable?.props.cellStyle;
let cellStyles = cellStyle ?? {};
// 方法
if (typeof cellStyle === 'function') {
cellStyles = cellStyle.call(null, {
rowIndex,
columnIndex,
row,
column,
});
}
// 是否是嵌套的子列
const fixedStyle = column.isSubColumn
? null
: getFixedColumnOffset(columnIndex, props?.fixed, props.store);
// 左边
ensurePosition(fixedStyle, 'left');
// 右边
ensurePosition(fixedStyle, 'right');
return Object.assign({}, cellStyles, fixedStyle);
};
return {
getRowClass,
getRowStyle,
getTableSpan,
getCellClass,
getCellStyle,
};
}
export default useStyles;