JSFiddle - React, Tailwind, and code Playground

by Michael Prosser

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>
<div id="calendar"></div>

CSS

#calendar{
  font-family:helvetica;
  padding-bottom: 100px;
}
#calendar>table{
  border-spacing: 2px;
  border: none;
  width: 100%;
}
#calendar>table>tbody.days-of-week{
  
}
#calendar>table>tbody.days-of-week>tr>th{
  background-color:#eee;
  padding:5px;
  font-weight: bold;
  font-size: 12px;
  width: calc(100% / 7);
  border: solid 1px #ccc;
}
#calendar>table tr>td{
  background-color:#fff;
  padding:5px;
  font-size: 12px;
  width: calc(100% / 7);
  border: solid 1px #eee;
  height: 70px;
  vertical-align: top;
  position:relative;
  overflow:visible;
  cursor: pointer;
}
#calendar>table tr>td:hover{
  border-color: #a5d3f7;
}
#calendar>table tr>td.selected{
  background-color: aliceblue;
  border-color: #a5d3f7;
}
#calendar>table tr>td>div.calendar-events{
  margin-top:10px;
}
#calendar>table tr>td>div.calendar-events:before{
  position:relative;
  content: "";
  display:block;
  height:6px;
  border-radius: 3px;
  background-color: #ccc;
  margin-left:15px;
  margin-right:5px;
}
#calendar>table tr>td>div.calendar-events:after{
  position:relative;
  content: "";
  display:block;
  height:6px;
  border-radius: 3px;
  background-color: #ccc;
  margin-top:10px;
  margin-left:15px;
  margin-right:5px;
}
#calendar>table tr>td>div.calendar-events:empty:before{
  display:none;
}
#calendar>table tr>td>div.calendar-events:empty:after{
  display:none;
}
#calendar .ui-day{
  position: absolute;
    z-index: 999;
    background-color: aliceblue;
    padding: 10px;
    width: 240px;
    border: solid 1px #a5d3f7;
    box-shadow: 1px 1px 2px 0px rgb(0 0 0 / 20%);
    top: 100%;
    left: 0px;
}

#calendar .ui-day.floatBackLeft{
  left: initial;
  right: 0px;
}
#calendar .ui-day>h1{
  font-size: 12px;
  text-align:center;
  padding: 4px;
  background-color:#fff;
  margin:0px;
  margin-left:-10px;
  margin-right:-10px;
  margin-top:-10px;
}
#calendar .ui-day>h3{
  font-size: 10px;
  text-align:center;
  padding: 4px;
  background-color:#559ed8;
  margin:0px;
 ...

JavaScript

function Calendar(elem, year, month){

	
	
	var t = this;
  
  t.month_labels = ["January","February","March","April","May","June","July","August","September","October","November","December"];
	
	t.getDay = function(date) { // get day number from 0 (monday) to 6 (sunday)
      let day = date.getDay();
      if (day == 0) day = 7; // make Sunday (0) the last day
      return day - 1;
    }
	t.year = year;
	t.mon = month - 1; // months in JS are 0..11, not 1..12
    t.d = new Date(t.year, t.mon);



    t.table = '<table><tbody class="days-of-week"><tr><th>Monday</th><th>Tuesday</th><th>Wednesday</th><th>Thursday</th><th>Friday</th><th>Saturday</th><th>Sunday</th></tr></tbody><tr>';

      // spaces for the first row
      // from Monday till the first day of the month
      // * * * 1  2  3  4
      for (let i = 0; i < t.getDay(t.d); i++) {
        t.table += '<td></td>';
      }

      // <td> with actual dates
      while (t.d.getMonth() == t.mon) {
        t.table += '<td data-date-day="' + t.d.getDate() + '" data-date-month="' + t.mon + '" data-date-year="' + t.year + '">' + t.d.getDate() + '<div class="calendar-events"></div></td>';

        if (t.getDay(t.d) % 7 == 6) { // sunday, last day of week - newline
          t.table += '</tr><tr>';
        }

        t.d.setDate(t.d.getDate() + 1);
      }

      // add spaces after last days of month for the last row
      // 29 30 31 * * * *
      if (t.getDay(t.d) != 0) {
        for (let i = t.getDay(t.d); i < 7; i++) {
          t.table += '<td></td>';
        }
      }

      // close the table
      t.table += '</tr></table>';
     

      elem.innerHTML = '<h1>' + t.month_labels[t.d.getMonth()] + '</h1>' + t.table;
      
      
      
      $(elem).find('td').click(function(){
      
      	t.loadDay($(this),$(this).attr('data-date-year'),$(this).attr('data-date-month'),$(this).attr('data-date-day'));
      
      });
      
      t.prePopulateDay = function(d){
      
      var element =...