Commit 37f4d7b9 authored by chenshouchao's avatar chenshouchao

feat: 新增虚拟卡片式列表

parent 7eeecd2b
......@@ -2,7 +2,5 @@
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
}
.itemBox {
/* flex: 1; */
position: relative;
}
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import MyCircularProgress from "@/components/mui/MyCircularProgress";
import style from "./index.module.css";
interface ICardTableProps {
......@@ -10,6 +11,7 @@ interface ICardTableProps {
horizontalSpacing?: number; // 水平方向的间隔
verticalSpacing?: number; // 垂直方向的间隔
renderBefore?: any;
loading?: boolean;
}
const CardTable = (props: ICardTableProps) => {
......@@ -22,6 +24,7 @@ const CardTable = (props: ICardTableProps) => {
verticalSpacing = 20,
itemMinWidth,
renderBefore,
loading = false,
} = props;
const [numberOfColumns, setNumberOfColumns] = useState(3);
......@@ -61,6 +64,7 @@ const CardTable = (props: ICardTableProps) => {
}}
ref={tableBoxRef}
>
<MyCircularProgress loading={loading} />
{renderBefore && renderBefore() && (
<div
className={style.itemBox}
......
.tableBox {
display: flex;
justify-content: flex-start;
flex-wrap: wrap;
height: 100%;
position: relative;
}
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
import VirtuallyList from "../VirtuallyList";
import style from "./index.module.scss";
interface IVrituallyCardTableProps {
data: Array<any>; // 列表数据
renderItem: any; // 单个卡片的渲染函数 这里面的元素的boxSizing属性最好是"border-box",
rowHeight: number; // 行高 这个属性的高度最好是itemHeight + verticalSpacing
itemMinWidth?: number; // 单个卡片的最小宽度,有这个参数时numberOfColumns参数失效,效果为根据屏幕大小和单个卡片的最小宽度来适配每行渲染个数
tableKey?: string; // 表格数据的key
numberOfColumns?: number; // 列数 每行渲染几个
horizontalSpacing?: number; // 水平方向的间隔
verticalSpacing?: number; // 垂直方向的间隔
loading?: boolean;
}
const VrituallyCardTable = (props: IVrituallyCardTableProps) => {
const {
data,
renderItem,
tableKey = "id",
rowHeight,
numberOfColumns: propsNumberOfColumns = 3,
horizontalSpacing = 20,
verticalSpacing = 20,
itemMinWidth,
loading = false,
} = props;
const [numberOfColumns, setNumberOfColumns] = useState(3);
const tableBoxRef: any = useRef(null);
const getNumberOfColumns = useCallback(() => {
if (itemMinWidth) {
const boxWidth = tableBoxRef?.current?.offsetWidth;
if (boxWidth) {
setNumberOfColumns(Math.floor(boxWidth / itemMinWidth));
} else {
setNumberOfColumns(propsNumberOfColumns);
}
} else {
setNumberOfColumns(propsNumberOfColumns);
}
}, [itemMinWidth, propsNumberOfColumns]);
useEffect(() => {
getNumberOfColumns();
}, [getNumberOfColumns]);
const boxWidth = useMemo(() => {
return `${100 / numberOfColumns}%`;
}, [numberOfColumns]);
window.onresize = () => {
getNumberOfColumns();
};
const listData = useMemo(() => {
let resData: any = [[]];
data.forEach((item) => {
if (resData[resData.length - 1].length >= numberOfColumns) {
resData.push([item]);
} else {
resData[resData.length - 1].push(item);
}
});
return resData;
}, [numberOfColumns, data]);
const renderRow = ({
index,
isScrolling,
isVisible,
key,
parent,
style,
}: any) => {
return (
<div key={key} style={style}>
<div
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
boxSizing: "border-box",
height: "100%",
}}
>
{listData[index].map((item: any, index: number) => {
return (
<div
className={style.itemBox}
key={item[tableKey] ? item[tableKey] : index}
style={{
width: boxWidth,
paddingLeft: `${horizontalSpacing / 2}px`,
paddingRight: `${horizontalSpacing / 2}px`,
paddingBottom: `${verticalSpacing}px`,
boxSizing: "border-box",
}}
>
{renderItem(item, index)}
</div>
);
})}
</div>
</div>
);
};
return (
<div
className={style.tableBox}
style={{
marginLeft: `-${horizontalSpacing / 2}px`,
marginRight: `-${horizontalSpacing / 2}px`,
width: `calc(100% + ${horizontalSpacing}px)`,
}}
ref={tableBoxRef}
>
<VirtuallyList
list={listData}
renderRow={renderRow}
rowHeight={rowHeight}
loading={loading}
></VirtuallyList>
</div>
);
};
export default VrituallyCardTable;
......@@ -390,7 +390,7 @@ const ParameterSetting = (props: IParameterSettingProps) => {
</MyTooltip>
);
},
[handleParameterChange, cpuList, gpuList]
[handleParameterChange, cpuList, gpuList, cpuLoading, gpuLoading]
);
// 输入参数
......
import CardTable from "@/components/CommonComponents/CardTable";
import VrituallyCardTable from "@/components/CommonComponents/VrituallyCardTable";
const CardTableDemo = () => {
const list = [
......@@ -44,12 +45,28 @@ const CardTableDemo = () => {
];
const renderItem = (item: any) => {
return (
<div style={{ border: "1px solid red", height: "200px" }}>{item.id}</div>
<div
style={{
border: "1px solid red",
height: "200px",
boxSizing: "border-box",
}}
>
{item.id}
</div>
);
};
return (
<div>
CardTableDemo
<div style={{ height: "600px" }}>
<VrituallyCardTable
data={list}
renderItem={renderItem}
numberOfColumns={4}
rowHeight={220}
></VrituallyCardTable>
</div>
<CardTable
data={list}
renderItem={renderItem}
......
......@@ -20,7 +20,7 @@ const Demo = () => {
},
{
value: "cardTable",
label: "cardTable",
label: "cardTable/virtuallyCardTable",
},
{
value: "iconfont",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment