kalendly 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +492 -0
- package/dist/core/index.d.mts +181 -0
- package/dist/core/index.d.ts +181 -0
- package/dist/core/index.js +349 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/index.mjs +309 -0
- package/dist/core/index.mjs.map +1 -0
- package/dist/index.d.mts +623 -0
- package/dist/index.d.ts +623 -0
- package/dist/index.js +1445 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1403 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react/index.d.mts +208 -0
- package/dist/react/index.d.ts +208 -0
- package/dist/react/index.js +558 -0
- package/dist/react/index.js.map +1 -0
- package/dist/react/index.mjs +516 -0
- package/dist/react/index.mjs.map +1 -0
- package/dist/react-native/index.d.mts +465 -0
- package/dist/react-native/index.d.ts +465 -0
- package/dist/react-native/index.js +894 -0
- package/dist/react-native/index.js.map +1 -0
- package/dist/react-native/index.mjs +851 -0
- package/dist/react-native/index.mjs.map +1 -0
- package/dist/styles/calendar.css +500 -0
- package/dist/vanilla/index.d.mts +214 -0
- package/dist/vanilla/index.d.ts +214 -0
- package/dist/vanilla/index.js +621 -0
- package/dist/vanilla/index.js.map +1 -0
- package/dist/vanilla/index.mjs +579 -0
- package/dist/vanilla/index.mjs.map +1 -0
- package/dist/vanilla/index.umd.js +604 -0
- package/dist/vanilla/index.umd.js.map +1 -0
- package/dist/vue/index.js +1 -0
- package/dist/vue/index.mjs +439 -0
- package/package.json +161 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("vue"),N=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Y=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];function y(n){return new Date(n.getFullYear(),n.getMonth(),n.getDate(),0,0,0)}function b(n,t){return y(n).getTime()===y(t).getTime()}function S(n){return b(n,new Date)}function _(n,t){const a=new Date().getFullYear(),c=n??a-30,i=t??a+10;return Array.from({length:i-c+1},(g,s)=>c+s)}function v(n,t){const a=y(t);return n.filter(c=>y(new Date(c.date)).getTime()===a.getTime())}function P(n,t){return v(n,t).length>0}function V(n,t,a=[],c=0){const i=new Date(n,t,1),s=new Date(n,t+1,0).getDate();let u=i.getDay();c===1&&(u=u===0?6:u-1);const f=[];let p=1;for(let D=0;D<6;D++){const h=[];for(let m=0;m<7;m++)if(D===0&&m<u)h.push(null);else if(p>s)h.push(null);else{const k=new Date(n,t,p),E=v(a,k);h.push({date:k,isCurrentMonth:!0,isToday:S(k),hasEvents:E.length>0,events:E}),p++}if(f.push(h),p>s&&h.every(m=>m===null))break}return f}function T(n){return n===null?"popup-center-bottom":n<3?"popup-right":n>4?"popup-left":"popup-center-bottom"}function w(n){if(!n)return[];const t=[];return n.isToday&&t.push("schedule--current--exam"),n.hasEvents&&t.push("has--event"),t}function x(n){return`${Y[n.getDay()]} ${n.getDate()}`}function F(n,t){return`${N[t]} ${n}`}class ${constructor(t){this.listeners=new Set,this.config=t;const a=t.initialDate||new Date;this.state={currentYear:a.getFullYear(),currentMonth:a.getMonth(),currentDate:a.getDate(),selectedDate:null,selectedDayIndex:null,tasks:[]}}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}notify(){this.listeners.forEach(t=>t())}getState(){return{...this.state}}getViewModel(){const t=V(this.state.currentYear,this.state.currentMonth,this.config.events,this.config.weekStartsOn);return{...this.state,months:N,days:Y,years:_(this.config.minYear,this.config.maxYear),monthAndYearText:F(this.state.currentYear,this.state.currentMonth),scheduleDay:this.state.selectedDate?x(this.state.selectedDate):"",calendarDates:t,popupPositionClass:T(this.state.selectedDayIndex)}}getActions(){return{next:this.next.bind(this),previous:this.previous.bind(this),jump:this.jump.bind(this),selectDate:this.selectDate.bind(this),updateTasks:this.updateTasks.bind(this)}}next(){this.state.currentMonth===11?(this.state.currentMonth=0,this.state.currentYear++):this.state.currentMonth++,this.state.selectedDate=null,this.state.selectedDayIndex=null,this.updateTasks(),this.notify()}previous(){this.state.currentMonth===0?(this.state.currentMonth=11,this.state.currentYear--):this.state.currentMonth--,this.state.selectedDate=null,this.state.selectedDayIndex=null,this.updateTasks(),this.notify()}jump(t,a){this.state.currentYear=t,this.state.currentMonth=a,this.state.selectedDate=null,this.state.selectedDayIndex=null,this.updateTasks(),this.notify()}selectDate(t,a){this.state.selectedDate=t,this.state.selectedDayIndex=a??null,this.state.currentDate=t.getDate(),this.state.currentMonth=t.getMonth(),this.state.currentYear=t.getFullYear(),this.updateTasks(),this.notify()}updateTasks(){if(!this.state.selectedDate){this.state.tasks=[];return}this.state.tasks=v(this.config.events,this.state.selectedDate)}updateEvents(t){this.config.events=t,this.updateTasks(),this.notify()}handleDateClick(t,a){this.selectDate(t,a)}hasEventsForDate(t){return v(this.config.events,t).length>0}getEventsForDate(t){return v(this.config.events,t)}clearSelection(){this.state.selectedDate=null,this.state.selectedDayIndex=null,this.state.tasks=[],this.notify()}destroy(){this.listeners.clear()}}const j={key:0,class:"page--title"},I={class:"calendar--content"},z={class:"calendar--card"},L={class:"calendar--card--header"},J={class:"calendar--table calendar--table--bordered"},W={class:"schedule--wrapper"},H={class:"schedule--block"},U={class:"schedule--day"},q={key:0,class:"event--wrapper"},K=["onClick"],G={key:1,class:"no-events-message"},Q={class:"calendar--form--jump"},R={class:"calendar--form--jump--item"},X=["value"],Z=["value"],ee={class:"calendar--form--jump--item"},te=["value"],ne=["value"],M=e.defineComponent({__name:"Calendar",props:{class:{default:""},style:{default:()=>({})},title:{default:"Event Schedule"},events:{default:()=>[]},initialDate:{},minYear:{},maxYear:{},weekStartsOn:{default:0},onDateSelect:{},onEventClick:{},onMonthChange:{}},emits:["date-select","event-click","month-change"],setup(n,{emit:t}){const a=n,c=t,i=new $({events:a.events,initialDate:a.initialDate,minYear:a.minYear,maxYear:a.maxYear,weekStartsOn:a.weekStartsOn}),g=e.ref(0),s=e.computed(()=>(g.value,i.getViewModel())),u=i.getActions(),f=r=>r?w(r):"",p=r=>{const o=r.target.closest("td");if(!o)return;const l=o.textContent?.trim();if(!l)return;const d=new Date(s.value.currentYear,s.value.currentMonth,parseInt(l)),C=o.parentNode?Array.from(o.parentNode.children).indexOf(o):0;i.handleDateClick(d,C),c("date-select",d)},D=()=>{u.next(),c("month-change",s.value.currentYear,s.value.currentMonth)},h=()=>{u.previous(),c("month-change",s.value.currentYear,s.value.currentMonth)},m=r=>{const o=r.target,l=parseInt(o.value);u.jump(s.value.currentYear,l),c("month-change",s.value.currentYear,l)},k=r=>{const o=r.target,l=parseInt(o.value);u.jump(l,s.value.currentMonth),c("month-change",l,s.value.currentMonth)},E=()=>{i.clearSelection()};e.watch(()=>a.events,r=>{i.updateEvents(r),g.value++},{deep:!0});let B=null;return e.onMounted(()=>{B=i.subscribe(()=>{g.value++})}),e.onUnmounted(()=>{B?.(),i.destroy()}),(r,o)=>(e.openBlock(),e.createElementBlock("div",{class:e.normalizeClass(["kalendly-calendar",a.class]),style:e.normalizeStyle(a.style)},[n.title||r.$slots.title?(e.openBlock(),e.createElementBlock("div",j,[e.renderSlot(r.$slots,"title",{},()=>[e.createElementVNode("h1",null,e.toDisplayString(n.title),1)])])):e.createCommentVNode("",!0),e.createElementVNode("div",I,[e.createElementVNode("div",z,[e.createElementVNode("h3",L,e.toDisplayString(s.value.monthAndYearText),1),e.createElementVNode("table",J,[e.createElementVNode("thead",null,[e.createElementVNode("tr",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value.days,l=>(e.openBlock(),e.createElementBlock("th",{key:l},e.toDisplayString(l.slice(0,3)),1))),128))])]),e.createElementVNode("tbody",{onClick:p},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value.calendarDates,(l,d)=>(e.openBlock(),e.createElementBlock("tr",{key:d},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(l,(C,A)=>(e.openBlock(),e.createElementBlock("td",{key:`${d}-${A}`,class:e.normalizeClass(f(C))},e.toDisplayString(C?.date.getDate()||""),3))),128))]))),128))])]),s.value.selectedDate?(e.openBlock(),e.createElementBlock("div",{key:0,class:e.normalizeClass(["date-popup",s.value.popupPositionClass])},[e.createElementVNode("button",{type:"button",class:"popup-close","aria-label":"Close",onClick:E}," ✕ "),e.createElementVNode("div",W,[e.createElementVNode("div",H,[e.createElementVNode("h2",U,e.toDisplayString(s.value.scheduleDay),1)]),s.value.tasks.length>0?(e.openBlock(),e.createElementBlock("div",q,[e.createElementVNode("ul",null,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value.tasks,l=>(e.openBlock(),e.createElementBlock("li",{key:l.id||l.name,class:"event--item",style:{cursor:"pointer"},onClick:d=>c("event-click",l)},[e.renderSlot(r.$slots,"event",{event:l},()=>[e.createTextVNode(e.toDisplayString(l.name),1)])],8,K))),128))])])):(e.openBlock(),e.createElementBlock("div",G,[e.renderSlot(r.$slots,"no-events",{},()=>[o[0]||(o[0]=e.createTextVNode(" No events scheduled for this day. ",-1))])]))])],2)):e.createCommentVNode("",!0),e.createElementVNode("div",{class:"calendar--navigation--buttons"},[e.createElementVNode("button",{class:"calendar--navigation--btn",onClick:h}," Previous "),e.createElementVNode("button",{class:"calendar--navigation--btn",onClick:D}," Next ")]),e.createElementVNode("form",Q,[o[1]||(o[1]=e.createElementVNode("div",{class:"calendar--lead"},"Jump To:",-1)),e.createElementVNode("div",null,[e.createElementVNode("label",R,[e.createElementVNode("select",{value:s.value.currentMonth,onChange:m},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value.months,(l,d)=>(e.openBlock(),e.createElementBlock("option",{key:d,value:d},e.toDisplayString(l),9,Z))),128))],40,X)])]),e.createElementVNode("div",null,[e.createElementVNode("label",ee,[e.createElementVNode("select",{value:s.value.currentYear,onChange:k},[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(s.value.years,l=>(e.openBlock(),e.createElementBlock("option",{key:l,value:l},e.toDisplayString(l),9,ne))),128))],40,te)])])])])])],6))}});function O(n){n.component("Kalendly",M)}const se={install:O,Calendar:M};function ae(n){return M}exports.Calendar=M;exports.CalendarEngine=$;exports.DAYS=Y;exports.MONTHS=N;exports.createCalendar=ae;exports.default=se;exports.formatDateForDisplay=x;exports.generateCalendarDates=V;exports.generateYears=_;exports.getCellClasses=w;exports.getEventsForDate=v;exports.getMonthYearText=F;exports.getPopupPositionClass=T;exports.hasEvents=P;exports.install=O;exports.isSameDay=b;exports.isToday=S;exports.normalizeDate=y;
|
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
import { defineComponent as j, ref as P, computed as V, watch as z, onMounted as J, onUnmounted as W, createElementBlock as l, openBlock as i, normalizeStyle as B, normalizeClass as x, createCommentVNode as F, createElementVNode as r, renderSlot as S, toDisplayString as p, Fragment as D, renderList as y, createTextVNode as N } from "vue";
|
|
2
|
+
const A = [
|
|
3
|
+
"Jan",
|
|
4
|
+
"Feb",
|
|
5
|
+
"Mar",
|
|
6
|
+
"Apr",
|
|
7
|
+
"May",
|
|
8
|
+
"Jun",
|
|
9
|
+
"Jul",
|
|
10
|
+
"Aug",
|
|
11
|
+
"Sep",
|
|
12
|
+
"Oct",
|
|
13
|
+
"Nov",
|
|
14
|
+
"Dec"
|
|
15
|
+
], I = [
|
|
16
|
+
"Sunday",
|
|
17
|
+
"Monday",
|
|
18
|
+
"Tuesday",
|
|
19
|
+
"Wednesday",
|
|
20
|
+
"Thursday",
|
|
21
|
+
"Friday",
|
|
22
|
+
"Saturday"
|
|
23
|
+
];
|
|
24
|
+
function w(t) {
|
|
25
|
+
return new Date(t.getFullYear(), t.getMonth(), t.getDate(), 0, 0, 0);
|
|
26
|
+
}
|
|
27
|
+
function U(t, e) {
|
|
28
|
+
return w(t).getTime() === w(e).getTime();
|
|
29
|
+
}
|
|
30
|
+
function H(t) {
|
|
31
|
+
return U(t, /* @__PURE__ */ new Date());
|
|
32
|
+
}
|
|
33
|
+
function K(t, e) {
|
|
34
|
+
const n = (/* @__PURE__ */ new Date()).getFullYear(), c = t ?? n - 30, h = e ?? n + 10;
|
|
35
|
+
return Array.from({ length: h - c + 1 }, (k, s) => c + s);
|
|
36
|
+
}
|
|
37
|
+
function Y(t, e) {
|
|
38
|
+
const n = w(e);
|
|
39
|
+
return t.filter((c) => w(new Date(c.date)).getTime() === n.getTime());
|
|
40
|
+
}
|
|
41
|
+
function ye(t, e) {
|
|
42
|
+
return Y(t, e).length > 0;
|
|
43
|
+
}
|
|
44
|
+
function L(t, e, n = [], c = 0) {
|
|
45
|
+
const h = new Date(t, e, 1), s = new Date(t, e + 1, 0).getDate();
|
|
46
|
+
let d = h.getDay();
|
|
47
|
+
c === 1 && (d = d === 0 ? 6 : d - 1);
|
|
48
|
+
const b = [];
|
|
49
|
+
let m = 1;
|
|
50
|
+
for (let C = 0; C < 6; C++) {
|
|
51
|
+
const f = [];
|
|
52
|
+
for (let g = 0; g < 7; g++)
|
|
53
|
+
if (C === 0 && g < d)
|
|
54
|
+
f.push(null);
|
|
55
|
+
else if (m > s)
|
|
56
|
+
f.push(null);
|
|
57
|
+
else {
|
|
58
|
+
const M = new Date(t, e, m), _ = Y(n, M);
|
|
59
|
+
f.push({
|
|
60
|
+
date: M,
|
|
61
|
+
isCurrentMonth: !0,
|
|
62
|
+
isToday: H(M),
|
|
63
|
+
hasEvents: _.length > 0,
|
|
64
|
+
events: _
|
|
65
|
+
}), m++;
|
|
66
|
+
}
|
|
67
|
+
if (b.push(f), m > s && f.every((g) => g === null))
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
return b;
|
|
71
|
+
}
|
|
72
|
+
function q(t) {
|
|
73
|
+
return t === null ? "popup-center-bottom" : t < 3 ? "popup-right" : t > 4 ? "popup-left" : "popup-center-bottom";
|
|
74
|
+
}
|
|
75
|
+
function G(t) {
|
|
76
|
+
if (!t) return [];
|
|
77
|
+
const e = [];
|
|
78
|
+
return t.isToday && e.push("schedule--current--exam"), t.hasEvents && e.push("has--event"), e;
|
|
79
|
+
}
|
|
80
|
+
function Q(t) {
|
|
81
|
+
return `${I[t.getDay()]} ${t.getDate()}`;
|
|
82
|
+
}
|
|
83
|
+
function R(t, e) {
|
|
84
|
+
return `${A[e]} ${t}`;
|
|
85
|
+
}
|
|
86
|
+
class X {
|
|
87
|
+
constructor(e) {
|
|
88
|
+
this.listeners = /* @__PURE__ */ new Set(), this.config = e;
|
|
89
|
+
const n = e.initialDate || /* @__PURE__ */ new Date();
|
|
90
|
+
this.state = {
|
|
91
|
+
currentYear: n.getFullYear(),
|
|
92
|
+
currentMonth: n.getMonth(),
|
|
93
|
+
currentDate: n.getDate(),
|
|
94
|
+
selectedDate: null,
|
|
95
|
+
selectedDayIndex: null,
|
|
96
|
+
tasks: []
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Subscribe to state changes
|
|
101
|
+
*/
|
|
102
|
+
subscribe(e) {
|
|
103
|
+
return this.listeners.add(e), () => this.listeners.delete(e);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Notify all listeners of state changes
|
|
107
|
+
*/
|
|
108
|
+
notify() {
|
|
109
|
+
this.listeners.forEach((e) => e());
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Get current state
|
|
113
|
+
*/
|
|
114
|
+
getState() {
|
|
115
|
+
return { ...this.state };
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Get view model with computed properties
|
|
119
|
+
*/
|
|
120
|
+
getViewModel() {
|
|
121
|
+
const e = L(
|
|
122
|
+
this.state.currentYear,
|
|
123
|
+
this.state.currentMonth,
|
|
124
|
+
this.config.events,
|
|
125
|
+
this.config.weekStartsOn
|
|
126
|
+
);
|
|
127
|
+
return {
|
|
128
|
+
...this.state,
|
|
129
|
+
months: A,
|
|
130
|
+
days: I,
|
|
131
|
+
years: K(this.config.minYear, this.config.maxYear),
|
|
132
|
+
monthAndYearText: R(
|
|
133
|
+
this.state.currentYear,
|
|
134
|
+
this.state.currentMonth
|
|
135
|
+
),
|
|
136
|
+
scheduleDay: this.state.selectedDate ? Q(this.state.selectedDate) : "",
|
|
137
|
+
calendarDates: e,
|
|
138
|
+
popupPositionClass: q(this.state.selectedDayIndex)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Get actions object
|
|
143
|
+
*/
|
|
144
|
+
getActions() {
|
|
145
|
+
return {
|
|
146
|
+
next: this.next.bind(this),
|
|
147
|
+
previous: this.previous.bind(this),
|
|
148
|
+
jump: this.jump.bind(this),
|
|
149
|
+
selectDate: this.selectDate.bind(this),
|
|
150
|
+
updateTasks: this.updateTasks.bind(this)
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
/**
|
|
154
|
+
* Navigate to next month
|
|
155
|
+
*/
|
|
156
|
+
next() {
|
|
157
|
+
this.state.currentMonth === 11 ? (this.state.currentMonth = 0, this.state.currentYear++) : this.state.currentMonth++, this.state.selectedDate = null, this.state.selectedDayIndex = null, this.updateTasks(), this.notify();
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Navigate to previous month
|
|
161
|
+
*/
|
|
162
|
+
previous() {
|
|
163
|
+
this.state.currentMonth === 0 ? (this.state.currentMonth = 11, this.state.currentYear--) : this.state.currentMonth--, this.state.selectedDate = null, this.state.selectedDayIndex = null, this.updateTasks(), this.notify();
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Jump to specific month and year
|
|
167
|
+
*/
|
|
168
|
+
jump(e, n) {
|
|
169
|
+
this.state.currentYear = e, this.state.currentMonth = n, this.state.selectedDate = null, this.state.selectedDayIndex = null, this.updateTasks(), this.notify();
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Select a specific date
|
|
173
|
+
*/
|
|
174
|
+
selectDate(e, n) {
|
|
175
|
+
this.state.selectedDate = e, this.state.selectedDayIndex = n ?? null, this.state.currentDate = e.getDate(), this.state.currentMonth = e.getMonth(), this.state.currentYear = e.getFullYear(), this.updateTasks(), this.notify();
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Update tasks for the currently selected date
|
|
179
|
+
*/
|
|
180
|
+
updateTasks() {
|
|
181
|
+
if (!this.state.selectedDate) {
|
|
182
|
+
this.state.tasks = [];
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.state.tasks = Y(
|
|
186
|
+
this.config.events,
|
|
187
|
+
this.state.selectedDate
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Update events configuration
|
|
192
|
+
*/
|
|
193
|
+
updateEvents(e) {
|
|
194
|
+
this.config.events = e, this.updateTasks(), this.notify();
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Handle date cell click
|
|
198
|
+
*/
|
|
199
|
+
handleDateClick(e, n) {
|
|
200
|
+
this.selectDate(e, n);
|
|
201
|
+
}
|
|
202
|
+
/**
|
|
203
|
+
* Check if date has events
|
|
204
|
+
*/
|
|
205
|
+
hasEventsForDate(e) {
|
|
206
|
+
return Y(this.config.events, e).length > 0;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Get events for a specific date
|
|
210
|
+
*/
|
|
211
|
+
getEventsForDate(e) {
|
|
212
|
+
return Y(this.config.events, e);
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Clear selected date
|
|
216
|
+
*/
|
|
217
|
+
clearSelection() {
|
|
218
|
+
this.state.selectedDate = null, this.state.selectedDayIndex = null, this.state.tasks = [], this.notify();
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Destroy the engine and cleanup listeners
|
|
222
|
+
*/
|
|
223
|
+
destroy() {
|
|
224
|
+
this.listeners.clear();
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
const Z = {
|
|
228
|
+
key: 0,
|
|
229
|
+
class: "page--title"
|
|
230
|
+
}, ee = { class: "calendar--content" }, te = { class: "calendar--card" }, se = { class: "calendar--card--header" }, ne = { class: "calendar--table calendar--table--bordered" }, ae = { class: "schedule--wrapper" }, re = { class: "schedule--block" }, le = { class: "schedule--day" }, ie = {
|
|
231
|
+
key: 0,
|
|
232
|
+
class: "event--wrapper"
|
|
233
|
+
}, oe = ["onClick"], ue = {
|
|
234
|
+
key: 1,
|
|
235
|
+
class: "no-events-message"
|
|
236
|
+
}, ce = { class: "calendar--form--jump" }, he = { class: "calendar--form--jump--item" }, de = ["value"], ve = ["value"], pe = { class: "calendar--form--jump--item" }, fe = ["value"], ge = ["value"], E = /* @__PURE__ */ j({
|
|
237
|
+
__name: "Calendar",
|
|
238
|
+
props: {
|
|
239
|
+
class: { default: "" },
|
|
240
|
+
style: { default: () => ({}) },
|
|
241
|
+
title: { default: "Event Schedule" },
|
|
242
|
+
events: { default: () => [] },
|
|
243
|
+
initialDate: {},
|
|
244
|
+
minYear: {},
|
|
245
|
+
maxYear: {},
|
|
246
|
+
weekStartsOn: { default: 0 },
|
|
247
|
+
onDateSelect: {},
|
|
248
|
+
onEventClick: {},
|
|
249
|
+
onMonthChange: {}
|
|
250
|
+
},
|
|
251
|
+
emits: ["date-select", "event-click", "month-change"],
|
|
252
|
+
setup(t, { emit: e }) {
|
|
253
|
+
const n = t, c = e, h = new X({
|
|
254
|
+
events: n.events,
|
|
255
|
+
initialDate: n.initialDate,
|
|
256
|
+
minYear: n.minYear,
|
|
257
|
+
maxYear: n.maxYear,
|
|
258
|
+
weekStartsOn: n.weekStartsOn
|
|
259
|
+
}), k = P(0), s = V(() => (k.value, h.getViewModel())), d = h.getActions(), b = (o) => o ? G(o) : "", m = (o) => {
|
|
260
|
+
const u = o.target.closest("td");
|
|
261
|
+
if (!u) return;
|
|
262
|
+
const a = u.textContent?.trim();
|
|
263
|
+
if (!a) return;
|
|
264
|
+
const v = new Date(
|
|
265
|
+
s.value.currentYear,
|
|
266
|
+
s.value.currentMonth,
|
|
267
|
+
parseInt(a)
|
|
268
|
+
), T = u.parentNode ? Array.from(u.parentNode.children).indexOf(u) : 0;
|
|
269
|
+
h.handleDateClick(v, T), c("date-select", v);
|
|
270
|
+
}, C = () => {
|
|
271
|
+
d.next(), c(
|
|
272
|
+
"month-change",
|
|
273
|
+
s.value.currentYear,
|
|
274
|
+
s.value.currentMonth
|
|
275
|
+
);
|
|
276
|
+
}, f = () => {
|
|
277
|
+
d.previous(), c(
|
|
278
|
+
"month-change",
|
|
279
|
+
s.value.currentYear,
|
|
280
|
+
s.value.currentMonth
|
|
281
|
+
);
|
|
282
|
+
}, g = (o) => {
|
|
283
|
+
const u = o.target, a = parseInt(u.value);
|
|
284
|
+
d.jump(s.value.currentYear, a), c("month-change", s.value.currentYear, a);
|
|
285
|
+
}, M = (o) => {
|
|
286
|
+
const u = o.target, a = parseInt(u.value);
|
|
287
|
+
d.jump(a, s.value.currentMonth), c("month-change", a, s.value.currentMonth);
|
|
288
|
+
}, _ = () => {
|
|
289
|
+
h.clearSelection();
|
|
290
|
+
};
|
|
291
|
+
z(
|
|
292
|
+
() => n.events,
|
|
293
|
+
(o) => {
|
|
294
|
+
h.updateEvents(o), k.value++;
|
|
295
|
+
},
|
|
296
|
+
{ deep: !0 }
|
|
297
|
+
);
|
|
298
|
+
let $ = null;
|
|
299
|
+
return J(() => {
|
|
300
|
+
$ = h.subscribe(() => {
|
|
301
|
+
k.value++;
|
|
302
|
+
});
|
|
303
|
+
}), W(() => {
|
|
304
|
+
$?.(), h.destroy();
|
|
305
|
+
}), (o, u) => (i(), l("div", {
|
|
306
|
+
class: x(["kalendly-calendar", n.class]),
|
|
307
|
+
style: B(n.style)
|
|
308
|
+
}, [
|
|
309
|
+
t.title || o.$slots.title ? (i(), l("div", Z, [
|
|
310
|
+
S(o.$slots, "title", {}, () => [
|
|
311
|
+
r("h1", null, p(t.title), 1)
|
|
312
|
+
])
|
|
313
|
+
])) : F("", !0),
|
|
314
|
+
r("div", ee, [
|
|
315
|
+
r("div", te, [
|
|
316
|
+
r("h3", se, p(s.value.monthAndYearText), 1),
|
|
317
|
+
r("table", ne, [
|
|
318
|
+
r("thead", null, [
|
|
319
|
+
r("tr", null, [
|
|
320
|
+
(i(!0), l(D, null, y(s.value.days, (a) => (i(), l("th", { key: a }, p(a.slice(0, 3)), 1))), 128))
|
|
321
|
+
])
|
|
322
|
+
]),
|
|
323
|
+
r("tbody", { onClick: m }, [
|
|
324
|
+
(i(!0), l(D, null, y(s.value.calendarDates, (a, v) => (i(), l("tr", { key: v }, [
|
|
325
|
+
(i(!0), l(D, null, y(a, (T, O) => (i(), l("td", {
|
|
326
|
+
key: `${v}-${O}`,
|
|
327
|
+
class: x(b(T))
|
|
328
|
+
}, p(T?.date.getDate() || ""), 3))), 128))
|
|
329
|
+
]))), 128))
|
|
330
|
+
])
|
|
331
|
+
]),
|
|
332
|
+
s.value.selectedDate ? (i(), l("div", {
|
|
333
|
+
key: 0,
|
|
334
|
+
class: x(["date-popup", s.value.popupPositionClass])
|
|
335
|
+
}, [
|
|
336
|
+
r("button", {
|
|
337
|
+
type: "button",
|
|
338
|
+
class: "popup-close",
|
|
339
|
+
"aria-label": "Close",
|
|
340
|
+
onClick: _
|
|
341
|
+
}, " ✕ "),
|
|
342
|
+
r("div", ae, [
|
|
343
|
+
r("div", re, [
|
|
344
|
+
r("h2", le, p(s.value.scheduleDay), 1)
|
|
345
|
+
]),
|
|
346
|
+
s.value.tasks.length > 0 ? (i(), l("div", ie, [
|
|
347
|
+
r("ul", null, [
|
|
348
|
+
(i(!0), l(D, null, y(s.value.tasks, (a) => (i(), l("li", {
|
|
349
|
+
key: a.id || a.name,
|
|
350
|
+
class: "event--item",
|
|
351
|
+
style: { cursor: "pointer" },
|
|
352
|
+
onClick: (v) => c("event-click", a)
|
|
353
|
+
}, [
|
|
354
|
+
S(o.$slots, "event", { event: a }, () => [
|
|
355
|
+
N(p(a.name), 1)
|
|
356
|
+
])
|
|
357
|
+
], 8, oe))), 128))
|
|
358
|
+
])
|
|
359
|
+
])) : (i(), l("div", ue, [
|
|
360
|
+
S(o.$slots, "no-events", {}, () => [
|
|
361
|
+
u[0] || (u[0] = N(" No events scheduled for this day. ", -1))
|
|
362
|
+
])
|
|
363
|
+
]))
|
|
364
|
+
])
|
|
365
|
+
], 2)) : F("", !0),
|
|
366
|
+
r("div", { class: "calendar--navigation--buttons" }, [
|
|
367
|
+
r("button", {
|
|
368
|
+
class: "calendar--navigation--btn",
|
|
369
|
+
onClick: f
|
|
370
|
+
}, " Previous "),
|
|
371
|
+
r("button", {
|
|
372
|
+
class: "calendar--navigation--btn",
|
|
373
|
+
onClick: C
|
|
374
|
+
}, " Next ")
|
|
375
|
+
]),
|
|
376
|
+
r("form", ce, [
|
|
377
|
+
u[1] || (u[1] = r("div", { class: "calendar--lead" }, "Jump To:", -1)),
|
|
378
|
+
r("div", null, [
|
|
379
|
+
r("label", he, [
|
|
380
|
+
r("select", {
|
|
381
|
+
value: s.value.currentMonth,
|
|
382
|
+
onChange: g
|
|
383
|
+
}, [
|
|
384
|
+
(i(!0), l(D, null, y(s.value.months, (a, v) => (i(), l("option", {
|
|
385
|
+
key: v,
|
|
386
|
+
value: v
|
|
387
|
+
}, p(a), 9, ve))), 128))
|
|
388
|
+
], 40, de)
|
|
389
|
+
])
|
|
390
|
+
]),
|
|
391
|
+
r("div", null, [
|
|
392
|
+
r("label", pe, [
|
|
393
|
+
r("select", {
|
|
394
|
+
value: s.value.currentYear,
|
|
395
|
+
onChange: M
|
|
396
|
+
}, [
|
|
397
|
+
(i(!0), l(D, null, y(s.value.years, (a) => (i(), l("option", {
|
|
398
|
+
key: a,
|
|
399
|
+
value: a
|
|
400
|
+
}, p(a), 9, ge))), 128))
|
|
401
|
+
], 40, fe)
|
|
402
|
+
])
|
|
403
|
+
])
|
|
404
|
+
])
|
|
405
|
+
])
|
|
406
|
+
])
|
|
407
|
+
], 6));
|
|
408
|
+
}
|
|
409
|
+
});
|
|
410
|
+
function me(t) {
|
|
411
|
+
t.component("Kalendly", E);
|
|
412
|
+
}
|
|
413
|
+
const ke = {
|
|
414
|
+
install: me,
|
|
415
|
+
Calendar: E
|
|
416
|
+
};
|
|
417
|
+
function Ce(t) {
|
|
418
|
+
return E;
|
|
419
|
+
}
|
|
420
|
+
export {
|
|
421
|
+
E as Calendar,
|
|
422
|
+
X as CalendarEngine,
|
|
423
|
+
I as DAYS,
|
|
424
|
+
A as MONTHS,
|
|
425
|
+
Ce as createCalendar,
|
|
426
|
+
ke as default,
|
|
427
|
+
Q as formatDateForDisplay,
|
|
428
|
+
L as generateCalendarDates,
|
|
429
|
+
K as generateYears,
|
|
430
|
+
G as getCellClasses,
|
|
431
|
+
Y as getEventsForDate,
|
|
432
|
+
R as getMonthYearText,
|
|
433
|
+
q as getPopupPositionClass,
|
|
434
|
+
ye as hasEvents,
|
|
435
|
+
me as install,
|
|
436
|
+
U as isSameDay,
|
|
437
|
+
H as isToday,
|
|
438
|
+
w as normalizeDate
|
|
439
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "kalendly",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A kalendly universal calendar scheduler component for React, Vue, and React Native",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"calendar",
|
|
7
|
+
"scheduler",
|
|
8
|
+
"react",
|
|
9
|
+
"vue",
|
|
10
|
+
"react-native",
|
|
11
|
+
"typescript",
|
|
12
|
+
"events",
|
|
13
|
+
"datepicker"
|
|
14
|
+
],
|
|
15
|
+
"author": "Callis Ezenwaka <callisezenwaka@outlook.com>",
|
|
16
|
+
"license": "MIT",
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/callezenwaka/kalendly.git"
|
|
20
|
+
},
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/callezenwaka/kalendly/issues"
|
|
23
|
+
},
|
|
24
|
+
"homepage": "https://github.com/callezenwaka/kalendly#readme",
|
|
25
|
+
"main": "./dist/index.js",
|
|
26
|
+
"module": "./dist/index.mjs",
|
|
27
|
+
"types": "./dist/index.d.ts",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=16.0.0"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": {
|
|
33
|
+
"types": "./dist/index.d.ts",
|
|
34
|
+
"import": "./dist/index.mjs",
|
|
35
|
+
"require": "./dist/index.cjs"
|
|
36
|
+
},
|
|
37
|
+
"./core": {
|
|
38
|
+
"types": "./dist/core/index.d.ts",
|
|
39
|
+
"import": "./dist/core/index.mjs",
|
|
40
|
+
"require": "./dist/core/index.cjs"
|
|
41
|
+
},
|
|
42
|
+
"./react": {
|
|
43
|
+
"types": "./dist/react/index.d.ts",
|
|
44
|
+
"import": "./dist/react/index.mjs",
|
|
45
|
+
"require": "./dist/react/index.cjs"
|
|
46
|
+
},
|
|
47
|
+
"./vue": {
|
|
48
|
+
"types": "./dist/vue/index.d.ts",
|
|
49
|
+
"import": "./dist/vue/index.mjs",
|
|
50
|
+
"require": "./dist/vue/index.cjs"
|
|
51
|
+
},
|
|
52
|
+
"./react-native": {
|
|
53
|
+
"types": "./dist/react-native/index.d.ts",
|
|
54
|
+
"import": "./dist/react-native/index.mjs",
|
|
55
|
+
"require": "./dist/react-native/index.cjs"
|
|
56
|
+
},
|
|
57
|
+
"./vanilla": {
|
|
58
|
+
"types": "./dist/vanilla/index.d.ts",
|
|
59
|
+
"import": "./dist/vanilla/index.mjs",
|
|
60
|
+
"require": "./dist/vanilla/index.cjs"
|
|
61
|
+
},
|
|
62
|
+
"./styles": "./dist/styles/calendar.css"
|
|
63
|
+
},
|
|
64
|
+
"files": [
|
|
65
|
+
"dist",
|
|
66
|
+
"README.md",
|
|
67
|
+
"LICENSE"
|
|
68
|
+
],
|
|
69
|
+
"scripts": {
|
|
70
|
+
"build": "npm run build:tsup && npm run build:vue && npm run copy:styles",
|
|
71
|
+
"build:tsup": "tsup",
|
|
72
|
+
"build:vue": "vite build",
|
|
73
|
+
"copy:styles": "mkdir -p dist/styles && cp src/styles/calendar.css dist/styles/",
|
|
74
|
+
"dev": "tsup --watch",
|
|
75
|
+
"dev:examples": "vite --config vite.examples.config.ts",
|
|
76
|
+
"test": "vitest",
|
|
77
|
+
"test:ui": "vitest --ui",
|
|
78
|
+
"test:run": "vitest run",
|
|
79
|
+
"test:coverage": "vitest run --coverage",
|
|
80
|
+
"test:watch": "vitest --watch",
|
|
81
|
+
"test:package": "node tests/integration/package-validation.test.mjs",
|
|
82
|
+
"test:manual": "echo 'Open tests/manual/*.html in browser' && npx serve . -p 8080",
|
|
83
|
+
"lint": "eslint src",
|
|
84
|
+
"lint:fix": "eslint src --fix",
|
|
85
|
+
"format": "prettier --write \"src/**/*.{ts,tsx,vue,js,jsx,json,css,md}\"",
|
|
86
|
+
"format:check": "prettier --check \"src/**/*.{ts,tsx,vue,js,jsx,json,css,md}\"",
|
|
87
|
+
"type-check": "tsc --noEmit",
|
|
88
|
+
"prepare": "husky",
|
|
89
|
+
"prepublishOnly": "npm run test && npm run build",
|
|
90
|
+
"prepack": "npm run test:package"
|
|
91
|
+
},
|
|
92
|
+
"peerDependencies": {
|
|
93
|
+
"react": ">=16.8.0",
|
|
94
|
+
"react-dom": ">=16.8.0",
|
|
95
|
+
"react-native": "^0.76.0",
|
|
96
|
+
"vue": ">=3.0.0"
|
|
97
|
+
},
|
|
98
|
+
"peerDependenciesMeta": {
|
|
99
|
+
"react": {
|
|
100
|
+
"optional": true
|
|
101
|
+
},
|
|
102
|
+
"react-dom": {
|
|
103
|
+
"optional": true
|
|
104
|
+
},
|
|
105
|
+
"vue": {
|
|
106
|
+
"optional": true
|
|
107
|
+
},
|
|
108
|
+
"react-native": {
|
|
109
|
+
"optional": true
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
"lint-staged": {
|
|
113
|
+
"*.{ts,tsx,vue,js,jsx,json,css,md}": [
|
|
114
|
+
"prettier --write"
|
|
115
|
+
],
|
|
116
|
+
"*.{ts,tsx,vue}": [
|
|
117
|
+
"eslint --fix",
|
|
118
|
+
"vitest related --run",
|
|
119
|
+
"bash -c 'tsc --noEmit'"
|
|
120
|
+
]
|
|
121
|
+
},
|
|
122
|
+
"devDependencies": {
|
|
123
|
+
"@eslint/js": "^9.18.0",
|
|
124
|
+
"@testing-library/dom": "^10.4.0",
|
|
125
|
+
"@testing-library/jest-dom": "^6.9.1",
|
|
126
|
+
"@testing-library/react": "^16.3.1",
|
|
127
|
+
"@testing-library/user-event": "^14.6.1",
|
|
128
|
+
"@testing-library/vue": "^8.1.0",
|
|
129
|
+
"@types/node": "^20.6.0",
|
|
130
|
+
"@types/react": "^18.2.21",
|
|
131
|
+
"@types/react-dom": "^18.2.7",
|
|
132
|
+
"@typescript-eslint/eslint-plugin": "^8.19.1",
|
|
133
|
+
"@typescript-eslint/parser": "^8.19.1",
|
|
134
|
+
"@vitejs/plugin-react": "^5.1.2",
|
|
135
|
+
"@vitejs/plugin-vue": "^6.0.2",
|
|
136
|
+
"@vitest/coverage-v8": "^4.0.16",
|
|
137
|
+
"@vitest/ui": "^4.0.16",
|
|
138
|
+
"@vue/compiler-sfc": "^3.5.25",
|
|
139
|
+
"@vue/eslint-config-typescript": "^14.1.3",
|
|
140
|
+
"esbuild-plugin-vue-next": "^0.1.4",
|
|
141
|
+
"eslint": "^9.18.0",
|
|
142
|
+
"eslint-plugin-react": "^7.37.2",
|
|
143
|
+
"eslint-plugin-react-hooks": "^5.1.0",
|
|
144
|
+
"eslint-plugin-vue": "^9.17.0",
|
|
145
|
+
"globals": "^15.14.0",
|
|
146
|
+
"eslint-config-prettier": "^9.1.0",
|
|
147
|
+
"husky": "^9.1.7",
|
|
148
|
+
"jsdom": "^27.4.0",
|
|
149
|
+
"lint-staged": "^16.2.7",
|
|
150
|
+
"prettier": "^3.4.2",
|
|
151
|
+
"react": "^18.3.1",
|
|
152
|
+
"react-dom": "^18.3.1",
|
|
153
|
+
"react-native": "^0.76.0",
|
|
154
|
+
"tsup": "^8.5.1",
|
|
155
|
+
"typescript": "^5.2.2",
|
|
156
|
+
"vite": "^7.2.6",
|
|
157
|
+
"vite-plugin-dts": "^4.5.4",
|
|
158
|
+
"vitest": "^4.0.16",
|
|
159
|
+
"vue": "^3.3.4"
|
|
160
|
+
}
|
|
161
|
+
}
|