@forcecalendar/interface 1.2.0 → 1.4.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.
@@ -1012,13 +1012,300 @@ 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();
1018
1099
  t && e.setAttribute("aria-label", `Event: ${t}`);
1019
1100
  }
1020
1101
  }
1021
- }, u = class extends l {
1102
+ }, u = 4, d = 15, f = 1;
1103
+ function p(e, t = d) {
1104
+ return Math.round(e / t) * t;
1105
+ }
1106
+ function m(e, t) {
1107
+ return Math.max(0, Math.min(e, 1440 - t));
1108
+ }
1109
+ function h(e, t) {
1110
+ let n = new Date(e);
1111
+ return n.setHours(t.getHours(), t.getMinutes(), t.getSeconds(), t.getMilliseconds()), n;
1112
+ }
1113
+ var g = class {
1114
+ constructor(e) {
1115
+ this.renderer = e, this.container = e.container, this.stateManager = e.stateManager, this._active = null, this._docListeners = [];
1116
+ }
1117
+ enableMonthMove() {
1118
+ this.renderer.addListener(this.container, "pointerdown", (e) => {
1119
+ if (e.button !== 0) return;
1120
+ let t = e.target.closest(".fc-event");
1121
+ !t || !this.container.contains(t) || t.closest(".fc-month-day") && this._arm(e, {
1122
+ mode: "month-move",
1123
+ eventEl: t,
1124
+ eventId: t.dataset.eventId,
1125
+ onDragMove: (e) => this._monthDragMove(e),
1126
+ onDrop: (e) => this._monthDrop(e)
1127
+ });
1128
+ });
1129
+ }
1130
+ enableTimeGrid(e) {
1131
+ this._columnSelector = e, this._injectResizeHandles(), this.renderer.addListener(this.container, "pointerdown", (t) => {
1132
+ if (t.button !== 0) return;
1133
+ let n = t.target.closest(".fc-resize-handle");
1134
+ if (n) {
1135
+ let e = n.closest(".fc-timed-event");
1136
+ if (!e) return;
1137
+ t.preventDefault(), this._arm(t, {
1138
+ mode: "resize",
1139
+ eventEl: e,
1140
+ eventId: e.dataset.eventId,
1141
+ originTop: parseFloat(e.style.top) || 0,
1142
+ originHeight: parseFloat(e.style.height) || 30,
1143
+ onDragMove: (e) => this._resizeDragMove(e),
1144
+ onDrop: () => this._resizeDrop()
1145
+ });
1146
+ return;
1147
+ }
1148
+ let r = t.target.closest(".fc-timed-event");
1149
+ if (r && this.container.contains(r)) {
1150
+ this._arm(t, {
1151
+ mode: "time-move",
1152
+ eventEl: r,
1153
+ eventId: r.dataset.eventId,
1154
+ originTop: parseFloat(r.style.top) || 0,
1155
+ originColumn: r.closest(e),
1156
+ onDragMove: (e) => this._timeMoveDragMove(e),
1157
+ onDrop: () => this._timeMoveDrop()
1158
+ });
1159
+ return;
1160
+ }
1161
+ let i = t.target.closest(e);
1162
+ i && !t.target.closest(".fc-event") && this._arm(t, {
1163
+ mode: "create",
1164
+ column: i,
1165
+ onDragMove: (e) => this._createDragMove(e),
1166
+ onDrop: () => this._createDrop()
1167
+ });
1168
+ });
1169
+ }
1170
+ _arm(e, t) {
1171
+ this._active = {
1172
+ ...t,
1173
+ startX: e.clientX,
1174
+ startY: e.clientY,
1175
+ dragging: !1
1176
+ };
1177
+ let n = (e) => this._onPointerMove(e), r = (e) => this._onPointerUp(e), i = () => this._cancel(), a = (e) => {
1178
+ e.key === "Escape" && this._cancel();
1179
+ }, o = this.container.ownerDocument;
1180
+ o.addEventListener("pointermove", n), o.addEventListener("pointerup", r), o.addEventListener("pointercancel", i), o.addEventListener("keydown", a), this._docListeners = [
1181
+ ["pointermove", n],
1182
+ ["pointerup", r],
1183
+ ["pointercancel", i],
1184
+ ["keydown", a]
1185
+ ];
1186
+ }
1187
+ _onPointerMove(e) {
1188
+ let t = this._active;
1189
+ if (t) {
1190
+ if (!t.dragging) {
1191
+ if (Math.abs(e.clientX - t.startX) < u && Math.abs(e.clientY - t.startY) < u) return;
1192
+ t.dragging = !0, t.eventEl && t.eventEl.classList.add("fc-dragging");
1193
+ }
1194
+ e.preventDefault(), t.onDragMove(e);
1195
+ }
1196
+ }
1197
+ _onPointerUp(e) {
1198
+ let t = this._active;
1199
+ if (this._teardownDocListeners(), t) {
1200
+ if (t.dragging) {
1201
+ let n = this.container.ownerDocument, r = (e) => {
1202
+ e.stopPropagation(), e.preventDefault();
1203
+ };
1204
+ n.addEventListener("click", r, {
1205
+ capture: !0,
1206
+ once: !0
1207
+ }), setTimeout(() => n.removeEventListener("click", r, { capture: !0 }), 0), t.onDrop(e);
1208
+ }
1209
+ this._cleanupVisuals(t), this._active = null;
1210
+ }
1211
+ }
1212
+ _cancel() {
1213
+ let e = this._active;
1214
+ this._teardownDocListeners(), this._active = null, e && this._cleanupVisuals(e);
1215
+ }
1216
+ _teardownDocListeners() {
1217
+ let e = this.container.ownerDocument;
1218
+ for (let [t, n] of this._docListeners) e.removeEventListener(t, n);
1219
+ this._docListeners = [];
1220
+ }
1221
+ _cleanupVisuals(e) {
1222
+ e.eventEl && (e.eventEl.classList.remove("fc-dragging"), e.eventEl.style.transform = ""), this.container.querySelectorAll(".fc-drop-target").forEach((e) => e.classList.remove("fc-drop-target")), this._selectionEl?.remove(), this._selectionEl = null;
1223
+ }
1224
+ _cellAtPoint(e, t) {
1225
+ for (let n of this.container.querySelectorAll(".fc-month-day")) {
1226
+ let r = n.getBoundingClientRect();
1227
+ if (e >= r.left && e < r.right && t >= r.top && t < r.bottom) return n;
1228
+ }
1229
+ return null;
1230
+ }
1231
+ _monthDragMove(e) {
1232
+ let t = this._active;
1233
+ t.eventEl.style.transform = `translate(${e.clientX - t.startX}px, ${e.clientY - t.startY}px)`;
1234
+ let n = this._cellAtPoint(e.clientX, e.clientY);
1235
+ n !== t.dropCell && (t.dropCell?.classList.remove("fc-drop-target"), n?.classList.add("fc-drop-target"), t.dropCell = n);
1236
+ }
1237
+ _monthDrop() {
1238
+ let e = this._active ?? {}, t = e.dropCell;
1239
+ if (!t) return;
1240
+ let n = this.stateManager.getEvents().find((t) => t.id === e.eventId);
1241
+ if (!n) return;
1242
+ let r = new Date(n.start), i = h(new Date(t.dataset.date), r), a = i.getTime() - r.getTime();
1243
+ a !== 0 && this.stateManager.updateEvent(e.eventId, {
1244
+ start: i,
1245
+ end: new Date(new Date(n.end).getTime() + a)
1246
+ });
1247
+ }
1248
+ _columnAtPoint(e) {
1249
+ for (let t of this.container.querySelectorAll(this._columnSelector)) {
1250
+ let n = t.getBoundingClientRect();
1251
+ if (e >= n.left && e < n.right) return t;
1252
+ }
1253
+ return null;
1254
+ }
1255
+ _timeMoveDragMove(e) {
1256
+ let t = this._active, n = this._columnAtPoint(e.clientX) || t.originColumn;
1257
+ t.dropColumn = n, t.deltaMinutes = p((e.clientY - t.startY) / f);
1258
+ let r = t.originColumn.getBoundingClientRect(), i = n.getBoundingClientRect();
1259
+ t.eventEl.style.transform = `translate(${i.left - r.left}px, ${t.deltaMinutes * f}px)`;
1260
+ }
1261
+ _timeMoveDrop() {
1262
+ let e = this._active ?? {}, t = this.stateManager.getEvents().find((t) => t.id === e.eventId);
1263
+ if (!t || !e.deltaMinutes && e.dropColumn === e.originColumn) return;
1264
+ let n = new Date(t.start), r = new Date(t.end).getTime() - n.getTime(), i = h(e.dropColumn ? new Date(e.dropColumn.dataset.date) : n, n), a = m(i.getHours() * 60 + i.getMinutes() + (e.deltaMinutes || 0), Math.round(r / 6e4)), o = new Date(i);
1265
+ o.setHours(Math.floor(a / 60), a % 60, 0, 0), o.getTime() !== n.getTime() && this.stateManager.updateEvent(e.eventId, {
1266
+ start: o,
1267
+ end: new Date(o.getTime() + r)
1268
+ });
1269
+ }
1270
+ _resizeDragMove(e) {
1271
+ let t = this._active, n = p((e.clientY - t.startY) / f);
1272
+ t.newHeight = Math.max(d, t.originHeight + n), t.newHeight = Math.min(t.newHeight, 1440 - t.originTop), t.eventEl.style.height = `${t.newHeight}px`;
1273
+ }
1274
+ _resizeDrop() {
1275
+ let e = this._active ?? {};
1276
+ if (!e.newHeight || e.newHeight === e.originHeight) return;
1277
+ let t = this.stateManager.getEvents().find((t) => t.id === e.eventId);
1278
+ if (!t) return;
1279
+ let n = new Date(new Date(t.start).getTime() + e.newHeight * 6e4);
1280
+ this.stateManager.updateEvent(e.eventId, { end: n });
1281
+ }
1282
+ _createDragMove(e) {
1283
+ let t = this._active, n = t.column.getBoundingClientRect(), r = t.startY - n.top, i = e.clientY - n.top;
1284
+ t.fromMinutes = p(Math.min(r, i) / f), t.toMinutes = p(Math.max(r, i) / f), t.fromMinutes = Math.max(0, t.fromMinutes), t.toMinutes = Math.min(1440, Math.max(t.toMinutes, t.fromMinutes + d)), this._selectionEl || (this._selectionEl = this.container.ownerDocument.createElement("div"), this._selectionEl.className = "fc-drag-selection", t.column.appendChild(this._selectionEl)), this._selectionEl.style.top = `${t.fromMinutes * f}px`, this._selectionEl.style.height = `${(t.toMinutes - t.fromMinutes) * f}px`;
1285
+ }
1286
+ _createDrop() {
1287
+ let e = this._active ?? {};
1288
+ if (e.fromMinutes == null) return;
1289
+ let t = new Date(e.column.dataset.date);
1290
+ t.setHours(Math.floor(e.fromMinutes / 60), e.fromMinutes % 60, 0, 0);
1291
+ let n = new Date(e.column.dataset.date);
1292
+ n.setHours(Math.floor(e.toMinutes / 60), e.toMinutes % 60, 0, 0), this.container.dispatchEvent(new CustomEvent("range-select", {
1293
+ detail: {
1294
+ start: t,
1295
+ end: n
1296
+ },
1297
+ bubbles: !0,
1298
+ composed: !0
1299
+ }));
1300
+ }
1301
+ _injectResizeHandles() {
1302
+ for (let e of this.container.querySelectorAll(".fc-timed-event")) {
1303
+ if (e.querySelector(".fc-resize-handle")) continue;
1304
+ let t = this.container.ownerDocument.createElement("div");
1305
+ t.className = "fc-resize-handle", t.setAttribute("aria-hidden", "true"), e.appendChild(t);
1306
+ }
1307
+ }
1308
+ }, _ = class extends l {
1022
1309
  constructor(e, t) {
1023
1310
  super(e, t), this.maxEventsToShow = 3;
1024
1311
  }
@@ -1151,7 +1438,7 @@ var n = class extends HTMLElement {
1151
1438
  let e = new Date(t.dataset.date);
1152
1439
  e.setDate(e.getDate() + (i - r)), this._pendingFocusMs = e.getTime(), i < 0 ? this.stateManager.previous() : this.stateManager.next();
1153
1440
  }
1154
- }), this.attachCommonEventHandlers();
1441
+ }), this.attachCommonEventHandlers(), new g(this).enableMonthMove();
1155
1442
  }
1156
1443
  _applyRovingTabindex(e = null) {
1157
1444
  let t = Array.from(this.container.querySelectorAll(".fc-month-day"));
@@ -1161,7 +1448,7 @@ var n = class extends HTMLElement {
1161
1448
  for (let e of t) e.setAttribute("tabindex", e === n ? "0" : "-1");
1162
1449
  return n;
1163
1450
  }
1164
- }, d = class extends l {
1451
+ }, v = class extends l {
1165
1452
  constructor(e, t) {
1166
1453
  super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1167
1454
  }
@@ -1258,7 +1545,7 @@ var n = class extends HTMLElement {
1258
1545
  return `
1259
1546
  <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
1547
  <!-- Hour grid lines -->
1261
- ${t.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
1548
+ ${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
1549
 
1263
1550
  <!-- Now indicator for today -->
1264
1551
  ${e.isToday ? this.renderNowIndicator() : ""}
@@ -1281,13 +1568,19 @@ var n = class extends HTMLElement {
1281
1568
  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
1569
  n.setHours(Math.floor(o / this.hourHeight), Math.floor(o % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(n);
1283
1570
  }), this.attachCommonEventHandlers();
1571
+ 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, {
1572
+ month: "long",
1573
+ day: "numeric",
1574
+ year: "numeric"
1575
+ }).format(n)}`;
1576
+ this._enhanceTimeGridAccessibility(".fc-week-day-column", r), new g(this).enableTimeGrid(".fc-week-day-column");
1284
1577
  }
1285
1578
  _scrollToCurrentTime() {
1286
1579
  if (this._scrolled) return;
1287
1580
  let e = this.container.querySelector("#week-scroll-container");
1288
1581
  e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
1289
1582
  }
1290
- }, f = class extends l {
1583
+ }, y = class extends l {
1291
1584
  constructor(e, t) {
1292
1585
  super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1293
1586
  }
@@ -1395,7 +1688,7 @@ var n = class extends HTMLElement {
1395
1688
  return `
1396
1689
  <div class="fc-day-column" data-date="${n.toISOString()}" style="position: relative; cursor: pointer;">
1397
1690
  <!-- Hour grid lines -->
1398
- ${r.map(() => `<div style="height: ${this.hourHeight}px; border-bottom: 1px solid var(--fc-background-hover);"></div>`).join("")}
1691
+ ${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
1692
 
1400
1693
  <!-- Now indicator for today -->
1401
1694
  ${t ? this.renderNowIndicator() : ""}
@@ -1418,13 +1711,20 @@ var n = class extends HTMLElement {
1418
1711
  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
1712
  n.setHours(Math.floor(o / this.hourHeight), Math.floor(o % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(n);
1420
1713
  }), this.attachCommonEventHandlers();
1714
+ let e = this.stateManager.getState().config.locale || "en-US", t = this.stateManager.getState().currentDate || /* @__PURE__ */ new Date(), n = new Intl.DateTimeFormat(e, {
1715
+ weekday: "long",
1716
+ month: "long",
1717
+ day: "numeric",
1718
+ year: "numeric"
1719
+ }).format(t);
1720
+ this._enhanceTimeGridAccessibility(".fc-day-column", n), new g(this).enableTimeGrid(".fc-day-column");
1421
1721
  }
1422
1722
  _scrollToCurrentTime() {
1423
1723
  if (this._scrolled) return;
1424
1724
  let e = this.container.querySelector("#day-scroll-container");
1425
1725
  e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
1426
1726
  }
1427
- }, p = class extends n {
1727
+ }, b = class extends n {
1428
1728
  constructor() {
1429
1729
  super(), this._isVisible = !1, this._cleanupFocusTrap = null, this.config = {
1430
1730
  title: "New Event",
@@ -1744,14 +2044,14 @@ var n = class extends HTMLElement {
1744
2044
  this._cleanupFocusTrap && this._cleanupFocusTrap(), this._handleKeyDown && (window.removeEventListener("keydown", this._handleKeyDown), this._handleKeyDown = null, this._keydownListenerAdded = !1);
1745
2045
  }
1746
2046
  };
1747
- customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form", p);
2047
+ customElements.get("forcecal-event-form") || customElements.define("forcecal-event-form", b);
1748
2048
  //#endregion
1749
2049
  //#region src/components/ForceCalendar.js
1750
- var m = class e extends n {
2050
+ var x = class e extends n {
1751
2051
  static RENDERERS = {
1752
- month: u,
1753
- week: d,
1754
- day: f
2052
+ month: _,
2053
+ week: v,
2054
+ day: y
1755
2055
  };
1756
2056
  static get observedAttributes() {
1757
2057
  return [
@@ -1861,7 +2161,7 @@ var m = class e extends n {
1861
2161
  if (t) {
1862
2162
  this._currentViewInstance && this._currentViewInstance.cleanup && this._currentViewInstance.cleanup();
1863
2163
  try {
1864
- let n = new (e.RENDERERS[this.currentView] || u)(t, this.stateManager);
2164
+ let n = new (e.RENDERERS[this.currentView] || _)(t, this.stateManager);
1865
2165
  n._viewType = this.currentView, this._currentViewInstance = n, n.render();
1866
2166
  } catch (e) {
1867
2167
  console.error("[ForceCalendar] Error switching view:", e);
@@ -1989,11 +2289,45 @@ var m = class e extends n {
1989
2289
  }
1990
2290
 
1991
2291
  .fc-month-day:focus-visible,
2292
+ .fc-hour-slot:focus-visible,
1992
2293
  .fc-event:focus-visible {
1993
2294
  outline: 2px solid var(--fc-primary-color);
1994
2295
  outline-offset: -2px;
1995
2296
  }
1996
2297
 
2298
+ .fc-event { touch-action: none; }
2299
+
2300
+ .fc-dragging {
2301
+ opacity: 0.6;
2302
+ z-index: 30;
2303
+ pointer-events: none;
2304
+ }
2305
+
2306
+ .fc-drop-target {
2307
+ outline: 2px dashed var(--fc-primary-color);
2308
+ outline-offset: -2px;
2309
+ }
2310
+
2311
+ .fc-resize-handle {
2312
+ position: absolute;
2313
+ left: 0;
2314
+ right: 0;
2315
+ bottom: 0;
2316
+ height: 6px;
2317
+ cursor: ns-resize;
2318
+ }
2319
+
2320
+ .fc-drag-selection {
2321
+ position: absolute;
2322
+ left: 2px;
2323
+ right: 2px;
2324
+ background: color-mix(in srgb, var(--fc-primary-color) 18%, transparent);
2325
+ border: 1px solid var(--fc-primary-color);
2326
+ border-radius: 4px;
2327
+ pointer-events: none;
2328
+ z-index: 20;
2329
+ }
2330
+
1997
2331
  .fc-nav-arrow:focus-visible,
1998
2332
  .fc-btn:focus-visible,
1999
2333
  .fc-btn-today:focus-visible,
@@ -2354,7 +2688,7 @@ var m = class e extends n {
2354
2688
  if (this._currentViewInstance && this._currentViewInstance._viewType === this.currentView && t.children.length > 0) return;
2355
2689
  this._currentViewInstance && (this._currentViewInstance.cleanup && this._currentViewInstance.cleanup(), this._viewUnsubscribe &&= (this._viewUnsubscribe(), null));
2356
2690
  try {
2357
- let n = new (e.RENDERERS[this.currentView] || u)(t, this.stateManager);
2691
+ let n = new (e.RENDERERS[this.currentView] || _)(t, this.stateManager);
2358
2692
  n._viewType = this.currentView, this._currentViewInstance = n, n.render();
2359
2693
  } catch (e) {
2360
2694
  console.error("[ForceCalendar] Error creating/rendering view:", e);
@@ -2370,6 +2704,8 @@ var m = class e extends n {
2370
2704
  n.open(/* @__PURE__ */ new Date());
2371
2705
  }), this.addListener(this.shadowRoot, "day-click", (e) => {
2372
2706
  n && n.open(e.detail.date);
2707
+ }), this.addListener(this.shadowRoot, "range-select", (e) => {
2708
+ this.emit("calendar-range-select", e.detail), n && n.open(e.detail.start);
2373
2709
  }), n && this.addListener(n, "save", (e) => {
2374
2710
  let t = e.detail, n = window.crypto && typeof window.crypto.randomUUID == "function" ? window.crypto.randomUUID() : Math.random().toString(36).substring(2, 15);
2375
2711
  this.stateManager.addEvent({
@@ -2448,8 +2784,8 @@ var m = class e extends n {
2448
2784
  this._busUnsubscribers.forEach((e) => e()), this._busUnsubscribers = [], this._stateUnsubscribe &&= (this._stateUnsubscribe(), null), this._currentViewInstance && this._currentViewInstance.cleanup && (this._currentViewInstance.cleanup(), this._currentViewInstance = null), this.stateManager && this.stateManager.destroy(), super.cleanup();
2449
2785
  }
2450
2786
  };
2451
- customElements.get("forcecal-main") || customElements.define("forcecal-main", m);
2787
+ customElements.get("forcecal-main") || customElements.define("forcecal-main", x);
2452
2788
  //#endregion
2453
- export { n as BaseComponent, l as BaseViewRenderer, s as DOMUtils, o as DateUtils, f as DayViewRenderer, r as EventBus, m as ForceCalendar, u as MonthViewRenderer, a as StateManager, c as StyleUtils, d as WeekViewRenderer, i as eventBus };
2789
+ export { n as BaseComponent, l as BaseViewRenderer, s as DOMUtils, o as DateUtils, y as DayViewRenderer, r as EventBus, x as ForceCalendar, _ as MonthViewRenderer, a as StateManager, c as StyleUtils, v as WeekViewRenderer, i as eventBus };
2454
2790
 
2455
2791
  //# sourceMappingURL=force-calendar-interface.esm.js.map