成品如下
组件分为左侧标题、右侧数据、底部时间轴
1.左右布局使用flex 左侧固定宽度,右侧自适应
2.右侧使用table、tr、td 搭建出架子 会议任务使用 absolute 定位,计算出相对位置,和宽度
3.垂直居中语法
top: 50%;
transform: translate(0, -50%);
import React from 'react';
import styles from './style.less';
const timeInterval = (start, end) => {
const t1 = new Date(`2017-1-1 ${start}`);
const t2 = new Date(`2017-1-1 ${end}`);
const interval = t2.getTime() - t1.getTime();
if (interval < 0) return 0;
return (interval / 1000 / 60 / 60).toFixed(2)
}
const MeetingCard = (props) => {
const weekRows = [
{ key: 'Monday' },
{ key: 'Tuesday' },
{ key: 'Wednesday' },
{ key: 'Thursday' },
{ key: 'Friday' },
{ key: 'Saturday' },
{ key: 'Sunday' },
];
const { dataSource = [
{
day: 'Monday',
data: [{
key: 1,
title: '123',
start: '09:00:00',
end: '10:00:00'
}],
},
{
day: 'Friday',
data: [{
key: 1,
title: '123',
start: '11:00:00',
end: '13:00:00'
}],
}
] } = props;
return (
<div className={styles.meetingCard}>
<div className={styles.rowHead}>
<div className={styles.week}>星期一</div>
<div className={styles.week}>星期二</div>
<div className={styles.week}>星期三</div>
<div className={styles.week}>星期四</div>
<div className={styles.week}>星期五</div>
<div className={styles.week}>星期六</div>
<div className={styles.week}>星期日</div>
</div>
<div className={styles.rowBody} >
<table>
{weekRows.map(weekday => (
<tr key={weekday.key}>
<td></td><td></td><td></td>
<td></td><td></td><td></td>
<td></td><td></td><td></td>
<td></td><td></td><td></td>
{dataSource.find(data => data.day === weekday.key) ?
dataSource.find(data => data.day === weekday.key).data.map(
(task) => (
<div key={task.key} className={styles.meetingSpan}
style={{
width: `${100 / 12 * timeInterval(task.start, task.end)}%`,
left: `${100 / 12 * timeInterval('08:00:00', task.start)}%`,
}} />
)
) : <></>}
</tr>
))}
</table>
<div className={styles.timeCard}>
<span className={styles.timeSpan}>8:00</span>
<span className={styles.timeSpan}>10:00</span>
<span className={styles.timeSpan}>12:00</span>
<span className={styles.timeSpan}>14:00</span>
<span className={styles.timeSpan}>16:00</span>
<span className={styles.timeSpan}>18:00</span>
</div>
</div>
</div>
);
};
export default MeetingCard
.meetingCard {
padding: 30px 10px;
display: flex;
.rowHead {
width: 60px;
.week {
width: 60;
height: 32.8px;
font-size: 13px;
line-height: 32.8px;
}
}
.rowBody {
flex: 1;
table {
border-spacing: 0;
border-collapse: collapse;
display: table;
width: 100%;
tr {
position: relative;
display: inline-table;
width: 100%;
td {
height: 32px;
padding: 0px;
display: table-cell;
vertical-align: inherit;
border-left: 1px solid #e7ecef;
border-bottom: 1px solid #e7ecef;
}
.meetingSpan {
top: 50%;
transform: translate(0, -50%);
position: absolute;
height: 16px;
background-color: #189;
border-radius: 4px;
}
}
}
.timeCard {
height: 32px;
.timeSpan {
display: inline-table;
width: calc(100% / 6);
line-height: 32px;
}
}
}
}