-
Notifications
You must be signed in to change notification settings - Fork 18
/
index.tsx
114 lines (104 loc) · 2.82 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import { Interpolation, Theme } from '@emotion/react';
import React, { useCallback } from 'react';
import CSS from 'csstype';
import { style } from './style';
import { normalizeUnit } from '../utils/cssUtil';
export interface AutoGridOption extends React.HTMLProps<HTMLDivElement> {
children?: React.ReactNode;
// 容器的样式
containerStyle?: Interpolation<Theme>;
// 元素之间空白槽的宽度
gap?: CSS.Property.Width;
// 列的数目
cols?: number;
// 是否显示正方形
isSquare?: boolean;
// 元素容器的样式
itemStyle?: Interpolation<Theme>;
}
/**
* 自动化生成表格
* @param props
*/
export function AutoGrid(props: AutoGridOption) {
let {
children,
cols = 1,
gap = 0,
isSquare = false,
itemStyle,
containerStyle,
...extra
} = props;
// 规范化数字单位
cols = +cols;
gap = normalizeUnit(gap) as string;
// 获取表格数据
const getGridData = useCallback(() => {
// 生成一个能创建表格的二维数组
let list: Array<React.ReactNode[]> = [];
React.Children.forEach(children, (child) => {
if (child !== null) {
if (list.length === 0 || list[list.length - 1].length >= cols) {
list.push([]);
}
list[list.length - 1].push(child);
}
});
return list;
}, [children]);
// 元素的最终样式
const finalItemBoxStyle: Interpolation<Theme> = [
style.itemBoxStyle,
{
marginRight: gap,
width: `calc((100% - ${cols - 1} * ${gap}) / ${cols})`,
},
];
/**
* 显示内容
*/
const showContent = () => {
const gridData = getGridData();
return gridData.map((row, rowIndex) => {
// 每行的槽样式,最后一行没有
let finalRowStyle: Interpolation<Theme> = [style.rowStyle];
if (rowIndex !== gridData.length - 1) {
// 最后一行不需要marginBottom
finalRowStyle.push({
marginBottom: gap,
});
}
return (
<div key={rowIndex} css={finalRowStyle}>
{row.map((item, colIndex) => {
let finalCss: Interpolation<Theme> = [...finalItemBoxStyle];
// 如果是方形的,加入方形相关的样式
if (isSquare) {
finalCss.push(style.itemBoxSquare);
}
finalCss.push(itemStyle);
if (isSquare) {
return (
<div css={finalCss} key={colIndex}>
<div css={style.itemInnerStyle}>{item}</div>
</div>
);
} else {
return (
<div css={finalItemBoxStyle} key={colIndex}>
{item}
</div>
);
}
})}
</div>
);
});
};
return (
<div {...extra} css={[containerStyle]}>
{showContent()}
</div>
);
}