@forcecalendar/interface 1.0.26 → 1.0.28

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/README.md ADDED
@@ -0,0 +1,9 @@
1
+ # @forcecalendar/interface
2
+
3
+ [![Tests](https://github.com/forceCalendar/interface/actions/workflows/test.yml/badge.svg)](https://github.com/forceCalendar/interface/actions/workflows/test.yml)
4
+ [![Code Quality](https://github.com/forceCalendar/interface/actions/workflows/code-quality.yml/badge.svg)](https://github.com/forceCalendar/interface/actions/workflows/code-quality.yml)
5
+ [![npm version](https://img.shields.io/npm/v/@forcecalendar/interface.svg)](https://www.npmjs.com/package/@forcecalendar/interface)
6
+ [![npm downloads](https://img.shields.io/npm/dt/@forcecalendar/interface.svg)](https://www.npmjs.com/package/@forcecalendar/interface)
7
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
8
+
9
+ Official interface layer for forceCalendar Core — enterprise calendar components for Salesforce and the web.
@@ -55,11 +55,13 @@ class O extends HTMLElement {
55
55
  e.addEventListener(t, i), this._listeners.push({ element: e, event: t, handler: i });
56
56
  }
57
57
  emit(e, t = {}) {
58
- this.dispatchEvent(new CustomEvent(e, {
59
- detail: t,
60
- bubbles: !0,
61
- composed: !0
62
- }));
58
+ this.dispatchEvent(
59
+ new CustomEvent(e, {
60
+ detail: t,
61
+ bubbles: !0,
62
+ composed: !0
63
+ })
64
+ );
63
65
  }
64
66
  // Style management
65
67
  getStyles() {
@@ -738,7 +740,7 @@ class C {
738
740
  */
739
741
  getTimezoneOffset(e, t) {
740
742
  t = this.database.resolveAlias(t);
741
- const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}`;
743
+ const s = `${t}_${e.getFullYear()}_${e.getMonth()}_${e.getDate()}_${e.getHours()}`;
742
744
  if (this.offsetCache.has(s))
743
745
  return this.cacheHits++, this._manageCacheSize(), this.offsetCache.get(s);
744
746
  if (this.cacheMisses++, typeof Intl < "u" && Intl.DateTimeFormat)
@@ -1022,6 +1024,12 @@ class w {
1022
1024
  } catch {
1023
1025
  throw new Error(`Invalid timezone: ${e.timeZone}`);
1024
1026
  }
1027
+ if (e.endTimeZone)
1028
+ try {
1029
+ new Intl.DateTimeFormat("en-US", { timeZone: e.endTimeZone });
1030
+ } catch {
1031
+ throw new Error(`Invalid end timezone: ${e.endTimeZone}`);
1032
+ }
1025
1033
  }
1026
1034
  /**
1027
1035
  * Create a new Event instance
@@ -1056,8 +1064,8 @@ class w {
1056
1064
  categories: U,
1057
1065
  // Support plural categories (no default)
1058
1066
  attachments: Y = [],
1059
- conferenceData: N = null,
1060
- metadata: P = {},
1067
+ conferenceData: P = null,
1068
+ metadata: N = {},
1061
1069
  ...V
1062
1070
  // Capture any extra properties
1063
1071
  }) {
@@ -1088,8 +1096,8 @@ class w {
1088
1096
  categories: U,
1089
1097
  // Pass categories to normalize
1090
1098
  attachments: Y,
1091
- conferenceData: N,
1092
- metadata: P,
1099
+ conferenceData: P,
1100
+ metadata: N,
1093
1101
  ...V
1094
1102
  // Pass any extra properties
1095
1103
  });
@@ -1768,8 +1776,10 @@ let f = class y {
1768
1776
  * @returns {number}
1769
1777
  */
1770
1778
  static getWeekNumber(e) {
1771
- const t = new Date(e.getFullYear(), 0, 1), s = (e - t) / 864e5;
1772
- return Math.ceil((s + t.getDay() + 1) / 7);
1779
+ const t = new Date(e);
1780
+ t.setHours(0, 0, 0, 0), t.setDate(t.getDate() + 4 - (t.getDay() || 7));
1781
+ const s = new Date(t.getFullYear(), 0, 1);
1782
+ return Math.ceil(((t - s) / 864e5 + 1) / 7);
1773
1783
  }
1774
1784
  /**
1775
1785
  * Get the day of week for a date
@@ -2261,7 +2271,39 @@ class K {
2261
2271
  if (n.count && d >= n.count)
2262
2272
  break;
2263
2273
  }
2264
- return a;
2274
+ return n.bySetPos && n.bySetPos.length > 0 && n.freq !== "MONTHLY" ? this._applyBySetPos(a, n) : a;
2275
+ }
2276
+ /**
2277
+ * Apply BYSETPOS to filter occurrences within each frequency period
2278
+ * @param {Array} occurrences - Generated occurrences
2279
+ * @param {Object} rule - Recurrence rule
2280
+ * @returns {Array} Filtered occurrences
2281
+ * @private
2282
+ */
2283
+ static _applyBySetPos(e, t) {
2284
+ if (e.length === 0) return e;
2285
+ const s = /* @__PURE__ */ new Map();
2286
+ for (const r of e) {
2287
+ let n;
2288
+ switch (t.freq) {
2289
+ case "YEARLY":
2290
+ n = r.start.getFullYear();
2291
+ break;
2292
+ case "WEEKLY":
2293
+ n = `${r.start.getFullYear()}-W${f.getWeekNumber(r.start)}`;
2294
+ break;
2295
+ default:
2296
+ n = `${r.start.getFullYear()}-${r.start.getMonth()}`;
2297
+ }
2298
+ s.has(n) || s.set(n, []), s.get(n).push(r);
2299
+ }
2300
+ const i = [];
2301
+ for (const r of s.values())
2302
+ for (const n of t.bySetPos) {
2303
+ const a = n > 0 ? n - 1 : r.length + n;
2304
+ a >= 0 && a < r.length && i.push(r[a]);
2305
+ }
2306
+ return i.sort((r, n) => r.start - n.start);
2265
2307
  }
2266
2308
  /**
2267
2309
  * Parse an RRULE string into a rule object
@@ -2281,6 +2323,15 @@ class K {
2281
2323
  static getNextOccurrence(e, t, s = "UTC") {
2282
2324
  const i = new Date(e);
2283
2325
  switch (t.freq) {
2326
+ case "SECONDLY":
2327
+ i.setSeconds(i.getSeconds() + t.interval);
2328
+ break;
2329
+ case "MINUTELY":
2330
+ i.setMinutes(i.getMinutes() + t.interval);
2331
+ break;
2332
+ case "HOURLY":
2333
+ i.setHours(i.getHours() + t.interval);
2334
+ break;
2284
2335
  case "DAILY":
2285
2336
  i.setDate(i.getDate() + t.interval);
2286
2337
  break;
@@ -2297,8 +2348,15 @@ class K {
2297
2348
  case "MONTHLY":
2298
2349
  if (t.byMonthDay && t.byMonthDay.length > 0) {
2299
2350
  const r = i.getMonth();
2300
- i.setMonth(r + t.interval), i.setDate(t.byMonthDay[0]);
2301
- } else t.byDay && t.byDay.length > 0 ? (i.setMonth(i.getMonth() + t.interval), this.setToWeekdayOfMonth(i, t.byDay[0], t.bySetPos[0] || 1)) : i.setMonth(i.getMonth() + t.interval);
2351
+ i.setMonth(r + t.interval);
2352
+ const n = new Date(i.getFullYear(), i.getMonth() + 1, 0).getDate();
2353
+ i.setDate(Math.min(t.byMonthDay[0], n));
2354
+ } else if (t.byDay && t.byDay.length > 0) {
2355
+ i.setMonth(i.getMonth() + t.interval);
2356
+ const n = t.byDay[0].match(/^(-?\d+)?([A-Z]{2})$/), o = (n && n[1] ? parseInt(n[1], 10) : null) || t.bySetPos && t.bySetPos[0] || 1;
2357
+ this.setToWeekdayOfMonth(i, t.byDay[0], o);
2358
+ } else
2359
+ i.setMonth(i.getMonth() + t.interval);
2302
2360
  break;
2303
2361
  case "YEARLY":
2304
2362
  t.byMonth && t.byMonth.length > 0 ? (i.setFullYear(i.getFullYear() + t.interval), i.setMonth(t.byMonth[0] - 1)) : i.setFullYear(i.getFullYear() + t.interval);
@@ -2373,10 +2431,11 @@ class K {
2373
2431
  const i = e.toDateString(), r = e.getTime();
2374
2432
  return t.exceptions.some((n) => {
2375
2433
  if (typeof n == "object" && n.date) {
2376
- const o = n.date instanceof Date ? n.date : new Date(n.date);
2377
- return n.matchTime ? Math.abs(o.getTime() - r) < 1e3 : o.toDateString() === i;
2434
+ const c = n.date instanceof Date ? n.date : new Date(n.date);
2435
+ return n.matchTime ? Math.abs(c.getTime() - r) < 1e3 : c.toDateString() === i;
2378
2436
  }
2379
- return (n instanceof Date ? n : new Date(n)).toDateString() === i;
2437
+ const a = n instanceof Date ? n : new Date(n);
2438
+ return a.getHours() !== 0 || a.getMinutes() !== 0 || a.getSeconds() !== 0 ? Math.abs(a.getTime() - r) < 1e3 : a.toDateString() === i;
2380
2439
  });
2381
2440
  }
2382
2441
  /**
@@ -3403,7 +3462,7 @@ class X {
3403
3462
  throw new Error(`Event with id ${e} not found`);
3404
3463
  this._unindexEvent(s);
3405
3464
  const i = s.clone(t);
3406
- return this.events.set(e, i), this._indexEvent(i), this._notifyChange({
3465
+ return this.events.set(e, i), this.optimizer.cache(e, i, "event"), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._indexEvent(i), this._notifyChange({
3407
3466
  type: "update",
3408
3467
  event: i,
3409
3468
  oldEvent: s,
@@ -3417,7 +3476,7 @@ class X {
3417
3476
  */
3418
3477
  removeEvent(e) {
3419
3478
  const t = this.events.get(e);
3420
- return t ? (this.events.delete(e), this._unindexEvent(t), this._notifyChange({
3479
+ return t ? (this.events.delete(e), this.optimizer.eventCache.delete(e), this.optimizer.queryCache.clear(), this.optimizer.dateRangeCache.clear(), this._unindexEvent(t), this._notifyChange({
3421
3480
  type: "remove",
3422
3481
  event: t,
3423
3482
  version: ++this.version
@@ -3554,21 +3613,15 @@ class X {
3554
3613
  */
3555
3614
  getOverlapGroups(e, t = !0) {
3556
3615
  let s = this.getEventsForDate(e);
3557
- t && (s = s.filter((n) => !n.allDay));
3558
- const i = [], r = /* @__PURE__ */ new Set();
3559
- return s.forEach((n) => {
3560
- if (r.has(n.id)) return;
3561
- const a = [n];
3562
- r.add(n.id);
3563
- let o = 0;
3564
- for (; o < a.length; ) {
3565
- const c = a[o];
3566
- s.forEach((l) => {
3567
- !r.has(l.id) && c.overlaps(l) && (a.push(l), r.add(l.id));
3568
- }), o++;
3569
- }
3570
- i.push(a);
3571
- }), i;
3616
+ if (t && (s = s.filter((a) => !a.allDay)), s.length === 0) return [];
3617
+ s.sort((a, o) => a.start - o.start || o.end - a.end);
3618
+ const i = [];
3619
+ let r = [s[0]], n = s[0].end;
3620
+ for (let a = 1; a < s.length; a++) {
3621
+ const o = s[a];
3622
+ o.start < n ? (r.push(o), o.end > n && (n = o.end)) : (i.push(r), r = [o], n = o.end);
3623
+ }
3624
+ return i.push(r), i;
3572
3625
  }
3573
3626
  /**
3574
3627
  * Calculate positions for overlapping events (for rendering)
@@ -3602,29 +3655,31 @@ class X {
3602
3655
  * Get events for a date range
3603
3656
  * @param {Date} start - Start date
3604
3657
  * @param {Date} end - End date
3605
- * @param {boolean|string} expandRecurring - Whether to expand recurring events, or timezone string
3606
- * @param {string} [timezone] - Timezone for the query (if expandRecurring is boolean)
3658
+ * @param {boolean|Object} [expandRecurringOrOptions=true] - Boolean to expand recurring events,
3659
+ * or options object: { expandRecurring?: boolean, timezone?: string }
3660
+ * @param {string} [timezone] - Timezone for the query
3607
3661
  * @returns {Event[]}
3608
3662
  */
3609
3663
  getEventsInRange(e, t, s = !0, i = null) {
3610
- typeof s == "string" && (i = s, s = !0), i = i || this.defaultTimezone;
3611
- const r = this.timezoneManager.toUTC(e, i), n = this.timezoneManager.toUTC(t, i), a = this.queryEvents({
3612
- start: r,
3613
- end: n,
3664
+ let r = !0;
3665
+ typeof s == "object" && s !== null ? (r = s.expandRecurring !== !1, i = s.timezone || i) : typeof s == "string" ? (i = s, r = !0) : r = s, i = i || this.defaultTimezone;
3666
+ const n = this.timezoneManager.toUTC(e, i), a = this.timezoneManager.toUTC(t, i), o = this.queryEvents({
3667
+ start: n,
3668
+ end: a,
3614
3669
  sort: "start"
3615
3670
  });
3616
- if (!s)
3617
- return a;
3618
- const o = [];
3619
- return a.forEach((c) => {
3620
- if (c.recurring && c.recurrenceRule) {
3621
- const l = this.expandRecurringEvent(c, e, t, i);
3622
- o.push(...l);
3671
+ if (!r)
3672
+ return o;
3673
+ const c = [];
3674
+ return o.forEach((l) => {
3675
+ if (l.recurring && l.recurrenceRule) {
3676
+ const h = this.expandRecurringEvent(l, e, t, i);
3677
+ c.push(...h);
3623
3678
  } else
3624
- o.push(c);
3625
- }), o.sort((c, l) => {
3626
- const h = c.getStartInTimezone(i), d = l.getStartInTimezone(i);
3627
- return h - d;
3679
+ c.push(l);
3680
+ }), c.sort((l, h) => {
3681
+ const d = l.getStartInTimezone(i), p = h.getStartInTimezone(i);
3682
+ return d - p;
3628
3683
  });
3629
3684
  }
3630
3685
  /**
@@ -3860,7 +3915,7 @@ class X {
3860
3915
  */
3861
3916
  addEvents(e) {
3862
3917
  return this.optimizer.measure("addEvents", () => {
3863
- this.startBatch();
3918
+ this.startBatch(!0);
3864
3919
  const t = [], s = [];
3865
3920
  for (const i of e)
3866
3921
  try {
@@ -3868,7 +3923,7 @@ class X {
3868
3923
  } catch (r) {
3869
3924
  s.push({ event: i, error: r.message });
3870
3925
  }
3871
- return this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
3926
+ return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to add ${s.length} events:`, s), t;
3872
3927
  });
3873
3928
  }
3874
3929
  /**
@@ -3878,7 +3933,7 @@ class X {
3878
3933
  */
3879
3934
  updateEvents(e) {
3880
3935
  return this.optimizer.measure("updateEvents", () => {
3881
- this.startBatch();
3936
+ this.startBatch(!0);
3882
3937
  const t = [], s = [];
3883
3938
  for (const { id: i, updates: r } of e)
3884
3939
  try {
@@ -3886,7 +3941,7 @@ class X {
3886
3941
  } catch (n) {
3887
3942
  s.push({ id: i, error: n.message });
3888
3943
  }
3889
- return this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
3944
+ return s.length > 0 && t.length === 0 ? this.rollbackBatch() : this.commitBatch(), s.length > 0 && console.warn(`Failed to update ${s.length} events:`, s), t;
3890
3945
  });
3891
3946
  }
3892
3947
  /**
@@ -3896,11 +3951,11 @@ class X {
3896
3951
  */
3897
3952
  removeEvents(e) {
3898
3953
  return this.optimizer.measure("removeEvents", () => {
3899
- this.startBatch();
3954
+ this.startBatch(!0);
3900
3955
  let t = 0;
3901
3956
  for (const s of e)
3902
3957
  this.removeEvent(s) && t++;
3903
- return this.commitBatch(), t;
3958
+ return t === 0 && e.length > 0 ? this.rollbackBatch() : this.commitBatch(), t;
3904
3959
  });
3905
3960
  }
3906
3961
  // ============ Performance Methods ============
@@ -4125,7 +4180,7 @@ let ee = class {
4125
4180
  */
4126
4181
  setState(e) {
4127
4182
  const t = this.state;
4128
- typeof e == "function" && (e = e(t));
4183
+ typeof e == "function" && (e = e(t)), e && typeof e == "object" && (delete e.__proto__, delete e.constructor, delete e.prototype);
4129
4184
  const s = {
4130
4185
  ...t,
4131
4186
  ...e,
@@ -4946,9 +5001,14 @@ class te {
4946
5001
  * Destroy the calendar and clean up
4947
5002
  */
4948
5003
  destroy() {
4949
- this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
4950
- typeof e.uninstall == "function" && e.uninstall(this);
4951
- }), this.plugins.clear(), this.views.clear(), this._emit("destroy");
5004
+ this._emit("destroy"), this.listeners.clear(), this.eventStore.destroy(), this.plugins.forEach((e) => {
5005
+ if (typeof e.uninstall == "function")
5006
+ try {
5007
+ e.uninstall(this);
5008
+ } catch (t) {
5009
+ console.error("Error uninstalling plugin:", t);
5010
+ }
5011
+ }), this.plugins.clear(), this.views.clear();
4952
5012
  }
4953
5013
  }
4954
5014
  class se {
@@ -5169,9 +5229,7 @@ class ie {
5169
5229
  });
5170
5230
  }
5171
5231
  emitStateChange(e, t) {
5172
- const s = Object.keys(t).filter(
5173
- (i) => e[i] !== t[i]
5174
- );
5232
+ const s = Object.keys(t).filter((i) => e[i] !== t[i]);
5175
5233
  s.forEach((i) => {
5176
5234
  u.emit(`state:${i}:changed`, {
5177
5235
  oldValue: e[i],
@@ -5214,7 +5272,12 @@ class ie {
5214
5272
  updateEvent(e, t) {
5215
5273
  this._syncEventsFromCore({ silent: !0 });
5216
5274
  const s = this.calendar.updateEvent(e, t);
5217
- return s ? (this._syncEventsFromCore(), u.emit("event:update", { event: s }), u.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), u.emit("event:error", { action: "update", eventId: e, updates: t, error: "Event not found in calendar" }), null);
5275
+ return s ? (this._syncEventsFromCore(), u.emit("event:update", { event: s }), u.emit("event:updated", { event: s }), s) : (console.error(`Failed to update event: ${e}`), u.emit("event:error", {
5276
+ action: "update",
5277
+ eventId: e,
5278
+ updates: t,
5279
+ error: "Event not found in calendar"
5280
+ }), null);
5218
5281
  }
5219
5282
  deleteEvent(e) {
5220
5283
  return this._syncEventsFromCore({ silent: !0 }), this.calendar.removeEvent(e) ? (this._syncEventsFromCore(), u.emit("event:remove", { eventId: e }), u.emit("event:deleted", { eventId: e }), !0) : (console.error(`Failed to delete event: ${e}`), u.emit("event:error", { action: "delete", eventId: e, error: "Event not found" }), !1);
@@ -5429,7 +5492,7 @@ class E extends f {
5429
5492
  return r && (r.toLowerCase() === "pm" && n < 12 ? o = n + 12 : r.toLowerCase() === "am" && n === 12 && (o = 0)), s.setHours(o, a || 0, 0, 0), s;
5430
5493
  }
5431
5494
  }
5432
- class F {
5495
+ class H {
5433
5496
  /**
5434
5497
  * Create element with attributes and children
5435
5498
  */
@@ -6070,7 +6133,7 @@ I(D, "breakpoints", {
6070
6133
  xl: "1200px",
6071
6134
  "2xl": "1400px"
6072
6135
  });
6073
- class H {
6136
+ class F {
6074
6137
  /**
6075
6138
  * @param {HTMLElement} container - The DOM element to render into
6076
6139
  * @param {StateManager} stateManager - The state manager instance
@@ -6109,7 +6172,7 @@ class H {
6109
6172
  * @returns {string}
6110
6173
  */
6111
6174
  escapeHTML(e) {
6112
- return e == null ? "" : F.escapeHTML(String(e));
6175
+ return e == null ? "" : H.escapeHTML(String(e));
6113
6176
  }
6114
6177
  /**
6115
6178
  * Check if a date is today
@@ -6219,7 +6282,7 @@ class H {
6219
6282
  });
6220
6283
  }
6221
6284
  }
6222
- class S extends H {
6285
+ class S extends F {
6223
6286
  constructor(e, t) {
6224
6287
  super(e, t), this.maxEventsToShow = 3;
6225
6288
  }
@@ -6294,7 +6357,7 @@ class S extends H {
6294
6357
  }), this.attachCommonEventHandlers();
6295
6358
  }
6296
6359
  }
6297
- class z extends H {
6360
+ class z extends F {
6298
6361
  constructor(e, t) {
6299
6362
  super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
6300
6363
  }
@@ -6334,7 +6397,8 @@ class z extends H {
6334
6397
  return `
6335
6398
  <div class="fc-week-header" style="display: grid; grid-template-columns: 60px repeat(7, 1fr); border-bottom: 1px solid #e5e7eb; background: #f9fafb; flex-shrink: 0;">
6336
6399
  <div style="border-right: 1px solid #e5e7eb;"></div>
6337
- ${e.map((t) => `
6400
+ ${e.map(
6401
+ (t) => `
6338
6402
  <div style="padding: 12px 8px; text-align: center; border-right: 1px solid #e5e7eb;">
6339
6403
  <div style="font-size: 10px; font-weight: 700; color: #6b7280; text-transform: uppercase; letter-spacing: 0.1em;">
6340
6404
  ${t.dayName}
@@ -6343,7 +6407,8 @@ class z extends H {
6343
6407
  ${t.dayOfMonth}
6344
6408
  </div>
6345
6409
  </div>
6346
- `).join("")}
6410
+ `
6411
+ ).join("")}
6347
6412
  </div>
6348
6413
  `;
6349
6414
  }
@@ -6353,16 +6418,20 @@ class z extends H {
6353
6418
  <div style="font-size: 9px; color: #6b7280; display: flex; align-items: center; justify-content: center; border-right: 1px solid #e5e7eb; text-transform: uppercase; font-weight: 700;">
6354
6419
  All day
6355
6420
  </div>
6356
- ${e.map((t) => `
6421
+ ${e.map(
6422
+ (t) => `
6357
6423
  <div class="fc-all-day-cell" data-date="${t.date.toISOString()}" style="border-right: 1px solid #e5e7eb; padding: 4px; display: flex; flex-direction: column; gap: 2px;">
6358
- ${t.allDayEvents.map((s) => `
6424
+ ${t.allDayEvents.map(
6425
+ (s) => `
6359
6426
  <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
6360
6427
  style="background-color: ${this.getEventColor(s)}; font-size: 10px; padding: 2px 4px; border-radius: 2px; color: white; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
6361
6428
  ${this.escapeHTML(s.title)}
6362
6429
  </div>
6363
- `).join("")}
6430
+ `
6431
+ ).join("")}
6364
6432
  </div>
6365
- `).join("")}
6433
+ `
6434
+ ).join("")}
6366
6435
  </div>
6367
6436
  `;
6368
6437
  }
@@ -6379,11 +6448,13 @@ class z extends H {
6379
6448
  _renderTimeGutter(e) {
6380
6449
  return `
6381
6450
  <div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
6382
- ${e.map((t) => `
6451
+ ${e.map(
6452
+ (t) => `
6383
6453
  <div style="height: ${this.hourHeight}px; font-size: 10px; color: #6b7280; text-align: right; padding-right: 8px; font-weight: 500;">
6384
6454
  ${t === 0 ? "" : this.formatHour(t)}
6385
6455
  </div>
6386
- `).join("")}
6456
+ `
6457
+ ).join("")}
6387
6458
  </div>
6388
6459
  `;
6389
6460
  }
@@ -6406,7 +6477,12 @@ class z extends H {
6406
6477
  const t = e.target.closest(".fc-week-day-column");
6407
6478
  if (!t || !this.container.contains(t) || e.target.closest(".fc-event")) return;
6408
6479
  const s = new Date(t.dataset.date), i = t.getBoundingClientRect(), r = this.container.querySelector("#week-scroll-container"), n = e.clientY - i.top + (r ? r.scrollTop : 0);
6409
- s.setHours(Math.floor(n / this.hourHeight), Math.floor(n % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(s);
6480
+ s.setHours(
6481
+ Math.floor(n / this.hourHeight),
6482
+ Math.floor(n % this.hourHeight / (this.hourHeight / 60)),
6483
+ 0,
6484
+ 0
6485
+ ), this.stateManager.selectDate(s);
6410
6486
  }), this.attachCommonEventHandlers();
6411
6487
  }
6412
6488
  _scrollToCurrentTime() {
@@ -6415,7 +6491,7 @@ class z extends H {
6415
6491
  e && (e.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
6416
6492
  }
6417
6493
  }
6418
- class L extends H {
6494
+ class L extends F {
6419
6495
  constructor(e, t) {
6420
6496
  super(e, t), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
6421
6497
  }
@@ -6488,12 +6564,14 @@ class L extends H {
6488
6564
  All day
6489
6565
  </div>
6490
6566
  <div class="fc-all-day-cell" data-date="${t.toISOString()}" style="padding: 6px 12px; display: flex; flex-wrap: wrap; gap: 4px;">
6491
- ${e.map((s) => `
6567
+ ${e.map(
6568
+ (s) => `
6492
6569
  <div class="fc-event fc-all-day-event" data-event-id="${this.escapeHTML(s.id)}"
6493
6570
  style="background-color: ${this.getEventColor(s)}; font-size: 12px; padding: 4px 8px; border-radius: 4px; color: white; cursor: pointer; font-weight: 500;">
6494
6571
  ${this.escapeHTML(s.title)}
6495
6572
  </div>
6496
- `).join("")}
6573
+ `
6574
+ ).join("")}
6497
6575
  </div>
6498
6576
  </div>
6499
6577
  `;
@@ -6511,11 +6589,13 @@ class L extends H {
6511
6589
  _renderTimeGutter(e) {
6512
6590
  return `
6513
6591
  <div class="fc-time-gutter" style="border-right: 1px solid #e5e7eb; background: #fafafa;">
6514
- ${e.map((t) => `
6592
+ ${e.map(
6593
+ (t) => `
6515
6594
  <div style="height: ${this.hourHeight}px; font-size: 11px; color: #6b7280; text-align: right; padding-right: 12px; font-weight: 500;">
6516
6595
  ${t === 0 ? "" : this.formatHour(t)}
6517
6596
  </div>
6518
- `).join("")}
6597
+ `
6598
+ ).join("")}
6519
6599
  </div>
6520
6600
  `;
6521
6601
  }
@@ -6538,7 +6618,12 @@ class L extends H {
6538
6618
  const t = e.target.closest(".fc-day-column");
6539
6619
  if (!t || !this.container.contains(t) || e.target.closest(".fc-event")) return;
6540
6620
  const s = new Date(t.dataset.date), i = t.getBoundingClientRect(), r = this.container.querySelector("#day-scroll-container"), n = e.clientY - i.top + (r ? r.scrollTop : 0);
6541
- s.setHours(Math.floor(n / this.hourHeight), Math.floor(n % this.hourHeight / (this.hourHeight / 60)), 0, 0), this.stateManager.selectDate(s);
6621
+ s.setHours(
6622
+ Math.floor(n / this.hourHeight),
6623
+ Math.floor(n % this.hourHeight / (this.hourHeight / 60)),
6624
+ 0,
6625
+ 0
6626
+ ), this.stateManager.selectDate(s);
6542
6627
  }), this.attachCommonEventHandlers();
6543
6628
  }
6544
6629
  _scrollToCurrentTime() {
@@ -6782,7 +6867,8 @@ class re extends O {
6782
6867
  <div class="form-group">
6783
6868
  <label id="color-label">Color</label>
6784
6869
  <div class="color-options" id="color-picker" role="radiogroup" aria-labelledby="color-label">
6785
- ${this.config.colors.map((e) => `
6870
+ ${this.config.colors.map(
6871
+ (e) => `
6786
6872
  <button type="button"
6787
6873
  class="color-btn ${e.color === this._formData.color ? "selected" : ""}"
6788
6874
  style="background-color: ${e.color}"
@@ -6791,7 +6877,8 @@ class re extends O {
6791
6877
  aria-label="${e.label}"
6792
6878
  aria-checked="${e.color === this._formData.color ? "true" : "false"}"
6793
6879
  role="radio"></button>
6794
- `).join("")}
6880
+ `
6881
+ ).join("")}
6795
6882
  </div>
6796
6883
  </div>
6797
6884
  </div>
@@ -6821,7 +6908,7 @@ class re extends O {
6821
6908
  });
6822
6909
  }
6823
6910
  open(e = /* @__PURE__ */ new Date()) {
6824
- this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = e, this._formData.end = new Date(e.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap = F.trapFocus(this.modalContent));
6911
+ this.hasAttribute("open") || this.setAttribute("open", ""), this.titleGroup.classList.remove("has-error"), this.endGroup.classList.remove("has-error"), this._formData.start = e, this._formData.end = new Date(e.getTime() + this.config.defaultDuration * 60 * 1e3), this._formData.title = "", this._formData.color = this.config.colors[0].color, this.startInput && (this.titleInput.value = "", this.startInput.value = this.formatDateForInput(this._formData.start), this.endInput.value = this.formatDateForInput(this._formData.end), this.updateColorSelection(), this._cleanupFocusTrap = H.trapFocus(this.modalContent));
6825
6912
  }
6826
6913
  close() {
6827
6914
  this.removeAttribute("open"), this._cleanupFocusTrap && (this._cleanupFocusTrap(), this._cleanupFocusTrap = null);
@@ -6869,29 +6956,47 @@ class ne extends O {
6869
6956
  this.stateManager = new ie(e), this.stateManager.subscribe(this.handleStateChange.bind(this)), this.setupEventListeners();
6870
6957
  }
6871
6958
  setupEventListeners() {
6872
- this._busUnsubscribers.forEach((t) => t()), this._busUnsubscribers = [], this._busUnsubscribers.push(u.on("navigation:*", (t, s) => {
6873
- this.emit("calendar-navigate", { action: s.split(":")[1], ...t });
6874
- })), this._busUnsubscribers.push(u.on("view:changed", (t) => {
6875
- this.emit("calendar-view-change", t);
6876
- }));
6959
+ this._busUnsubscribers.forEach((t) => t()), this._busUnsubscribers = [], this._busUnsubscribers.push(
6960
+ u.on("navigation:*", (t, s) => {
6961
+ this.emit("calendar-navigate", { action: s.split(":")[1], ...t });
6962
+ })
6963
+ ), this._busUnsubscribers.push(
6964
+ u.on("view:changed", (t) => {
6965
+ this.emit("calendar-view-change", t);
6966
+ })
6967
+ );
6877
6968
  const e = (t, s) => {
6878
6969
  this.emit(`calendar-event-${t}`, s);
6879
6970
  };
6880
- this._busUnsubscribers.push(u.on("event:add", (t) => {
6881
- e("add", t);
6882
- })), this._busUnsubscribers.push(u.on("event:update", (t) => {
6883
- e("update", t);
6884
- })), this._busUnsubscribers.push(u.on("event:remove", (t) => {
6885
- e("remove", t);
6886
- })), this._busUnsubscribers.push(u.on("event:added", (t) => {
6887
- e("add", t), this.emit("calendar-event-added", t);
6888
- })), this._busUnsubscribers.push(u.on("event:updated", (t) => {
6889
- e("update", t), this.emit("calendar-event-updated", t);
6890
- })), this._busUnsubscribers.push(u.on("event:deleted", (t) => {
6891
- e("remove", t), this.emit("calendar-event-deleted", t);
6892
- })), this._busUnsubscribers.push(u.on("date:selected", (t) => {
6893
- this.emit("calendar-date-select", t);
6894
- }));
6971
+ this._busUnsubscribers.push(
6972
+ u.on("event:add", (t) => {
6973
+ e("add", t);
6974
+ })
6975
+ ), this._busUnsubscribers.push(
6976
+ u.on("event:update", (t) => {
6977
+ e("update", t);
6978
+ })
6979
+ ), this._busUnsubscribers.push(
6980
+ u.on("event:remove", (t) => {
6981
+ e("remove", t);
6982
+ })
6983
+ ), this._busUnsubscribers.push(
6984
+ u.on("event:added", (t) => {
6985
+ e("add", t), this.emit("calendar-event-added", t);
6986
+ })
6987
+ ), this._busUnsubscribers.push(
6988
+ u.on("event:updated", (t) => {
6989
+ e("update", t), this.emit("calendar-event-updated", t);
6990
+ })
6991
+ ), this._busUnsubscribers.push(
6992
+ u.on("event:deleted", (t) => {
6993
+ e("remove", t), this.emit("calendar-event-deleted", t);
6994
+ })
6995
+ ), this._busUnsubscribers.push(
6996
+ u.on("date:selected", (t) => {
6997
+ this.emit("calendar-date-select", t);
6998
+ })
6999
+ );
6895
7000
  }
6896
7001
  handleStateChange(e, t) {
6897
7002
  var o, c;
@@ -7361,7 +7466,7 @@ class ne extends O {
7361
7466
  return `
7362
7467
  <div class="force-calendar">
7363
7468
  <div class="fc-error">
7364
- <p><strong>Error:</strong> ${F.escapeHTML(r.message || "An error occurred")}</p>
7469
+ <p><strong>Error:</strong> ${H.escapeHTML(r.message || "An error occurred")}</p>
7365
7470
  </div>
7366
7471
  </div>
7367
7472
  `;
@@ -7552,8 +7657,8 @@ customElements.get("forcecal-main") || customElements.define("forcecal-main", ne
7552
7657
  typeof window < "u" && typeof customElements < "u" && console.log("Force Calendar Interface loading...");
7553
7658
  export {
7554
7659
  O as BaseComponent,
7555
- H as BaseViewRenderer,
7556
- F as DOMUtils,
7660
+ F as BaseViewRenderer,
7661
+ H as DOMUtils,
7557
7662
  E as DateUtils,
7558
7663
  L as DayViewRenderer,
7559
7664
  se as EventBus,