JSFiddle - React, Tailwind, and code Playground
HTML
<div class="calendar jsCalendar" data-localized_date='{"days":{"names":{"min":["Sun","Mon","Tue","Wed","Thu","Fri","Sat"]}},"months":{"names":{"long":["January","February","March","April","May","June","July","August","September","October","November","December"]}}}'></div>
CSS
/* @group calendar */
body {font-family: Helvetica, Arial, sans-serif;}
.hidden {display:none;}
.noTransition {-webkit-transition:none !important;}
.calendar {-webkit-user-select:none; max-width:400px; margin-bottom:20px;}
.calButtonBar {overflow:hidden; -webkit-user-select:none; margin:0 0 10px; padding:0;}
.calButtonBar li {width:25%; list-style-type:none; float:left; overflow:hidden; text-align:center;}
.calPrevious a, .calNext a {display:block; width:28px; height:28px; text-decoration:none; color:#333; font-weight:bold;}
.calPrevious a {float:right;}
.calNext a {float:left;}
.calButtonBar .calMonth {font-weight:bold; font-size:16px; padding-top:2px; width:50%; color:#333;}
.calGrid {position:relative;}
.calGrid table {border-spacing:0; border-collapse:collapse; width:100%;}
.turnup, .turndown {position:absolute; top:0; left:0; background-color:#fff;}
.calGrid th {width:14%; height:24px; color:#333;}
.calGrid td {width:14%; border:solid 1px #ccc; padding:0;}
.calGrid td a {display:block; width:100%; height:16px; padding:10px 0; text-align:center; color:#444; -webkit-tap-highlight-color:rgba(0,0,0,0); text-decoration:none; transition-property:background-color, color; transition-duration:200ms; -webkit-transition-property:background-color, color; -webkit-transition-duration:200ms; -moz-transition-property:background-color, color; -moz-transition-duration:200ms; }
.calGrid td a.inactive {color:#f1f1f2;}
.calGrid td a.today {}
.calGrid td a.startDate, .calGrid td a.endDate {color:#fff; background-color:#444;}
.calGrid td a.betweenDates {background-color:#ccc;}
.calGrid tr.first td {border-top:none 0;}
.calGrid tr.last td {border-bottom:none 0;}
/* @group animation */
.in, .out {-webkit-animation-duration:250ms; -webkit-animation-fill-mode:forwards; -webkit-animation-timing-function:ease-in-out;}
.in {z-index:10;}
.out {z-index:0;}
/* @group page turn animation */
.turnup, .turndown {-webkit-animation-duration:400ms; -webkit-transform-origin: 50% 0%;...
JavaScript
$(".jsCalendar").bind("startDateChanged", function() {
$(this).data("startdate");
}).bind("endDateChanged", function() {
$(this).data("enddate");
});
(function() {
$(document).ready(function() {
var $calendars = $(".jsCalendar");
for (var i = 0, maxI = $calendars.length; i < maxI; i++) {
var calendar = new Calendar();
calendar.ready($calendars.eq(i));
}
});
function Calendar() {
var self = this,
$calendar,
$previous,
$next,
$month,
$weekdays,
$days,
$rows,
startDate,
endDate,
currentMonth,
today,
minDate,
dateInfo,
singleDate,
firstDayOfWeek = 0,
tap = 'click',
noAnimEnd = "noAnimationEnd",
startDateString = "startDate",
endDateString = "endDate",
setDate = function (type, value) {
value && value.clearTime && value.clearTime();
if (type == startDateString) {
startDate = value;
} else {
endDate = value;
}
drawSelection();
$calendar.data(type.toLowerCase(), !value ? "" : value.toString());
$calendar.trigger(type + "Changed");
},
dateSelected = function (evt) {
evt.preventDefault();
var $this = $(this);
if ($this.hasClass("inactive") || ($this.text().length == 0)) {
return;
}
var selectedDate = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), parseInt($this.text()));
if (singleDate) {
setDate(startDateString, !startDate || (selectedDate.getTime() != startDate.getTime()) ? selectedDate : null);
return;
}
if (!startDate) {
if (!endDate) {
...