@tasknotes/calendar 0.1.10 → 0.1.12
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 +9 -0
- package/dist/calendar.css +36 -2
- package/dist/cjs/core.cjs +20 -26
- package/dist/cjs/index.cjs +40 -35
- package/dist/cjs/react.cjs +40 -35
- package/dist/esm/{chunk-5PHSJK36.js → chunk-AACI7SZC.js} +21 -10
- package/dist/esm/{chunk-66A6EMCU.js → chunk-JWORVABV.js} +20 -26
- package/dist/esm/core.js +1 -1
- package/dist/esm/index.js +2 -2
- package/dist/esm/react.js +2 -2
- package/dist/types/core/layout.d.cts +5 -0
- package/dist/types/core/layout.d.ts +5 -0
- package/dist/types/dom/calendar.d.cts +1 -0
- package/dist/types/dom/calendar.d.ts +1 -0
- package/dist/types/dom/context.d.cts +2 -0
- package/dist/types/dom/context.d.ts +2 -0
- package/dist/types/dom/options.d.cts +6 -0
- package/dist/types/dom/options.d.ts +6 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.12
|
|
4
|
+
|
|
5
|
+
- Hosts can pass a `tooltip(el, text)` option to show hover tooltips their own way (Obsidian's `setTooltip`, say). Without it, tooltips stay as `title` attributes.
|
|
6
|
+
|
|
7
|
+
## 0.1.11
|
|
8
|
+
|
|
9
|
+
- Hour-long timed items keep their time in narrow columns. Only single-row short items drop the time label when narrow; in the stacked layout the title is clamped to the lines left above the time (callumalpass/tasknotes#2528).
|
|
10
|
+
- Back-to-back timed items no longer count as overlapping: an item starting exactly where a short item ends stays in the same column instead of going side by side or into a collision stack, and the short item is drawn at its real height (callumalpass/tasknotes#2529).
|
|
11
|
+
|
|
3
12
|
## 0.1.10
|
|
4
13
|
|
|
5
14
|
- Freeze Month source layout during a move and draw an inert target placeholder; preserve timed drag width across collision layouts.
|
package/dist/calendar.css
CHANGED
|
@@ -293,8 +293,42 @@
|
|
|
293
293
|
.tnc-item--timed.is-short .tnc-item-time {
|
|
294
294
|
flex: none;
|
|
295
295
|
}
|
|
296
|
-
|
|
297
|
-
|
|
296
|
+
/* Stacked layout: the time keeps its line and the title gets the lines left over
|
|
297
|
+
(11px text: n title lines need 13.75 * (n + 1) + 1px). Single-row short items drop the time when narrow. */
|
|
298
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
299
|
+
flex: 0 1 auto;
|
|
300
|
+
min-height: 0;
|
|
301
|
+
}
|
|
302
|
+
.tnc-item--timed:not(.is-short) .tnc-item-time {
|
|
303
|
+
flex: none;
|
|
304
|
+
}
|
|
305
|
+
@container (max-height: 97.2px) {
|
|
306
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
307
|
+
-webkit-line-clamp: 5;
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
@container (max-height: 83.4px) {
|
|
311
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
312
|
+
-webkit-line-clamp: 4;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
@container (max-height: 69.7px) {
|
|
316
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
317
|
+
-webkit-line-clamp: 3;
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
@container (max-height: 55.9px) {
|
|
321
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
322
|
+
-webkit-line-clamp: 2;
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
@container (max-height: 42.2px) {
|
|
326
|
+
.tnc-item--timed:not(.is-short) .tnc-item-title {
|
|
327
|
+
-webkit-line-clamp: 1;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
@container (max-width: 239px) {
|
|
331
|
+
.tnc-item--timed.is-short .tnc-item-time {
|
|
298
332
|
display: none;
|
|
299
333
|
}
|
|
300
334
|
}
|
package/dist/cjs/core.cjs
CHANGED
|
@@ -490,43 +490,44 @@ function segmentInWindow(n, day, minMinute, maxMinute, zone) {
|
|
|
490
490
|
};
|
|
491
491
|
}
|
|
492
492
|
var defaultOrder = (a, b) => a.startMs - b.startMs || b.endMs - b.startMs - (a.endMs - a.startMs) || Number(b.allDay) - Number(a.allDay) || a.item.title.localeCompare(b.item.title);
|
|
493
|
+
function collides(a, b, minMinutes) {
|
|
494
|
+
if (b.startMin < a.endMin) return true;
|
|
495
|
+
if (b.startMin === a.endMin && a.endMin > a.startMin) return false;
|
|
496
|
+
return b.startMin < a.startMin + minMinutes;
|
|
497
|
+
}
|
|
498
|
+
function overlaps(a, b, minMinutes) {
|
|
499
|
+
return a.startMin <= b.startMin ? collides(a, b, minMinutes) : collides(b, a, minMinutes);
|
|
500
|
+
}
|
|
493
501
|
function packTimed(segs, minMinutes, order = defaultOrder) {
|
|
494
|
-
const sorted = segs.
|
|
502
|
+
const sorted = [...segs].sort((a, b) => a.startMin - b.startMin || Math.max(b.endMin, b.startMin + minMinutes) - Math.max(a.endMin, a.startMin + minMinutes) || order(a.item, b.item));
|
|
495
503
|
const out = [];
|
|
496
504
|
let cluster = [];
|
|
497
|
-
let
|
|
498
|
-
let clusterEnd = -Infinity;
|
|
505
|
+
let colLast = [];
|
|
499
506
|
let clusterIndex = 0;
|
|
500
507
|
const flush = () => {
|
|
501
508
|
if (cluster.length) clusterIndex++;
|
|
502
|
-
const cols =
|
|
509
|
+
const cols = colLast.length;
|
|
503
510
|
for (const p of cluster) {
|
|
504
511
|
p.cols = cols;
|
|
505
512
|
let span = 1;
|
|
506
|
-
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && o
|
|
513
|
+
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && overlaps(o, p, minMinutes))) span++;
|
|
507
514
|
p.span = span;
|
|
508
515
|
}
|
|
509
516
|
cluster = [];
|
|
510
|
-
|
|
517
|
+
colLast = [];
|
|
511
518
|
};
|
|
512
519
|
for (const s of sorted) {
|
|
513
|
-
if (
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
let col = colEnds.findIndex((end) => end <= s.startMin);
|
|
518
|
-
if (col < 0) {
|
|
519
|
-
col = colEnds.length;
|
|
520
|
-
colEnds.push(0);
|
|
521
|
-
}
|
|
522
|
-
colEnds[col] = s.end;
|
|
520
|
+
if (!cluster.some((o) => collides(o, s, minMinutes))) flush();
|
|
521
|
+
let col = colLast.findIndex((last) => !collides(last, s, minMinutes));
|
|
522
|
+
if (col < 0) col = colLast.length;
|
|
523
523
|
const p = { ...s, col, cols: 1, span: 1, cluster: clusterIndex, split: false };
|
|
524
|
+
colLast[col] = p;
|
|
524
525
|
cluster.push(p);
|
|
525
526
|
out.push(p);
|
|
526
|
-
clusterEnd = Math.max(clusterEnd, s.end);
|
|
527
527
|
}
|
|
528
528
|
flush();
|
|
529
|
-
|
|
529
|
+
const starts = new Set(out.map((p) => p.startMin));
|
|
530
|
+
for (const p of out) if (p.endMin > p.startMin && p.startMin + minMinutes > p.endMin && starts.has(p.endMin)) p.abutted = true;
|
|
530
531
|
return out;
|
|
531
532
|
}
|
|
532
533
|
function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTES_PER_DAY]) {
|
|
@@ -548,15 +549,8 @@ function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTE
|
|
|
548
549
|
}
|
|
549
550
|
function markSplit(lane, other, minMinutes) {
|
|
550
551
|
if (!lane.length || !other.length) return;
|
|
551
|
-
const end = (p) => Math.max(p.endMin, p.startMin + minMinutes);
|
|
552
|
-
const ranges = /* @__PURE__ */ new Map();
|
|
553
|
-
for (const p of lane) {
|
|
554
|
-
const r = ranges.get(p.cluster);
|
|
555
|
-
if (r) r[1] = Math.max(r[1], end(p));
|
|
556
|
-
else ranges.set(p.cluster, [p.startMin, end(p)]);
|
|
557
|
-
}
|
|
558
552
|
const split = /* @__PURE__ */ new Set();
|
|
559
|
-
for (const
|
|
553
|
+
for (const p of lane) if (!split.has(p.cluster) && other.some((o) => overlaps(p, o, minMinutes))) split.add(p.cluster);
|
|
560
554
|
for (const p of lane) p.split = split.has(p.cluster);
|
|
561
555
|
}
|
|
562
556
|
function layoutRow(items, days, order = defaultOrder) {
|
package/dist/cjs/index.cjs
CHANGED
|
@@ -502,43 +502,44 @@ function segmentInWindow(n, day, minMinute, maxMinute, zone) {
|
|
|
502
502
|
};
|
|
503
503
|
}
|
|
504
504
|
var defaultOrder = (a, b) => a.startMs - b.startMs || b.endMs - b.startMs - (a.endMs - a.startMs) || Number(b.allDay) - Number(a.allDay) || a.item.title.localeCompare(b.item.title);
|
|
505
|
+
function collides(a, b, minMinutes) {
|
|
506
|
+
if (b.startMin < a.endMin) return true;
|
|
507
|
+
if (b.startMin === a.endMin && a.endMin > a.startMin) return false;
|
|
508
|
+
return b.startMin < a.startMin + minMinutes;
|
|
509
|
+
}
|
|
510
|
+
function overlaps(a, b, minMinutes) {
|
|
511
|
+
return a.startMin <= b.startMin ? collides(a, b, minMinutes) : collides(b, a, minMinutes);
|
|
512
|
+
}
|
|
505
513
|
function packTimed(segs, minMinutes, order = defaultOrder) {
|
|
506
|
-
const sorted = segs.
|
|
514
|
+
const sorted = [...segs].sort((a, b) => a.startMin - b.startMin || Math.max(b.endMin, b.startMin + minMinutes) - Math.max(a.endMin, a.startMin + minMinutes) || order(a.item, b.item));
|
|
507
515
|
const out = [];
|
|
508
516
|
let cluster = [];
|
|
509
|
-
let
|
|
510
|
-
let clusterEnd = -Infinity;
|
|
517
|
+
let colLast = [];
|
|
511
518
|
let clusterIndex = 0;
|
|
512
519
|
const flush = () => {
|
|
513
520
|
if (cluster.length) clusterIndex++;
|
|
514
|
-
const cols =
|
|
521
|
+
const cols = colLast.length;
|
|
515
522
|
for (const p of cluster) {
|
|
516
523
|
p.cols = cols;
|
|
517
524
|
let span = 1;
|
|
518
|
-
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && o
|
|
525
|
+
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && overlaps(o, p, minMinutes))) span++;
|
|
519
526
|
p.span = span;
|
|
520
527
|
}
|
|
521
528
|
cluster = [];
|
|
522
|
-
|
|
529
|
+
colLast = [];
|
|
523
530
|
};
|
|
524
531
|
for (const s of sorted) {
|
|
525
|
-
if (
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
}
|
|
529
|
-
let col = colEnds.findIndex((end) => end <= s.startMin);
|
|
530
|
-
if (col < 0) {
|
|
531
|
-
col = colEnds.length;
|
|
532
|
-
colEnds.push(0);
|
|
533
|
-
}
|
|
534
|
-
colEnds[col] = s.end;
|
|
532
|
+
if (!cluster.some((o) => collides(o, s, minMinutes))) flush();
|
|
533
|
+
let col = colLast.findIndex((last) => !collides(last, s, minMinutes));
|
|
534
|
+
if (col < 0) col = colLast.length;
|
|
535
535
|
const p = { ...s, col, cols: 1, span: 1, cluster: clusterIndex, split: false };
|
|
536
|
+
colLast[col] = p;
|
|
536
537
|
cluster.push(p);
|
|
537
538
|
out.push(p);
|
|
538
|
-
clusterEnd = Math.max(clusterEnd, s.end);
|
|
539
539
|
}
|
|
540
540
|
flush();
|
|
541
|
-
|
|
541
|
+
const starts = new Set(out.map((p) => p.startMin));
|
|
542
|
+
for (const p of out) if (p.endMin > p.startMin && p.startMin + minMinutes > p.endMin && starts.has(p.endMin)) p.abutted = true;
|
|
542
543
|
return out;
|
|
543
544
|
}
|
|
544
545
|
function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTES_PER_DAY]) {
|
|
@@ -560,15 +561,8 @@ function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTE
|
|
|
560
561
|
}
|
|
561
562
|
function markSplit(lane, other, minMinutes) {
|
|
562
563
|
if (!lane.length || !other.length) return;
|
|
563
|
-
const end = (p) => Math.max(p.endMin, p.startMin + minMinutes);
|
|
564
|
-
const ranges = /* @__PURE__ */ new Map();
|
|
565
|
-
for (const p of lane) {
|
|
566
|
-
const r = ranges.get(p.cluster);
|
|
567
|
-
if (r) r[1] = Math.max(r[1], end(p));
|
|
568
|
-
else ranges.set(p.cluster, [p.startMin, end(p)]);
|
|
569
|
-
}
|
|
570
564
|
const split = /* @__PURE__ */ new Set();
|
|
571
|
-
for (const
|
|
565
|
+
for (const p of lane) if (!split.has(p.cluster) && other.some((o) => overlaps(p, o, minMinutes))) split.add(p.cluster);
|
|
572
566
|
for (const p of lane) p.split = split.has(p.cluster);
|
|
573
567
|
}
|
|
574
568
|
function layoutRow(items, days, order = defaultOrder) {
|
|
@@ -1063,6 +1057,7 @@ var LAYOUT_KEYS = /* @__PURE__ */ new Set([
|
|
|
1063
1057
|
"text",
|
|
1064
1058
|
"timeline",
|
|
1065
1059
|
"editable",
|
|
1060
|
+
"tooltip",
|
|
1066
1061
|
"itemContent",
|
|
1067
1062
|
"itemClassNames",
|
|
1068
1063
|
"listItemContent",
|
|
@@ -1699,8 +1694,10 @@ var DateStrip = class {
|
|
|
1699
1694
|
const head = h(doc, "div", "tnc-strip-head");
|
|
1700
1695
|
this.title = h(doc, "button", "tnc-strip-title", { type: "button", "aria-expanded": "false" });
|
|
1701
1696
|
this.title.addEventListener("click", () => this.setExpanded(!this.expanded));
|
|
1702
|
-
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev
|
|
1703
|
-
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next
|
|
1697
|
+
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev }, "\u2039");
|
|
1698
|
+
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next }, "\u203A");
|
|
1699
|
+
ctx.tooltip(prev, text.prev);
|
|
1700
|
+
ctx.tooltip(next, text.next);
|
|
1704
1701
|
prev.addEventListener("click", () => this.step(-1));
|
|
1705
1702
|
next.addEventListener("click", () => this.step(1));
|
|
1706
1703
|
this.todayBtn = h(doc, "button", "tnc-strip-today", { type: "button" }, text.today);
|
|
@@ -2292,7 +2289,7 @@ var TimeGridView = class {
|
|
|
2292
2289
|
el.classList.toggle("is-short", short);
|
|
2293
2290
|
setStyle(el, {
|
|
2294
2291
|
top: top(p.startMin),
|
|
2295
|
-
height: `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
2292
|
+
height: p.abutted ? height(p) : `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
2296
2293
|
...inLane(lane, p.split, left, width),
|
|
2297
2294
|
"--tnc-event-readable-width": pct(span / cols / width),
|
|
2298
2295
|
"z-index": String(p.col + 1)
|
|
@@ -2324,10 +2321,10 @@ var TimeGridView = class {
|
|
|
2324
2321
|
h(ctx.doc, "span", "tnc-collision-title", { "aria-hidden": "true" }, items.join(" \xB7 "))
|
|
2325
2322
|
);
|
|
2326
2323
|
link.setAttribute("aria-label", `${count}, ${interval}: ${items.join(", ")}`);
|
|
2327
|
-
link
|
|
2324
|
+
ctx.tooltip(link, link.getAttribute("aria-label"));
|
|
2328
2325
|
} else {
|
|
2326
|
+
ctx.tooltip(link, "");
|
|
2329
2327
|
link.removeAttribute("aria-label");
|
|
2330
|
-
link.removeAttribute("title");
|
|
2331
2328
|
}
|
|
2332
2329
|
const cols = maxStack;
|
|
2333
2330
|
setStyle(link, {
|
|
@@ -3105,9 +3102,9 @@ var YearView = class {
|
|
|
3105
3102
|
);
|
|
3106
3103
|
const label = this.ctx.fmt.longDate(c.day);
|
|
3107
3104
|
c.el.setAttribute("aria-label", items.length ? `${label}, ${this.ctx.text.itemCount(items.length)}` : label);
|
|
3108
|
-
c.el
|
|
3105
|
+
this.ctx.tooltip(c.el, items.length ? `${label}
|
|
3109
3106
|
${items.slice(0, 8).map((n) => `\u2022 ${n.item.title}`).join("\n")}${items.length > 8 ? `
|
|
3110
|
-
${this.ctx.text.more(items.length - 8)}` : ""}` : label;
|
|
3107
|
+
${this.ctx.text.more(items.length - 8)}` : ""}` : label);
|
|
3111
3108
|
}
|
|
3112
3109
|
}
|
|
3113
3110
|
showSelection(_sel) {
|
|
@@ -3542,6 +3539,11 @@ var Calendar = class {
|
|
|
3542
3539
|
const specific = what === "start" ? it.startEditable : it.durationEditable;
|
|
3543
3540
|
return specific ?? base;
|
|
3544
3541
|
}
|
|
3542
|
+
tooltip(el, text) {
|
|
3543
|
+
if (this.opts.tooltip) this.opts.tooltip(el, text);
|
|
3544
|
+
else if (text) el.title = text;
|
|
3545
|
+
else el.removeAttribute("title");
|
|
3546
|
+
}
|
|
3545
3547
|
navLink(day, label, cls) {
|
|
3546
3548
|
const btn = h(this.doc, "button", `tnc-navlink ${cls}`, { type: "button", "data-nav-date": formatDay(day) }, label);
|
|
3547
3549
|
btn.addEventListener("click", (ev) => {
|
|
@@ -3943,7 +3945,8 @@ var Calendar = class {
|
|
|
3943
3945
|
const cfg = tb === true ? {} : tb;
|
|
3944
3946
|
const views = cfg.views ?? ["month", "week", "days", "day", "list", "year"];
|
|
3945
3947
|
const btn = (label, hint, cls, onClick, pressed) => {
|
|
3946
|
-
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button",
|
|
3948
|
+
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", "aria-label": hint }, label);
|
|
3949
|
+
this.tooltip(b, hint);
|
|
3947
3950
|
if (pressed !== void 0) b.setAttribute("aria-pressed", String(pressed));
|
|
3948
3951
|
b.addEventListener("click", onClick);
|
|
3949
3952
|
return b;
|
|
@@ -4143,7 +4146,9 @@ var Calendar = class {
|
|
|
4143
4146
|
addPorts(el, n) {
|
|
4144
4147
|
const edges = n.item.kind === "milestone" ? ["finish"] : ["start", "finish"];
|
|
4145
4148
|
for (const edge of edges) {
|
|
4146
|
-
|
|
4149
|
+
const port = h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge });
|
|
4150
|
+
this.tooltip(port, "Drag to link");
|
|
4151
|
+
el.append(port);
|
|
4147
4152
|
}
|
|
4148
4153
|
}
|
|
4149
4154
|
/* ============================================================== popover */
|
package/dist/cjs/react.cjs
CHANGED
|
@@ -806,6 +806,7 @@ var LAYOUT_KEYS = /* @__PURE__ */ new Set([
|
|
|
806
806
|
"text",
|
|
807
807
|
"timeline",
|
|
808
808
|
"editable",
|
|
809
|
+
"tooltip",
|
|
809
810
|
"itemContent",
|
|
810
811
|
"itemClassNames",
|
|
811
812
|
"listItemContent",
|
|
@@ -838,43 +839,44 @@ function segmentInWindow(n, day, minMinute, maxMinute, zone) {
|
|
|
838
839
|
};
|
|
839
840
|
}
|
|
840
841
|
var defaultOrder = (a, b) => a.startMs - b.startMs || b.endMs - b.startMs - (a.endMs - a.startMs) || Number(b.allDay) - Number(a.allDay) || a.item.title.localeCompare(b.item.title);
|
|
842
|
+
function collides(a, b, minMinutes) {
|
|
843
|
+
if (b.startMin < a.endMin) return true;
|
|
844
|
+
if (b.startMin === a.endMin && a.endMin > a.startMin) return false;
|
|
845
|
+
return b.startMin < a.startMin + minMinutes;
|
|
846
|
+
}
|
|
847
|
+
function overlaps(a, b, minMinutes) {
|
|
848
|
+
return a.startMin <= b.startMin ? collides(a, b, minMinutes) : collides(b, a, minMinutes);
|
|
849
|
+
}
|
|
841
850
|
function packTimed(segs, minMinutes, order = defaultOrder) {
|
|
842
|
-
const sorted = segs.
|
|
851
|
+
const sorted = [...segs].sort((a, b) => a.startMin - b.startMin || Math.max(b.endMin, b.startMin + minMinutes) - Math.max(a.endMin, a.startMin + minMinutes) || order(a.item, b.item));
|
|
843
852
|
const out = [];
|
|
844
853
|
let cluster = [];
|
|
845
|
-
let
|
|
846
|
-
let clusterEnd = -Infinity;
|
|
854
|
+
let colLast = [];
|
|
847
855
|
let clusterIndex = 0;
|
|
848
856
|
const flush = () => {
|
|
849
857
|
if (cluster.length) clusterIndex++;
|
|
850
|
-
const cols =
|
|
858
|
+
const cols = colLast.length;
|
|
851
859
|
for (const p of cluster) {
|
|
852
860
|
p.cols = cols;
|
|
853
861
|
let span = 1;
|
|
854
|
-
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && o
|
|
862
|
+
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && overlaps(o, p, minMinutes))) span++;
|
|
855
863
|
p.span = span;
|
|
856
864
|
}
|
|
857
865
|
cluster = [];
|
|
858
|
-
|
|
866
|
+
colLast = [];
|
|
859
867
|
};
|
|
860
868
|
for (const s of sorted) {
|
|
861
|
-
if (
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
}
|
|
865
|
-
let col = colEnds.findIndex((end) => end <= s.startMin);
|
|
866
|
-
if (col < 0) {
|
|
867
|
-
col = colEnds.length;
|
|
868
|
-
colEnds.push(0);
|
|
869
|
-
}
|
|
870
|
-
colEnds[col] = s.end;
|
|
869
|
+
if (!cluster.some((o) => collides(o, s, minMinutes))) flush();
|
|
870
|
+
let col = colLast.findIndex((last) => !collides(last, s, minMinutes));
|
|
871
|
+
if (col < 0) col = colLast.length;
|
|
871
872
|
const p = { ...s, col, cols: 1, span: 1, cluster: clusterIndex, split: false };
|
|
873
|
+
colLast[col] = p;
|
|
872
874
|
cluster.push(p);
|
|
873
875
|
out.push(p);
|
|
874
|
-
clusterEnd = Math.max(clusterEnd, s.end);
|
|
875
876
|
}
|
|
876
877
|
flush();
|
|
877
|
-
|
|
878
|
+
const starts = new Set(out.map((p) => p.startMin));
|
|
879
|
+
for (const p of out) if (p.endMin > p.startMin && p.startMin + minMinutes > p.endMin && starts.has(p.endMin)) p.abutted = true;
|
|
878
880
|
return out;
|
|
879
881
|
}
|
|
880
882
|
function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTES_PER_DAY]) {
|
|
@@ -896,15 +898,8 @@ function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTE
|
|
|
896
898
|
}
|
|
897
899
|
function markSplit(lane, other, minMinutes) {
|
|
898
900
|
if (!lane.length || !other.length) return;
|
|
899
|
-
const end = (p) => Math.max(p.endMin, p.startMin + minMinutes);
|
|
900
|
-
const ranges = /* @__PURE__ */ new Map();
|
|
901
|
-
for (const p of lane) {
|
|
902
|
-
const r = ranges.get(p.cluster);
|
|
903
|
-
if (r) r[1] = Math.max(r[1], end(p));
|
|
904
|
-
else ranges.set(p.cluster, [p.startMin, end(p)]);
|
|
905
|
-
}
|
|
906
901
|
const split = /* @__PURE__ */ new Set();
|
|
907
|
-
for (const
|
|
902
|
+
for (const p of lane) if (!split.has(p.cluster) && other.some((o) => overlaps(p, o, minMinutes))) split.add(p.cluster);
|
|
908
903
|
for (const p of lane) p.split = split.has(p.cluster);
|
|
909
904
|
}
|
|
910
905
|
function layoutRow(items, days, order = defaultOrder) {
|
|
@@ -1607,8 +1602,10 @@ var DateStrip = class {
|
|
|
1607
1602
|
const head = h(doc, "div", "tnc-strip-head");
|
|
1608
1603
|
this.title = h(doc, "button", "tnc-strip-title", { type: "button", "aria-expanded": "false" });
|
|
1609
1604
|
this.title.addEventListener("click", () => this.setExpanded(!this.expanded));
|
|
1610
|
-
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev
|
|
1611
|
-
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next
|
|
1605
|
+
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev }, "\u2039");
|
|
1606
|
+
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next }, "\u203A");
|
|
1607
|
+
ctx.tooltip(prev, text.prev);
|
|
1608
|
+
ctx.tooltip(next, text.next);
|
|
1612
1609
|
prev.addEventListener("click", () => this.step(-1));
|
|
1613
1610
|
next.addEventListener("click", () => this.step(1));
|
|
1614
1611
|
this.todayBtn = h(doc, "button", "tnc-strip-today", { type: "button" }, text.today);
|
|
@@ -2200,7 +2197,7 @@ var TimeGridView = class {
|
|
|
2200
2197
|
el.classList.toggle("is-short", short);
|
|
2201
2198
|
setStyle(el, {
|
|
2202
2199
|
top: top(p.startMin),
|
|
2203
|
-
height: `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
2200
|
+
height: p.abutted ? height(p) : `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
2204
2201
|
...inLane(lane, p.split, left, width),
|
|
2205
2202
|
"--tnc-event-readable-width": pct(span / cols / width),
|
|
2206
2203
|
"z-index": String(p.col + 1)
|
|
@@ -2232,10 +2229,10 @@ var TimeGridView = class {
|
|
|
2232
2229
|
h(ctx.doc, "span", "tnc-collision-title", { "aria-hidden": "true" }, items.join(" \xB7 "))
|
|
2233
2230
|
);
|
|
2234
2231
|
link.setAttribute("aria-label", `${count}, ${interval}: ${items.join(", ")}`);
|
|
2235
|
-
link
|
|
2232
|
+
ctx.tooltip(link, link.getAttribute("aria-label"));
|
|
2236
2233
|
} else {
|
|
2234
|
+
ctx.tooltip(link, "");
|
|
2237
2235
|
link.removeAttribute("aria-label");
|
|
2238
|
-
link.removeAttribute("title");
|
|
2239
2236
|
}
|
|
2240
2237
|
const cols = maxStack;
|
|
2241
2238
|
setStyle(link, {
|
|
@@ -3013,9 +3010,9 @@ var YearView = class {
|
|
|
3013
3010
|
);
|
|
3014
3011
|
const label = this.ctx.fmt.longDate(c.day);
|
|
3015
3012
|
c.el.setAttribute("aria-label", items.length ? `${label}, ${this.ctx.text.itemCount(items.length)}` : label);
|
|
3016
|
-
c.el
|
|
3013
|
+
this.ctx.tooltip(c.el, items.length ? `${label}
|
|
3017
3014
|
${items.slice(0, 8).map((n) => `\u2022 ${n.item.title}`).join("\n")}${items.length > 8 ? `
|
|
3018
|
-
${this.ctx.text.more(items.length - 8)}` : ""}` : label;
|
|
3015
|
+
${this.ctx.text.more(items.length - 8)}` : ""}` : label);
|
|
3019
3016
|
}
|
|
3020
3017
|
}
|
|
3021
3018
|
showSelection(_sel) {
|
|
@@ -3450,6 +3447,11 @@ var Calendar = class {
|
|
|
3450
3447
|
const specific = what === "start" ? it.startEditable : it.durationEditable;
|
|
3451
3448
|
return specific ?? base;
|
|
3452
3449
|
}
|
|
3450
|
+
tooltip(el, text) {
|
|
3451
|
+
if (this.opts.tooltip) this.opts.tooltip(el, text);
|
|
3452
|
+
else if (text) el.title = text;
|
|
3453
|
+
else el.removeAttribute("title");
|
|
3454
|
+
}
|
|
3453
3455
|
navLink(day, label, cls) {
|
|
3454
3456
|
const btn = h(this.doc, "button", `tnc-navlink ${cls}`, { type: "button", "data-nav-date": formatDay(day) }, label);
|
|
3455
3457
|
btn.addEventListener("click", (ev) => {
|
|
@@ -3851,7 +3853,8 @@ var Calendar = class {
|
|
|
3851
3853
|
const cfg = tb === true ? {} : tb;
|
|
3852
3854
|
const views = cfg.views ?? ["month", "week", "days", "day", "list", "year"];
|
|
3853
3855
|
const btn = (label, hint, cls, onClick, pressed) => {
|
|
3854
|
-
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button",
|
|
3856
|
+
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", "aria-label": hint }, label);
|
|
3857
|
+
this.tooltip(b, hint);
|
|
3855
3858
|
if (pressed !== void 0) b.setAttribute("aria-pressed", String(pressed));
|
|
3856
3859
|
b.addEventListener("click", onClick);
|
|
3857
3860
|
return b;
|
|
@@ -4051,7 +4054,9 @@ var Calendar = class {
|
|
|
4051
4054
|
addPorts(el, n) {
|
|
4052
4055
|
const edges = n.item.kind === "milestone" ? ["finish"] : ["start", "finish"];
|
|
4053
4056
|
for (const edge of edges) {
|
|
4054
|
-
|
|
4057
|
+
const port = h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge });
|
|
4058
|
+
this.tooltip(port, "Drag to link");
|
|
4059
|
+
el.append(port);
|
|
4055
4060
|
}
|
|
4056
4061
|
}
|
|
4057
4062
|
/* ============================================================== popover */
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
wallTime,
|
|
28
28
|
weekdayOf,
|
|
29
29
|
ymdOfDay
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-JWORVABV.js";
|
|
31
31
|
|
|
32
32
|
// src/dom/format.ts
|
|
33
33
|
var Formatter = class {
|
|
@@ -262,6 +262,7 @@ var LAYOUT_KEYS = /* @__PURE__ */ new Set([
|
|
|
262
262
|
"text",
|
|
263
263
|
"timeline",
|
|
264
264
|
"editable",
|
|
265
|
+
"tooltip",
|
|
265
266
|
"itemContent",
|
|
266
267
|
"itemClassNames",
|
|
267
268
|
"listItemContent",
|
|
@@ -984,8 +985,10 @@ var DateStrip = class {
|
|
|
984
985
|
const head = h(doc, "div", "tnc-strip-head");
|
|
985
986
|
this.title = h(doc, "button", "tnc-strip-title", { type: "button", "aria-expanded": "false" });
|
|
986
987
|
this.title.addEventListener("click", () => this.setExpanded(!this.expanded));
|
|
987
|
-
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev
|
|
988
|
-
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next
|
|
988
|
+
const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev }, "\u2039");
|
|
989
|
+
const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next }, "\u203A");
|
|
990
|
+
ctx.tooltip(prev, text.prev);
|
|
991
|
+
ctx.tooltip(next, text.next);
|
|
989
992
|
prev.addEventListener("click", () => this.step(-1));
|
|
990
993
|
next.addEventListener("click", () => this.step(1));
|
|
991
994
|
this.todayBtn = h(doc, "button", "tnc-strip-today", { type: "button" }, text.today);
|
|
@@ -1577,7 +1580,7 @@ var TimeGridView = class {
|
|
|
1577
1580
|
el.classList.toggle("is-short", short);
|
|
1578
1581
|
setStyle(el, {
|
|
1579
1582
|
top: top(p.startMin),
|
|
1580
|
-
height: `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
1583
|
+
height: p.abutted ? height(p) : `max(${height(p)}, ${opts.eventMinHeight}px)`,
|
|
1581
1584
|
...inLane(lane, p.split, left, width),
|
|
1582
1585
|
"--tnc-event-readable-width": pct(span / cols / width),
|
|
1583
1586
|
"z-index": String(p.col + 1)
|
|
@@ -1609,10 +1612,10 @@ var TimeGridView = class {
|
|
|
1609
1612
|
h(ctx.doc, "span", "tnc-collision-title", { "aria-hidden": "true" }, items.join(" \xB7 "))
|
|
1610
1613
|
);
|
|
1611
1614
|
link.setAttribute("aria-label", `${count}, ${interval}: ${items.join(", ")}`);
|
|
1612
|
-
link
|
|
1615
|
+
ctx.tooltip(link, link.getAttribute("aria-label"));
|
|
1613
1616
|
} else {
|
|
1617
|
+
ctx.tooltip(link, "");
|
|
1614
1618
|
link.removeAttribute("aria-label");
|
|
1615
|
-
link.removeAttribute("title");
|
|
1616
1619
|
}
|
|
1617
1620
|
const cols = maxStack;
|
|
1618
1621
|
setStyle(link, {
|
|
@@ -2390,9 +2393,9 @@ var YearView = class {
|
|
|
2390
2393
|
);
|
|
2391
2394
|
const label = this.ctx.fmt.longDate(c.day);
|
|
2392
2395
|
c.el.setAttribute("aria-label", items.length ? `${label}, ${this.ctx.text.itemCount(items.length)}` : label);
|
|
2393
|
-
c.el
|
|
2396
|
+
this.ctx.tooltip(c.el, items.length ? `${label}
|
|
2394
2397
|
${items.slice(0, 8).map((n) => `\u2022 ${n.item.title}`).join("\n")}${items.length > 8 ? `
|
|
2395
|
-
${this.ctx.text.more(items.length - 8)}` : ""}` : label;
|
|
2398
|
+
${this.ctx.text.more(items.length - 8)}` : ""}` : label);
|
|
2396
2399
|
}
|
|
2397
2400
|
}
|
|
2398
2401
|
showSelection(_sel) {
|
|
@@ -2827,6 +2830,11 @@ var Calendar = class {
|
|
|
2827
2830
|
const specific = what === "start" ? it.startEditable : it.durationEditable;
|
|
2828
2831
|
return specific ?? base;
|
|
2829
2832
|
}
|
|
2833
|
+
tooltip(el, text) {
|
|
2834
|
+
if (this.opts.tooltip) this.opts.tooltip(el, text);
|
|
2835
|
+
else if (text) el.title = text;
|
|
2836
|
+
else el.removeAttribute("title");
|
|
2837
|
+
}
|
|
2830
2838
|
navLink(day, label, cls) {
|
|
2831
2839
|
const btn = h(this.doc, "button", `tnc-navlink ${cls}`, { type: "button", "data-nav-date": formatDay(day) }, label);
|
|
2832
2840
|
btn.addEventListener("click", (ev) => {
|
|
@@ -3228,7 +3236,8 @@ var Calendar = class {
|
|
|
3228
3236
|
const cfg = tb === true ? {} : tb;
|
|
3229
3237
|
const views = cfg.views ?? ["month", "week", "days", "day", "list", "year"];
|
|
3230
3238
|
const btn = (label, hint, cls, onClick, pressed) => {
|
|
3231
|
-
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button",
|
|
3239
|
+
const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", "aria-label": hint }, label);
|
|
3240
|
+
this.tooltip(b, hint);
|
|
3232
3241
|
if (pressed !== void 0) b.setAttribute("aria-pressed", String(pressed));
|
|
3233
3242
|
b.addEventListener("click", onClick);
|
|
3234
3243
|
return b;
|
|
@@ -3428,7 +3437,9 @@ var Calendar = class {
|
|
|
3428
3437
|
addPorts(el, n) {
|
|
3429
3438
|
const edges = n.item.kind === "milestone" ? ["finish"] : ["start", "finish"];
|
|
3430
3439
|
for (const edge of edges) {
|
|
3431
|
-
|
|
3440
|
+
const port = h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge });
|
|
3441
|
+
this.tooltip(port, "Drag to link");
|
|
3442
|
+
el.append(port);
|
|
3432
3443
|
}
|
|
3433
3444
|
}
|
|
3434
3445
|
/* ============================================================== popover */
|
|
@@ -425,43 +425,44 @@ function segmentInWindow(n, day, minMinute, maxMinute, zone) {
|
|
|
425
425
|
};
|
|
426
426
|
}
|
|
427
427
|
var defaultOrder = (a, b) => a.startMs - b.startMs || b.endMs - b.startMs - (a.endMs - a.startMs) || Number(b.allDay) - Number(a.allDay) || a.item.title.localeCompare(b.item.title);
|
|
428
|
+
function collides(a, b, minMinutes) {
|
|
429
|
+
if (b.startMin < a.endMin) return true;
|
|
430
|
+
if (b.startMin === a.endMin && a.endMin > a.startMin) return false;
|
|
431
|
+
return b.startMin < a.startMin + minMinutes;
|
|
432
|
+
}
|
|
433
|
+
function overlaps(a, b, minMinutes) {
|
|
434
|
+
return a.startMin <= b.startMin ? collides(a, b, minMinutes) : collides(b, a, minMinutes);
|
|
435
|
+
}
|
|
428
436
|
function packTimed(segs, minMinutes, order = defaultOrder) {
|
|
429
|
-
const sorted = segs.
|
|
437
|
+
const sorted = [...segs].sort((a, b) => a.startMin - b.startMin || Math.max(b.endMin, b.startMin + minMinutes) - Math.max(a.endMin, a.startMin + minMinutes) || order(a.item, b.item));
|
|
430
438
|
const out = [];
|
|
431
439
|
let cluster = [];
|
|
432
|
-
let
|
|
433
|
-
let clusterEnd = -Infinity;
|
|
440
|
+
let colLast = [];
|
|
434
441
|
let clusterIndex = 0;
|
|
435
442
|
const flush = () => {
|
|
436
443
|
if (cluster.length) clusterIndex++;
|
|
437
|
-
const cols =
|
|
444
|
+
const cols = colLast.length;
|
|
438
445
|
for (const p of cluster) {
|
|
439
446
|
p.cols = cols;
|
|
440
447
|
let span = 1;
|
|
441
|
-
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && o
|
|
448
|
+
while (p.col + span < cols && !cluster.some((o) => o.col === p.col + span && overlaps(o, p, minMinutes))) span++;
|
|
442
449
|
p.span = span;
|
|
443
450
|
}
|
|
444
451
|
cluster = [];
|
|
445
|
-
|
|
452
|
+
colLast = [];
|
|
446
453
|
};
|
|
447
454
|
for (const s of sorted) {
|
|
448
|
-
if (
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
}
|
|
452
|
-
let col = colEnds.findIndex((end) => end <= s.startMin);
|
|
453
|
-
if (col < 0) {
|
|
454
|
-
col = colEnds.length;
|
|
455
|
-
colEnds.push(0);
|
|
456
|
-
}
|
|
457
|
-
colEnds[col] = s.end;
|
|
455
|
+
if (!cluster.some((o) => collides(o, s, minMinutes))) flush();
|
|
456
|
+
let col = colLast.findIndex((last) => !collides(last, s, minMinutes));
|
|
457
|
+
if (col < 0) col = colLast.length;
|
|
458
458
|
const p = { ...s, col, cols: 1, span: 1, cluster: clusterIndex, split: false };
|
|
459
|
+
colLast[col] = p;
|
|
459
460
|
cluster.push(p);
|
|
460
461
|
out.push(p);
|
|
461
|
-
clusterEnd = Math.max(clusterEnd, s.end);
|
|
462
462
|
}
|
|
463
463
|
flush();
|
|
464
|
-
|
|
464
|
+
const starts = new Set(out.map((p) => p.startMin));
|
|
465
|
+
for (const p of out) if (p.endMin > p.startMin && p.startMin + minMinutes > p.endMin && starts.has(p.endMin)) p.abutted = true;
|
|
465
466
|
return out;
|
|
466
467
|
}
|
|
467
468
|
function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTES_PER_DAY]) {
|
|
@@ -483,15 +484,8 @@ function layoutTimedDay(items, day, zone, minMinutes, order, window = [0, MINUTE
|
|
|
483
484
|
}
|
|
484
485
|
function markSplit(lane, other, minMinutes) {
|
|
485
486
|
if (!lane.length || !other.length) return;
|
|
486
|
-
const end = (p) => Math.max(p.endMin, p.startMin + minMinutes);
|
|
487
|
-
const ranges = /* @__PURE__ */ new Map();
|
|
488
|
-
for (const p of lane) {
|
|
489
|
-
const r = ranges.get(p.cluster);
|
|
490
|
-
if (r) r[1] = Math.max(r[1], end(p));
|
|
491
|
-
else ranges.set(p.cluster, [p.startMin, end(p)]);
|
|
492
|
-
}
|
|
493
487
|
const split = /* @__PURE__ */ new Set();
|
|
494
|
-
for (const
|
|
488
|
+
for (const p of lane) if (!split.has(p.cluster) && other.some((o) => overlaps(p, o, minMinutes))) split.add(p.cluster);
|
|
495
489
|
for (const p of lane) p.split = split.has(p.cluster);
|
|
496
490
|
}
|
|
497
491
|
function layoutRow(items, days, order = defaultOrder) {
|
package/dist/esm/core.js
CHANGED
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-
|
|
10
|
+
} from "./chunk-AACI7SZC.js";
|
|
11
11
|
import {
|
|
12
12
|
DAY_MS,
|
|
13
13
|
ItemStore,
|
|
@@ -49,7 +49,7 @@ import {
|
|
|
49
49
|
wallTime,
|
|
50
50
|
weekdayOf,
|
|
51
51
|
ymdOfDay
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-JWORVABV.js";
|
|
53
53
|
|
|
54
54
|
// src/tasknotes/bases.ts
|
|
55
55
|
var FROM_BASES = {
|
package/dist/esm/react.js
CHANGED
|
@@ -24,6 +24,11 @@ export interface TimedPlacement<D = unknown> extends TimedSegment<D> {
|
|
|
24
24
|
* Only then does the item keep to its lane's share of the column.
|
|
25
25
|
*/
|
|
26
26
|
split: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Another item starts exactly where this short one ends, so it is drawn at
|
|
29
|
+
* its real height instead of being stretched to the minimum height.
|
|
30
|
+
*/
|
|
31
|
+
abutted?: boolean;
|
|
27
32
|
}
|
|
28
33
|
export interface TimedDayLayout<D = unknown> {
|
|
29
34
|
day: Day;
|
|
@@ -24,6 +24,11 @@ export interface TimedPlacement<D = unknown> extends TimedSegment<D> {
|
|
|
24
24
|
* Only then does the item keep to its lane's share of the column.
|
|
25
25
|
*/
|
|
26
26
|
split: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Another item starts exactly where this short one ends, so it is drawn at
|
|
29
|
+
* its real height instead of being stretched to the minimum height.
|
|
30
|
+
*/
|
|
31
|
+
abutted?: boolean;
|
|
27
32
|
}
|
|
28
33
|
export interface TimedDayLayout<D = unknown> {
|
|
29
34
|
day: Day;
|
|
@@ -146,6 +146,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
|
|
|
146
146
|
dayArg(day: Day): DayArg;
|
|
147
147
|
dayClasses(day: Day): string[];
|
|
148
148
|
isEditable(n: NormalizedItem<D>, what: "start" | "duration", presentation?: boolean): boolean;
|
|
149
|
+
tooltip(el: HTMLElement, text: string): void;
|
|
149
150
|
navLink(day: Day, label: Node | string, cls: string): HTMLElement;
|
|
150
151
|
navigate(day: Day, jsEvent: MouseEvent | KeyboardEvent, view?: "day" | "month"): void;
|
|
151
152
|
createItemEl(meta: ElMeta<D>): HTMLElement;
|
|
@@ -146,6 +146,7 @@ export declare class Calendar<D = unknown> implements ViewContext<D> {
|
|
|
146
146
|
dayArg(day: Day): DayArg;
|
|
147
147
|
dayClasses(day: Day): string[];
|
|
148
148
|
isEditable(n: NormalizedItem<D>, what: "start" | "duration", presentation?: boolean): boolean;
|
|
149
|
+
tooltip(el: HTMLElement, text: string): void;
|
|
149
150
|
navLink(day: Day, label: Node | string, cls: string): HTMLElement;
|
|
150
151
|
navigate(day: Day, jsEvent: MouseEvent | KeyboardEvent, view?: "day" | "month"): void;
|
|
151
152
|
createItemEl(meta: ElMeta<D>): HTMLElement;
|
|
@@ -59,6 +59,8 @@ export interface ViewContext<D = unknown> {
|
|
|
59
59
|
/** Refreshes parts of an item element that depend on position (time label). */
|
|
60
60
|
refreshItemEl(el: HTMLElement, meta: ElMeta<D>): void;
|
|
61
61
|
destroyItemEl(el: HTMLElement): void;
|
|
62
|
+
/** Sets or clears (empty `text`) an element's hover tooltip through `opts.tooltip`. */
|
|
63
|
+
tooltip(el: HTMLElement, text: string): void;
|
|
62
64
|
/** Builds a nav link (day number / header) for a day. */
|
|
63
65
|
navLink(day: Day, label: Node | string, cls: string): HTMLElement;
|
|
64
66
|
openMore(day: Day, anchor: HTMLElement, jsEvent: MouseEvent | KeyboardEvent, itemIds?: readonly string[]): void;
|
|
@@ -59,6 +59,8 @@ export interface ViewContext<D = unknown> {
|
|
|
59
59
|
/** Refreshes parts of an item element that depend on position (time label). */
|
|
60
60
|
refreshItemEl(el: HTMLElement, meta: ElMeta<D>): void;
|
|
61
61
|
destroyItemEl(el: HTMLElement): void;
|
|
62
|
+
/** Sets or clears (empty `text`) an element's hover tooltip through `opts.tooltip`. */
|
|
63
|
+
tooltip(el: HTMLElement, text: string): void;
|
|
62
64
|
/** Builds a nav link (day number / header) for a day. */
|
|
63
65
|
navLink(day: Day, label: Node | string, cls: string): HTMLElement;
|
|
64
66
|
openMore(day: Day, anchor: HTMLElement, jsEvent: MouseEvent | KeyboardEvent, itemIds?: readonly string[]): void;
|
|
@@ -433,6 +433,12 @@ export interface CalendarOptions<D = unknown> {
|
|
|
433
433
|
}) => void;
|
|
434
434
|
/** Return false to skip the built-in popover. */
|
|
435
435
|
onMoreClick?: (arg: MoreArg<D>) => boolean | void;
|
|
436
|
+
/**
|
|
437
|
+
* Shows `text` as `el`'s hover tooltip; an empty `text` clears it. Default:
|
|
438
|
+
* the `title` attribute. Hosts with their own tooltips (Obsidian's
|
|
439
|
+
* `setTooltip`, say) pass them here.
|
|
440
|
+
*/
|
|
441
|
+
tooltip?: (el: HTMLElement, text: string) => void;
|
|
436
442
|
itemContent?: (arg: ItemArg<D>) => Node | string | null | undefined;
|
|
437
443
|
itemClassNames?: (arg: ItemArg<D>) => string[] | string | undefined;
|
|
438
444
|
itemDidMount?: (arg: ItemArg<D>) => void;
|
|
@@ -433,6 +433,12 @@ export interface CalendarOptions<D = unknown> {
|
|
|
433
433
|
}) => void;
|
|
434
434
|
/** Return false to skip the built-in popover. */
|
|
435
435
|
onMoreClick?: (arg: MoreArg<D>) => boolean | void;
|
|
436
|
+
/**
|
|
437
|
+
* Shows `text` as `el`'s hover tooltip; an empty `text` clears it. Default:
|
|
438
|
+
* the `title` attribute. Hosts with their own tooltips (Obsidian's
|
|
439
|
+
* `setTooltip`, say) pass them here.
|
|
440
|
+
*/
|
|
441
|
+
tooltip?: (el: HTMLElement, text: string) => void;
|
|
436
442
|
itemContent?: (arg: ItemArg<D>) => Node | string | null | undefined;
|
|
437
443
|
itemClassNames?: (arg: ItemArg<D>) => string[] | string | undefined;
|
|
438
444
|
itemDidMount?: (arg: ItemArg<D>) => void;
|
package/package.json
CHANGED