react-custom-calendars
Version:
A calendar that can be customized to your liking 🧨
135 lines (134 loc) • 3.94 kB
JavaScript
import { useState as x, useMemo as w } from "react";
const U = (t, r) => {
const c = t.getUTCFullYear(), a = t.getUTCMonth() + 1, o = t.getUTCDate();
let e = r;
return r.includes("yyyy") && (e = e.replace("yyyy", c.toString())), r.includes("MM") && (e = e.replace("MM", a.toString().padStart(2, "0"))), r.includes("dd") && (e = e.replace("dd", o.toString().padStart(2, "0"))), e;
}, p = (t, r, c, a = !1) => {
const e = new Date(Date.UTC(t, r, 1)).getUTCDay(), l = new Date(Date.UTC(t, r + 1, 0)).getUTCDate(), s = r - 1, n = s < 0 ? t - 1 : t, D = s < 0 ? 11 : s, u = new Date(
Date.UTC(n, D + 1, 0)
).getUTCDate(), i = r + 1, d = i > 11 ? t + 1 : t, S = i > 11 ? 0 : i, C = Array(6).fill(null).map(() => Array(7).fill(0)), T = {}, m = {};
let v = 1, h = 1;
for (let g = 0; g < 6; g++)
for (let f = 0; f < 7; f++)
if (g === 0 && f < e) {
const M = u - (e - f - 1);
if (C[g][f] = a ? -M : 0, a) {
const k = new Date(
Date.UTC(n, D, M)
);
T[M] = U(k, c);
}
} else if (v <= l)
C[g][f] = v++;
else {
if (C[g][f] = a ? -h : 0, a) {
const M = new Date(
Date.UTC(d, S, h)
);
m[h] = U(M, c);
}
h++;
}
return { matrix: C, year: t, month: r, prevMonthDates: T, nextMonthDates: m };
}, O = (t, r, c, a, o, e, l) => {
let s = t.find((n) => n.includes(a));
return !s && a > 28 && (s = t[t.length - 1]), s ? s.map((n) => {
if (n > 0)
return U(new Date(Date.UTC(r, c, n)), l);
if (n < 0) {
const D = Math.abs(n), u = o[D] || e[D];
return u ? U(new Date(u), l) : "0";
}
return "0";
}) : [];
}, Y = (t, r, c, a, o = !1, e = {}, l = {}) => t.map(
(s) => s.map((n) => {
if (n > 0)
return U(new Date(Date.UTC(r, c, n)), a);
if (o && n < 0) {
const D = Math.abs(n), u = e[D] || l[D];
return u ? U(new Date(u), a) : "0";
}
return "0";
})
), F = ({ type: t, initialDate: r }) => {
if (!t)
throw new Error("Calendar type is required");
const [c, a] = x(() => {
if (r)
return new Date(
Date.UTC(r.getUTCFullYear(), r.getUTCMonth(), 1)
).toISOString();
const D = /* @__PURE__ */ new Date();
return new Date(
Date.UTC(D.getUTCFullYear(), D.getUTCMonth(), 1)
).toISOString();
}), [o, e] = c.split("T")[0].split("-").map(Number), l = w(() => p(o, e - 1, t), [o, e]), s = w(() => Y(l.matrix, o, e - 1, t), [l, t, o, e]), n = (D) => {
const u = new Date(Date.UTC(o, e - 1 + D, 1));
a(u.toISOString());
};
return {
currentDate: c,
setCurrentDate: a,
monthCalendarData: s,
moveToNext: () => n(1),
moveToPrev: () => n(-1),
moveToPeriod: n
};
}, I = ({ type: t, initialDate: r }) => {
if (!t)
throw new Error("Calendar type is required");
const [c, a] = x(() => {
if (r)
return new Date(
Date.UTC(
r.getUTCFullYear(),
r.getUTCMonth(),
r.getUTCDate()
)
).toISOString();
const T = /* @__PURE__ */ new Date();
return new Date(
Date.UTC(T.getUTCFullYear(), T.getUTCMonth(), T.getUTCDate())
).toISOString();
}), [o, e, l] = c.split("T")[0].split("-").map(Number), {
matrix: s,
year: n,
month: D,
prevMonthDates: u,
nextMonthDates: i
} = w(() => p(o, e - 1, t, !0), [o, e]), d = w(() => O(
s,
o,
e - 1,
l,
u,
i,
t
), [s, o, e, l, u, i, t]), S = w(() => Y(
s,
n,
D,
t,
!0,
u,
i
), [s, n, D, t, u, i]), C = (T) => {
const m = new Date(Date.UTC(o, e - 1, l + T * 7));
a(m.toISOString());
};
return {
currentDate: c,
setCurrentDate: a,
weekDates: d,
monthlyWeekGrid: S,
moveToNext: () => C(1),
moveToPrev: () => C(-1),
moveToPeriod: C,
matrix: s
};
};
export {
F as MonthCalendar,
I as WeekCalendar
};