React

by rew222

HTML

<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<div id="app"></div>

CSS

.calendar-container,
.calendar,
.calendar-header,
td,
tr {
    padding: 0;
    margin: 0;
}

.calendar-container {
    border: 2px solid skyblue;
}

.calendar {
    background-color: white;
    border-spacing: 0;
    border-collapse: collapse;
    width: 100%;
}

.calendar-header {
    border-bottom: 1px dashed skyblue;
    font-size: 1.6em;
}

.calendar-header td {
    border-spacing: 0;
    padding-left: 5px;
}

.day,
.empty-slot,
.week-day {
    text-align: center;
    height: 40px;
}

.week-day {
    font-size: 0.8em;
}

.day {
    font-size: 0.8em;
}

.day {
    cursor: pointer;
    width: 24px;
    height: 24px;
    line-height: 24px;
}

.current-day {
    background-color: #4285f4;
    width: 28px;
    height: 28px;
    line-height: 28px;
    border-radius: 2%;
    color: white;
}
.selected-day {
    background-color:yellow;
    width: 28px;
    height: 28px;
    line-height: 28px;
    border-radius: 2%;
    color: black;
}

.month-popup {
    position: absolute;
    padding: 5px;
    background: white;
    border: 2px solid skyblue;
}

.month-popup div {
    padding: 0.3em;
}

.nav-month {
    position: absolute;
    top: 0.6em;
    font-size: 0.6em;
    right:3px;
}

.prev {
}

.next {
}

.editor-year {
    max-width: 3.6em;
}

.label-month,
.label-year {
    font-size: 0.6em;
}

.label-month {
    cursor: pointer;
}

React

class Calendar extends React.Component{
    state = {
        dateContext: moment(),
        today: moment(),
        showMonthPopup: false,
        showYearPopup: false,
        selectedDay: null
    }

    constructor(props) {
        super(props);
        this.width = props.width || "350px";
        this.style = props.style || {};
        this.style.width = this.width; // add this
    }


    weekdays = moment.weekdays(); //["Sunday", "Monday", "Tuesday", "Wednessday", "Thursday", "Friday", "Saturday"]
    weekdaysShort = moment.weekdaysShort(); // ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
    months = moment.months();
    year = () => {
        return this.state.dateContext.format("Y");
    }
    
    month = () => {
        return this.state.dateContext.format("MMMM");
    }
    daysInMonth = () => {
        return this.state.dateContext.daysInMonth();
    }
    currentDate = () => {
        console.log("currentDate: ", this.state.dateContext.get("date"));
        return this.state.dateContext.get("date");
    }
    currentDay = () => {
        return this.state.dateContext.format("D");
    }

    firstDayOfMonth = () => {
        let dateContext = this.state.dateContext;
        let firstDay = moment(dateContext).startOf('month').format('d'); // Day of week 0...1..5...6
        return firstDay;
    }

    setMonth = (month) => {
        let monthNo = this.months.indexOf(month);
        let dateContext = Object.assign({}, this.state.dateContext);
        dateContext = moment(dateContext).set("month", monthNo);
        this.setState({
            dateContext: dateContext
        });
    }

    nextMonth = () => {
        let dateContext = Object.assign({}, this.state.dateContext);
        dateContext = moment(dateContext).add(1, "month");
        this.setState({
            dateContext: dateContext
        });
        this.props.onNextMonth && this.props.onNextMonth();
    }

    prevMonth = () => {
        let dateContext = Object.assign({},...