@tasknotes/calendar 0.1.11 → 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 CHANGED
@@ -1,5 +1,9 @@
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
+
3
7
  ## 0.1.11
4
8
 
5
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).
@@ -1057,6 +1057,7 @@ var LAYOUT_KEYS = /* @__PURE__ */ new Set([
1057
1057
  "text",
1058
1058
  "timeline",
1059
1059
  "editable",
1060
+ "tooltip",
1060
1061
  "itemContent",
1061
1062
  "itemClassNames",
1062
1063
  "listItemContent",
@@ -1693,8 +1694,10 @@ var DateStrip = class {
1693
1694
  const head = h(doc, "div", "tnc-strip-head");
1694
1695
  this.title = h(doc, "button", "tnc-strip-title", { type: "button", "aria-expanded": "false" });
1695
1696
  this.title.addEventListener("click", () => this.setExpanded(!this.expanded));
1696
- const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev, title: text.prev }, "\u2039");
1697
- const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next, title: text.next }, "\u203A");
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);
1698
1701
  prev.addEventListener("click", () => this.step(-1));
1699
1702
  next.addEventListener("click", () => this.step(1));
1700
1703
  this.todayBtn = h(doc, "button", "tnc-strip-today", { type: "button" }, text.today);
@@ -2318,10 +2321,10 @@ var TimeGridView = class {
2318
2321
  h(ctx.doc, "span", "tnc-collision-title", { "aria-hidden": "true" }, items.join(" \xB7 "))
2319
2322
  );
2320
2323
  link.setAttribute("aria-label", `${count}, ${interval}: ${items.join(", ")}`);
2321
- link.title = link.getAttribute("aria-label");
2324
+ ctx.tooltip(link, link.getAttribute("aria-label"));
2322
2325
  } else {
2326
+ ctx.tooltip(link, "");
2323
2327
  link.removeAttribute("aria-label");
2324
- link.removeAttribute("title");
2325
2328
  }
2326
2329
  const cols = maxStack;
2327
2330
  setStyle(link, {
@@ -3099,9 +3102,9 @@ var YearView = class {
3099
3102
  );
3100
3103
  const label = this.ctx.fmt.longDate(c.day);
3101
3104
  c.el.setAttribute("aria-label", items.length ? `${label}, ${this.ctx.text.itemCount(items.length)}` : label);
3102
- c.el.title = items.length ? `${label}
3105
+ this.ctx.tooltip(c.el, items.length ? `${label}
3103
3106
  ${items.slice(0, 8).map((n) => `\u2022 ${n.item.title}`).join("\n")}${items.length > 8 ? `
3104
- ${this.ctx.text.more(items.length - 8)}` : ""}` : label;
3107
+ ${this.ctx.text.more(items.length - 8)}` : ""}` : label);
3105
3108
  }
3106
3109
  }
3107
3110
  showSelection(_sel) {
@@ -3536,6 +3539,11 @@ var Calendar = class {
3536
3539
  const specific = what === "start" ? it.startEditable : it.durationEditable;
3537
3540
  return specific ?? base;
3538
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
+ }
3539
3547
  navLink(day, label, cls) {
3540
3548
  const btn = h(this.doc, "button", `tnc-navlink ${cls}`, { type: "button", "data-nav-date": formatDay(day) }, label);
3541
3549
  btn.addEventListener("click", (ev) => {
@@ -3937,7 +3945,8 @@ var Calendar = class {
3937
3945
  const cfg = tb === true ? {} : tb;
3938
3946
  const views = cfg.views ?? ["month", "week", "days", "day", "list", "year"];
3939
3947
  const btn = (label, hint, cls, onClick, pressed) => {
3940
- const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", title: hint, "aria-label": hint }, label);
3948
+ const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", "aria-label": hint }, label);
3949
+ this.tooltip(b, hint);
3941
3950
  if (pressed !== void 0) b.setAttribute("aria-pressed", String(pressed));
3942
3951
  b.addEventListener("click", onClick);
3943
3952
  return b;
@@ -4137,7 +4146,9 @@ var Calendar = class {
4137
4146
  addPorts(el, n) {
4138
4147
  const edges = n.item.kind === "milestone" ? ["finish"] : ["start", "finish"];
4139
4148
  for (const edge of edges) {
4140
- el.append(h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge, title: "Drag to link" }));
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);
4141
4152
  }
4142
4153
  }
4143
4154
  /* ============================================================== popover */
@@ -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",
@@ -1601,8 +1602,10 @@ var DateStrip = class {
1601
1602
  const head = h(doc, "div", "tnc-strip-head");
1602
1603
  this.title = h(doc, "button", "tnc-strip-title", { type: "button", "aria-expanded": "false" });
1603
1604
  this.title.addEventListener("click", () => this.setExpanded(!this.expanded));
1604
- const prev = h(doc, "button", "tnc-strip-nav tnc-strip-prev", { type: "button", "aria-label": text.prev, title: text.prev }, "\u2039");
1605
- const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next, title: text.next }, "\u203A");
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);
1606
1609
  prev.addEventListener("click", () => this.step(-1));
1607
1610
  next.addEventListener("click", () => this.step(1));
1608
1611
  this.todayBtn = h(doc, "button", "tnc-strip-today", { type: "button" }, text.today);
@@ -2226,10 +2229,10 @@ var TimeGridView = class {
2226
2229
  h(ctx.doc, "span", "tnc-collision-title", { "aria-hidden": "true" }, items.join(" \xB7 "))
2227
2230
  );
2228
2231
  link.setAttribute("aria-label", `${count}, ${interval}: ${items.join(", ")}`);
2229
- link.title = link.getAttribute("aria-label");
2232
+ ctx.tooltip(link, link.getAttribute("aria-label"));
2230
2233
  } else {
2234
+ ctx.tooltip(link, "");
2231
2235
  link.removeAttribute("aria-label");
2232
- link.removeAttribute("title");
2233
2236
  }
2234
2237
  const cols = maxStack;
2235
2238
  setStyle(link, {
@@ -3007,9 +3010,9 @@ var YearView = class {
3007
3010
  );
3008
3011
  const label = this.ctx.fmt.longDate(c.day);
3009
3012
  c.el.setAttribute("aria-label", items.length ? `${label}, ${this.ctx.text.itemCount(items.length)}` : label);
3010
- c.el.title = items.length ? `${label}
3013
+ this.ctx.tooltip(c.el, items.length ? `${label}
3011
3014
  ${items.slice(0, 8).map((n) => `\u2022 ${n.item.title}`).join("\n")}${items.length > 8 ? `
3012
- ${this.ctx.text.more(items.length - 8)}` : ""}` : label;
3015
+ ${this.ctx.text.more(items.length - 8)}` : ""}` : label);
3013
3016
  }
3014
3017
  }
3015
3018
  showSelection(_sel) {
@@ -3444,6 +3447,11 @@ var Calendar = class {
3444
3447
  const specific = what === "start" ? it.startEditable : it.durationEditable;
3445
3448
  return specific ?? base;
3446
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
+ }
3447
3455
  navLink(day, label, cls) {
3448
3456
  const btn = h(this.doc, "button", `tnc-navlink ${cls}`, { type: "button", "data-nav-date": formatDay(day) }, label);
3449
3457
  btn.addEventListener("click", (ev) => {
@@ -3845,7 +3853,8 @@ var Calendar = class {
3845
3853
  const cfg = tb === true ? {} : tb;
3846
3854
  const views = cfg.views ?? ["month", "week", "days", "day", "list", "year"];
3847
3855
  const btn = (label, hint, cls, onClick, pressed) => {
3848
- const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", title: hint, "aria-label": hint }, label);
3856
+ const b = h(this.doc, "button", `tnc-btn ${cls}`, { type: "button", "aria-label": hint }, label);
3857
+ this.tooltip(b, hint);
3849
3858
  if (pressed !== void 0) b.setAttribute("aria-pressed", String(pressed));
3850
3859
  b.addEventListener("click", onClick);
3851
3860
  return b;
@@ -4045,7 +4054,9 @@ var Calendar = class {
4045
4054
  addPorts(el, n) {
4046
4055
  const edges = n.item.kind === "milestone" ? ["finish"] : ["start", "finish"];
4047
4056
  for (const edge of edges) {
4048
- el.append(h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge, title: "Drag to link" }));
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);
4049
4060
  }
4050
4061
  }
4051
4062
  /* ============================================================== popover */
@@ -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, title: text.prev }, "\u2039");
988
- const next = h(doc, "button", "tnc-strip-nav tnc-strip-next", { type: "button", "aria-label": text.next, title: text.next }, "\u203A");
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);
@@ -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.title = link.getAttribute("aria-label");
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.title = items.length ? `${label}
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", title: hint, "aria-label": hint }, label);
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
- el.append(h(this.doc, "span", `tnc-port tnc-port-${edge}`, { "aria-hidden": "true", "data-edge": edge, title: "Drag to link" }));
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 */
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-TTM45UAN.js";
10
+ } from "./chunk-AACI7SZC.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-TTM45UAN.js";
3
+ } from "./chunk-AACI7SZC.js";
4
4
  import "./chunk-JWORVABV.js";
5
5
 
6
6
  // src/react/index.tsx
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tasknotes/calendar",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
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",