Skip to content

Commit

Permalink
type(Table): 优化 table columns render 属性类型提示 (#657)
Browse files Browse the repository at this point in the history
  • Loading branch information
cuilanxin committed Mar 11, 2022
1 parent 997ffe1 commit 7e25a6e
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 39 deletions.
16 changes: 9 additions & 7 deletions packages/react-table/src/Thead.tsx
Expand Up @@ -3,22 +3,24 @@ import { IProps, noop } from '@uiw/utils';
import { TableProps, TableColumns } from './';
import './style/index.less';

export interface TheadProps extends IProps {
data?: TableProps['data'][];
onCellHead?: TableProps['onCellHead'];
export interface TheadProps<T extends { [key: string]: V }, V = any> extends IProps {
data?: TableColumns<T, V>[][];
onCellHead?: TableProps<T, V>['onCellHead'];
}

export default (props: TheadProps & React.HTMLAttributes<HTMLTableSectionElement> = {}) => {
export default function TheadComponent<T extends { [key: string]: V }, V>(
props: TheadProps<T, V> & React.HTMLAttributes<HTMLTableSectionElement> = {},
) {
const { prefixCls = 'w-table', className, data = [], onCellHead = noop, ...other } = props;
return (
<thead className={[prefixCls, className].filter(Boolean).join(' ').trim()} {...other}>
{data &&
data.length > 0 &&
data.map((tds?: TableColumns[], rowNum?: number) => (
data.map((tds?: TableColumns<T>[], rowNum?: number) => (
<tr key={rowNum}>
{(tds || []).map((item, colNum) => {
const { title, key, render, children, ellipsis, ...thProps } = item;
const titleNode: TableColumns['title'] =
const titleNode: TableColumns<T>['title'] =
typeof title === 'function' ? title(item, colNum, rowNum!) : title;
if (thProps.colSpan === 0) {
return null;
Expand All @@ -36,4 +38,4 @@ export default (props: TheadProps & React.HTMLAttributes<HTMLTableSectionElement
))}
</thead>
);
};
}
28 changes: 11 additions & 17 deletions packages/react-table/src/index.tsx
Expand Up @@ -4,28 +4,22 @@ import Thead from './Thead';
import { getLevelItems, getAllColumnsKeys } from './util';
import './style/index.less';

export type TableColumns = {
title?: string | ((data: TableColumns, rowNum: number, colNum: number) => JSX.Element) | JSX.Element;
export type TableColumns<T extends { [key: string]: V }, V = any> = {
title?: string | ((data: TableColumns<T, V>, rowNum: number, colNum: number) => JSX.Element) | JSX.Element;
key?: string;
width?: number;
colSpan?: number;
children?: TableColumns[];
children?: TableColumns<T, V>[];
ellipsis?: boolean;
render?: (
text: string,
keyName: string,
rowData: { [key: string]: any },
rowNumber: number,
columnNumber: number,
) => void;
render?: (text: V, keyName: V, rowData: T, rowNumber: number, columnNumber: number) => React.ReactNode;
style?: React.CSSProperties;
[key: string]: any;
};

export interface TableProps extends IProps, Omit<HTMLDivProps, 'title'> {
export interface TableProps<T extends { [key: string]: V }, V> extends IProps, Omit<HTMLDivProps, 'title'> {
prefixCls?: string;
columns?: TableColumns[];
data?: Record<string, string | number | JSX.Element | boolean>[];
columns?: TableColumns<T, V>[];
data?: Array<T>;
title?: React.ReactNode;
footer?: React.ReactNode;
bordered?: boolean;
Expand All @@ -36,7 +30,7 @@ export interface TableProps extends IProps, Omit<HTMLDivProps, 'title'> {
evn: React.MouseEvent<HTMLTableCellElement>,
) => void | React.ReactNode;
onCellHead?: (
data: TableColumns,
data: TableColumns<T, V>,
rowNum: number,
colNum: number,
evn: React.MouseEvent<HTMLTableCellElement>,
Expand All @@ -49,7 +43,7 @@ export interface ICellOptions {
keyName: string;
}

export default (props: TableProps = {}) => {
export default function Table<T extends { [key: string]: V }, V>(props: TableProps<T, V> = {}) {
const {
prefixCls = 'w-table',
className,
Expand All @@ -67,7 +61,7 @@ export default (props: TableProps = {}) => {

const cls = [prefixCls, className, bordered ? `${prefixCls}-bordered` : null].filter(Boolean).join(' ').trim();
const { header, render, ellipsis } = getLevelItems(columns);
const keys = getAllColumnsKeys(columns);
const keys = getAllColumnsKeys<T>(columns);
return (
<div>
<div style={{ overflowY: 'scroll' }} className={cls} {...other}>
Expand Down Expand Up @@ -122,4 +116,4 @@ export default (props: TableProps = {}) => {
{footer && <div className={`${prefixCls}-footer`}>{footer}</div>}
</div>
);
};
}
30 changes: 15 additions & 15 deletions packages/react-table/src/util.ts
Expand Up @@ -4,8 +4,8 @@ import { TableColumns } from './';
* Get colspan number
* @param {Array} date
*/
function getColspanNum(data: TableColumns[] = [], num = 1) {
let childs: TableColumns[] = [];
function getColspanNum<T>(data: TableColumns<T>[] = [], num = 1) {
let childs: TableColumns<T>[] = [];
for (let i = 0; i < data.length; i += 1) {
if (data[i].children) {
childs = childs.concat(data[i].children || []);
Expand All @@ -21,8 +21,8 @@ function getColspanNum(data: TableColumns[] = [], num = 1) {
* Get rowspan number
* @param {Array} date
*/
function getRowspanNum(data: TableColumns[] = [], child = []) {
let childs: TableColumns[] = [];
function getRowspanNum<T>(data: TableColumns<T>[] = [], child = []) {
let childs: TableColumns<T>[] = [];
for (let i = 0; i < data.length; i += 1) {
if (!data[i].children) {
childs.push(data[i]);
Expand All @@ -33,8 +33,8 @@ function getRowspanNum(data: TableColumns[] = [], child = []) {
return childs;
}

export interface ILevelItems {
header: TableColumns[][];
export interface ILevelItems<T> {
header: TableColumns<T>[][];
ellipsis?: Record<string, boolean>;
render: {
[key: string]: any;
Expand All @@ -45,7 +45,7 @@ export interface ILevelItems {
* JSON Array => Array
* @param {Array} date
*/
export const getLevelItems = (data: TableColumns[], result?: ILevelItems): ILevelItems => {
export function getLevelItems<T>(data: TableColumns<T>[], result?: ILevelItems<T>): ILevelItems<T> {
if (!result) {
result = { header: [], render: {} };
}
Expand All @@ -55,8 +55,8 @@ export const getLevelItems = (data: TableColumns[], result?: ILevelItems): ILeve
if (result && !result.render) {
result.render = {};
}
let child: TableColumns[] = [];
const levelTop: TableColumns[] = [];
let child: TableColumns<T>[] = [];
const levelTop: TableColumns<T>[] = [];
for (let i = 0; i < data.length; i += 1) {
if (data[i].render && data[i].key) {
result.render[data[i].key as string] = data[i].render;
Expand All @@ -68,13 +68,13 @@ export const getLevelItems = (data: TableColumns[], result?: ILevelItems): ILeve
if (result.header.length === 0) {
// Calculation rowspan
if (data[i].children && data[i].children && data[i].children!.length > 0) {
data[i].colSpan = getRowspanNum(data[i].children as TableColumns[]).length;
data[i].colSpan = getRowspanNum(data[i].children as TableColumns<T>[]).length;
}
levelTop.push(data[i]);
}
if (data[i] && data[i].children) {
child = child.concat(
data[i].children!.map((item: TableColumns) => {
data[i].children!.map((item: TableColumns<T>) => {
// Calculation rowspan
if (item.children && item.children.length > 0) {
item.colSpan = getRowspanNum(item.children).length;
Expand All @@ -100,7 +100,7 @@ export const getLevelItems = (data: TableColumns[], result?: ILevelItems): ILeve
if (child && child.length > 0) {
const num = getColspanNum(child);
result.header.push(
child.map((item: TableColumns) => {
child.map((item: TableColumns<T>) => {
if (num === 1) return item;
if (!item.children || (item.children && item.children.length === 0)) {
item.rowSpan = num;
Expand All @@ -111,13 +111,13 @@ export const getLevelItems = (data: TableColumns[], result?: ILevelItems): ILeve
result = getLevelItems(child, result);
}
return result;
};
}

/**
* Get all columns keys
* @param {Array} data
*/
export const getAllColumnsKeys = (data: TableColumns[], keys: any[] = []): string[] => {
export function getAllColumnsKeys<T>(data: TableColumns<T>[], keys: any[] = []): string[] {
for (let i = 0; i < data.length; i += 1) {
if (data[i].children) {
keys = keys.concat(getAllColumnsKeys(data[i].children || []));
Expand All @@ -126,4 +126,4 @@ export const getAllColumnsKeys = (data: TableColumns[], keys: any[] = []): strin
}
}
return keys;
};
}

0 comments on commit 7e25a6e

Please sign in to comment.