vue-simple-calendar
Version:
Simple Vue 3 calendar event control
2 lines (1 loc) • 17.5 kB
JavaScript
import{defineComponent as e,openBlock as t,createBlock as a,renderSlot as r,createVNode as i,createCommentVNode as n,Fragment as s,renderList as o,toDisplayString as d,withModifiers as l,createTextVNode as h}from"vue";var u={today(){return this.dateOnly(new Date)},beginningOfPeriod(e,t,a){switch(t){case"year":return new Date(e.getFullYear(),0);case"month":return new Date(e.getFullYear(),e.getMonth());case"week":return this.beginningOfWeek(e,a);default:return e}},daysOfWeek(e){return[...Array(7)].map(((t,a)=>this.addDays(e,a)))},addDays:(e,t)=>new Date(e.getFullYear(),e.getMonth(),e.getDate()+t,e.getHours(),e.getMinutes(),e.getSeconds()),beginningOfWeek(e,t){return this.addDays(e,(t-e.getDay()-7)%-7)},endOfWeek(e,t){return this.addDays(this.beginningOfWeek(e,t),7)},beginningOfMonth:e=>new Date(e.getFullYear(),e.getMonth()),instanceOfMonth:e=>Math.ceil(e.getDate()/7),incrementPeriod:(e,t,a)=>new Date(e.getFullYear()+("year"==t?a:0),e.getMonth()+("month"==t?a:0),e.getDate()+("week"==t?7*a:0)),paddedMonth:e=>("0"+String(e.getMonth()+1)).slice(-2),paddedDay:e=>("0"+String(e.getDate())).slice(-2),isoYearMonth(e){return e.getFullYear()+"-"+this.paddedMonth(e)},isoYearMonthDay(e){return this.isoYearMonth(e)+"-"+this.paddedDay(e)},isoMonthDay(e){return this.paddedMonth(e)+"-"+this.paddedDay(e)},formattedTime(e,t,a){if(0===e.getHours()&&0===e.getMinutes()&&0===e.getSeconds())return"";if(!this.supportsIntl()){var r=6e4*(new Date).getTimezoneOffset();return new Date(e.getTime()-r).toISOString().slice(11,16)}return e.toLocaleTimeString(t,a)},formattedPeriod(e,t,a,r){const i=e.getFullYear()===t.getFullYear(),n=this.isSameMonth(e,t),s=!("year"===a)&&!("month"===a);let o=[];return o.push(r[e.getMonth()]),s&&(o.push(" "),o.push(e.getDate())),i||(o.push(s?", ":" "),o.push(e.getFullYear())),n&&i?s&&o.push(" – "):(o.push(" – "),n||o.push(r[t.getMonth()]),s&&o.push(" ")),s?(o.push(t.getDate()),o.push(", ")):o.push(" "),o.push(t.getFullYear()),o.join("")},dayDiff:(e,t)=>(Date.UTC(t.getFullYear(),t.getMonth(),t.getDate())-Date.UTC(e.getFullYear(),e.getMonth(),e.getDate()))/864e5,isSameDate(e,t){return e&&t&&0===this.dayDiff(e,t)},isSameDateTime:(e,t)=>e&&t&&e.getTime()===t.getTime(),isSameMonth:(e,t)=>e&&t&&e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth(),isPastMonth(e){return this.beginningOfMonth(e)<this.beginningOfMonth(this.today())},isFutureMonth(e){return this.beginningOfMonth(e)>this.beginningOfMonth(this.today())},isInFuture(e){return this.dateOnly(e)>this.today()},isInPast(e){return this.dateOnly(e)<this.today()},isLastInstanceOfMonth(e){return e.getMonth()!==this.addDays(e,7).getMonth()},isLastDayOfMonth(e){return e.getMonth()!==this.addDays(e,1).getMonth()},fromIsoStringToLocalDate(e){let t=[...Array(7)].map((e=>0));return e.split(/\D/,7).forEach(((e,a)=>t[a]=Number(e))),t[1]--,new Date(t[0],t[1],t[2],t[3],t[4],t[5],t[6])},toLocalDate(e){return"string"==typeof e?this.fromIsoStringToLocalDate(e):new Date(e)},dateOnly(e){const t=new Date(e);return t.setHours(0,0,0,0),t},languageCode:e=>e.substring(0,2),supportsIntl:()=>"undefined"!=typeof Intl,getFormattedMonthNames(e,t){if(!this.supportsIntl())return[...Array(12)].map((e=>""));const a=new Intl.DateTimeFormat(e,{month:t});return[...Array(12)].map(((e,t)=>a.format(new Date(2017,t,1))))},getFormattedWeekdayNames(e,t,a){if(!this.supportsIntl())return[...Array(7)].map((e=>""));const r=new Intl.DateTimeFormat(e,{weekday:t});return[...Array(7)].map(((e,t)=>r.format(new Date(2017,0,(t+1+a)%7))))},getDefaultBrowserLocale:()=>"undefined"==typeof navigator?"unk":(navigator.languages&&navigator.languages.length?navigator.languages[0]:navigator.language).toLowerCase(),normalizeItem(e,t){const a=e.classes?[...e.classes]:[];return t&&a.push("isHovered"),{originalItem:e,startDate:this.toLocalDate(e.startDate),endDate:this.toLocalDate(e.endDate||e.startDate),classes:a,title:e.title||"Untitled",id:e.id}}};class g{constructor(){this.currentDragItem=null,this.dateSelectionOrigin=null,this.currentHoveredItemId="",this.CalendarMath=u}}var p=e({name:"CalendarView",props:{showDate:{type:Date,default:void 0},displayPeriodUom:{type:String,default:"month"},displayPeriodCount:{type:Number,default:1},displayWeekNumbers:{type:Boolean,default:!1},locale:{type:String,default:void 0},monthNameFormat:{type:String,default:"long"},weekdayNameFormat:{type:String,default:"short"},showTimes:{type:Boolean,default:!1},timeFormatOptions:{type:Object,default:()=>{}},disablePast:{type:Boolean,default:!1},disableFuture:{type:Boolean,default:!1},enableDateSelection:{type:Boolean,default:!1},selectionStart:{type:Date,default:null},selectionEnd:{type:Date,default:null},enableDragDrop:{type:Boolean,default:!1},startingDayOfWeek:{type:Number,default:0},items:{type:Array,default:()=>[]},dateClasses:{type:Object,default:()=>{}},itemTop:{type:String,default:"1.4em"},itemContentHeight:{type:String,default:"1.4em"},itemBorderHeight:{type:String,default:"2px"},periodChangedCallback:{type:Function,default:void 0},currentPeriodLabel:{type:String,default:""},currentPeriodLabelIcons:{type:String,default:"⇤-⇥"},doEmitItemMouseEvents:{type:Boolean,default:!1}},emits:["input","period-changed","click-date","click-item","item-mouseenter","item-mouseleave","drag-start","drag-over-date","drag-enter-date","drag-leave-date","drop-on-date","date-selection","date-selection-start","date-selection-finish"],data:()=>new g,computed:{displayLocale(){return this.locale||u.getDefaultBrowserLocale()},defaultedShowDate(){return this.showDate?u.dateOnly(this.showDate):u.today()},periodStart(){return u.beginningOfPeriod(this.defaultedShowDate,this.displayPeriodUom,this.startingDayOfWeek)},periodEnd(){return u.addDays(u.incrementPeriod(this.periodStart,this.displayPeriodUom,this.displayPeriodCount),-1)},periodStartCalendarWeek(){const e=u.beginningOfWeek(u.beginningOfPeriod(this.periodStart,"year",0),this.startingDayOfWeek),t=u.beginningOfWeek(this.periodStart,this.startingDayOfWeek);return 1+Math.floor(u.dayDiff(e,t)/7)},displayFirstDate(){return u.beginningOfWeek(this.periodStart,this.startingDayOfWeek)},displayLastDate(){return u.endOfWeek(this.periodEnd,this.startingDayOfWeek)},weeksOfPeriod(){const e=Math.floor((u.dayDiff(this.displayFirstDate,this.displayLastDate)+1)/7);return[...Array(e)].map(((e,t)=>u.addDays(this.displayFirstDate,7*t)))},monthNames(){return u.getFormattedMonthNames(this.displayLocale,this.monthNameFormat)},weekdayNames(){return u.getFormattedWeekdayNames(this.displayLocale,this.weekdayNameFormat,this.startingDayOfWeek)},fixedItems(){const e=this;return this.items?this.items.map((t=>u.normalizeItem(t,t.id===e.currentHoveredItemId))):[]},currentPeriodStart(){return u.beginningOfPeriod(u.today(),this.displayPeriodUom,this.startingDayOfWeek)},currentPeriodEnd(){return u.addDays(u.incrementPeriod(this.currentPeriodStart,this.displayPeriodUom,this.displayPeriodCount),-1)},periodLabel(){return u.formattedPeriod(this.periodStart,this.periodEnd,this.displayPeriodUom,this.monthNames)},currentPeriodLabelFinal(){const e=this.currentPeriodStart,t=this.periodStart;return this.currentPeriodLabel?"icons"===this.currentPeriodLabel?this.currentPeriodLabelIcons[Math.sign(e.getTime()-t.getTime())+1]:this.currentPeriodLabel:u.formattedPeriod(e,this.currentPeriodEnd,this.displayPeriodUom,this.monthNames)},headerProps(){return{previousYear:this.getIncrementedPeriod(-12),previousPeriod:this.getIncrementedPeriod(-1),nextPeriod:this.getIncrementedPeriod(1),previousFullPeriod:this.getIncrementedPeriod(-this.displayPeriodCount),nextFullPeriod:this.getIncrementedPeriod(this.displayPeriodCount),nextYear:this.getIncrementedPeriod(12),currentPeriod:this.currentPeriodStart,currentPeriodLabel:this.currentPeriodLabelFinal,periodStart:this.periodStart,periodEnd:this.periodEnd,displayLocale:this.displayLocale,displayFirstDate:this.displayFirstDate,displayLastDate:this.displayLastDate,monthNames:this.monthNames,fixedItems:this.fixedItems,periodLabel:this.periodLabel}},periodRange(){return{periodStart:this.periodStart,periodEnd:this.periodEnd,displayFirstDate:this.displayFirstDate,displayLastDate:this.displayLastDate}}},watch:{periodRange:{immediate:!0,handler(e){this.periodChangedCallback&&(this.$emit("period-changed"),this.periodChangedCallback(e,"watch"))}}},methods:{onClickDay(e,t){this.disablePast&&u.isInPast(e)||this.disableFuture&&u.isInFuture(e)||this.$emit("click-date",e,this.findAndSortItemsInDateRange(e,e),t)},onClickItem(e,t){this.$emit("click-item",e,t)},getColumnDOWClass(e){return"dow"+(e+this.startingDayOfWeek)%7},getIncrementedPeriod(e){const t=u.incrementPeriod(this.periodStart,this.displayPeriodUom,e),a=u.incrementPeriod(t,this.displayPeriodUom,this.displayPeriodCount);return this.disablePast&&a<=u.today()||this.disableFuture&&t>u.today()?null:t},onMouseEnterItem(e,t){this.currentHoveredItemId=e.id,this.doEmitItemMouseEvents&&this.$emit("item-mouseenter",e,t)},onMouseLeaveItem(e,t){this.currentHoveredItemId="",this.doEmitItemMouseEvents&&this.$emit("item-mouseleave",e,t)},onDragDateStart(e,t){var a,r;if(!this.enableDateSelection)return!1;null==(a=t.dataTransfer)||a.setData("text",e.toString());let i=new Image;return i.src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==",null==(r=t.dataTransfer)||r.setDragImage(i,10,10),this.dateSelectionOrigin=e,this.emitDateSelection("date-selection-start",e,t),!0},onDragItemStart(e,t){var a;return!!this.enableDragDrop&&(null==(a=t.dataTransfer)||a.setData("text",e.id),this.currentDragItem=e,this.dateSelectionOrigin=null,this.$emit("drag-start",e,t),!0)},handleDragEvent(e,t,a){return!!this.enableDragDrop&&(this.$emit(e,this.currentDragItem,t,a),!0)},onDragOver(e,t){this.handleDragEvent("drag-over-date",e,t)},onDragEnter(e,t){if(this.enableDateSelection&&this.dateSelectionOrigin)return void this.emitDateSelection("date-selection",e,t);if(!this.handleDragEvent("drag-enter-date",e,t))return;t.target.classList.add("draghover")},onDragLeave(e,t){if(this.enableDateSelection&&this.selectionStart)return;if(!this.handleDragEvent("drag-leave-date",e,t))return;t.target.classList.remove("draghover")},onDrop(e,t){if(this.enableDateSelection&&this.dateSelectionOrigin)return void this.emitDateSelection("date-selection-finish",e,t);if(!this.handleDragEvent("drop-on-date",e,t))return;t.target.classList.remove("draghover")},emitDateSelection(e,t,a){this.dateSelectionOrigin&&this.$emit(e,t<=this.dateSelectionOrigin?[t,this.dateSelectionOrigin,a]:[this.dateSelectionOrigin,t,a])},itemComparer:(e,t)=>e.startDate<t.startDate?-1:t.startDate<e.startDate?1:e.endDate>t.endDate?-1:t.endDate>e.endDate?1:e.id<t.id?-1:1,findAndSortItemsInWeek(e){return this.findAndSortItemsInDateRange(e,u.addDays(e,6))},findAndSortItemsInDateRange(e,t){return this.fixedItems.filter((a=>a.endDate>=e&&u.dateOnly(a.startDate)<=t),this).sort(this.itemComparer)},dayHasItems(e){return!!this.fixedItems.find((t=>t.endDate>=e&&u.dateOnly(t.startDate)<=e))},dayIsSelected(e){return!(!this.selectionStart||!this.selectionEnd)&&(!(e<u.dateOnly(this.selectionStart))&&!(e>u.dateOnly(this.selectionEnd)))},getWeekItems(e){const t=this.findAndSortItemsInWeek(e),a=[],r=[[],[],[],[],[],[],[]];for(let i=0;i<t.length;i++){const n=Object.assign({},t[i],{classes:[...t[i].classes],itemRow:0}),s=n.startDate<e,o=s?0:u.dayDiff(e,n.startDate),d=Math.min(7-o,u.dayDiff(u.addDays(e,o),n.endDate)+1);s&&n.classes.push("continued"),u.dayDiff(e,n.endDate)>6&&n.classes.push("toBeContinued"),u.isInPast(n.endDate)&&n.classes.push("past"),n.originalItem.url&&n.classes.push("hasUrl");for(let e=0;e<7;e++)if(e===o){let t=0;for(;r[e][t];)t++;n.itemRow=t,r[e][t]=!0}else e<o+d&&(r[e][n.itemRow]=!0);n.classes.push(`offset${o}`),n.classes.push(`span${d}`),a.push(n)}return a},getFormattedTimeRange(e){const t='<span class="startTime">'+u.formattedTime(e.startDate,this.displayLocale,this.timeFormatOptions)+"</span>";let a="";return u.isSameDateTime(e.startDate,e.endDate)||(a=u.formattedTime(e.endDate,this.displayLocale,this.timeFormatOptions)+"</span>"),t+a},getItemTitle(e){return this.showTimes?this.getFormattedTimeRange(e)+" "+e.title:e.title},getItemTop(e){const t=e.itemRow,a=this.itemContentHeight,r=this.itemBorderHeight;return`calc(${this.itemTop} + ${t}*${a} + ${t}*${r})`}}});const m={class:"cv-header-days"},c={key:0,class:"cv-weeknumber"},D={key:0,class:"cv-weeknumber"},y={class:"cv-weekdays"},f={class:"cv-day-number"};p.render=function(e,h,u,g,p,b){return t(),a("div",{"aria-label":"Calendar",class:["cv-wrapper","locale-"+e.CalendarMath.languageCode(e.displayLocale),"locale-"+e.displayLocale,"y"+e.periodStart.getFullYear(),"m"+e.CalendarMath.paddedMonth(e.periodStart),"period-"+e.displayPeriodUom,"periodCount-"+e.displayPeriodCount,{past:e.CalendarMath.isPastMonth(e.periodStart),future:e.CalendarMath.isFutureMonth(e.periodStart),noIntl:!e.CalendarMath.supportsIntl}]},[r(e.$slots,"header",{headerProps:e.headerProps}),i("div",m,[e.displayWeekNumbers?(t(),a("div",c)):n("",!0),(t(!0),a(s,null,o(e.weekdayNames,((i,n)=>r(e.$slots,"dayHeader",{index:e.getColumnDOWClass(n),label:i},(()=>[(t(),a("div",{key:e.getColumnDOWClass(n),class:[e.getColumnDOWClass(n),"cv-header-day"]},d(i),3))])))),256))]),i("div",{"aria-multiselectable":e.enableDateSelection,class:"cv-weeks"},[(t(!0),a(s,null,o(e.weeksOfPeriod,((h,u)=>(t(),a("div",{key:`${u}-week`,class:["cv-week","week"+(u+1),"ws"+e.CalendarMath.isoYearMonthDay(h)]},[e.displayWeekNumbers?(t(),a("div",D,[r(e.$slots,"weekNumber",{date:h,numberInYear:e.periodStartCalendarWeek+u,numberInPeriod:u+1},(()=>[i("span",null,d(e.periodStartCalendarWeek+u),1)]))])):n("",!0),i("div",y,[(t(!0),a(s,null,o(e.CalendarMath.daysOfWeek(h),((n,s)=>(t(),a("div",{key:e.getColumnDOWClass(s),draggable:e.enableDateSelection,class:["cv-day",e.getColumnDOWClass(s),"d"+e.CalendarMath.isoYearMonthDay(n),"d"+e.CalendarMath.isoMonthDay(n),"d"+e.CalendarMath.paddedDay(n),"instance"+e.CalendarMath.instanceOfMonth(n),{today:e.CalendarMath.isSameDate(n,e.CalendarMath.today()),outsideOfMonth:!e.CalendarMath.isSameMonth(n,e.defaultedShowDate),past:e.CalendarMath.isInPast(n),future:e.CalendarMath.isInFuture(n),last:e.CalendarMath.isLastDayOfMonth(n),lastInstance:e.CalendarMath.isLastInstanceOfMonth(n),hasItems:e.dayHasItems(n),selectionStart:e.CalendarMath.isSameDate(n,e.selectionStart),selectionEnd:e.CalendarMath.isSameDate(n,e.selectionEnd)},...e.dateClasses&&e.dateClasses[e.CalendarMath.isoYearMonthDay(n)]||[]],"aria-grabbed":e.enableDateSelection?e.dayIsSelected(n):"undefined","aria-label":n.getDate(),"aria-selected":e.dayIsSelected(n),"aria-dropeffect":e.enableDragDrop&&e.currentDragItem?"move":e.enableDateSelection&&e.dateSelectionOrigin?"execute":"none",onClick:t=>e.onClickDay(n,t),onDragstart:t=>e.onDragDateStart(n,t),onDrop:l((t=>e.onDrop(n,t)),["prevent"]),onDragover:l((t=>e.onDragOver(n,t)),["prevent"]),onDragenter:l((t=>e.onDragEnter(n,t)),["prevent"]),onDragleave:l((t=>e.onDragLeave(n,t)),["prevent"])},[i("div",f,d(n.getDate()),1),r(e.$slots,"dayContent",{day:n})],42,["draggable","aria-grabbed","aria-label","aria-selected","aria-dropeffect","onClick","onDragstart","onDrop","onDragover","onDragenter","onDragleave"])))),128)),(t(!0),a(s,null,o(e.getWeekItems(h),(i=>r(e.$slots,"item",{value:i,weekStartDate:h,top:e.getItemTop(i)},(()=>[(t(),a("div",{key:i.id,draggable:e.enableDragDrop,"aria-grabbed":e.enableDragDrop?i==e.currentDragItem:"undefined",class:[i.classes,"cv-item"],title:i.title,style:`top:${e.getItemTop(i)};${i.originalItem.style}`,onDragstart:t=>e.onDragItemStart(i,t),onMouseenter:t=>e.onMouseEnterItem(i,t),onMouseleave:t=>e.onMouseLeaveItem(i,t),onClick:l((t=>e.onClickItem(i,t)),["stop"]),innerHTML:e.getItemTitle(i)},null,46,["draggable","aria-grabbed","title","onDragstart","onMouseenter","onMouseleave","onClick","innerHTML"]))])))),256))])],2)))),128))],8,["aria-multiselectable"])],2)};var b=e({name:"CalendarViewHeader",props:{headerProps:{type:Object,required:!0},previousYearLabel:{type:String,default:"<<"},previousPeriodLabel:{type:String,default:"<"},nextPeriodLabel:{type:String,default:">"},nextYearLabel:{type:String,default:">>"}},emits:["input"],methods:{onInput(e){this.$emit("input",e)}}});const v={class:"cv-header"},P={class:"cv-header-nav"},I={class:"periodLabel"};b.render=function(e,n,s,o,u,g){return t(),a("div",v,[i("div",P,[i("button",{disabled:!e.headerProps.previousYear,class:"previousYear","aria-label":"Previous Year",onClick:n[1]||(n[1]=l((t=>e.onInput(e.headerProps.previousYear)),["prevent"]))},d(e.previousYearLabel),9,["disabled"]),i("button",{disabled:!e.headerProps.previousPeriod,class:"previousPeriod","aria-label":"Previous Period",onClick:n[2]||(n[2]=l((t=>e.onInput(e.headerProps.previousPeriod)),["prevent"])),innerHTML:e.previousPeriodLabel},null,8,["disabled","innerHTML"]),i("button",{class:"currentPeriod","aria-label":"Current Period",onClick:n[3]||(n[3]=l((t=>e.onInput(e.headerProps.currentPeriod)),["prevent"]))},d(e.headerProps.currentPeriodLabel),1),i("button",{disabled:!e.headerProps.nextPeriod,class:"nextPeriod","aria-label":"Next Period",onClick:n[4]||(n[4]=l((t=>e.onInput(e.headerProps.nextPeriod)),["prevent"]))},d(e.nextPeriodLabel),9,["disabled"]),i("button",{disabled:!e.headerProps.nextYear,class:"nextYear","aria-label":"Next Year",onClick:n[5]||(n[5]=l((t=>e.onInput(e.headerProps.nextYear)),["prevent"]))},d(e.nextYearLabel),9,["disabled"])]),i("div",I,[r(e.$slots,"label",{},(()=>[h(d(e.headerProps.periodLabel),1)]))])])};export{u as CalendarMath,p as CalendarView,b as CalendarViewHeader};