我要构建一个日历Web应用程序。为此,我需要一个周视图,以显示该周的所有事件。我要参考的是Google日历,因为该设计是现代的,而且结构非常好。所以对于应用程序,我将React和redux用作状态管理。但是我似乎遇到了一个困扰我一段时间的问题。使滚动条可以用作Google日历周视图中的滚动条(即垂直滚动条)。
重要组成部分: 最低级别的组件(名称:身体)
import React from 'react';
import { withStyles, withWidth, Typography } from '@material-ui/core';
import moment from 'moment';
import {
weekHeadMaxWidthXl,
weekHeadMinWidthXl,
weekHeadMaxWidthLg,
weekHeadMinWidthLg,
weekHeadMaxWidthMd,
weekHeadMinWidthMd,
weekHeadMaxWidthSm,
weekHeadMinWidthSm,
weekHeadMaxWidthXs,
weekHeadMinWidthXs,
weekHeadHightXl
} from '../../../util/dimension';
const style = theme => ({
bodyContainer: {
display: "flex",
flexDirection: "row",
overflow: "auto",
width: "100%",
},
hourContainer: {
display: "flex",
flexDirection: "column",
marginTop: 1,
[theme.breakpoints.only('xl')]: {
maxWidth: weekHeadMaxWidthXl,
minWidth: weekHeadMinWidthXl,
width: "100%",
},
[theme.breakpoints.only('lg')]: {
maxWidth: weekHeadMaxWidthLg,
minWidth: weekHeadMinWidthLg,
width: "100%",
},
[theme.breakpoints.only('md')]: {
maxWidth: weekHeadMaxWidthMd,
minWidth: weekHeadMinWidthMd,
width: "100%",
},
[theme.breakpoints.only('sm')]: {
maxWidth: weekHeadMaxWidthSm,
minWidth: weekHeadMinWidthSm,
width: "100%",
backgroundColor: "#"
},
[theme.breakpoints.only('xs')]: {
maxWidth: weekHeadMaxWidthXs,
minWidth: weekHeadMinWidthXs,
width: "100%",
},
},
hour: {
[theme.breakpoints.only('xl')]: {
maxHeight: "50px",
height: "46px",
minHeight: "44px",
},
[theme.breakpoints.only('lg')]: {
maxHeight: "50px",
height: "46px",
minHeight: "44px",
},
[theme.breakpoints.only('md')]: {
maxHeight: "50px",
height: "46px",
minHeight: "44px",
},
[theme.breakpoints.only('sm')]: {
maxHeight: "50px",
height: "46px",
minHeight: "44px",
},
borderBottom: "solid 1px #e7e7e7",
borderLeft: "solid 1px #e7e7e7",
backgroundColor: "#FFF"
},
offset: {
display: "flex",
justifyContent: "center",
paddingTop: 10,
backgroundColor: "#FFF",
borderBottom: "solid 1px #e7e7e7",
borderTop: "solid 1px #e7e7e7",
[theme.breakpoints.only('xl')]: {
maxWidth: 55,
minWidth: 50,
width: 53,
},
[theme.breakpoints.only('lg')]: {
maxWidth: 53,
minWidth: 47,
width: 50,
},
[theme.breakpoints.only('md')]: {
maxWidth: 50,
minWidth: 43,
width: 47,
},
[theme.breakpoints.only('sm')]: {
maxWidth: 47,
minWidth: 38,
width: 43,
},
[theme.breakpoints.only('xs')]: {
maxWidth: 47,
minWidth: 43,
width: 38,
},
},
});
const body = props => {
const { classes } = props;
let days = [];
const getHours = () => {
let hours = [];
for (let i = 0; i < 24; i++) {
hours.push(<div key={"hours " + i} className={classes.hour}>
<Typography> {i} </Typography>
</div>)
}
return hours
}
days.push(<div key="offset" className={classes.offset}></div>)
for (let j = 0; j < 7; j++) {
days.push(<div key={"days " + j} className={classes.hourContainer}>
{getHours()}
</div>)
}
return (<div className={classes.bodyContainer}>
{days}
</div>);
}
export default withWidth()(withStyles(style)(body));
组件实现主体。 (名称:日历)
import React from 'react';
import { withStyles, Typography, TableCell } from '@material-ui/core';
import withWidth, { isWidthUp } from '@material-ui/core/withWidth';
import { connect } from 'react-redux'
import { changeWindowSizeAction } from '../../redux/actions/settingsActions';
import Month from './views/month/month';
import MonthOffset from './views/month/offset';
import WeekHead from './views/week/head';
import WeekBody from './views/week/body';
const styles = theme => ({
week: {
height: "100vh",
},
weekBody: {
height: "100vh",
overflowY: "auto"
}
});
class Calendar extends React.Component {
getFullDayBookings = bookings => {
return bookings.filter(B => B.allDay);
}
generateComponent = (variant, props) => {
switch (variant) {
case "month":
return <Month onDayClick={props.onDayClick} onBookingClick={props.onBookingClick} dateNr={props.nr} day={props.day} bookings={this.formatBookings()} />
case "week":
return this.generateWeek()
case "day":
return null;
case "agenda":
return null;
case "offset":
return <MonthOffset dateNr={props.nr} variant="month" />
default:
return (
<TableCell className={props.classes.monthCell}>
</TableCell>
);
}
}
generateWeek = () => {
return (<div className={this.props.classes.week}>
<WeekHead bookings={this.formatBookings().filter(E => E.allDay)} />
<div className={this.props.classes.weekBody}>
<WeekBody />
</div>
</div>)
}
formatBookings = () => {
if (this.props.bookings.length > 0) {
return this.filterBookings(this.props.bookings, this.props.bookingFilter)
} else {
return [];
}
}
filterBookings = (bookings, filter) => {
if (bookings.length > 0) {
let notToRender = Object.keys(filter).filter(F => {
if (!filter[F]) {
return F;
}
});
return bookings.filter(E => {
if (notToRender.length > 0) {
if (notToRender.indexOf(E.room) === -1) {
return E
}
} else {
return E;
}
});
} else {
return []
}
}
render() {
return (this.generateComponent(this.props.variant, this.props))
}
}
const mapDispatchToProps = dispatch => {
return {
changeWindowSize: wSize => (dispatch(changeWindowSizeAction(wSize)))
}
}
const mapStateToProps = state => {
return {
windowSize: state.settings.windowSize,
}
}
export default withWidth()(withStyles(styles)(connect(mapStateToProps, mapDispatchToProps)(Calendar)));
实施日历的组件(名称:星期)
import React from 'react';
import { connect } from 'react-redux';
import Calendar from '../components/calendar/Calendar';
import { withStyles, Typography } from '@material-ui/core';
import moment from 'moment';
const styles = theme => ({
});
const testEvents = [
{ "title": "Test - NotAllDay", "id": 1, "room": "office" },
{ "title": "Test - NotAllDay", "id": 2, "room": "office" },
{ "title": "Test - Cafe", "id": 3, "room": "cafe", "allDay": true, "startDate": moment(), "endDate": moment().add(2, "days") },
{ "title": "Test - NotAllDay", "id": 11, "room": "office" }]
class Week extends React.Component {
render(){
return <Calendar variant="week" bookings={testEvents} bookingFilter={this.props.filter}/>
}
}
const mapStateToPops = state => ({
currentDate: state.settings.calendarState,
filter: state.settings.roomsRender,
});
const mapDispatchToProps = dispatch => ({
});
export default withStyles(styles)(connect(mapStateToPops, mapDispatchToProps)(Week));
最后一个组件实施周
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { withStyles } from '@material-ui/core/styles/';
import classNames from 'classnames';
import PropTypes from 'prop-types';
import Banner from '../containers/Banner';
import Sidebar from '../containers/Sidebar';
import Month from '../containers/Month';
import Week from '../containers/Week';
import './styles.css';
const styles = theme => ({
DisplayContainer: {
flex: 1,
height: "100vh"
},
content: {
height: "100%",
flex: 3,
flexGrow: 1,
backgroundColor: theme.palette.background.default,
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.sharp,
duration: theme.transitions.duration.leavingScreen,
}),
},
'content-left': {
marginLeft: 0,
},
contentShift: {
transition: theme.transitions.create('margin', {
easing: theme.transitions.easing.easeOut,
duration: theme.transitions.duration.enteringScreen,
}),
},
'contentShift-left': {
marginLeft: 240,
},
});
class Overview extends Component {
calendarView = () => {
switch (this.props.calendarType) {
case "month":
return <Month />
case "week":
return <Week />
case "day":
return <div></div>
case "agenda":
return <div></div>
default:
return <div></div>
}
}
render() {
const { classes, theme } = this.props;
return (
<div className={classes.DisplayContainer}>
<div className="Banner">
<Banner />
</div>
<div>
<Sidebar />
</div>
<main className={classNames(classes.content, classes[`content-left`], {
[classes.contentShift]: this.props.showMenu,
[classes[`contentShift-left`]]: this.props.showMenu,
})}>
{this.calendarView()}
</main>
</div>
)
}
}
Overview.propTypes ={
classes: PropTypes.object.isRequired,
}
const mapStateToProps = state => {
return {
showMenu: state.settings.showMenu,
calendarType: state.settings.calendarType,
}
}
export default withStyles(styles)(connect(mapStateToProps)(Overview));
“月”视图可以正常工作。它们有一些错误,但是应用程序很久没有完成。所以,是的,如果有人可以指出我的方向或提供一些内部知识,那太好了!
多谢指教!
答案 0 :(得分:1)
这是CSS修复程序:
将此CSS添加到您的应用程序中:
html, #root {
height: 100%
}
.jss2.jss3{
height: calc(100% - 65px);
}
.jss189 {
height: calc(100% - 132px);
}