@progress/kendo-react-scheduler
Version:
React Scheduler brings the functionality of Outlook's Calendar to a single UI component. KendoReact Scheduler package
370 lines (369 loc) • 13.7 kB
JavaScript
/**
* @license
*-------------------------------------------------------------------------------------------
* Copyright © 2026 Progress Software Corporation. All rights reserved.
* Licensed under commercial license. See LICENSE.md in the package root for more information
*-------------------------------------------------------------------------------------------
*/
import * as a from "react";
import n from "prop-types";
import { getModelFields as Oe, toSchedulerGroups as We, findMaster as y, setField as d, getField as s } from "./utils/index.mjs";
import { validatePackage as Ne, getLicenseMessage as Pe, useWebMcpRegister as He, useRtl as ze, clone as b, classNames as _e, WatermarkOverlay as Be } from "@progress/kendo-react-common";
import { SchedulerContext as Ue } from "./context/SchedulerContext.mjs";
import { useControlledState as W } from "./hooks/useControlledState.mjs";
import { useInternationalization as Ge, useLocalization as Ke } from "@progress/kendo-react-intl";
import { SchedulerHeader as Ze } from "./components/header/SchedulerHeader.mjs";
import { SchedulerNavigation as se } from "./components/header/navigation/SchedulerNavigation.mjs";
import { SchedulerViewSelector as je } from "./components/header/view-selector/SchedulerViewSelector.mjs";
import { addMonths as Y, addDays as $, ZonedDate as qe } from "@progress/kendo-date-math";
import { SchedulerFooter as Je } from "./components/footer/SchedulerFooter.mjs";
import { ButtonGroup as Qe, Button as R, ToolbarSpacer as Xe } from "@progress/kendo-react-buttons";
import { today as ee, messages as T, previousTitle as te, nextTitle as re, showFullDay as ae, showWorkDay as ne } from "./messages/index.mjs";
import { NavigationDatePicker as Ye } from "./components/header/navigation/NavigationDatePicker.mjs";
import { ViewSelectorList as $e } from "./components/header/view-selector/ViewSelectorList.mjs";
import { BusinessHours as et } from "./components/footer/bussiness-hours/BussinessHours.mjs";
import { DayView as P, dayViewDefaultProps as tt } from "./views/day/DayView.mjs";
import { packageMetadata as oe } from "./package-metadata.mjs";
import { chevronRightIcon as le, chevronLeftIcon as ce, clockIcon as rt } from "@progress/kendo-svg-icons";
import { DATA_ACTION as N } from "./constants/index.mjs";
import { AgendaView as at, agendaViewDefaultProps as nt } from "./views/agenda/AgendaView.mjs";
import { MonthView as ot, monthViewDefaultProps as lt } from "./views/month/MonthView.mjs";
import { WeekView as ct, weekViewDefaultProps as st } from "./views/week/WeekView.mjs";
import { WorkWeekView as it, workWeekDefaultProps as ut } from "./views/week/WorkWeekView.mjs";
import { TimelineView as dt, timeLineViewDefaultProps as mt } from "./views/time/TimelineView.mjs";
const gt = "{0:D}", ht = "{0:d}", ft = "application", k = /* @__PURE__ */ new Map();
k.set(at, nt);
k.set(P, tt);
k.set(ot, lt);
k.set(ct, st);
k.set(it, ut);
k.set(dt, mt);
const ie = a.forwardRef((r, ue) => {
var J, Q, X;
const de = !Ne(oe, { component: "Scheduler" }), me = Pe(oe), { timezone: V, onDataChange: M } = r, g = a.useRef(null), p = a.useRef(null);
a.useImperativeHandle(p, () => ({ props: r, element: g.current })), a.useImperativeHandle(ue, () => p.current), He("scheduler", p, r, r.webMcp);
const v = ze(g), A = Ge(), C = Ke(), { fields: t } = a.useMemo(() => Oe(r.modelFields), [r.modelFields]), [D, h] = W(
r.defaultDate || f.defaultDate,
r.date,
r.onDateChange
), x = a.Children.toArray(r.children || []).map(
(e) => {
var l;
return a.isValidElement(e) ? a.cloneElement(e, { ...k.get(e.type), ...(l = e.props) != null ? l : {} }) : e;
}
), ge = a.cloneElement(/* @__PURE__ */ a.createElement(P, null), k.get(P)), [H, z] = W(
r.defaultView || x[0] && x[0].props.name || "day",
r.view,
r.onViewChange
), [S, _] = W(!0), i = x.find((e) => e.props.name === H) || x[0] || ge, w = ((J = r.data) != null ? J : f.data) || f.data, he = We(r.group, r.resources), fe = r.group && r.group.orientation ? r.group.orientation : "horizontal", pe = i.props.selectedDateFormat || gt, De = i.props.selectedShortDateFormat || ht, B = i.props.slotDuration, we = i.props.dateRange !== void 0 ? typeof i.props.dateRange == "function" ? i.props.dateRange.call(void 0, {
intl: A,
date: D,
timezone: V,
numberOfDays: i.props.numberOfDays,
workWeekStart: i.props.workWeekStart || A.firstDay(),
workWeekEnd: i.props.workWeekEnd || (A.firstDay() + i.props.numberOfDays) % 6
}) : i.props.dateRange : { start: f.defaultDate, end: f.defaultDate }, E = a.useCallback(
({
created: e = [],
updated: l = [],
deleted: m = []
}) => {
if (M) {
const o = {
created: e,
updated: l,
deleted: m
};
M.call(void 0, o);
}
},
[M]
), U = a.useCallback(
(e) => {
const l = [e.dataItem];
E({ created: l });
},
[E]
), G = a.useCallback(
(e) => {
const l = [], m = [];
if (e.series)
if (Array.isArray(e.dataItem))
e.dataItem.forEach((o) => {
const c = b(y(e.dataItem, t, w)), u = b(o);
d(u, t.originalStart, s(c, t.originalStart)), d(u, t.recurrenceId, s(c, t.recurrenceId)), d(
u,
t.recurrenceExceptions,
s(c, t.recurrenceExceptions)
), m.push(u);
});
else {
const o = b(y(e.dataItem, t, w)), c = b(e.dataItem);
d(c, t.originalStart, s(o, t.originalStart)), d(c, t.recurrenceId, s(o, t.recurrenceId)), d(
c,
t.recurrenceExceptions,
s(o, t.recurrenceExceptions)
), m.push(c);
}
else if (Array.isArray(e.dataItem))
e.dataItem.forEach((o) => {
const c = s(o, t.recurrenceRule) !== null && s(o, t.recurrenceRule) !== void 0;
if (s(o, t.recurrenceId) !== null && s(o, t.recurrenceId) !== void 0 && c) {
const I = b(y(o, t, w)), O = s(o, t.originalStart), Le = s(I, t.recurrenceExceptions) || [];
d(I, t.recurrenceExceptions, [...Le, O]), d(o, t.recurrenceRule, null), m.push(I), l.push(o);
} else
m.push(o);
});
else {
const o = s(e.dataItem, t.recurrenceRule) !== null && s(e.dataItem, t.recurrenceRule) !== void 0;
if (s(e.dataItem, t.recurrenceId) !== null && s(e.dataItem, t.recurrenceId) !== void 0 && o) {
const u = b(y(e.dataItem, t, w)), I = s(e.dataItem, t.originalStart), O = s(u, t.recurrenceExceptions) || [];
d(u, t.recurrenceExceptions, [...O, I]), d(e.dataItem, t.recurrenceRule, null), m.push(u), l.push(e.dataItem);
} else
m.push(e.dataItem);
}
E({ updated: m, created: l });
},
[E, t, w]
), K = a.useCallback(
(e) => {
const l = [], m = [];
if (e.series) {
const o = b(y(e.dataItem, t, w)), c = b(e.dataItem);
d(c, t.originalStart, s(o, t.originalStart)), d(c, t.recurrenceId, s(o, t.recurrenceId)), d(c, t.recurrenceRule, s(o, t.recurrenceRule)), d(c, t.recurrenceExceptions, s(o, t.recurrenceExceptions)), m.push(c);
} else if (!(s(e.dataItem, t.recurrenceRule) !== null && s(e.dataItem, t.recurrenceRule) !== void 0))
m.push(e.dataItem);
else {
const c = b(y(e.dataItem, t, w)), u = s(e.dataItem, t.originalStart), I = s(c, t.recurrenceExceptions) || [];
d(c, t.recurrenceExceptions, [...I, u]), d(e.dataItem, t.recurrenceRule, null), l.push(c);
}
E({ updated: l, deleted: m });
},
[E, t, w]
), Z = a.useCallback(
(e) => {
switch (e.type) {
case N.create:
U(e);
break;
case N.update:
G(e);
break;
case N.remove:
K(e);
break;
}
},
[U, K, G]
), be = a.useCallback(
(e, l) => {
z(e, {
...l,
target: p.current
});
},
[z, p]
), ke = a.useCallback(
(e, l) => {
h(e, {
...l,
target: p.current
});
},
[h, p]
), ve = a.useCallback(
(e) => {
e.value && h(e.value, {
...e,
target: p.current,
nativeEvent: e.nativeEvent
});
},
[h, p]
), Ie = a.useCallback(
(e) => {
var c, u;
e.preventDefault();
const l = (u = (c = i.props.step) != null ? c : i.props.numberOfDays) != null ? u : 1, o = l > 27 ? Y(D, Math.round(l / 27)) : $(D, l);
h(o, e);
},
[D, h, i.props.numberOfDays, i.props.step]
), Ee = a.useCallback(
(e) => {
var c, u;
e.preventDefault();
const l = (u = (c = i.props.step) != null ? c : i.props.numberOfDays) != null ? u : 1, o = l > 27 ? Y(D, -Math.round(l / 27)) : $(D, -l);
h(o, e);
},
[D, h, i.props.numberOfDays, i.props.step]
), ye = a.useCallback(
(e) => {
e.preventDefault();
const l = qe.fromLocalDate(/* @__PURE__ */ new Date(), V);
h(new Date(l.getTime()), e);
},
[h, V]
), xe = a.useCallback(() => {
_(!S);
}, [_, S]), Se = a.useCallback(() => {
g.current && (g.current.style.boxShadow = "0 0.5px 0.5px 0.5px rgba(0, 0, 0, .12)");
}, [g]), Ce = a.useCallback(() => {
g.current && (g.current.style.boxShadow = "");
}, [g]), Re = a.useMemo(
() => {
var e;
return { ...r.style, height: (e = r.height) != null ? e : f.height };
},
[r.height, r.style]
), Te = a.useMemo(
() => _e(
{ "k-rtl": r.rtl !== void 0 ? r.rtl : v === "rtl" },
"k-scheduler",
r.className
),
[r.className, r.rtl, v]
), F = C.toLanguageString(ee, T[ee]), j = C.toLanguageString(te, T[te]), q = C.toLanguageString(re, T[re]), Ve = i.props.header || r.header || f.header, Me = i.props.footer || r.footer || f.footer, Ae = se, [L, Fe] = a.useState(null);
return /* @__PURE__ */ a.createElement(
Ue,
{
element: g,
props: r,
views: x,
fields: t,
groups: he,
dateRange: we,
orientation: fe,
dateFormat: { dateFormat: pe, shortDateFormat: De },
date: [D, ke],
activeView: [H, be],
selection: [L, Fe],
data: [w, Z]
},
/* @__PURE__ */ a.createElement(
"div",
{
ref: g,
id: r.id,
style: Re,
className: Te,
tabIndex: (Q = r.tabIndex) != null ? Q : f.tabIndex,
dir: v,
role: r.role || ft,
"aria-label": r.ariaLabel,
"aria-labelledby": r.ariaLabelledby,
"aria-activedescendant": L && L.props.id || void 0,
onFocus: Se,
onBlur: Ce
},
/* @__PURE__ */ a.createElement(Ve, null, /* @__PURE__ */ a.createElement(Ae, null, /* @__PURE__ */ a.createElement(Qe, { className: "k-scheduler-navigation" }, /* @__PURE__ */ a.createElement(
R,
{
role: "button",
tabIndex: -1,
title: F,
"aria-label": F,
onClick: ye
},
F
), /* @__PURE__ */ a.createElement(
R,
{
role: "button",
tabIndex: -1,
icon: v === "rtl" ? "chevron-right" : "chevron-left",
svgIcon: v === "rtl" ? le : ce,
title: j,
"aria-label": j,
onClick: Ee
}
), /* @__PURE__ */ a.createElement(
R,
{
role: "button",
tabIndex: -1,
icon: v === "rtl" ? "chevron-left" : "chevron-right",
svgIcon: v === "rtl" ? ce : le,
title: q,
"aria-label": q,
onClick: Ie
}
))), /* @__PURE__ */ a.createElement(Ye, { value: D, onChange: ve }), /* @__PURE__ */ a.createElement(Xe, null), /* @__PURE__ */ a.createElement($e, null)),
i && /* @__PURE__ */ a.createElement(
i.type,
{
editable: (X = r.editable) != null ? X : f.editable,
key: i.props.name,
item: r.item,
viewItem: r.viewItem,
editItem: r.editItem,
task: r.task,
viewTask: r.viewTask,
editTask: r.viewTask,
slot: r.slot,
viewSlot: r.viewSlot,
editSlot: r.editSlot,
form: r.form,
onDataAction: Z,
showWorkHours: S,
...i.props
}
),
/* @__PURE__ */ a.createElement(Me, null, B && B < 1440 && /* @__PURE__ */ a.createElement(et, null, /* @__PURE__ */ a.createElement(R, { tabIndex: -1, onClick: xe, icon: "clock", svgIcon: rt }, C.toLanguageString(
S ? ae : ne,
T[S ? ae : ne]
)))),
de && /* @__PURE__ */ a.createElement(Be, { message: me })
)
);
}), f = {
data: [],
height: 600,
tabIndex: -1,
editable: !1,
defaultDate: /* @__PURE__ */ new Date(),
header: Ze,
footer: Je,
navigation: se,
viewSelector: je
};
ie.propTypes = {
data: n.array,
editable: n.oneOfType([
n.bool,
n.shape({
add: n.bool,
drag: n.bool,
edit: n.bool,
remove: n.bool,
resize: n.bool
})
]),
view: n.string,
defaultView: n.string,
date: n.any,
defaultDate: n.any,
rtl: n.bool,
height: n.oneOfType([n.number, n.string]),
children: n.any,
timezone: n.string,
group: n.any,
resources: n.any,
modelFields: n.shape({
id: n.string,
start: n.string,
startTimezone: n.string,
end: n.string,
endTimezone: n.string,
isAllDay: n.string,
title: n.string,
description: n.string,
recurrenceRule: n.string,
recurrenceId: n.string,
recurrenceException: n.string
})
};
ie.displayName = "KendoReactScheduler";
export {
ie as Scheduler,
f as schedulerDefaultProps
};