@forcecalendar/interface 1.2.0 → 1.3.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/dist/force-calendar-interface.esm.js +97 -2
- package/dist/force-calendar-interface.esm.js.map +1 -1
- package/dist/force-calendar-interface.umd.js +6 -5
- package/dist/force-calendar-interface.umd.js.map +1 -1
- package/package.json +1 -1
- package/src/components/ForceCalendar.js +1 -0
- package/src/renderers/BaseViewRenderer.js +140 -0
- package/src/renderers/DayViewRenderer.js +6 -1
- package/src/renderers/WeekViewRenderer.js +7 -1
- package/types/renderers/BaseViewRenderer.d.ts +29 -0
|
@@ -1012,6 +1012,87 @@ var n = class extends HTMLElement {
|
|
|
1012
1012
|
let t = e.dataset.eventId, n = this.stateManager.getEvents().find((e) => e.id === t);
|
|
1013
1013
|
n && this.stateManager.selectEvent(n);
|
|
1014
1014
|
}
|
|
1015
|
+
_enhanceTimeGridAccessibility(e, t) {
|
|
1016
|
+
let n = this.container.querySelector(".fc-time-grid");
|
|
1017
|
+
if (!n) return;
|
|
1018
|
+
n.setAttribute("role", "grid"), n.setAttribute("aria-label", t);
|
|
1019
|
+
let r = this.container.querySelector(".fc-time-gutter");
|
|
1020
|
+
r && r.setAttribute("aria-hidden", "true");
|
|
1021
|
+
let i = this.stateManager.getState().config.locale || "en-US", a = new Intl.DateTimeFormat(i, {
|
|
1022
|
+
weekday: "long",
|
|
1023
|
+
month: "long",
|
|
1024
|
+
day: "numeric"
|
|
1025
|
+
}), o = Array.from(this.container.querySelectorAll(e));
|
|
1026
|
+
for (let e of o) {
|
|
1027
|
+
e.setAttribute("role", "row");
|
|
1028
|
+
let t = new Date(e.dataset.date), n = a.format(t);
|
|
1029
|
+
e.setAttribute("aria-label", n);
|
|
1030
|
+
for (let t of e.querySelectorAll(".fc-hour-slot")) t.setAttribute("role", "gridcell"), t.setAttribute("tabindex", "-1"), t.setAttribute("aria-label", `${n}, ${this.formatHour(Number(t.dataset.hour))}`);
|
|
1031
|
+
}
|
|
1032
|
+
if (this._applySlotRovingTabindex(o), this._pendingSlotFocus) {
|
|
1033
|
+
let { colIndex: e, hour: t } = this._pendingSlotFocus;
|
|
1034
|
+
this._pendingSlotFocus = null;
|
|
1035
|
+
let n = this._slotAt(o, e, t);
|
|
1036
|
+
n && (this._applySlotRovingTabindex(o, n), n.focus());
|
|
1037
|
+
}
|
|
1038
|
+
this.addListener(this.container, "keydown", (t) => {
|
|
1039
|
+
let n = t.target.closest(".fc-hour-slot");
|
|
1040
|
+
if (!n || !this.container.contains(n)) return;
|
|
1041
|
+
let r = n.closest(e), i = o.indexOf(r), a = Number(n.dataset.hour), s = null;
|
|
1042
|
+
switch (t.key) {
|
|
1043
|
+
case "ArrowDown":
|
|
1044
|
+
s = this._slotAt(o, i, a + 1);
|
|
1045
|
+
break;
|
|
1046
|
+
case "ArrowUp":
|
|
1047
|
+
s = this._slotAt(o, i, a - 1);
|
|
1048
|
+
break;
|
|
1049
|
+
case "ArrowRight":
|
|
1050
|
+
s = this._slotAt(o, i + 1, a);
|
|
1051
|
+
break;
|
|
1052
|
+
case "ArrowLeft":
|
|
1053
|
+
s = this._slotAt(o, i - 1, a);
|
|
1054
|
+
break;
|
|
1055
|
+
case "Home":
|
|
1056
|
+
s = this._slotAt(o, i, 0);
|
|
1057
|
+
break;
|
|
1058
|
+
case "End":
|
|
1059
|
+
s = this._slotAt(o, i, 23);
|
|
1060
|
+
break;
|
|
1061
|
+
case "PageUp":
|
|
1062
|
+
case "PageDown":
|
|
1063
|
+
t.preventDefault(), this._pendingSlotFocus = {
|
|
1064
|
+
colIndex: i,
|
|
1065
|
+
hour: a
|
|
1066
|
+
}, t.key === "PageDown" ? this.stateManager.next() : this.stateManager.previous();
|
|
1067
|
+
return;
|
|
1068
|
+
case "Enter":
|
|
1069
|
+
case " ": {
|
|
1070
|
+
t.preventDefault();
|
|
1071
|
+
let e = new Date(r.dataset.date);
|
|
1072
|
+
e.setHours(a, 0, 0, 0), this._pendingSlotFocus = {
|
|
1073
|
+
colIndex: i,
|
|
1074
|
+
hour: a
|
|
1075
|
+
}, this.stateManager.selectDate(e);
|
|
1076
|
+
return;
|
|
1077
|
+
}
|
|
1078
|
+
default: return;
|
|
1079
|
+
}
|
|
1080
|
+
t.preventDefault(), s && (this._applySlotRovingTabindex(o, s), s.scrollIntoView?.({ block: "nearest" }), s.focus());
|
|
1081
|
+
});
|
|
1082
|
+
}
|
|
1083
|
+
_slotAt(e, t, n) {
|
|
1084
|
+
return t < 0 || t >= e.length || n < 0 || n > 23 ? null : e[t].querySelector(`.fc-hour-slot[data-hour="${n}"]`);
|
|
1085
|
+
}
|
|
1086
|
+
_applySlotRovingTabindex(e, t = null) {
|
|
1087
|
+
let n = this.container.querySelectorAll(".fc-hour-slot");
|
|
1088
|
+
if (n.length !== 0) {
|
|
1089
|
+
if (!t) {
|
|
1090
|
+
let r = e.find((e) => this.isToday(new Date(e.dataset.date))) || e[0];
|
|
1091
|
+
t = r && r.querySelector(".fc-hour-slot[data-hour=\"9\"]"), t ||= n[0];
|
|
1092
|
+
}
|
|
1093
|
+
for (let e of n) e.setAttribute("tabindex", e === t ? "0" : "-1");
|
|
1094
|
+
}
|
|
1095
|
+
}
|
|
1015
1096
|
_enhanceEventAccessibility() {
|
|
1016
1097
|
for (let e of this.container.querySelectorAll(".fc-event")) if (e.setAttribute("role", "button"), e.setAttribute("tabindex", "0"), !e.hasAttribute("aria-label")) {
|
|
1017
1098
|
let t = (e.getAttribute("title") || e.textContent || "").trim();
|
|
@@ -1258,7 +1339,7 @@ var n = class extends HTMLElement {
|
|
|
1258
1339
|
return `
|
|
1259
1340
|
<div class="fc-week-day-column" data-date="${e.date.toISOString()}" style="border-right: 1px solid var(--fc-border-color); position: relative; cursor: pointer;">
|
|
1260
1341
|
<!-- Hour grid lines -->
|
|
1261
|
-
${t.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
|
|
1342
|
+
${t.map((e) => `<div class="fc-hour-slot" data-hour="${e}" style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
|
|
1262
1343
|
|
|
1263
1344
|
<!-- Now indicator for today -->
|
|
1264
1345
|
${e.isToday ? this.renderNowIndicator() : ""}
|
|
@@ -1281,6 +1362,12 @@ var n = class extends HTMLElement {
|
|
|
1281
1362
|
let n = new Date(t.dataset.date), r = this.container.querySelector("#week-scroll-container"), i = t.offsetTop, a = e.clientY - t.getBoundingClientRect().top + (r ? r.scrollTop : 0) - i, o = Math.max(0, Math.min(a + i, this.totalHeight));
|
|
1282
1363
|
n.setHours(Math.floor(o / this.hourHeight), Math.floor(o % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(n);
|
|
1283
1364
|
}), this.attachCommonEventHandlers();
|
|
1365
|
+
let e = this.stateManager.getViewData()?.days || [], t = this.stateManager.getState().config.locale || "en-US", n = e[0] ? new Date(e[0].date) : /* @__PURE__ */ new Date(), r = `Week of ${new Intl.DateTimeFormat(t, {
|
|
1366
|
+
month: "long",
|
|
1367
|
+
day: "numeric",
|
|
1368
|
+
year: "numeric"
|
|
1369
|
+
}).format(n)}`;
|
|
1370
|
+
this._enhanceTimeGridAccessibility(".fc-week-day-column", r);
|
|
1284
1371
|
}
|
|
1285
1372
|
_scrollToCurrentTime() {
|
|
1286
1373
|
if (this._scrolled) return;
|
|
@@ -1395,7 +1482,7 @@ var n = class extends HTMLElement {
|
|
|
1395
1482
|
return `
|
|
1396
1483
|
<div class="fc-day-column" data-date="${n.toISOString()}" style="position: relative; cursor: pointer;">
|
|
1397
1484
|
<!-- Hour grid lines -->
|
|
1398
|
-
${r.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
|
|
1485
|
+
${r.map((e) => `<div class="fc-hour-slot" data-hour="${e}" style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
|
|
1399
1486
|
|
|
1400
1487
|
<!-- Now indicator for today -->
|
|
1401
1488
|
${t ? this.renderNowIndicator() : ""}
|
|
@@ -1418,6 +1505,13 @@ var n = class extends HTMLElement {
|
|
|
1418
1505
|
let n = new Date(t.dataset.date), r = this.container.querySelector("#day-scroll-container"), i = t.offsetTop, a = e.clientY - t.getBoundingClientRect().top + (r ? r.scrollTop : 0) - i, o = Math.max(0, Math.min(a + i, this.totalHeight));
|
|
1419
1506
|
n.setHours(Math.floor(o / this.hourHeight), Math.floor(o % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(n);
|
|
1420
1507
|
}), this.attachCommonEventHandlers();
|
|
1508
|
+
let e = this.stateManager.getState().config.locale || "en-US", t = this.stateManager.getState().currentDate || /* @__PURE__ */ new Date(), n = new Intl.DateTimeFormat(e, {
|
|
1509
|
+
weekday: "long",
|
|
1510
|
+
month: "long",
|
|
1511
|
+
day: "numeric",
|
|
1512
|
+
year: "numeric"
|
|
1513
|
+
}).format(t);
|
|
1514
|
+
this._enhanceTimeGridAccessibility(".fc-day-column", n);
|
|
1421
1515
|
}
|
|
1422
1516
|
_scrollToCurrentTime() {
|
|
1423
1517
|
if (this._scrolled) return;
|
|
@@ -1989,6 +2083,7 @@ var m = class e extends n {
|
|
|
1989
2083
|
}
|
|
1990
2084
|
|
|
1991
2085
|
.fc-month-day:focus-visible,
|
|
2086
|
+
.fc-hour-slot:focus-visible,
|
|
1992
2087
|
.fc-event:focus-visible {
|
|
1993
2088
|
outline: 2px solid var(--fc-primary-color);
|
|
1994
2089
|
outline-offset: -2px;
|