@forcecalendar/interface 1.0.60 → 1.0.61

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forcecalendar/interface",
3
- "version": "1.0.60",
3
+ "version": "1.0.61",
4
4
  "type": "module",
5
5
  "description": "Official interface layer for forceCalendar Core - Enterprise calendar components",
6
6
  "main": "dist/force-calendar-interface.umd.js",
@@ -37,6 +37,38 @@ export class ForceCalendar extends BaseComponent {
37
37
  this._busUnsubscribers = [];
38
38
  }
39
39
 
40
+ /**
41
+ * Route observed-attribute changes into the StateManager.
42
+ * Without this, attribute updates after mount (view, locale, timezone,
43
+ * week-starts-on, date) only re-rendered from stale state and had no
44
+ * visible effect. 'height' is presentational and picked up by render().
45
+ */
46
+ propChanged(name, oldValue, newValue) {
47
+ if (!this.stateManager || oldValue === newValue) return;
48
+
49
+ switch (name) {
50
+ case 'view':
51
+ if (newValue) this.stateManager.setView(newValue);
52
+ break;
53
+ case 'date': {
54
+ const date = newValue ? new Date(newValue) : null;
55
+ if (date && !isNaN(date.getTime())) this.stateManager.setDate(date);
56
+ break;
57
+ }
58
+ case 'locale':
59
+ if (newValue) this.stateManager.updateConfig({ locale: newValue });
60
+ break;
61
+ case 'timezone':
62
+ if (newValue) this.stateManager.updateConfig({ timeZone: newValue });
63
+ break;
64
+ case 'week-starts-on': {
65
+ const day = parseInt(newValue, 10);
66
+ if (!Number.isNaN(day)) this.stateManager.updateConfig({ weekStartsOn: day });
67
+ break;
68
+ }
69
+ }
70
+ }
71
+
40
72
  initialize() {
41
73
  // Initialize state manager with config from attributes
42
74
  const config = {
@@ -183,8 +183,13 @@ export class BaseComponent extends HTMLElement {
183
183
  */
184
184
  _restoreScrollPositions(positions) {
185
185
  if (!this._contentWrapper || positions.size === 0) return;
186
+ // CSS.escape may be absent in sandboxed or test environments
187
+ const escapeId =
188
+ typeof CSS !== 'undefined' && typeof CSS.escape === 'function'
189
+ ? CSS.escape
190
+ : id => String(id).replace(/["\\]/g, '\\$&');
186
191
  positions.forEach((pos, id) => {
187
- const el = this._contentWrapper.querySelector(`[id="${CSS.escape(id)}"]`);
192
+ const el = this._contentWrapper.querySelector(`[id="${escapeId(id)}"]`);
188
193
  if (el) {
189
194
  el.scrollTop = pos.top;
190
195
  el.scrollLeft = pos.left;