@tasknotes/calendar 0.1.0 → 0.1.2

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/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Changed
6
+
7
+ - Year views narrower than 520px (phones, sidebars) show two compact months a row. Days are shaded by how busy they are, with no dots, and any day with items is visibly shaded.
8
+
9
+ ### Fixed
10
+
11
+ - Clicking or tapping a day in the year view reports it through `onDateClick`. Before, only Enter or Space on a focused day did.
12
+ - The calendar keeps its sticky headers and popovers in its own stacking context, so host overlays such as side sheets and dialogs draw above the week header and all-day row.
13
+
14
+ ## 0.1.1
15
+
16
+ ### Fixed
17
+
18
+ - Calendars moved into another window after creation (e.g. Obsidian "Move to new window") rebind their listeners, timers and observers to that window, so dragging, selection and resizing keep working. `adopt()` is also public for hosts that move a calendar programmatically.
19
+ - Time-grid day columns keep a minimum width (`--tnc-col-min`, 64px); narrow containers scroll sideways with the time axis pinned instead of crushing week views on phones.
20
+
3
21
  ## 0.1.0
4
22
 
5
23
  Initial public release.
package/dist/calendar.css CHANGED
@@ -32,12 +32,16 @@
32
32
  --tnc-dot-size: 8px;
33
33
  --tnc-dot-gap: 3px;
34
34
  --tnc-gutter-w: 52px;
35
+ /* Narrowest a time-grid day column gets; narrower containers scroll sideways. */
36
+ --tnc-col-min: 64px;
35
37
  --tnc-weeknum-w: 32px;
36
38
  --tnc-dg-top-h: 24px;
37
39
  --tnc-day-min-h: 92px;
38
40
  --tnc-item-c: var(--tnc-accent);
39
41
 
40
42
  position: relative;
43
+ /* Keep the calendar's own layers (sticky headers, popovers) below host overlays. */
44
+ isolation: isolate;
41
45
  display: flex;
42
46
  flex-direction: column;
43
47
  min-height: 0;
@@ -462,6 +466,18 @@
462
466
  display: grid;
463
467
  grid-template-columns: var(--tnc-cols);
464
468
  }
469
+ .tnc-tg-top,
470
+ .tnc-tg-body {
471
+ min-width: calc(var(--tnc-gutter-w) + var(--tnc-ncols, 1) * var(--tnc-col-min));
472
+ }
473
+ .tnc-gutter-head,
474
+ .tnc-gutter-label,
475
+ .tnc-gutter {
476
+ position: sticky;
477
+ left: 0;
478
+ z-index: 6;
479
+ background: var(--tnc-surface);
480
+ }
465
481
  .tnc-gutter-head {
466
482
  display: flex;
467
483
  align-items: flex-end;
@@ -557,7 +573,6 @@
557
573
  position: relative;
558
574
  }
559
575
  .tnc-gutter {
560
- position: relative;
561
576
  border-right: 1px solid var(--tnc-line);
562
577
  }
563
578
  .tnc-slot-label {
@@ -865,6 +880,8 @@
865
880
  display: flex;
866
881
  flex-direction: column;
867
882
  min-height: 0;
883
+ /* Narrow calendars (phones, sidebars) use the compact year below. */
884
+ container-type: inline-size;
868
885
  }
869
886
  .tnc-year-scroll {
870
887
  flex: 1 1 auto;
@@ -935,6 +952,35 @@
935
952
  background: var(--tnc-c, var(--tnc-accent));
936
953
  }
937
954
 
955
+ /* Two months a row: each day is a shaded square, and its count is in its label. */
956
+ @container (max-width: 520px) {
957
+ .tnc-year-scroll {
958
+ padding: 8px 4px;
959
+ }
960
+ .tnc-year-grid {
961
+ grid-template-columns: repeat(2, minmax(0, 1fr));
962
+ gap: 14px 12px;
963
+ }
964
+ .tnc-ym-title {
965
+ font-size: 12px;
966
+ padding-bottom: 4px;
967
+ }
968
+ .tnc-ym-days {
969
+ gap: 1px;
970
+ }
971
+ .tnc-ym-day {
972
+ border-radius: 4px;
973
+ font-size: 10px;
974
+ }
975
+ /* Without dots, one item must still read as busy. */
976
+ .tnc-ym-day.has-items {
977
+ background: color-mix(in srgb, var(--tnc-accent) calc((0.3 + var(--tnc-heat) * 0.7) * 50%), transparent);
978
+ }
979
+ .tnc-ym-dots {
980
+ display: none;
981
+ }
982
+ }
983
+
938
984
  /* -------------------------------------------------------------- timeline */
939
985
  .tnc-tl {
940
986
  display: flex;
@@ -1515,8 +1515,9 @@ var TimeGridView = class {
1515
1515
  const { ctx } = this;
1516
1516
  const { doc, opts, days, today } = ctx;
1517
1517
  this.weights = days.map((d) => d === today && opts.todayWidth > 1 && days.length > 1 ? opts.todayWidth : 1);
1518
- const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(0, ${w}fr)`).join(" ")}`;
1518
+ const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(var(--tnc-col-min), ${w}fr)`).join(" ")}`;
1519
1519
  this.el.style.setProperty("--tnc-cols", tpl);
1520
+ this.el.style.setProperty("--tnc-ncols", String(days.length));
1520
1521
  const gutterHead = h(doc, "div", "tnc-gutter-head", { role: "columnheader" });
1521
1522
  if (opts.weekNumbers && days[0] !== void 0) gutterHead.textContent = ctx.text.weekNumber(isoWeekNumber(days[0]));
1522
1523
  this.headRow.replaceChildren(gutterHead);
@@ -2624,13 +2625,10 @@ var Calendar = class {
2624
2625
  this.bindEvents();
2625
2626
  this.rebuild(true);
2626
2627
  this.scheduleTick();
2627
- const RO = this.win.ResizeObserver;
2628
- if (RO) {
2629
- this.resizeObs = new RO(() => this.current?.resize?.());
2630
- this.resizeObs.observe(this.root);
2631
- }
2628
+ this.observeResize();
2632
2629
  }
2633
2630
  host;
2631
+ /** The document/window the calendar currently lives in; see `adopt()`. */
2634
2632
  doc;
2635
2633
  win;
2636
2634
  root;
@@ -2663,6 +2661,37 @@ var Calendar = class {
2663
2661
  destroyed = false;
2664
2662
  pendingChange = null;
2665
2663
  frame = null;
2664
+ observeResize() {
2665
+ this.resizeObs?.disconnect();
2666
+ const RO = this.win.ResizeObserver;
2667
+ if (RO) {
2668
+ this.resizeObs = new RO(() => this.current?.resize?.());
2669
+ this.resizeObs.observe(this.root);
2670
+ }
2671
+ }
2672
+ onAdoptCheck = () => {
2673
+ this.adopt();
2674
+ };
2675
+ /**
2676
+ * Hosts may move a live calendar into another window (e.g. Obsidian's
2677
+ * "Move to new window"). Listeners, timers and observers belong to a window,
2678
+ * so rebind them to the root's current document and rebuild the view there.
2679
+ */
2680
+ adopt() {
2681
+ const doc = this.root.ownerDocument;
2682
+ if (this.destroyed || doc === this.doc || this.session) return;
2683
+ const old = this.win;
2684
+ if (this.timer !== null) old.clearTimeout(this.timer);
2685
+ if (this.frame !== null) old.cancelAnimationFrame(this.frame);
2686
+ this.timer = this.frame = null;
2687
+ this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
2688
+ this.doc = doc;
2689
+ this.win = doc.defaultView ?? old;
2690
+ this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
2691
+ this.observeResize();
2692
+ this.rebuild(false);
2693
+ this.scheduleTick();
2694
+ }
2666
2695
  /* ================================================================ public */
2667
2696
  /** Replaces all items, re-rendering only what changed. */
2668
2697
  setItems(items) {
@@ -3227,6 +3256,7 @@ var Calendar = class {
3227
3256
  applyChange(change) {
3228
3257
  if (!change.added.length && !change.updated.length && !change.removed.length && !change.days.size && !change.spans) return;
3229
3258
  this.conflicts = dependencyConflicts(this.store);
3259
+ this.adopt();
3230
3260
  this.pendingChange = this.pendingChange ? this.merge(this.pendingChange, change) : change;
3231
3261
  if (this.session?.active) {
3232
3262
  this.flush();
@@ -3387,6 +3417,8 @@ var Calendar = class {
3387
3417
  r.addEventListener("dragleave", this.onNativeDragLeave);
3388
3418
  r.addEventListener("drop", this.onNativeDrop);
3389
3419
  r.addEventListener("touchmove", this.onTouchMove, { passive: false });
3420
+ r.addEventListener("pointerover", this.onAdoptCheck);
3421
+ r.addEventListener("focusin", this.onAdoptCheck);
3390
3422
  this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
3391
3423
  }
3392
3424
  unbindEvents() {
@@ -3403,6 +3435,8 @@ var Calendar = class {
3403
3435
  r.removeEventListener("dragleave", this.onNativeDragLeave);
3404
3436
  r.removeEventListener("drop", this.onNativeDrop);
3405
3437
  r.removeEventListener("touchmove", this.onTouchMove);
3438
+ r.removeEventListener("pointerover", this.onAdoptCheck);
3439
+ r.removeEventListener("focusin", this.onAdoptCheck);
3406
3440
  this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
3407
3441
  this.listenDoc(false);
3408
3442
  }
@@ -3900,6 +3934,12 @@ var Calendar = class {
3900
3934
  ev.preventDefault();
3901
3935
  };
3902
3936
  onClick = (ev) => {
3937
+ const yearDay = ev.target.closest?.(".tnc-ym-day");
3938
+ if (yearDay && this.root.contains(yearDay)) {
3939
+ const day = parseDay(yearDay.dataset.date ?? "");
3940
+ if (day !== null) this.clickSlot({ kind: "day", day }, ev, true);
3941
+ return;
3942
+ }
3903
3943
  const el = this.itemElFrom(ev.target);
3904
3944
  if (!el || ev.target.closest(".tnc-resize, .tnc-port")) return;
3905
3945
  const meta = this.meta.get(el);
@@ -3959,7 +3999,7 @@ var Calendar = class {
3959
3999
  return;
3960
4000
  }
3961
4001
  const target = ev.target;
3962
- if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-ym-day, .tnc-dg-day[tabindex]")) {
4002
+ if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-dg-day[tabindex]")) {
3963
4003
  const day = parseDay(target.dataset.date ?? "");
3964
4004
  if (day !== null) {
3965
4005
  ev.preventDefault();
@@ -1423,8 +1423,9 @@ var TimeGridView = class {
1423
1423
  const { ctx } = this;
1424
1424
  const { doc, opts, days, today } = ctx;
1425
1425
  this.weights = days.map((d) => d === today && opts.todayWidth > 1 && days.length > 1 ? opts.todayWidth : 1);
1426
- const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(0, ${w}fr)`).join(" ")}`;
1426
+ const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(var(--tnc-col-min), ${w}fr)`).join(" ")}`;
1427
1427
  this.el.style.setProperty("--tnc-cols", tpl);
1428
+ this.el.style.setProperty("--tnc-ncols", String(days.length));
1428
1429
  const gutterHead = h(doc, "div", "tnc-gutter-head", { role: "columnheader" });
1429
1430
  if (opts.weekNumbers && days[0] !== void 0) gutterHead.textContent = ctx.text.weekNumber(isoWeekNumber(days[0]));
1430
1431
  this.headRow.replaceChildren(gutterHead);
@@ -2532,13 +2533,10 @@ var Calendar = class {
2532
2533
  this.bindEvents();
2533
2534
  this.rebuild(true);
2534
2535
  this.scheduleTick();
2535
- const RO = this.win.ResizeObserver;
2536
- if (RO) {
2537
- this.resizeObs = new RO(() => this.current?.resize?.());
2538
- this.resizeObs.observe(this.root);
2539
- }
2536
+ this.observeResize();
2540
2537
  }
2541
2538
  host;
2539
+ /** The document/window the calendar currently lives in; see `adopt()`. */
2542
2540
  doc;
2543
2541
  win;
2544
2542
  root;
@@ -2571,6 +2569,37 @@ var Calendar = class {
2571
2569
  destroyed = false;
2572
2570
  pendingChange = null;
2573
2571
  frame = null;
2572
+ observeResize() {
2573
+ this.resizeObs?.disconnect();
2574
+ const RO = this.win.ResizeObserver;
2575
+ if (RO) {
2576
+ this.resizeObs = new RO(() => this.current?.resize?.());
2577
+ this.resizeObs.observe(this.root);
2578
+ }
2579
+ }
2580
+ onAdoptCheck = () => {
2581
+ this.adopt();
2582
+ };
2583
+ /**
2584
+ * Hosts may move a live calendar into another window (e.g. Obsidian's
2585
+ * "Move to new window"). Listeners, timers and observers belong to a window,
2586
+ * so rebind them to the root's current document and rebuild the view there.
2587
+ */
2588
+ adopt() {
2589
+ const doc = this.root.ownerDocument;
2590
+ if (this.destroyed || doc === this.doc || this.session) return;
2591
+ const old = this.win;
2592
+ if (this.timer !== null) old.clearTimeout(this.timer);
2593
+ if (this.frame !== null) old.cancelAnimationFrame(this.frame);
2594
+ this.timer = this.frame = null;
2595
+ this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
2596
+ this.doc = doc;
2597
+ this.win = doc.defaultView ?? old;
2598
+ this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
2599
+ this.observeResize();
2600
+ this.rebuild(false);
2601
+ this.scheduleTick();
2602
+ }
2574
2603
  /* ================================================================ public */
2575
2604
  /** Replaces all items, re-rendering only what changed. */
2576
2605
  setItems(items) {
@@ -3135,6 +3164,7 @@ var Calendar = class {
3135
3164
  applyChange(change) {
3136
3165
  if (!change.added.length && !change.updated.length && !change.removed.length && !change.days.size && !change.spans) return;
3137
3166
  this.conflicts = dependencyConflicts(this.store);
3167
+ this.adopt();
3138
3168
  this.pendingChange = this.pendingChange ? this.merge(this.pendingChange, change) : change;
3139
3169
  if (this.session?.active) {
3140
3170
  this.flush();
@@ -3295,6 +3325,8 @@ var Calendar = class {
3295
3325
  r.addEventListener("dragleave", this.onNativeDragLeave);
3296
3326
  r.addEventListener("drop", this.onNativeDrop);
3297
3327
  r.addEventListener("touchmove", this.onTouchMove, { passive: false });
3328
+ r.addEventListener("pointerover", this.onAdoptCheck);
3329
+ r.addEventListener("focusin", this.onAdoptCheck);
3298
3330
  this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
3299
3331
  }
3300
3332
  unbindEvents() {
@@ -3311,6 +3343,8 @@ var Calendar = class {
3311
3343
  r.removeEventListener("dragleave", this.onNativeDragLeave);
3312
3344
  r.removeEventListener("drop", this.onNativeDrop);
3313
3345
  r.removeEventListener("touchmove", this.onTouchMove);
3346
+ r.removeEventListener("pointerover", this.onAdoptCheck);
3347
+ r.removeEventListener("focusin", this.onAdoptCheck);
3314
3348
  this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
3315
3349
  this.listenDoc(false);
3316
3350
  }
@@ -3808,6 +3842,12 @@ var Calendar = class {
3808
3842
  ev.preventDefault();
3809
3843
  };
3810
3844
  onClick = (ev) => {
3845
+ const yearDay = ev.target.closest?.(".tnc-ym-day");
3846
+ if (yearDay && this.root.contains(yearDay)) {
3847
+ const day = parseDay(yearDay.dataset.date ?? "");
3848
+ if (day !== null) this.clickSlot({ kind: "day", day }, ev, true);
3849
+ return;
3850
+ }
3811
3851
  const el = this.itemElFrom(ev.target);
3812
3852
  if (!el || ev.target.closest(".tnc-resize, .tnc-port")) return;
3813
3853
  const meta = this.meta.get(el);
@@ -3867,7 +3907,7 @@ var Calendar = class {
3867
3907
  return;
3868
3908
  }
3869
3909
  const target = ev.target;
3870
- if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-ym-day, .tnc-dg-day[tabindex]")) {
3910
+ if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-dg-day[tabindex]")) {
3871
3911
  const day = parseDay(target.dataset.date ?? "");
3872
3912
  if (day !== null) {
3873
3913
  ev.preventDefault();
@@ -817,8 +817,9 @@ var TimeGridView = class {
817
817
  const { ctx } = this;
818
818
  const { doc, opts, days, today } = ctx;
819
819
  this.weights = days.map((d) => d === today && opts.todayWidth > 1 && days.length > 1 ? opts.todayWidth : 1);
820
- const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(0, ${w}fr)`).join(" ")}`;
820
+ const tpl = `var(--tnc-gutter-w) ${this.weights.map((w) => `minmax(var(--tnc-col-min), ${w}fr)`).join(" ")}`;
821
821
  this.el.style.setProperty("--tnc-cols", tpl);
822
+ this.el.style.setProperty("--tnc-ncols", String(days.length));
822
823
  const gutterHead = h(doc, "div", "tnc-gutter-head", { role: "columnheader" });
823
824
  if (opts.weekNumbers && days[0] !== void 0) gutterHead.textContent = ctx.text.weekNumber(isoWeekNumber(days[0]));
824
825
  this.headRow.replaceChildren(gutterHead);
@@ -1926,13 +1927,10 @@ var Calendar = class {
1926
1927
  this.bindEvents();
1927
1928
  this.rebuild(true);
1928
1929
  this.scheduleTick();
1929
- const RO = this.win.ResizeObserver;
1930
- if (RO) {
1931
- this.resizeObs = new RO(() => this.current?.resize?.());
1932
- this.resizeObs.observe(this.root);
1933
- }
1930
+ this.observeResize();
1934
1931
  }
1935
1932
  host;
1933
+ /** The document/window the calendar currently lives in; see `adopt()`. */
1936
1934
  doc;
1937
1935
  win;
1938
1936
  root;
@@ -1965,6 +1963,37 @@ var Calendar = class {
1965
1963
  destroyed = false;
1966
1964
  pendingChange = null;
1967
1965
  frame = null;
1966
+ observeResize() {
1967
+ this.resizeObs?.disconnect();
1968
+ const RO = this.win.ResizeObserver;
1969
+ if (RO) {
1970
+ this.resizeObs = new RO(() => this.current?.resize?.());
1971
+ this.resizeObs.observe(this.root);
1972
+ }
1973
+ }
1974
+ onAdoptCheck = () => {
1975
+ this.adopt();
1976
+ };
1977
+ /**
1978
+ * Hosts may move a live calendar into another window (e.g. Obsidian's
1979
+ * "Move to new window"). Listeners, timers and observers belong to a window,
1980
+ * so rebind them to the root's current document and rebuild the view there.
1981
+ */
1982
+ adopt() {
1983
+ const doc = this.root.ownerDocument;
1984
+ if (this.destroyed || doc === this.doc || this.session) return;
1985
+ const old = this.win;
1986
+ if (this.timer !== null) old.clearTimeout(this.timer);
1987
+ if (this.frame !== null) old.cancelAnimationFrame(this.frame);
1988
+ this.timer = this.frame = null;
1989
+ this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
1990
+ this.doc = doc;
1991
+ this.win = doc.defaultView ?? old;
1992
+ this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
1993
+ this.observeResize();
1994
+ this.rebuild(false);
1995
+ this.scheduleTick();
1996
+ }
1968
1997
  /* ================================================================ public */
1969
1998
  /** Replaces all items, re-rendering only what changed. */
1970
1999
  setItems(items) {
@@ -2529,6 +2558,7 @@ var Calendar = class {
2529
2558
  applyChange(change) {
2530
2559
  if (!change.added.length && !change.updated.length && !change.removed.length && !change.days.size && !change.spans) return;
2531
2560
  this.conflicts = dependencyConflicts(this.store);
2561
+ this.adopt();
2532
2562
  this.pendingChange = this.pendingChange ? this.merge(this.pendingChange, change) : change;
2533
2563
  if (this.session?.active) {
2534
2564
  this.flush();
@@ -2689,6 +2719,8 @@ var Calendar = class {
2689
2719
  r.addEventListener("dragleave", this.onNativeDragLeave);
2690
2720
  r.addEventListener("drop", this.onNativeDrop);
2691
2721
  r.addEventListener("touchmove", this.onTouchMove, { passive: false });
2722
+ r.addEventListener("pointerover", this.onAdoptCheck);
2723
+ r.addEventListener("focusin", this.onAdoptCheck);
2692
2724
  this.doc.addEventListener("pointerdown", this.onDocPointerDown, true);
2693
2725
  }
2694
2726
  unbindEvents() {
@@ -2705,6 +2737,8 @@ var Calendar = class {
2705
2737
  r.removeEventListener("dragleave", this.onNativeDragLeave);
2706
2738
  r.removeEventListener("drop", this.onNativeDrop);
2707
2739
  r.removeEventListener("touchmove", this.onTouchMove);
2740
+ r.removeEventListener("pointerover", this.onAdoptCheck);
2741
+ r.removeEventListener("focusin", this.onAdoptCheck);
2708
2742
  this.doc.removeEventListener("pointerdown", this.onDocPointerDown, true);
2709
2743
  this.listenDoc(false);
2710
2744
  }
@@ -3202,6 +3236,12 @@ var Calendar = class {
3202
3236
  ev.preventDefault();
3203
3237
  };
3204
3238
  onClick = (ev) => {
3239
+ const yearDay = ev.target.closest?.(".tnc-ym-day");
3240
+ if (yearDay && this.root.contains(yearDay)) {
3241
+ const day = parseDay(yearDay.dataset.date ?? "");
3242
+ if (day !== null) this.clickSlot({ kind: "day", day }, ev, true);
3243
+ return;
3244
+ }
3205
3245
  const el = this.itemElFrom(ev.target);
3206
3246
  if (!el || ev.target.closest(".tnc-resize, .tnc-port")) return;
3207
3247
  const meta = this.meta.get(el);
@@ -3261,7 +3301,7 @@ var Calendar = class {
3261
3301
  return;
3262
3302
  }
3263
3303
  const target = ev.target;
3264
- if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-ym-day, .tnc-dg-day[tabindex]")) {
3304
+ if ((ev.key === "Enter" || ev.key === " ") && target.matches(".tnc-dg-day[tabindex]")) {
3265
3305
  const day = parseDay(target.dataset.date ?? "");
3266
3306
  if (day !== null) {
3267
3307
  ev.preventDefault();
package/dist/esm/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  TIMELINE_UNIT_DAYS,
8
8
  defaultOptions,
9
9
  localeFirstDay
10
- } from "./chunk-UWCSL5AN.js";
10
+ } from "./chunk-ZJQMMA6W.js";
11
11
  import {
12
12
  DAY_MS,
13
13
  ItemStore,
package/dist/esm/react.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Calendar
3
- } from "./chunk-UWCSL5AN.js";
3
+ } from "./chunk-ZJQMMA6W.js";
4
4
  import "./chunk-DVMZ5OXN.js";
5
5
 
6
6
  // src/react/index.tsx
@@ -12,8 +12,9 @@ import { type CalendarOptions, type CalendarText, type DayArg, type ExternalDrag
12
12
  */
13
13
  export declare class Calendar<D = unknown> implements ViewContext<D> {
14
14
  readonly host: HTMLElement;
15
- readonly doc: Document;
16
- readonly win: Window;
15
+ /** The document/window the calendar currently lives in; see `adopt()`. */
16
+ doc: Document;
17
+ win: Window;
17
18
  readonly root: HTMLElement;
18
19
  readonly store: ItemStore<D>;
19
20
  readonly meta: WeakMap<Element, ElMeta<D>>;
@@ -54,6 +55,14 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
54
55
  private pendingChange;
55
56
  private frame;
56
57
  constructor(host: HTMLElement, options?: Partial<CalendarOptions<D>>, items?: Iterable<CalendarItem<D>>);
58
+ private observeResize;
59
+ private readonly onAdoptCheck;
60
+ /**
61
+ * Hosts may move a live calendar into another window (e.g. Obsidian's
62
+ * "Move to new window"). Listeners, timers and observers belong to a window,
63
+ * so rebind them to the root's current document and rebuild the view there.
64
+ */
65
+ adopt(): void;
57
66
  /** Replaces all items, re-rendering only what changed. */
58
67
  setItems(items: Iterable<CalendarItem<D>>): void;
59
68
  upsertItems(items: Iterable<CalendarItem<D>>): void;
@@ -12,8 +12,9 @@ import { type CalendarOptions, type CalendarText, type DayArg, type ExternalDrag
12
12
  */
13
13
  export declare class Calendar<D = unknown> implements ViewContext<D> {
14
14
  readonly host: HTMLElement;
15
- readonly doc: Document;
16
- readonly win: Window;
15
+ /** The document/window the calendar currently lives in; see `adopt()`. */
16
+ doc: Document;
17
+ win: Window;
17
18
  readonly root: HTMLElement;
18
19
  readonly store: ItemStore<D>;
19
20
  readonly meta: WeakMap<Element, ElMeta<D>>;
@@ -54,6 +55,14 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
54
55
  private pendingChange;
55
56
  private frame;
56
57
  constructor(host: HTMLElement, options?: Partial<CalendarOptions<D>>, items?: Iterable<CalendarItem<D>>);
58
+ private observeResize;
59
+ private readonly onAdoptCheck;
60
+ /**
61
+ * Hosts may move a live calendar into another window (e.g. Obsidian's
62
+ * "Move to new window"). Listeners, timers and observers belong to a window,
63
+ * so rebind them to the root's current document and rebuild the view there.
64
+ */
65
+ adopt(): void;
57
66
  /** Replaces all items, re-rendering only what changed. */
58
67
  setItems(items: Iterable<CalendarItem<D>>): void;
59
68
  upsertItems(items: Iterable<CalendarItem<D>>): void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tasknotes/calendar",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Task-native calendar engine for TaskNotes: incremental layout, time grid, month, list, year and timeline views.",
5
5
  "license": "MIT",
6
6
  "type": "module",