UNPKG

vue-simple-calendar

Version:
447 lines (446 loc) 22.4 kB
var we = Object.defineProperty; var Ae = (e, n, a) => n in e ? we(e, n, { enumerable: !0, configurable: !0, writable: !0, value: a }) : e[n] = a; var Y = (e, n, a) => Ae(e, typeof n != "symbol" ? n + "" : n, a); import { defineComponent as ue, reactive as We, computed as f, watch as Ne, createElementBlock as D, openBlock as v, normalizeClass as F, unref as g, renderSlot as C, createElementVNode as y, createCommentVNode as Q, Fragment as w, renderList as A, toDisplayString as P, withModifiers as M, createTextVNode as J, normalizeStyle as de } from "vue"; const N = () => R(/* @__PURE__ */ new Date()), He = (e, n, a) => { switch (n) { case "year": return new Date(e.getFullYear(), 0); case "month": return new Date(e.getFullYear(), e.getMonth()); case "week": return X(e, a); default: return e; } }, Be = (e) => [...Array(7)].map((n, a) => L(e, a)), L = (e, n) => new Date(e.getFullYear(), e.getMonth(), e.getDate() + n, e.getHours(), e.getMinutes(), e.getSeconds()), X = (e, n) => L(e, (n - e.getDay() - 7) % -7), Ee = (e, n) => L(X(e, n), 7), W = (e) => new Date(e.getFullYear(), e.getMonth()), Ue = (e) => Math.ceil(e.getDate() / 7), Re = (e, n, a) => new Date(e.getFullYear() + (n == "year" ? a : 0), e.getMonth() + (n == "month" ? a : 0), e.getDate() + (n == "week" ? a * 7 : 0)), Z = (e) => ("0" + String(e.getMonth() + 1)).slice(-2), x = (e) => ("0" + String(e.getDate())).slice(-2), ce = (e) => e.getFullYear() + "-" + Z(e), Ve = (e) => ce(e) + "-" + x(e), ze = (e) => Z(e) + "-" + x(e), je = (e, n, a) => { if (e.getHours() === 0 && e.getMinutes() === 0 && e.getSeconds() === 0) return ""; if (!V()) { var d = (/* @__PURE__ */ new Date()).getTimezoneOffset() * 6e4; return new Date(e.getTime() - d).toISOString().slice(11, 16); } return e.toLocaleTimeString(n, a); }, qe = (e, n, a, d) => { const u = e.getFullYear() === n.getFullYear(), c = me(e, n), k = !(a === "year") && !(a === "month"); let p = []; return p.push(d[e.getMonth()]), k && (p.push(" "), p.push(e.getDate())), u || (p.push(k ? ", " : " "), p.push(e.getFullYear())), !c || !u ? (p.push(" – "), c || p.push(d[n.getMonth()]), k && p.push(" ")) : k && p.push(" – "), k ? (p.push(n.getDate()), p.push(", ")) : p.push(" "), p.push(n.getFullYear()), p.join(""); }, ge = (e, n) => { const a = Date.UTC(n.getFullYear(), n.getMonth(), n.getDate()), d = Date.UTC(e.getFullYear(), e.getMonth(), e.getDate()); return (a - d) / 864e5; }, Ge = (e, n) => !!e && !!n && ge(e, n) === 0, Qe = (e, n) => !!e && !!n && e.getTime() === n.getTime(), me = (e, n) => !!e && !!n && e.getFullYear() === n.getFullYear() && e.getMonth() === n.getMonth(), Je = (e) => W(e) < W(N()), Ke = (e) => W(e) > W(N()), Xe = (e) => R(e) > N(), Ze = (e) => R(e) < N(), xe = (e) => e.getMonth() !== L(e, 7).getMonth(), _e = (e) => e.getMonth() !== L(e, 1).getMonth(), fe = (e) => { let n = [...Array(7)].map((a) => 0); return e.split(/\D/, 7).forEach((a, d) => n[d] = Number(a)), n[1]--, new Date(n[0], n[1], n[2], n[3], n[4], n[5], n[6]); }, K = (e) => typeof e == "string" ? fe(e) : new Date(e), R = (e) => { const n = new Date(e); return n.setHours(0, 0, 0, 0), n; }, et = (e) => e.substring(0, 2), V = () => typeof Intl < "u", tt = (e, n) => { if (!V()) return [...Array(12)].map((d) => ""); const a = new Intl.DateTimeFormat(e, { month: n }); return [...Array(12)].map((d, u) => a.format(new Date(2017, u, 1))); }, at = (e, n, a) => { if (!V()) return [...Array(7)].map((u) => ""); const d = new Intl.DateTimeFormat(e, { weekday: n }); return [...Array(7)].map((u, c) => d.format(new Date(2017, 0, (c + 1 + a) % 7))); }, nt = () => typeof navigator > "u" ? "unk" : (navigator.languages && navigator.languages.length ? navigator.languages[0] : navigator.language).toLowerCase(), rt = (e, n) => { const a = e.classes ? [...e.classes] : []; return n && a.push("isHovered"), { originalItem: e, startDate: K(e.startDate), // For an item without an end date, the end date is the start date endDate: K(e.endDate || e.startDate), classes: a, // Items without a title are untitled title: e.title || "Untitled", // An ID is *required*. Auto-generating leads to weird bugs because these are used as keys and passed in items id: e.id, // Pass the URL along url: e.url, // Use the item's title as the tooltip if the tooltip is undefined or null (but not if it is blank -- use blank to essentially disable tooltips) tooltip: e.tooltip ?? e.title }; }, o = { addDays: L, beginningOfMonth: W, beginningOfPeriod: He, beginningOfWeek: X, dateOnly: R, dayDiff: ge, daysOfWeek: Be, endOfWeek: Ee, formattedPeriod: qe, formattedTime: je, fromIsoStringToLocalDate: fe, getDefaultBrowserLocale: nt, getFormattedMonthNames: tt, getFormattedWeekdayNames: at, incrementPeriod: Re, instanceOfMonth: Ue, isFutureMonth: Ke, isInFuture: Xe, isInPast: Ze, isLastDayOfMonth: _e, isLastInstanceOfMonth: xe, isoMonthDay: ze, isoYearMonth: ce, isoYearMonthDay: Ve, isPastMonth: Je, isSameDate: Ge, isSameDateTime: Qe, isSameMonth: me, languageCode: et, normalizeItem: rt, paddedDay: x, paddedMonth: Z, supportsIntl: V, today: N, toLocalDate: K }; class ot { constructor() { Y(this, "currentDragItem"); Y(this, "dateSelectionOrigin"); Y(this, "currentHoveredItemId", ""); Y(this, "CalendarMath", o); } } const st = { class: "cv-header-days" }, it = { key: 0, class: "cv-weeknumber" }, lt = ["aria-multiselectable"], dt = { key: 0, class: "cv-weeknumber" }, ut = { class: "cv-weekdays" }, ct = ["draggable", "aria-grabbed", "aria-label", "aria-selected", "aria-dropeffect", "onClick", "onDragstart", "onDrop", "onDragover", "onDragenter", "onDragleave"], gt = { class: "cv-day-number" }, mt = { key: 0, class: "cv-fom-name" }, ft = ["draggable", "aria-grabbed", "title", "onDragstart", "onMouseenter", "onMouseleave", "onClick", "innerHTML"], pt = ["draggable", "aria-grabbed", "title", "onDragstart", "onMouseenter", "onMouseleave", "onClick"], Ot = /* @__PURE__ */ ue({ __name: "CalendarView", props: { showDate: { default: void 0 }, displayPeriodUom: { default: "month" }, displayPeriodCount: { default: 1 }, displayWeekNumbers: { type: Boolean, default: !1 }, locale: { default: void 0 }, monthNameFormat: { default: "long" }, weekdayNameFormat: { default: "short" }, showTimes: { type: Boolean, default: !1 }, timeFormatOptions: { default: () => ({}) }, disablePast: { type: Boolean, default: !1 }, disableFuture: { type: Boolean, default: !1 }, enableDateSelection: { type: Boolean, default: !1 }, selectionStart: { default: void 0 }, selectionEnd: { default: void 0 }, enableDragDrop: { type: Boolean, default: !1 }, startingDayOfWeek: { default: 0 }, items: { default: () => [] }, dateClasses: { default: () => ({}) }, itemTop: { default: "1.4em" }, itemContentHeight: { default: "1.4em" }, itemBorderHeight: { default: "2px" }, periodChangedCallback: { type: Function, default: void 0 }, currentPeriodLabel: { default: "" }, currentPeriodLabelIcons: { default: "⇤-⇥" }, enableTooltip: { type: Boolean, default: !0 }, doEmitItemMouseEvents: { type: Boolean, default: !1 }, enableHtmlTitles: { type: Boolean, default: !0 }, monthNameOn1st: { type: Boolean, default: !0 } }, emits: ["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"], setup(e, { emit: n }) { const a = e, d = n, u = We(new ot()), c = f(() => a.locale || o.getDefaultBrowserLocale()), I = f(() => a.showDate ? o.dateOnly(a.showDate) : o.today()), h = f(() => o.beginningOfPeriod(I.value, a.displayPeriodUom, a.startingDayOfWeek)), k = f( () => o.addDays(o.incrementPeriod(h.value, a.displayPeriodUom, a.displayPeriodCount), -1) ), p = f(() => { const t = new Date(h.value.getFullYear(), 0, 1), s = o.addDays(t, (11 - t.getDay()) % 7), i = o.beginningOfPeriod(s, "week", a.startingDayOfWeek), m = o.beginningOfWeek(h.value, a.startingDayOfWeek); return 1 + Math.floor(o.dayDiff(i, m) / 7); }), H = f(() => o.beginningOfWeek(h.value, a.startingDayOfWeek)), z = f(() => o.endOfWeek(k.value, a.startingDayOfWeek)), pe = f(() => { const t = Math.floor((o.dayDiff(H.value, z.value) + 1) / 7); return [...Array(t)].map((s, i) => o.addDays(H.value, i * 7)); }), B = f(() => o.getFormattedMonthNames(c.value, a.monthNameFormat)), De = f(() => o.getFormattedWeekdayNames(c.value, a.weekdayNameFormat, a.startingDayOfWeek)), j = f(() => a.items ? a.items.map((t) => o.normalizeItem(t, t.id === u.currentHoveredItemId)) : []), q = f(() => o.beginningOfPeriod(o.today(), a.displayPeriodUom, a.startingDayOfWeek)), ve = f( () => o.addDays(o.incrementPeriod(q.value, a.displayPeriodUom, a.displayPeriodCount), -1) ), he = f(() => o.formattedPeriod(h.value, k.value, a.displayPeriodUom, B.value)), be = f(() => { const t = q.value, s = h.value; return a.currentPeriodLabel ? a.currentPeriodLabel === "icons" ? a.currentPeriodLabelIcons[Math.sign(t.getTime() - s.getTime()) + 1] : a.currentPeriodLabel : o.formattedPeriod(t, ve.value, a.displayPeriodUom, B.value); }), ye = f(() => a.monthNameOn1st && (a.displayPeriodUom !== "month" || a.displayPeriodCount > 1)), _ = (t) => ye.value && t.getDate() == 1 ? B.value[t.getMonth()] : "", Pe = f( () => ({ // Dates for UI navigation previousYear: S(-12), previousPeriod: S(-1), nextPeriod: S(1), previousFullPeriod: S(-a.displayPeriodCount), nextFullPeriod: S(a.displayPeriodCount), nextYear: S(12), currentPeriod: q.value, currentPeriodLabel: be.value, // Dates for header display periodStart: h.value, periodEnd: k.value, // Extra information that could be useful to a custom header displayLocale: c.value, displayFirstDate: H.value, displayLastDate: z.value, monthNames: B.value, fixedItems: j.value, periodLabel: he.value }) ), Me = f(() => ({ periodStart: h, periodEnd: k, displayFirstDate: H, displayLastDate: z })); Ne( () => Me, (t) => { a.periodChangedCallback && (d("period-changed"), a.periodChangedCallback(t, "watch")); }, { immediate: !0, deep: !0 } ); const ke = (t, s) => { a.disablePast && o.isInPast(t) || a.disableFuture && o.isInFuture(t) || d("click-date", t, re(t, t), s); }, ee = (t, s) => d("click-item", t, s), $ = (t) => "dow" + (t + a.startingDayOfWeek) % 7, S = (t) => { const s = o.incrementPeriod(h.value, a.displayPeriodUom, t), i = o.incrementPeriod(s, a.displayPeriodUom, a.displayPeriodCount); return a.disablePast && i <= o.today() || a.disableFuture && s > o.today() ? null : s; }, te = (t, s) => { u.currentHoveredItemId = t.id, a.doEmitItemMouseEvents && d("item-mouseenter", t, s); }, ae = (t, s) => { u.currentHoveredItemId = "", a.doEmitItemMouseEvents && d("item-mouseleave", t, s); }, Ie = (t, s) => { var m, r; if (!a.enableDateSelection) return !1; (m = s.dataTransfer) == null || m.setData("text", t.toString()); let i = new Image(); return i.src = "data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==", (r = s.dataTransfer) == null || r.setDragImage(i, 10, 10), u.dateSelectionOrigin = t, d("date-selection-start", G(t), s), !0; }, ne = (t, s) => { var i; return a.enableDragDrop ? ((i = s.dataTransfer) == null || i.setData("text", t.id), u.currentDragItem = t, u.dateSelectionOrigin = void 0, d("drag-start", t, s), !0) : !1; }, G = (t) => t <= u.dateSelectionOrigin ? [t, u.dateSelectionOrigin] : [u.dateSelectionOrigin, t], Oe = (t, s) => { a.enableDragDrop && d("drag-over-date", u.currentDragItem, t, s); }, Ce = (t, s) => { if (a.enableDateSelection && u.dateSelectionOrigin && d("date-selection", G(t), s), !a.enableDragDrop) return; d("drag-enter-date", u.currentDragItem, t, s), s.target.classList.add("draghover"); }, Se = (t, s) => { if (a.enableDateSelection && a.selectionStart || !a.enableDragDrop) return; d("drag-leave-date", u.currentDragItem, t, s), s.target.classList.remove("draghover"); }, Fe = (t, s) => { if (a.enableDateSelection && u.dateSelectionOrigin) { d("date-selection-finish", G(t), s); return; } if (!a.enableDragDrop) return; d("drop-on-date", u.currentDragItem, t, s), s.target.classList.remove("draghover"); }, Le = (t, s) => t.startDate < s.startDate ? -1 : s.startDate < t.startDate ? 1 : t.endDate > s.endDate ? -1 : s.endDate > t.endDate ? 1 : t.id < s.id ? -1 : 1, $e = (t) => re(t, o.addDays(t, 6)), re = (t, s) => j.value.filter((i) => i.endDate >= t && o.dateOnly(i.startDate) <= s, this).sort(Le), Te = (t) => !!j.value.find((s) => s.endDate >= t && o.dateOnly(s.startDate) <= t), oe = (t) => !(!a.selectionStart || !a.selectionEnd || t < o.dateOnly(a.selectionStart) || t > o.dateOnly(a.selectionEnd)), se = (t) => { const s = $e(t), i = [], m = [[], [], [], [], [], [], []]; if (!s) return i; for (let r = 0; r < s.length; r++) { const l = Object.assign({}, s[r], { classes: [...s[r].classes], itemRow: 0 }), b = l.startDate < t, T = b ? 0 : o.dayDiff(t, l.startDate), le = Math.max(1, Math.min(7 - T, o.dayDiff(o.addDays(t, T), l.endDate) + 1)); b && l.classes.push("continued"), o.dayDiff(t, l.endDate) > 6 && l.classes.push("toBeContinued"), o.isInPast(l.endDate) && l.classes.push("past"), l.originalItem.url && l.classes.push("hasUrl"); for (let O = 0; O < 7; O++) if (O === T) { let U = 0; for (; m[O][U]; ) U++; l.itemRow = U, m[O][U] = !0; } else O < T + le && (m[O][l.itemRow] = !0); l.classes.push(`offset${T}`), l.classes.push(`span${le}`), i.push(l); } return i; }, Ye = (t) => { const s = '<span class="startTime">' + o.formattedTime(t.startDate, c.value, a.timeFormatOptions) + "</span>"; let i = ""; return o.isSameDateTime(t.startDate, t.endDate) || (i = '<span class="endTime">' + o.formattedTime(t.endDate, c.value, a.timeFormatOptions) + "</span>"), s + i; }, ie = (t) => a.showTimes ? Ye(t) + " " + t.title : t.title, E = (t) => { const s = t.itemRow, i = a.itemContentHeight, m = a.itemBorderHeight; return `calc(${a.itemTop} + ${s}*${i} + ${s}*${m})`; }; return (t, s) => (v(), D("div", { "aria-label": "Calendar", class: F([ "cv-wrapper", `locale-${g(o).languageCode(c.value)}`, `locale-${c.value}`, `y${h.value.getFullYear()}`, `m${g(o).paddedMonth(h.value)}`, `period-${t.displayPeriodUom}`, `periodCount-${t.displayPeriodCount}`, { past: g(o).isPastMonth(h.value), future: g(o).isFutureMonth(h.value), noIntl: !g(o).supportsIntl } ]) }, [ C(t.$slots, "header", { headerProps: Pe.value }), y("div", st, [ t.displayWeekNumbers ? (v(), D("div", it)) : Q("", !0), (v(!0), D(w, null, A(De.value, (i, m) => C(t.$slots, "day-header", { index: $(m), label: i }, () => [ (v(), D("div", { key: $(m), class: F([$(m), "cv-header-day"]) }, P(i), 3)) ])), 256)) ]), y("div", { "aria-multiselectable": t.enableDateSelection, class: "cv-weeks" }, [ (v(!0), D(w, null, A(pe.value, (i, m) => (v(), D("div", { key: `${m}-week`, class: F(["cv-week", `week${m + 1}`, `ws${g(o).isoYearMonthDay(i)}`]) }, [ t.displayWeekNumbers ? (v(), D("div", dt, [ C(t.$slots, "week-number", { date: i, numberInYear: p.value + m, numberInPeriod: m + 1 }, () => [ y("span", null, P(p.value + m), 1) ]) ])) : Q("", !0), y("div", ut, [ (v(!0), D(w, null, A(g(o).daysOfWeek(i), (r, l) => (v(), D("div", { key: $(l), draggable: t.enableDateSelection, class: F([ "cv-day", $(l), `d${g(o).isoYearMonthDay(r)}`, `d${g(o).isoMonthDay(r)}`, `d${g(o).paddedDay(r)}`, `instance${g(o).instanceOfMonth(r)}`, { today: g(o).isSameDate(r, g(o).today()), outsideOfMonth: !g(o).isSameMonth(r, I.value), past: g(o).isInPast(r), future: g(o).isInFuture(r), last: g(o).isLastDayOfMonth(r), lastInstance: g(o).isLastInstanceOfMonth(r), hasItems: Te(r), selectionStart: g(o).isSameDate(r, t.selectionStart), selectionEnd: g(o).isSameDate(r, t.selectionEnd) }, ...t.dateClasses && t.dateClasses[g(o).isoYearMonthDay(r)] || [] ]), "aria-grabbed": t.enableDateSelection ? oe(r) : void 0, "aria-label": r.getDate().toString(), "aria-selected": oe(r), "aria-dropeffect": t.enableDragDrop && u.currentDragItem ? "move" : t.enableDateSelection && u.dateSelectionOrigin ? "execute" : "none", onClick: (b) => ke(r, b), onDragstart: (b) => Ie(r, b), onDrop: M((b) => Fe(r, b), ["prevent"]), onDragover: M((b) => Oe(r, b), ["prevent"]), onDragenter: M((b) => Ce(r, b), ["prevent"]), onDragleave: M((b) => Se(r, b), ["prevent"]) }, [ y("div", gt, [ _(r) ? (v(), D("span", mt, P(_(r)), 1)) : Q("", !0), J(" " + P(r.getDate()), 1) ]), C(t.$slots, "day-content", { day: r }) ], 42, ct))), 128)), a.enableHtmlTitles ? (v(!0), D(w, { key: 0 }, A(se(i), (r) => C(t.$slots, "item", { value: r, weekStartDate: i, top: E(r) }, () => [ (v(), D("div", { key: r.id, draggable: t.enableDragDrop, "aria-grabbed": t.enableDragDrop ? r == u.currentDragItem : void 0, class: F([r.classes, "cv-item"]), title: t.enableTooltip ? r.tooltip || r.title : void 0, style: de(`top:${E(r)};${r.originalItem.style}`), onDragstart: (l) => ne(r, l), onMouseenter: (l) => te(r, l), onMouseleave: (l) => ae(r, l), onClick: M((l) => ee(r, l), ["stop"]), innerHTML: ie(r) }, null, 46, ft)) ])), 256)) : (v(!0), D(w, { key: 1 }, A(se(i), (r) => C(t.$slots, "item", { value: r, weekStartDate: i, top: E(r) }, () => [ (v(), D("div", { key: r.id, draggable: t.enableDragDrop, "aria-grabbed": t.enableDragDrop ? r == u.currentDragItem : void 0, class: F([r.classes, "cv-item"]), title: t.enableTooltip ? r.tooltip || r.title : void 0, style: de(`top:${E(r)};${r.originalItem.style}`), onDragstart: (l) => ne(r, l), onMouseenter: (l) => te(r, l), onMouseleave: (l) => ae(r, l), onClick: M((l) => ee(r, l), ["stop"]) }, P(t.enableTooltip ?? "p") + " " + P(ie(r)), 47, pt)), s[0] || (s[0] = J(" div> ")) ])), 256)) ]) ], 2))), 128)) ], 8, lt) ], 2)); } }), Dt = { class: "cv-header" }, vt = { class: "cv-header-nav" }, ht = ["disabled"], bt = ["disabled", "innerHTML"], yt = ["disabled"], Pt = ["disabled"], Mt = { class: "periodLabel" }, Ct = /* @__PURE__ */ ue({ __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"], setup(e, { emit: n }) { const a = n, d = (u) => a("input", u); return (u, c) => (v(), D("div", Dt, [ y("div", vt, [ y("button", { disabled: !e.headerProps.previousYear, class: "previousYear", "aria-label": "Previous Year", onClick: c[0] || (c[0] = M((I) => d(e.headerProps.previousYear), ["prevent"])) }, P(e.previousYearLabel), 9, ht), y("button", { disabled: !e.headerProps.previousPeriod, class: "previousPeriod", "aria-label": "Previous Period", onClick: c[1] || (c[1] = M((I) => d(e.headerProps.previousPeriod), ["prevent"])), innerHTML: e.previousPeriodLabel }, null, 8, bt), y("button", { class: "currentPeriod", "aria-label": "Current Period", onClick: c[2] || (c[2] = M((I) => d(e.headerProps.currentPeriod), ["prevent"])) }, P(e.headerProps.currentPeriodLabel), 1), y("button", { disabled: !e.headerProps.nextPeriod, class: "nextPeriod", "aria-label": "Next Period", onClick: c[3] || (c[3] = M((I) => d(e.headerProps.nextPeriod), ["prevent"])) }, P(e.nextPeriodLabel), 9, yt), y("button", { disabled: !e.headerProps.nextYear, class: "nextYear", "aria-label": "Next Year", onClick: c[4] || (c[4] = M((I) => d(e.headerProps.nextYear), ["prevent"])) }, P(e.nextYearLabel), 9, Pt) ]), y("div", Mt, [ C(u.$slots, "label", {}, () => [ J(P(e.headerProps.periodLabel), 1) ]) ]) ])); } }); export { o as CalendarMath, Ot as CalendarView, Ct as CalendarViewHeader };