@uplink-protocol/calendar-controller
Version:
Flexible calendar API supporting both calendar and date-picker integrations for any JavaScript framework or library
236 lines (218 loc) • 12.5 kB
HTML
<html lang="en">
<head> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>Date Picker Example</title>
<script src="https://cdn.tailwindcss.com"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.0/css/all.min.css">
<link rel="stylesheet" href="css/styles.css">
<link rel="stylesheet" href="css/calendar-theme.css">
<script> // Custom Tailwind configuration
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3b82f6',
'primary-light': '#eff6ff'
}
}
}
}
</script> <style>
/* Custom styles for better transitions */
.calendar-popup {
transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out;
}
.calendar-popup.hidden {
opacity: 0;
pointer-events: none;
transform: translateY(-10px);
}
/* Override padding to match screenshot */
.calendar-popup {
padding: 1.5rem;
}
/* Override the calendar layout to match screenshot */
#calendar {
gap: 0.5rem;
}
/* Button appearance cleanup */
#monthYearSelector {
padding: 0.5rem;
border-radius: 0.25rem;
}
/* Make the popup responsive */
.calendar-popup {
width: 100%;
max-width: 620px;
min-width: min(380px, 100vw - 32px); /* Responsive with minimum width */
}
</style>
</head>
<body class="container mx-auto max-w-4xl p-6 font-sans">
<h1 class="text-3xl font-bold mb-6">Date Picker Example</h1>
<!-- Date Input Field with Trigger Button -->
<div class="mb-6 relative">
<div class="flex items-center">
<div class="relative flex-grow"> <input
type="text"
id="dateInput"
class="date-input w-full px-4 py-2 border rounded focus:ring focus:border-primary"
placeholder="Select a date..."
autocomplete="off"
aria-label="Date input field"
aria-controls="calendarPopup"
>
<button
id="calendarTrigger"
class="absolute right-2 top-1/2 transform -translate-y-1/2 text-gray-400 hover:text-gray-600"
aria-label="Open calendar"
>
<i class="fa-solid fa-calendar"></i>
</button>
</div>
</div>
</div>
<div class="mb-6 space-x-2">
<button id="toggleMode" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded transition">
<i class="fa-solid fa-calendar-days mr-2"></i>
<span id="toggleModeText">Single Date</span>
</button>
<button id="clearSelection" class="px-4 py-2 bg-gray-100 hover:bg-gray-200 rounded transition">
<i class="fa-solid fa-eraser mr-2"></i>Clear Selection
</button>
</div>
<!-- Calendar Popup -->
<div id="calendarPopup" class="calendar-popup hidden absolute z-50 bg-white rounded-lg shadow-xl p-4" role="dialog" aria-modal="true" aria-label="Date picker calendar">
<div class="flex">
<!-- Sidebar for Quick Date Selection -->
<div id="datepickerSidebar" class="w-52 pr-4 border-r border-gray-200">
<div class="flex mb-4">
<button id="singleMonthMode" class="flex-1 py-1.5 px-2 text-center rounded-l-lg font-medium bg-primary text-white" aria-pressed="true" title="Single month view">
<i class="fa-regular fa-calendar mr-2"></i>Month
</button>
<button id="doubleMonthMode" class="flex-1 py-1.5 px-2 text-center rounded-r-lg font-medium hover:bg-gray-100" aria-pressed="false" title="Double month view">
<i class="fa-solid fa-calendar-days mr-2"></i>Range
</button>
</div>
<h3 class="text-sm font-semibold text-gray-600 mb-2 uppercase tracking-wider">Quick Select</h3>
<div class="space-y-2">
<button id="selectToday" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Today
</button>
<button id="selectTomorrow" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Tomorrow
</button>
<button id="selectNextWeek" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Next Week
</button>
<button id="selectNextMonth" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Next Month
</button>
</div>
<h3 class="text-sm font-semibold text-gray-600 mt-4 mb-2 uppercase tracking-wider">Date Range</h3>
<div class="space-y-2">
<button id="selectThisWeek" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
This Week
</button>
<button id="selectThisMonth" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
This Month
</button>
<button id="selectNextWeekRange" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Next 7 Days
</button>
<button id="selectNext30Days" class="w-full py-1.5 px-3 text-sm text-left rounded hover:bg-gray-100 transition">
Next 30 Days
</button>
</div>
</div>
<!-- Main Calendar Views -->
<div id="calendarViewContainer" class="flex-1 pl-4">
<!-- Calendar Header with Navigation -->
<div class="flex justify-between items-center mb-6">
<div class="flex space-x-1">
<button id="prevYear" class="w-8 h-8 flex items-center justify-center hover:bg-gray-100 rounded transition" aria-label="Previous year">
<i class="fa-solid fa-angles-left text-gray-500"></i>
</button>
<button id="prevMonth" class="w-8 h-8 flex items-center justify-center hover:bg-gray-100 rounded transition" aria-label="Previous month">
<i class="fa-solid fa-angle-left text-gray-500"></i>
</button>
</div>
<!-- Month/Year Selector -->
<div class="relative">
<button id="monthYearSelector" class="text-lg font-medium hover:bg-gray-100 flex items-center px-3 py-1 rounded" aria-haspopup="true" title="Select month and year">
<span id="currentMonthYear"></span>
<i class="fa-solid fa-chevron-down ml-2 text-xs text-gray-500"></i>
</button>
<!-- Month/Year Dropdown (Hidden by Default) -->
<div id="monthYearDropdown" class="absolute left-0 top-full mt-1 bg-white shadow-lg rounded-lg p-4 hidden z-10 w-[280px]">
<div class="flex border-b pb-2 mb-2">
<button id="viewModeMonths" class="flex-1 py-1 px-2 text-center rounded font-medium bg-primary text-white" aria-pressed="true">Months</button>
<button id="viewModeYears" class="flex-1 py-1 px-2 text-center rounded font-medium hover:bg-gray-100" aria-pressed="false">Years</button>
</div>
<div id="monthsList" class="grid grid-cols-3 gap-2"></div>
<div id="yearsList" class="grid grid-cols-3 gap-2 hidden"></div>
</div>
</div>
<div class="flex space-x-1">
<button id="nextMonth" class="w-8 h-8 flex items-center justify-center hover:bg-gray-100 rounded transition" aria-label="Next month">
<i class="fa-solid fa-angle-right text-gray-500"></i>
</button>
<button id="nextYear" class="w-8 h-8 flex items-center justify-center hover:bg-gray-100 rounded transition" aria-label="Next year">
<i class="fa-solid fa-angles-right text-gray-500"></i>
</button>
</div>
</div>
<!-- Single Month View -->
<div id="singleMonthView" class="calendar-view">
<div id="weekdays" class="grid grid-cols-7 mb-2"></div>
<div id="calendar" class="grid grid-cols-7 gap-1"></div>
</div>
<!-- Double Month View -->
<div id="doubleMonthView" class="calendar-view hidden">
<div class="flex space-x-4">
<div class="flex-1">
<h3 id="firstMonthTitle" class="text-center mb-2 font-medium"></h3>
<div id="firstMonthWeekdays" class="grid grid-cols-7 mb-2"></div>
<div id="firstMonthCalendar" class="grid grid-cols-7 gap-1"></div>
</div>
<div class="flex-1">
<h3 id="secondMonthTitle" class="text-center mb-2 font-medium"></h3>
<div id="secondMonthWeekdays" class="grid grid-cols-7 mb-2"></div>
<div id="secondMonthCalendar" class="grid grid-cols-7 gap-1"></div>
</div>
</div>
</div>
<!-- Month View (All Months) -->
<div id="monthsView" class="calendar-view hidden">
<h3 class="text-center mb-4 text-lg font-medium">Select a Month</h3>
<div id="monthsGrid" class="grid grid-cols-3 gap-3"></div>
</div>
<!-- Year View (Range of Years) -->
<div id="yearsView" class="calendar-view hidden">
<h3 class="text-center mb-4 text-lg font-medium">Select a Year</h3>
<div id="yearsGrid" class="grid grid-cols-5 gap-3"></div>
</div>
<!-- Footer Actions --> <div class="mt-6 flex justify-end space-x-2">
<button id="todayButton" class="px-3 py-1.5 text-sm font-medium text-primary hover:bg-primary-light rounded transition">
Today
</button>
<button id="clearSelectionBtn" class="px-3 py-1.5 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded transition">
Clear
</button>
<button id="closeButton" class="px-3 py-1.5 text-sm font-medium text-gray-600 hover:bg-gray-100 rounded transition">
Close
</button>
</div>
</div>
</div>
</div>
<div class="mt-6 text-lg">
<div id="selectedDate" class="mb-2"></div>
<div id="selectedRange"></div>
</div>
<script src="js/controller.js" type="module"></script>
<script src="js/view.js" type="module"></script>
<script src="js/main.js" type="module"></script>
</body>
</html>