@forcecalendar/interface 1.0.56 → 1.0.58

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.
@@ -11,7 +11,7 @@ class M extends HTMLElement {
11
11
  this._initialized || (this.initialize(), this._initialized = !0), this.mount();
12
12
  }
13
13
  disconnectedCallback() {
14
- this.unmount(), this.cleanup();
14
+ this.unmount(), this.cleanup(), this._styleEl = null, this._contentWrapper = null;
15
15
  }
16
16
  // To be overridden by child classes
17
17
  initialize() {
@@ -83,13 +83,51 @@ class M extends HTMLElement {
83
83
  // Template rendering
84
84
  render() {
85
85
  this.cleanup();
86
- const t = `
87
- <style>
88
- ${this.getBaseStyles()}
89
- ${this.getStyles()}
90
- </style>
91
- `, e = this.template();
92
- this.shadowRoot.innerHTML = t + e, this.afterRender();
86
+ const t = this.template();
87
+ this._styleEl || (this._styleEl = document.createElement("style"), this.shadowRoot.appendChild(this._styleEl), this._contentWrapper = document.createElement("div"), this._contentWrapper.setAttribute("id", "fc-root"), this._contentWrapper.style.display = "contents", this.shadowRoot.appendChild(this._contentWrapper)), this._styleEl.textContent = this.getBaseStyles() + `
88
+ ` + this.getStyles();
89
+ const e = this._saveScrollPositions(), r = this._getActiveElementSelector();
90
+ this._contentWrapper.innerHTML = t, this._restoreScrollPositions(e), this._restoreFocus(r), this.afterRender();
91
+ }
92
+ /**
93
+ * Save scroll positions of all scrollable containers within shadow DOM
94
+ * @returns {Map<string, {top: number, left: number}>}
95
+ */
96
+ _saveScrollPositions() {
97
+ const t = /* @__PURE__ */ new Map();
98
+ return this._contentWrapper && this._contentWrapper.querySelectorAll("[id]").forEach((r) => {
99
+ (r.scrollTop !== 0 || r.scrollLeft !== 0) && t.set(r.id, { top: r.scrollTop, left: r.scrollLeft });
100
+ }), t;
101
+ }
102
+ /**
103
+ * Restore previously saved scroll positions
104
+ * @param {Map<string, {top: number, left: number}>} positions
105
+ */
106
+ _restoreScrollPositions(t) {
107
+ !this._contentWrapper || t.size === 0 || t.forEach((e, r) => {
108
+ const i = this._contentWrapper.querySelector(`[id="${CSS.escape(r)}"]`);
109
+ i && (i.scrollTop = e.top, i.scrollLeft = e.left);
110
+ });
111
+ }
112
+ /**
113
+ * Get a CSS selector for the currently focused element within shadow DOM
114
+ * @returns {string|null}
115
+ */
116
+ _getActiveElementSelector() {
117
+ const t = this.shadowRoot.activeElement;
118
+ return !t || t === this._contentWrapper ? null : t.id ? `[id="${CSS.escape(t.id)}"]` : t.dataset && t.dataset.action ? `[data-action="${CSS.escape(t.dataset.action)}"]` : t.dataset && t.dataset.view ? `[data-view="${CSS.escape(t.dataset.view)}"]` : t.tagName ? t.tagName.toLowerCase() : null;
119
+ }
120
+ /**
121
+ * Restore focus to a previously focused element
122
+ * @param {string|null} selector
123
+ */
124
+ _restoreFocus(t) {
125
+ if (!(!t || !this._contentWrapper))
126
+ try {
127
+ const e = this._contentWrapper.querySelector(t);
128
+ e && typeof e.focus == "function" && e.focus();
129
+ } catch {
130
+ }
93
131
  }
94
132
  template() {
95
133
  return "";
@@ -111,7 +149,7 @@ class M extends HTMLElement {
111
149
  this.setProp(t, r), this._initialized && this.render();
112
150
  }
113
151
  }
114
- class T {
152
+ class S {
115
153
  constructor() {
116
154
  this.events = /* @__PURE__ */ new Map(), this.wildcardHandlers = /* @__PURE__ */ new Set();
117
155
  }
@@ -211,9 +249,11 @@ class T {
211
249
  }
212
250
  /**
213
251
  * Check if event name matches a pattern
252
+ * Only `*` acts as a wildcard; all other characters match literally
214
253
  */
215
254
  matchesPattern(t, e) {
216
- return new RegExp("^" + e.replace(/\*/g, ".*") + "$").test(t);
255
+ const r = e.replace(/[.+?^${}()|[\]\\]/g, "\\$&");
256
+ return new RegExp("^" + r.replace(/\*/g, ".*") + "$").test(t);
217
257
  }
218
258
  /**
219
259
  * Clear all event subscriptions
@@ -249,10 +289,10 @@ class T {
249
289
  return t;
250
290
  }
251
291
  }
252
- const U = new T();
292
+ const U = new S();
253
293
  class V {
254
294
  constructor(t = {}) {
255
- this.eventBus = new T(), this.calendar = new L({
295
+ this.eventBus = new S(), this.calendar = new L({
256
296
  view: t.view || "month",
257
297
  date: t.date || /* @__PURE__ */ new Date(),
258
298
  weekStartsOn: t.weekStartsOn ?? 0,
@@ -1245,7 +1285,7 @@ v(f, "breakpoints", {
1245
1285
  xl: "1200px",
1246
1286
  "2xl": "1400px"
1247
1287
  });
1248
- class E {
1288
+ class k {
1249
1289
  /**
1250
1290
  * @param {HTMLElement} container - The DOM element to render into
1251
1291
  * @param {StateManager} stateManager - The state manager instance
@@ -1399,18 +1439,18 @@ class E {
1399
1439
  * @returns {string} HTML string
1400
1440
  */
1401
1441
  renderTimedEvent(t, e = {}) {
1402
- const { compact: r = !0, overlapLayout: i = null } = e, s = new Date(t.start), n = new Date(t.end), a = s.getHours() * 60 + s.getMinutes(), o = Math.max((n - s) / (1e3 * 60), r ? 20 : 30), c = this.getEventColor(t), l = this.getContrastingTextColor(c), d = r ? "4px 8px" : "8px 12px", p = r ? "11px" : "13px", g = r ? 2 : 12, b = r ? 2 : 24, S = r ? "4px" : "6px";
1442
+ const { compact: r = !0, overlapLayout: i = null } = e, s = new Date(t.start), n = new Date(t.end), a = s.getHours() * 60 + s.getMinutes(), o = Math.max((n - s) / (1e3 * 60), r ? 20 : 30), c = this.getEventColor(t), l = this.getContrastingTextColor(c), d = r ? "4px 8px" : "8px 12px", p = r ? "11px" : "13px", g = r ? 2 : 12, b = r ? 2 : 24, T = r ? "4px" : "6px";
1403
1443
  let x, w;
1404
1444
  if (i && i.has(t.id)) {
1405
- const { column: C, totalColumns: _ } = i.get(t.id), $ = `(100% - ${g + b}px)`;
1406
- x = `calc(${g}px + ${C} * ${$} / ${_})`, w = `calc(${$} / ${_})`;
1445
+ const { column: C, totalColumns: E } = i.get(t.id), $ = `(100% - ${g + b}px)`;
1446
+ x = `calc(${g}px + ${C} * ${$} / ${E})`, w = `calc(${$} / ${E})`;
1407
1447
  } else
1408
1448
  x = `${g}px`, w = `calc(100% - ${g + b}px)`;
1409
1449
  return `
1410
1450
  <div class="fc-event fc-timed-event" data-event-id="${this.escapeHTML(t.id)}"
1411
1451
  style="position: absolute; top: ${a}px; height: ${o}px;
1412
1452
  left: ${x}; width: ${w};
1413
- background-color: ${c}; border-radius: ${S};
1453
+ background-color: ${c}; border-radius: ${T};
1414
1454
  padding: ${d}; font-size: ${p};
1415
1455
  font-weight: 500; color: ${l}; overflow: hidden;
1416
1456
  box-shadow: 0 1px 2px rgba(0,0,0,0.1);
@@ -1445,7 +1485,7 @@ class E {
1445
1485
  });
1446
1486
  }
1447
1487
  }
1448
- class D extends E {
1488
+ class _ extends k {
1449
1489
  constructor(t, e) {
1450
1490
  super(t, e), this.maxEventsToShow = 3;
1451
1491
  }
@@ -1503,10 +1543,10 @@ class D extends E {
1503
1543
  `;
1504
1544
  }
1505
1545
  _renderEvent(t) {
1506
- const e = this.getEventColor(t);
1546
+ const e = this.getEventColor(t), r = this.getContrastingTextColor(e);
1507
1547
  return `
1508
1548
  <div class="fc-event" data-event-id="${this.escapeHTML(t.id)}"
1509
- style="background-color: ${e}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: white; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
1549
+ style="background-color: ${e}; font-size: 11px; padding: 2px 6px; border-radius: 3px; color: ${r}; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer;">
1510
1550
  ${this.escapeHTML(t.title)}
1511
1551
  </div>
1512
1552
  `;
@@ -1520,7 +1560,7 @@ class D extends E {
1520
1560
  }), this.attachCommonEventHandlers();
1521
1561
  }
1522
1562
  }
1523
- class z extends E {
1563
+ class z extends k {
1524
1564
  constructor(t, e) {
1525
1565
  super(t, e), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1526
1566
  }
@@ -1659,7 +1699,7 @@ class z extends E {
1659
1699
  t && (t.scrollTop = 8 * this.hourHeight - 50, this._scrolled = !0);
1660
1700
  }
1661
1701
  }
1662
- class B extends E {
1702
+ class B extends k {
1663
1703
  constructor(t, e) {
1664
1704
  super(t, e), this.hourHeight = 60, this.totalHeight = 24 * this.hourHeight;
1665
1705
  }
@@ -2216,7 +2256,7 @@ const m = class m extends M {
2216
2256
  if (t) {
2217
2257
  this._currentViewInstance && this._currentViewInstance.cleanup && this._currentViewInstance.cleanup();
2218
2258
  try {
2219
- const e = m.RENDERERS[this.currentView] || D, r = new e(t, this.stateManager);
2259
+ const e = m.RENDERERS[this.currentView] || _, r = new e(t, this.stateManager);
2220
2260
  r._viewType = this.currentView, this._currentViewInstance = r, r.render();
2221
2261
  } catch (e) {
2222
2262
  console.error("[ForceCalendar] Error switching view:", e);
@@ -2700,7 +2740,7 @@ const m = class m extends M {
2700
2740
  return;
2701
2741
  this._currentViewInstance && (this._currentViewInstance.cleanup && this._currentViewInstance.cleanup(), this._viewUnsubscribe && (this._viewUnsubscribe(), this._viewUnsubscribe = null));
2702
2742
  try {
2703
- const i = m.RENDERERS[this.currentView] || D, s = new i(t, this.stateManager);
2743
+ const i = m.RENDERERS[this.currentView] || _, s = new i(t, this.stateManager);
2704
2744
  s._viewType = this.currentView, this._currentViewInstance = s, s.render();
2705
2745
  } catch (i) {
2706
2746
  console.error("[ForceCalendar] Error creating/rendering view:", i);
@@ -2811,21 +2851,21 @@ const m = class m extends M {
2811
2851
  }
2812
2852
  };
2813
2853
  v(m, "RENDERERS", {
2814
- month: D,
2854
+ month: _,
2815
2855
  week: z,
2816
2856
  day: B
2817
2857
  });
2818
- let k = m;
2819
- customElements.get("forcecal-main") || customElements.define("forcecal-main", k);
2858
+ let D = m;
2859
+ customElements.get("forcecal-main") || customElements.define("forcecal-main", D);
2820
2860
  export {
2821
2861
  M as BaseComponent,
2822
- E as BaseViewRenderer,
2862
+ k as BaseViewRenderer,
2823
2863
  y as DOMUtils,
2824
2864
  u as DateUtils,
2825
2865
  B as DayViewRenderer,
2826
- T as EventBus,
2827
- k as ForceCalendar,
2828
- D as MonthViewRenderer,
2866
+ S as EventBus,
2867
+ D as ForceCalendar,
2868
+ _ as MonthViewRenderer,
2829
2869
  V as StateManager,
2830
2870
  f as StyleUtils,
2831
2871
  z as WeekViewRenderer,