@umriss-ui/schedule 0.1.1 → 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
@@ -15,6 +15,35 @@ moves from here under the rule above.
15
15
 
16
16
  ---
17
17
 
18
+ ## 0.1.2 – Phones, touch and a review (Sep. 2026)
19
+
20
+ ### Changed
21
+
22
+ - **The lane headers take at most 40 % of the schedule.** `headerWidth` is
23
+ now `min(headerWidth px, 40%)`, so that on a phone the plot keeps the larger
24
+ part.
25
+ - **The wheel over the lane headers scrolls the lanes**, as it does over the
26
+ plot; Ctrl or ⌘ there zooms around the plot's first instant.
27
+ - **A finger's tap may wander ten pixels** and still select; the mouse keeps
28
+ its three.
29
+
30
+ ### Fixed
31
+
32
+ - A pinch that ends with one finger still down pans on with that finger,
33
+ instead of doing nothing until it is lifted; a third finger no longer breaks
34
+ the pinch.
35
+ - A pan ended by `pointercancel` gives the cursor back.
36
+ - A schedule unmounted during a drag stops its auto-pan and the timer of a
37
+ folded group it rested over; before, the auto-pan ran on and kept reporting
38
+ `onDomainChange`.
39
+ - A new `calendar` - an inline array counts, being new on every render - under
40
+ a view panned past the old calendar's ends no longer turns the domain into
41
+ NaN and the plot blank.
42
+ - A lane or group id containing a space no longer breaks the fold control's
43
+ `aria-controls`.
44
+
45
+ ---
46
+
18
47
  ## 0.1.1 – The README catches up (Sep. 2026)
19
48
 
20
49
  Nothing in the code changed. The README names the online demo, the design
package/README.md CHANGED
@@ -122,8 +122,11 @@ application's hands; it is a view state, never an intent.
122
122
 
123
123
  A tooltip on a hovered subtask or transport names the order, the times, setup
124
124
  and teardown and the findings; `tooltip` replaces its content or switches it
125
- off. `now` draws the present across the lanes. The wheel scrolls the lanes and
126
- releases the page at their end, Ctrl or ⌘ and a pinch zoom, Shift pans;
125
+ off. `now` draws the present across the lanes. The wheel over the schedule,
126
+ lane headers included, scrolls the lanes and releases the page at their end,
127
+ Ctrl or ⌘ and a pinch zoom, Shift pans; on a touch screen one finger pans and a
128
+ tap selects. The lane headers take at most 40 % of the width, so that on a
129
+ phone the plot keeps the larger part;
127
130
  `onDomainChange` reports the visible span, and a ref handle turns a client
128
131
  point into a time and a lane and back.
129
132
 
package/dist/index.d.ts CHANGED
@@ -258,7 +258,8 @@ export declare interface ScheduleProps {
258
258
  height?: number;
259
259
  /** Height of one lane in pixels. */
260
260
  laneHeight?: number;
261
- /** Width of the lane headers in pixels. */
261
+ /** Width of the lane headers in pixels - at most 40 % of the schedule, so
262
+ that on a phone the plot keeps the larger part. */
262
263
  headerWidth?: number;
263
264
  /** An operating calendar: the intervals in which time counts. Nights and
264
265
  weekends outside them are cut out of the axis. Default: the wall clock. */
package/dist/schedule.js CHANGED
@@ -2,9 +2,9 @@ import "./schedule.css";
2
2
  var He = Object.defineProperty;
3
3
  var Ye = (n, t, e) => t in n ? He(n, t, { enumerable: !0, configurable: !0, writable: !0, value: e }) : n[t] = e;
4
4
  var f = (n, t, e) => Ye(n, typeof t != "symbol" ? t + "" : t, e);
5
- import { jsxs as H, Fragment as zt, jsx as w } from "react/jsx-runtime";
6
- import { useContext as fe, createContext as pe, useRef as $, useEffect as B, forwardRef as Xe, useState as it, useId as Ke, useLayoutEffect as vt, useImperativeHandle as We, useSyncExternalStore as Ue, useMemo as q } from "react";
7
- import { toOperatingTimeClamped as Y, resolveColours as ze, removedIntervals as qe, MINUTE as U, calendarFrom as et, toWallClock as X, DAY as st, timeStep as je, operatingTimeTicks as Ve, HOUR as Tt, LinearScale as Ze, subscribeTheme as Je } from "@umriss-ui/charts";
5
+ import { jsxs as Y, Fragment as zt, jsx as w } from "react/jsx-runtime";
6
+ import { useContext as fe, createContext as pe, useRef as $, useEffect as O, forwardRef as Xe, useState as it, useId as Ke, useLayoutEffect as vt, useImperativeHandle as Ue, useSyncExternalStore as We, useMemo as q } from "react";
7
+ import { toOperatingTimeClamped as B, resolveColours as ze, removedIntervals as qe, MINUTE as U, calendarFrom as j, toWallClock as W, DAY as st, timeStep as je, operatingTimeTicks as Ve, HOUR as Tt, LinearScale as Ze, subscribeTheme as Je } from "@umriss-ui/charts";
8
8
  import { useFormats as me, useWording as ge } from "@umriss-ui/core";
9
9
  const ke = pe(null), we = pe(null);
10
10
  function ve() {
@@ -18,9 +18,9 @@ function Qe(n) {
18
18
  }
19
19
  function Ct(n, t, e, s, o) {
20
20
  const i = Qe(n), r = $(null);
21
- B(() => (r.current = e(i, t), () => {
21
+ O(() => (r.current = e(i, t), () => {
22
22
  r.current !== null && o(i, r.current), r.current = null;
23
- }), [i]), B(() => {
23
+ }), [i]), O(() => {
24
24
  r.current !== null && s(i, r.current, t);
25
25
  });
26
26
  }
@@ -59,14 +59,14 @@ function qt(n) {
59
59
  }
60
60
  const l = [], d = /* @__PURE__ */ new Map();
61
61
  let p = [], g = null, b = 0;
62
- const A = (m) => (l.push({ ...m, top: b }), b += m.height, l.length - 1), _ = (m) => m.find((C) => s.has(C)), S = () => {
62
+ const I = (m) => (l.push({ ...m, top: b }), b += m.height, l.length - 1), _ = (m) => m.find((C) => s.has(C)), S = () => {
63
63
  if (g === null) return;
64
64
  const { row: m, lanes: C } = g, L = l[m], E = Math.max(L.height, C.length * ns + 2 * yt);
65
65
  l[m] = { ...L, height: E }, b += E - L.height;
66
66
  const F = E - 2 * yt, G = Math.max(os, Math.floor(F / C.length));
67
- C.forEach((j, ot) => {
68
- const z = c.get(j) ?? [];
69
- d.set(j, {
67
+ C.forEach((V, ot) => {
68
+ const z = c.get(V) ?? [];
69
+ d.set(V, {
70
70
  top: L.top + yt + ot * G,
71
71
  height: G,
72
72
  miniature: !0,
@@ -85,7 +85,7 @@ function qt(n) {
85
85
  p = p.slice(0, E);
86
86
  for (const F of C.slice(E)) {
87
87
  if (p.push(F), F === L) break;
88
- A({
88
+ I({
89
89
  kind: "groupHead",
90
90
  lane: void 0,
91
91
  group: F,
@@ -96,7 +96,7 @@ function qt(n) {
96
96
  });
97
97
  }
98
98
  if (L !== void 0) {
99
- const F = C.indexOf(L), G = A({
99
+ const F = C.indexOf(L), G = I({
100
100
  kind: "miniature",
101
101
  lane: void 0,
102
102
  group: L,
@@ -108,7 +108,7 @@ function qt(n) {
108
108
  g = { group: L, row: G, lanes: [m.id] };
109
109
  continue;
110
110
  }
111
- A({ kind: "lane", lane: m.id, group: C[C.length - 1], depth: C.length, within: C, lanes: 1, height: o }), d.set(m.id, {
111
+ I({ kind: "lane", lane: m.id, group: C[C.length - 1], depth: C.length, within: C, lanes: 1, height: o }), d.set(m.id, {
112
112
  top: l[l.length - 1].top,
113
113
  height: o,
114
114
  miniature: !1,
@@ -152,7 +152,7 @@ function ut(n) {
152
152
  function St(n, t) {
153
153
  return (n.leaves ?? "teardown") === "main" ? t.to : t.to + (t.teardown ?? 0);
154
154
  }
155
- function At(n, t) {
155
+ function It(n, t) {
156
156
  return (n.arrives ?? "setup") === "main" ? t.from : t.from - (t.setup ?? 0);
157
157
  }
158
158
  function jt(n, t) {
@@ -169,7 +169,7 @@ function jt(n, t) {
169
169
  return { ...n, lane: t.lane };
170
170
  }
171
171
  }
172
- function In(n, t) {
172
+ function An(n, t) {
173
173
  return {
174
174
  id: t,
175
175
  task: n.task,
@@ -180,9 +180,9 @@ function In(n, t) {
180
180
  ...n.teardown === void 0 ? {} : { teardown: n.teardown }
181
181
  };
182
182
  }
183
- const as = 6, be = 3, tt = 2, Vt = 3, Zt = 3;
183
+ const as = 6, be = 3, et = 2, Vt = 3, Zt = 3;
184
184
  function P(n, t) {
185
- return Math.round(n.scale.toPx(Y(t, n.calendar)));
185
+ return Math.round(n.scale.toPx(B(t, n.calendar)));
186
186
  }
187
187
  function ct(n, t) {
188
188
  const e = Lt(n.rows, t);
@@ -222,7 +222,7 @@ function Ce(n, t, e) {
222
222
  const hs = 64;
223
223
  function us(n, t) {
224
224
  if (n.miniature) return null;
225
- const e = ht(n.subtask.appearance).hatched ? tt + be + 1 : 0, s = Math.max(n.mainFrom + e, 0), o = Math.min(n.mainTo - e, t) - s;
225
+ const e = ht(n.subtask.appearance).hatched ? et + be + 1 : 0, s = Math.max(n.mainFrom + e, 0), o = Math.min(n.mainTo - e, t) - s;
226
226
  return o < hs ? null : { x: s, width: o, y: n.y, height: n.height };
227
227
  }
228
228
  const cs = 10;
@@ -231,22 +231,22 @@ function Qt(n, t, e) {
231
231
  return n === "centre" || e.y === t.y ? s : Math.round(e.y > t.y ? t.y + t.height - 1 : t.y + 1);
232
232
  }
233
233
  function bt(n, t, e, s, o) {
234
- const i = t.route ?? o.route, r = t.attach ?? o.attach, a = t.ends ?? o.ends, u = P(n, St(t, e.subtask)), c = P(n, At(t, s.subtask)), l = Qt(r, e, s), d = Qt(r, s, e);
234
+ const i = t.route ?? o.route, r = t.attach ?? o.attach, a = t.ends ?? o.ends, u = P(n, St(t, e.subtask)), c = P(n, It(t, s.subtask)), l = Qt(r, e, s), d = Qt(r, s, e);
235
235
  if (i === "straight")
236
236
  return { transport: t, kind: i, ends: a, x1: u, y1: l, x2: c, y2: d, c1x: u, c2x: c, points: [u, l, c, d] };
237
237
  if (i === "orthogonal") {
238
238
  const _ = u + cs, S = l === d ? _ : Math.round((_ + c) / 2);
239
239
  return { transport: t, kind: i, ends: a, x1: u, y1: l, x2: c, y2: d, c1x: u, c2x: c, points: l === d ? [u, l, c, d] : [u, l, S, l, S, d, c, d] };
240
240
  }
241
- const p = Math.max(14, Math.abs(c - u) / 2), g = u + p, b = c - p, A = [];
241
+ const p = Math.max(14, Math.abs(c - u) / 2), g = u + p, b = c - p, I = [];
242
242
  for (let _ = 0; _ <= 16; _++) {
243
243
  const S = _ / 16, m = 1 - S;
244
- A.push(
244
+ I.push(
245
245
  m * m * m * u + 3 * m * m * S * g + 3 * m * S * S * b + S * S * S * c,
246
246
  m * m * m * l + 3 * m * m * S * l + 3 * m * S * S * d + S * S * S * d
247
247
  );
248
248
  }
249
- return { transport: t, kind: "curve", ends: a, x1: u, y1: l, x2: c, y2: d, c1x: g, c2x: b, points: A };
249
+ return { transport: t, kind: "curve", ends: a, x1: u, y1: l, x2: c, y2: d, c1x: g, c2x: b, points: I };
250
250
  }
251
251
  function ds(n, t, e) {
252
252
  let s = 1 / 0;
@@ -257,7 +257,7 @@ function ds(n, t, e) {
257
257
  }
258
258
  return s;
259
259
  }
260
- function It(n) {
260
+ function At(n) {
261
261
  const t = [], e = /* @__PURE__ */ new Map();
262
262
  n.forEach((s, o) => {
263
263
  const { from: i, to: r } = ut(s);
@@ -296,13 +296,13 @@ function _t(n, t) {
296
296
  for (const o of t) {
297
297
  const i = e.get(o.from), r = e.get(o.to);
298
298
  if (i === void 0 || r === void 0) continue;
299
- const a = St(o, i), u = At(o, r), c = a + o.duration - u;
299
+ const a = St(o, i), u = It(o, r), c = a + o.duration - u;
300
300
  c > 0 && s.push({ transport: o.id, departure: a, arrival: u, shortBy: c });
301
301
  }
302
302
  return s;
303
303
  }
304
304
  function _n(n, t) {
305
- return { overlaps: It(n), lateTransports: _t(n, t) };
305
+ return { overlaps: At(n), lateTransports: _t(n, t) };
306
306
  }
307
307
  class ps {
308
308
  /** `changed` is called after every registration change. */
@@ -373,7 +373,7 @@ class ps {
373
373
  for (const s of e.tasks) this.tasks.set(s.id, s);
374
374
  } else
375
375
  this.transports.push(...e.data);
376
- return this.subtaskById = new Map(this.subtasks.map((e) => [e.id, e])), this.overlaps = It(this.subtasks), this.lateById = new Map(_t(this.subtasks, this.transports).map((e) => [e.transport, e])), this.depth = fs(this.subtasks), !0;
376
+ return this.subtaskById = new Map(this.subtasks.map((e) => [e.id, e])), this.overlaps = At(this.subtasks), this.lateById = new Map(_t(this.subtasks, this.transports).map((e) => [e.transport, e])), this.depth = fs(this.subtasks), !0;
377
377
  }
378
378
  /** The task a transport belongs to: its departing subtask's. */
379
379
  taskOfTransport(t) {
@@ -462,15 +462,15 @@ function ks(n, t) {
462
462
  else
463
463
  for (const a of s.boxes) r.has(a.subtask) && Se(n, t, a, 1);
464
464
  }
465
- for (const i of e.overlaps) Ae(n, t, o, i);
466
- Es(n, t, o), Ps(n, t);
465
+ for (const i of e.overlaps) Ie(n, t, o, i);
466
+ Fs(n, t, o), Ds(n, t);
467
467
  }
468
468
  function ws(n, t) {
469
469
  const { view: e, hover: s } = t, o = e.viewport();
470
470
  if (t.ghost === null) {
471
471
  if (s.kind === "subtask") {
472
472
  const l = e.boxById.get(s.subtask.id);
473
- l !== void 0 && Ds(n, t, l);
473
+ l !== void 0 && Es(n, t, l);
474
474
  } else if (s.kind === "transport") {
475
475
  const l = e.paths.find((d) => d.transport === s.transport);
476
476
  l !== void 0 && Mt(n, t, l, !0);
@@ -481,7 +481,7 @@ function ws(n, t) {
481
481
  vs(n, t, o, t.ghost.refusedLanes);
482
482
  const u = Le(o, i);
483
483
  if (u === null) return;
484
- for (const l of r) Ae(n, t, o, l);
484
+ for (const l of r) Ie(n, t, o, l);
485
485
  const c = new Set(a.map((l) => l.transport));
486
486
  for (const l of t.data.transports) {
487
487
  if (l.from !== i.id && l.to !== i.id) continue;
@@ -499,7 +499,7 @@ function vs(n, t, e, s) {
499
499
  const a = ct(e, r);
500
500
  if (a === null) continue;
501
501
  const { top: u, height: c } = a;
502
- u + c < 0 || u > i || (n.globalAlpha = 0.6, n.fillStyle = t.colours.surface, n.fillRect(0, u, o, c), n.globalAlpha = 1, _s(n, 0, u, o, c, t.colours.muted, 0.7, As, 1));
502
+ u + c < 0 || u > i || (n.globalAlpha = 0.6, n.fillStyle = t.colours.surface, n.fillRect(0, u, o, c), n.globalAlpha = 1, As(n, 0, u, o, c, t.colours.muted, 0.7, Ss, 1));
503
503
  }
504
504
  }
505
505
  function ys(n, t, e, s) {
@@ -574,31 +574,31 @@ function Se(n, t, e, s) {
574
574
  }
575
575
  const r = ht(e.subtask.appearance), a = i.tasks.get(e.subtask.task) ?? i.muted, u = Ft(r, a, i), c = e.y, l = e.height, d = Math.max(1, e.mainTo - e.mainFrom), p = u.onDark ? i.onAccent : i.text;
576
576
  n.lineWidth = 1, n.fillStyle = a, n.strokeStyle = a;
577
- for (const [b, A] of [
577
+ for (const [b, I] of [
578
578
  [e.outerFrom, e.mainFrom],
579
579
  [e.mainTo, e.outerTo]
580
580
  ])
581
- A <= b || (n.globalAlpha = 0.28 * s, n.fillRect(b, c, A - b, l), n.globalAlpha = s, n.strokeRect(b + 0.5, c + 0.5, A - b - 1, l - 1));
581
+ I <= b || (n.globalAlpha = 0.28 * s, n.fillRect(b, c, I - b, l), n.globalAlpha = s, n.strokeRect(b + 0.5, c + 0.5, I - b - 1, l - 1));
582
582
  u.fill !== null && (n.globalAlpha = s, n.fillStyle = u.fill, n.fillRect(e.mainFrom, c, d, l));
583
583
  const g = e.subtask.progress;
584
584
  if (g !== void 0) {
585
- const b = Math.min(4, Math.max(2, Math.round(l / 6))), A = c + l - b - Ls, _ = Math.round(d * Math.max(0, Math.min(1, g)));
586
- n.fillStyle = u.fill === null ? a : p, n.globalAlpha = 0.3 * s, n.fillRect(e.mainFrom, A, d, b), n.globalAlpha = s, _ > 0 && n.fillRect(e.mainFrom, A, _, b);
585
+ const b = Math.min(4, Math.max(2, Math.round(l / 6))), I = c + l - b - Ls, _ = Math.round(d * Math.max(0, Math.min(1, g)));
586
+ n.fillStyle = u.fill === null ? a : p, n.globalAlpha = 0.3 * s, n.fillRect(e.mainFrom, I, d, b), n.globalAlpha = s, _ > 0 && n.fillRect(e.mainFrom, I, _, b);
587
587
  }
588
588
  if (r.hatched) {
589
- const b = Math.max(1, Math.min(be, Math.floor((d - 2 * tt) / 3))), A = d >= 4 * b ? tt : 0, _ = l >= 4 * tt ? tt : 0;
590
- n.globalAlpha = s, n.fillStyle = p, n.fillRect(e.mainFrom + A, c + _, b, l - 2 * _), n.fillRect(e.mainTo - A - b, c + _, b, l - 2 * _);
589
+ const b = Math.max(1, Math.min(be, Math.floor((d - 2 * et) / 3))), I = d >= 4 * b ? et : 0, _ = l >= 4 * et ? et : 0;
590
+ n.globalAlpha = s, n.fillStyle = p, n.fillRect(e.mainFrom + I, c + _, b, l - 2 * _), n.fillRect(e.mainTo - I - b, c + _, b, l - 2 * _);
591
591
  }
592
- r.open && Fs(n, e, c, l, i.surface, o.width), r.dashed && (n.globalAlpha = s, n.strokeStyle = a, n.setLineDash([4, 3]), n.strokeRect(e.mainFrom + 0.5, c + 0.5, d - 1, l - 1), n.setLineDash([])), n.globalAlpha = 1, e.depth > 0 && s === 1 && (n.strokeStyle = i.surface, n.strokeRect(e.outerFrom - 0.5, c - 0.5, e.outerTo - e.outerFrom + 1, l + 1));
592
+ r.open && _s(n, e, c, l, i.surface, o.width), r.dashed && (n.globalAlpha = s, n.strokeStyle = a, n.setLineDash([4, 3]), n.strokeRect(e.mainFrom + 0.5, c + 0.5, d - 1, l - 1), n.setLineDash([])), n.globalAlpha = 1, e.depth > 0 && s === 1 && (n.strokeStyle = i.surface, n.strokeRect(e.outerFrom - 0.5, c - 0.5, e.outerTo - e.outerFrom + 1, l + 1));
593
593
  }
594
- const Ss = 7, As = 6, Is = 16;
595
- function _s(n, t, e, s, o, i, r, a = Ss, u = 2) {
594
+ const Ss = 6, Is = 16;
595
+ function As(n, t, e, s, o, i, r, a, u) {
596
596
  n.save(), n.beginPath(), n.rect(t, e, s, o), n.clip(), n.globalAlpha = 0.5 * r, n.strokeStyle = i, n.lineWidth = u, n.beginPath();
597
597
  for (let c = t - o; c < t + s + o; c += a)
598
598
  n.moveTo(c, e + o), n.lineTo(c + o, e);
599
599
  n.stroke(), n.restore();
600
600
  }
601
- function Fs(n, t, e, s, o, i) {
601
+ function _s(n, t, e, s, o, i) {
602
602
  const r = t.mainFrom < 0, a = t.mainTo > i, u = Math.max(1, Math.min(t.mainTo, i) - Math.max(t.mainFrom, 0)), c = Math.min(Is, u);
603
603
  r && ne(n, 0, c, e, s, o, 1), a && ne(n, i, -c, e, s, o, 1);
604
604
  }
@@ -623,7 +623,7 @@ function Mt(n, t, e, s, o) {
623
623
  ])
624
624
  n.beginPath(), n.arc(d, p, u ? 3 : 2.5, 0, Math.PI * 2), n.fill();
625
625
  }
626
- function Es(n, t, e) {
626
+ function Fs(n, t, e) {
627
627
  const { data: s } = t;
628
628
  if (s.lateById.size !== 0) {
629
629
  n.fillStyle = t.colours.alarm;
@@ -639,7 +639,7 @@ function Es(n, t, e) {
639
639
  }
640
640
  }
641
641
  }
642
- function Ae(n, t, e, s) {
642
+ function Ie(n, t, e, s) {
643
643
  const o = ct(e, s.lane);
644
644
  if (o === null) return;
645
645
  const i = P(e, s.from), r = Math.max(i + 2, P(e, s.to));
@@ -648,12 +648,12 @@ function Ae(n, t, e, s) {
648
648
  a !== null && n.fillRect(i, a.top - e.scrollY + 1, r - i, 3);
649
649
  }
650
650
  }
651
- function Ds(n, t, e) {
651
+ function Es(n, t, e) {
652
652
  const { colours: s } = t, o = ht(e.subtask.appearance), i = Ft(o, s.tasks.get(e.subtask.task) ?? s.muted, s);
653
653
  n.globalAlpha = xs, n.fillStyle = i.onDark ? s.onAccent : s.text, n.fillRect(e.outerFrom, e.y, Math.max(1, e.outerTo - e.outerFrom), e.height), n.globalAlpha = 1;
654
654
  }
655
655
  const xs = 0.2;
656
- function Ps(n, t) {
656
+ function Ds(n, t) {
657
657
  const e = t.selectedTask;
658
658
  if (e !== null) {
659
659
  n.strokeStyle = t.colours.text;
@@ -666,28 +666,28 @@ function Ps(n, t) {
666
666
  }
667
667
  }
668
668
  }
669
- const rt = 32, Ns = 18;
669
+ const rt = 32, Ps = 18;
670
670
  function ie(n, t) {
671
671
  if (!(t > 2 * rt)) return 0;
672
672
  const e = rt - n, s = n - (t - rt), o = Math.max(e, s);
673
673
  if (o <= 0) return 0;
674
- const i = Math.min(1, o / rt), r = Ns * i * i;
674
+ const i = Math.min(1, o / rt), r = Ps * i * i;
675
675
  return e > 0 ? -r : r;
676
676
  }
677
- function Gs(n, t, e, s) {
677
+ function Ns(n, t, e, s) {
678
678
  const o = /* @__PURE__ */ new Set();
679
679
  if (s === void 0) return o;
680
680
  for (const i of n)
681
681
  i !== e && (s(t, i) || o.add(i));
682
682
  return o;
683
683
  }
684
- function Ie(n) {
684
+ function Ae(n) {
685
685
  return new Date(n).getTimezoneOffset() * U;
686
686
  }
687
- function Rs(n, t) {
687
+ function Gs(n, t) {
688
688
  const { step: e, offset: s } = typeof t == "number" ? { step: t, offset: 0 } : t;
689
689
  if (!(e > 0) || !Number.isFinite(n)) return n;
690
- const o = Ie(n) + s;
690
+ const o = Ae(n) + s;
691
691
  return o + Math.round((n - o) / e) * e;
692
692
  }
693
693
  const re = "\0placing", ae = /* @__PURE__ */ new Set();
@@ -703,8 +703,8 @@ function le(n) {
703
703
  return "nothing";
704
704
  }
705
705
  }
706
- const he = 3, $s = 600;
707
- class Bs {
706
+ const he = 3, Rs = 10, $s = 600;
707
+ class Os {
708
708
  constructor(t) {
709
709
  f(this, "gesture", { kind: "none" });
710
710
  f(this, "touches", /* @__PURE__ */ new Map());
@@ -788,8 +788,8 @@ class Bs {
788
788
  pointerDown(t) {
789
789
  var a, u, c, l, d;
790
790
  const { x: e, y: s } = this.local(t.clientX, t.clientY);
791
- if (t.pointerType === "touch" && (this.touches.set(t.pointerId, { x: e, y: s }), this.touches.size === 2)) {
792
- this.cancelEdit(), this.gesture = { kind: "pinch", distance: this.touchDistance() };
791
+ if (t.pointerType === "touch" && (this.touches.set(t.pointerId, { x: e, y: s }), this.touches.size >= 2)) {
792
+ this.gesture.kind !== "pinch" && (this.cancelEdit(), this.gesture = { kind: "pinch", distance: this.touchDistance() });
793
793
  return;
794
794
  }
795
795
  if (t.button !== 0) return;
@@ -841,7 +841,7 @@ class Bs {
841
841
  askRefused(t, e) {
842
842
  if (!this.host.view.options.intents.includes(e === null ? "place" : "lane")) return ae;
843
843
  const s = this.host.data.lanes.map((o) => o.id);
844
- return Gs(s, t, e, this.host.handlers().canMoveTo);
844
+ return Ns(s, t, e, this.host.handlers().canMoveTo);
845
845
  }
846
846
  /** What a press at a point would start, given the intents the caller handles. */
847
847
  modeAt(t, e) {
@@ -866,7 +866,7 @@ class Bs {
866
866
  }
867
867
  const o = this.gesture;
868
868
  if (o.kind === "pending" && o.pointerId === t.pointerId) {
869
- if (Math.hypot(e - o.x0, s - o.y0) < he) return;
869
+ if (Math.hypot(e - o.x0, s - o.y0) < (t.pointerType === "touch" ? Rs : he)) return;
870
870
  if (o.mode === "pan" || o.subtask === null)
871
871
  this.gesture = { kind: "pan", pointerId: o.pointerId, lastX: o.x0, lastY: o.y0 }, this.setCursor("grabbing");
872
872
  else {
@@ -899,7 +899,8 @@ class Bs {
899
899
  pointerUp(t) {
900
900
  var i, r;
901
901
  if (t.pointerType === "touch" && (this.touches.delete(t.pointerId), this.gesture.kind === "pinch")) {
902
- this.touches.size < 2 && (this.gesture = { kind: "none" });
902
+ const [a] = this.touches;
903
+ this.touches.size === 1 && a !== void 0 ? this.gesture = { kind: "pan", pointerId: a[0], lastX: a[1].x, lastY: a[1].y } : this.touches.size === 0 && (this.gesture = { kind: "none" });
903
904
  return;
904
905
  }
905
906
  const e = this.gesture, { x: s, y: o } = this.local(t.clientX, t.clientY);
@@ -944,7 +945,7 @@ class Bs {
944
945
  this.panFrame !== 0 && cancelAnimationFrame(this.panFrame), this.panFrame = 0;
945
946
  }
946
947
  pointerCancel(t) {
947
- this.touches.delete(t.pointerId), this.closeGestureFolds(), this.cancelEdit(), this.gesture = { kind: "none" };
948
+ this.touches.delete(t.pointerId), this.closeGestureFolds(), this.cancelEdit(), this.gesture = { kind: "none" }, this.setCursor("default");
948
949
  }
949
950
  /** Reads the hover anew where the pointer already is - after the data
950
951
  changed under it. A drop that moves a subtask changes what lies under the
@@ -974,7 +975,7 @@ class Bs {
974
975
  their end; Ctrl or ⌘ zooms - a trackpad pinch arrives as a wheel with
975
976
  Ctrl -; horizontal or Shift pans through time. */
976
977
  wheel(t) {
977
- const e = this.host.view, { x: s } = this.local(t.clientX, t.clientY), o = t.deltaMode === 1 ? 16 : t.deltaMode === 2 ? e.height : 1, i = t.deltaX * o, r = t.deltaY * o;
978
+ const e = this.host.view, s = Math.max(0, Math.min(e.width, this.local(t.clientX, t.clientY).x)), o = t.deltaMode === 1 ? 16 : t.deltaMode === 2 ? e.height : 1, i = t.deltaX * o, r = t.deltaY * o;
978
979
  if (t.ctrlKey || t.metaKey) {
979
980
  t.preventDefault();
980
981
  const c = Math.abs(r) < 50 ? 0.01 : 15e-4;
@@ -1109,8 +1110,8 @@ class Bs {
1109
1110
  let c = i.from;
1110
1111
  const l = o.viewport().scale, d = l.fromPx(e) - t.t0;
1111
1112
  if (a.includes("move") && Math.abs(d * l.m) >= he) {
1112
- const g = et(o.options.calendar), b = Y(i.from, g) + d, A = g.intervals.length === 0 ? b : X(Math.max(0, Math.min(g.total, b)), g);
1113
- c = this.snapInside(A, r);
1113
+ const g = j(o.options.calendar), b = B(i.from, g) + d, I = g.intervals.length === 0 ? b : W(Math.max(0, Math.min(g.total, b)), g);
1114
+ c = this.snapInside(I, r);
1114
1115
  }
1115
1116
  let p = t.ghost.lane;
1116
1117
  if (a.includes("lane")) {
@@ -1134,8 +1135,8 @@ class Bs {
1134
1135
  on to the seam, where time counts again. An intent never asks for a time
1135
1136
  the plant does not run. */
1136
1137
  snapInside(t, e) {
1137
- const s = Rs(t, e), o = et(this.host.view.options.calendar);
1138
- return o.intervals.length === 0 ? s : X(Y(s, o), o);
1138
+ const s = Gs(t, e), o = j(this.host.view.options.calendar);
1139
+ return o.intervals.length === 0 ? s : W(B(s, o), o);
1139
1140
  }
1140
1141
  intentsOf(t, e, s) {
1141
1142
  const o = [], i = this.host.view.options.intents, r = t.id;
@@ -1156,16 +1157,16 @@ class Bs {
1156
1157
  computed on every pointer movement. */
1157
1158
  ghostFindings(t, e) {
1158
1159
  const s = this.host.data, o = (l) => l.lane === t.lane || l.lane === e, r = [...s.subtasks.filter((l) => l.id !== t.id && o(l)), t], a = (l) => l.first === t.id || l.second === t.id, u = s.transports.filter((l) => l.from === t.id || l.to === t.id), c = t.id === re ? s.subtasks : s.subtasks.map((l) => l.id === t.id ? t : l);
1159
- return { overlaps: It(r).filter(a), late: _t(c, u) };
1160
+ return { overlaps: At(r).filter(a), late: _t(c, u) };
1160
1161
  }
1161
1162
  }
1162
- const _e = [], Os = 56;
1163
- function Hs(n, t = Os) {
1163
+ const _e = [], Bs = 56;
1164
+ function Hs(n, t = Bs) {
1164
1165
  return n > 0 ? Math.min(st, Math.max(15 * U, je(n * t, 1))) : 15 * U;
1165
1166
  }
1166
1167
  function Ys(n, t, e = _e) {
1167
1168
  const [s, o] = Fe(n, e);
1168
- return Ve(e, s, o, t, Ie(s)).filter(
1169
+ return Ve(e, s, o, t, Ae(s)).filter(
1169
1170
  (i) => i.operatingTime >= n[0] && i.operatingTime <= n[1]
1170
1171
  );
1171
1172
  }
@@ -1178,8 +1179,8 @@ function Xs(n, t = _e) {
1178
1179
  o.push({
1179
1180
  start: r,
1180
1181
  end: a,
1181
- from: Y(r, t),
1182
- to: Y(a, t)
1182
+ from: B(r, t),
1183
+ to: B(a, t)
1183
1184
  });
1184
1185
  }
1185
1186
  return o;
@@ -1190,17 +1191,17 @@ function Ks(n, t, e, s) {
1190
1191
  const i = Math.min(s.max, Math.max(s.min, o * e)), r = (t - n[0]) / o, a = t - r * i;
1191
1192
  return [a, a + i];
1192
1193
  }
1193
- function Ws(n, t) {
1194
+ function Us(n, t) {
1194
1195
  return [n[0] + t, n[1] + t];
1195
1196
  }
1196
1197
  function Fe(n, t) {
1197
- const e = et(t);
1198
+ const e = j(t);
1198
1199
  if (e.intervals.length === 0) return [n[0], n[1]];
1199
1200
  const s = (o) => Math.max(0, Math.min(e.total, o));
1200
- return [X(s(n[0]), e), X(s(n[1]), e)];
1201
+ return [W(s(n[0]), e), W(s(n[1]), e)];
1201
1202
  }
1202
1203
  const lt = 44;
1203
- class Us {
1204
+ class Ws {
1204
1205
  constructor(t) {
1205
1206
  f(this, "options", {
1206
1207
  laneHeight: lt,
@@ -1235,9 +1236,14 @@ class Us {
1235
1236
  there, and a new calendar keeps the wall-clock span in view. */
1236
1237
  setOptions(t, e) {
1237
1238
  const s = t.calendar !== this.options.calendar, o = this.options.calendar;
1238
- if (this.options = t, e !== null || s) {
1239
- const i = e ?? [X(this.domain[0], o), X(this.domain[1], o)];
1240
- this.domain = [Y(i[0], t.calendar), Y(i[1], t.calendar)];
1239
+ if (this.options = t, e !== null)
1240
+ this.domain = [B(e[0], t.calendar), B(e[1], t.calendar)];
1241
+ else if (s) {
1242
+ const i = j(o), r = (a) => {
1243
+ const u = i.intervals.length === 0 ? a : Math.max(0, Math.min(i.total, a));
1244
+ return B(W(u, i), t.calendar) + (a - u);
1245
+ };
1246
+ this.domain = [r(this.domain[0]), r(this.domain[1])];
1241
1247
  }
1242
1248
  }
1243
1249
  viewport() {
@@ -1301,7 +1307,7 @@ class Us {
1301
1307
  nowX() {
1302
1308
  const t = this.options.now;
1303
1309
  if (t === null || this.width <= 0) return null;
1304
- const e = Math.round(this.viewport().scale.toPx(Y(t, this.options.calendar)));
1310
+ const e = Math.round(this.viewport().scale.toPx(B(t, this.options.calendar)));
1305
1311
  return e >= 0 && e <= this.width ? e : null;
1306
1312
  }
1307
1313
  hitAt(t, e) {
@@ -1320,8 +1326,8 @@ class Us {
1320
1326
  }
1321
1327
  /** The wall-clock time at a plot x; within the calendar's extent. */
1322
1328
  timeAt(t) {
1323
- const e = this.viewport().scale.fromPx(t), s = et(this.options.calendar);
1324
- return s.intervals.length === 0 ? e : X(Math.max(0, Math.min(s.total, e)), s);
1329
+ const e = this.viewport().scale.fromPx(t), s = j(this.options.calendar);
1330
+ return s.intervals.length === 0 ? e : W(Math.max(0, Math.min(s.total, e)), s);
1325
1331
  }
1326
1332
  /** The lane at a y, strips included: what the pointer is ON.
1327
1333
 
@@ -1352,7 +1358,7 @@ class Us {
1352
1358
  neither - a scroll through the lanes is no news about the time. */
1353
1359
  pan(t, e) {
1354
1360
  const s = this.domain[0], o = this.scrollY, i = this.domain[1] - s;
1355
- this.width > 0 && t !== 0 && (this.domain = Ws(this.domain, t / this.width * i)), this.scrollY = Math.max(0, Math.min(this.maxScroll(), this.scrollY + e));
1361
+ this.width > 0 && t !== 0 && (this.domain = Us(this.domain, t / this.width * i)), this.scrollY = Math.max(0, Math.min(this.maxScroll(), this.scrollY + e));
1356
1362
  const r = this.domain[0] !== s;
1357
1363
  return { moved: r || this.scrollY !== o, time: r };
1358
1364
  }
@@ -1382,7 +1388,7 @@ const ue = {
1382
1388
  class zs {
1383
1389
  constructor() {
1384
1390
  f(this, "data", new ps(() => this.viewChanged()));
1385
- f(this, "view", new Us(this.data));
1391
+ f(this, "view", new Ws(this.data));
1386
1392
  f(this, "gestures");
1387
1393
  f(this, "handlersNow", {});
1388
1394
  f(this, "placing", null);
@@ -1435,7 +1441,7 @@ class zs {
1435
1441
  f(this, "drop", (t) => this.gestures.drop(t));
1436
1442
  f(this, "dragLeave", () => this.gestures.clearPlacing());
1437
1443
  f(this, "cancelEdit", () => this.gestures.cancelEdit());
1438
- this.gestures = new Bs({
1444
+ this.gestures = new Os({
1439
1445
  data: this.data,
1440
1446
  view: this.view,
1441
1447
  plotElement: () => this.plot,
@@ -1499,7 +1505,7 @@ class zs {
1499
1505
  }
1500
1506
  unbind() {
1501
1507
  var t;
1502
- (t = this.unsubscribeTheme) == null || t.call(this), this.unsubscribeTheme = null, this.frame !== 0 && cancelAnimationFrame(this.frame), this.domainFrame !== 0 && cancelAnimationFrame(this.domainFrame), this.frame = this.domainFrame = 0, this.root = this.plot = this.dataCanvas = this.overlayCanvas = null;
1508
+ this.gestures.cancelEdit(), (t = this.unsubscribeTheme) == null || t.call(this), this.unsubscribeTheme = null, this.frame !== 0 && cancelAnimationFrame(this.frame), this.domainFrame !== 0 && cancelAnimationFrame(this.domainFrame), this.frame = this.domainFrame = 0, this.root = this.plot = this.dataCanvas = this.overlayCanvas = null;
1503
1509
  }
1504
1510
  resize(t, e) {
1505
1511
  const s = Math.max(0, Math.round(t)), o = Math.max(0, Math.round(e));
@@ -1576,7 +1582,7 @@ class zs {
1576
1582
  }
1577
1583
  /** The visible span, as two wall-clock instants. */
1578
1584
  visibleDomain() {
1579
- const t = et(this.view.options.calendar), e = (s) => t.intervals.length === 0 ? s : X(Math.max(0, Math.min(t.total, s)), t);
1585
+ const t = j(this.view.options.calendar), e = (s) => t.intervals.length === 0 ? s : W(Math.max(0, Math.min(t.total, s)), t);
1580
1586
  return [e(this.view.domain[0]), e(this.view.domain[1])];
1581
1587
  }
1582
1588
  /** Reported once per frame, however many wheel steps a planner turns - and
@@ -1668,7 +1674,7 @@ function yn({ target: n }) {
1668
1674
  };
1669
1675
  if (n.kind === "subtask") {
1670
1676
  const { subtask: l, task: d } = n;
1671
- return /* @__PURE__ */ H(zt, { children: [
1677
+ return /* @__PURE__ */ Y(zt, { children: [
1672
1678
  /* @__PURE__ */ w("span", { className: v.tooltipHead, children: (d == null ? void 0 : d.name) ?? l.task }),
1673
1679
  /* @__PURE__ */ w("span", { children: l.name ?? l.id }),
1674
1680
  /* @__PURE__ */ w("span", { className: v.tooltipTimes, children: e.scheduleGhostTimes(s(l.from), s(l.to)) }),
@@ -1679,7 +1685,7 @@ function yn({ target: n }) {
1679
1685
  ] });
1680
1686
  }
1681
1687
  const { transport: i, task: r, from: a, to: u, late: c } = n;
1682
- return /* @__PURE__ */ H(zt, { children: [
1688
+ return /* @__PURE__ */ Y(zt, { children: [
1683
1689
  /* @__PURE__ */ w("span", { className: v.tooltipHead, children: (r == null ? void 0 : r.name) ?? (r == null ? void 0 : r.id) ?? i.id }),
1684
1690
  /* @__PURE__ */ w("span", { children: e.scheduleRoute((a == null ? void 0 : a.name) ?? i.from, (u == null ? void 0 : u.name) ?? i.to) }),
1685
1691
  /* @__PURE__ */ w("span", { children: `${e.scheduleTransport} ${o(i.duration)}` }),
@@ -1700,7 +1706,7 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1700
1706
  onIntent: p,
1701
1707
  canMoveTo: g,
1702
1708
  onInteraction: b,
1703
- selectedTask: A,
1709
+ selectedTask: I,
1704
1710
  onSelectedTaskChange: _,
1705
1711
  collapsedGroups: S,
1706
1712
  defaultCollapsedGroups: m,
@@ -1709,38 +1715,38 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1709
1715
  placing: E,
1710
1716
  route: F = "curve",
1711
1717
  attach: G = "centre",
1712
- ends: j = "dot",
1718
+ ends: V = "dot",
1713
1719
  label: ot,
1714
1720
  tooltip: z,
1715
- now: V,
1721
+ now: Z,
1716
1722
  className: Et,
1717
1723
  style: Ee,
1718
- children: De
1719
- } = t, [k] = it(() => new zs()), Dt = Ke(), xt = $(null), Pt = $(null), Nt = $(null), Gt = $(null), K = me(), W = ge(), [dt, ft] = o, Rt = (c == null ? void 0 : c.min) ?? ce.min, $t = (c == null ? void 0 : c.max) ?? ce.max, Bt = $(null), Ot = typeof l == "object" ? l.step : null, Ht = typeof l == "object" ? l.offset : null, Yt = typeof l == "object" ? null : l, [xe, Pe] = it(() => Date.now());
1720
- B(() => {
1721
- if (V !== !0) return;
1724
+ children: xe
1725
+ } = t, [k] = it(() => new zs()), xt = Ke(), Dt = $(null), Pt = $(null), Nt = $(null), Gt = $(null), X = me(), K = ge(), [dt, ft] = o, Rt = (c == null ? void 0 : c.min) ?? ce.min, $t = (c == null ? void 0 : c.max) ?? ce.max, Ot = $(null), Bt = typeof l == "object" ? l.step : null, Ht = typeof l == "object" ? l.offset : null, Yt = typeof l == "object" ? null : l, [De, Pe] = it(() => Date.now());
1726
+ O(() => {
1727
+ if (Z !== !0) return;
1722
1728
  const h = setInterval(() => Pe(Date.now()), U);
1723
1729
  return () => clearInterval(h);
1724
- }, [V]);
1725
- const Xt = V === !0 ? xe : typeof V == "number" ? V : null;
1730
+ }, [Z]);
1731
+ const Xt = Z === !0 ? De : typeof Z == "number" ? Z : null;
1726
1732
  vt(() => {
1727
- const h = `${dt}|${ft}`, y = Bt.current !== h;
1728
- Bt.current = h;
1729
- const I = Yt ?? { step: Ot ?? 0, offset: Ht ?? 0 };
1733
+ const h = `${dt}|${ft}`, y = Ot.current !== h;
1734
+ Ot.current = h;
1735
+ const A = Yt ?? { step: Bt ?? 0, offset: Ht ?? 0 };
1730
1736
  k.setOptions(
1731
- { laneHeight: r, calendar: u, zoomLimits: { min: Rt, max: $t }, snap: I, intents: d, now: Xt, route: F, attach: G, ends: j },
1737
+ { laneHeight: r, calendar: u, zoomLimits: { min: Rt, max: $t }, snap: A, intents: d, now: Xt, route: F, attach: G, ends: V },
1732
1738
  y ? [dt, ft] : null
1733
1739
  );
1734
- }, [k, dt, ft, r, u, Rt, $t, Yt, Ot, Ht, d, Xt, F, G, j]), B(() => {
1740
+ }, [k, dt, ft, r, u, Rt, $t, Yt, Bt, Ht, d, Xt, F, G, V]), O(() => {
1735
1741
  k.setHandlers({ onIntent: p, canMoveTo: g, onInteraction: b, onSelectedTaskChange: _, onCollapsedGroupsChange: C, onDomainChange: L });
1736
1742
  }, [k, p, g, b, _, C, L]);
1737
1743
  const Ne = $(m);
1738
- B(() => {
1744
+ O(() => {
1739
1745
  const h = Ne.current;
1740
1746
  h !== void 0 && k.setDefaultCollapsedGroups(h);
1741
- }, [k]), B(() => {
1747
+ }, [k]), O(() => {
1742
1748
  k.setCollapsedGroups(S);
1743
- }, [k, S]), We(
1749
+ }, [k, S]), Ue(
1744
1750
  e,
1745
1751
  () => ({
1746
1752
  positionAt: (h, y) => k.positionAt(h, y),
@@ -1748,80 +1754,80 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1748
1754
  visibleDomain: () => k.visibleDomain()
1749
1755
  }),
1750
1756
  [k]
1751
- ), B(() => {
1752
- k.setControlledTask(A);
1753
- }, [k, A]), B(() => {
1757
+ ), O(() => {
1758
+ k.setControlledTask(I);
1759
+ }, [k, I]), O(() => {
1754
1760
  k.setPlacing(E ?? null);
1755
- }, [k, E]), B(() => {
1756
- const h = xt.current, y = Pt.current, I = Nt.current, R = Gt.current;
1757
- if (!h || !y || !I || !R) return;
1758
- k.bind(h, y, I, R);
1759
- const D = y.getBoundingClientRect();
1760
- k.resize(D.width, D.height);
1761
- const x = new ResizeObserver((N) => {
1762
- var Ut;
1763
- const Q = (Ut = N[N.length - 1]) == null ? void 0 : Ut.contentRect;
1764
- Q !== void 0 && k.resize(Q.width, Q.height);
1761
+ }, [k, E]), O(() => {
1762
+ const h = Dt.current, y = Pt.current, A = Nt.current, R = Gt.current;
1763
+ if (!h || !y || !A || !R) return;
1764
+ k.bind(h, y, A, R);
1765
+ const x = y.getBoundingClientRect();
1766
+ k.resize(x.width, x.height);
1767
+ const D = new ResizeObserver((N) => {
1768
+ var Wt;
1769
+ const tt = (Wt = N[N.length - 1]) == null ? void 0 : Wt.contentRect;
1770
+ tt !== void 0 && k.resize(tt.width, tt.height);
1765
1771
  });
1766
- x.observe(y);
1767
- const Z = (N) => k.wheel(N);
1768
- y.addEventListener("wheel", Z, { passive: !1 });
1769
- const J = (N) => {
1772
+ D.observe(y);
1773
+ const J = (N) => k.wheel(N);
1774
+ h.addEventListener("wheel", J, { passive: !1 });
1775
+ const Q = (N) => {
1770
1776
  N.key === "Escape" && k.cancelEdit() && N.preventDefault();
1771
1777
  };
1772
- return window.addEventListener("keydown", J), () => {
1773
- window.removeEventListener("keydown", J), y.removeEventListener("wheel", Z), x.disconnect(), k.unbind();
1778
+ return window.addEventListener("keydown", Q), () => {
1779
+ window.removeEventListener("keydown", Q), h.removeEventListener("wheel", J), D.disconnect(), k.unbind();
1774
1780
  };
1775
1781
  }, [k]);
1776
- const T = Ue(k.subscribe, k.getSnapshot, k.getServerSnapshot), Ge = (h, y) => {
1777
- const I = new Date(h);
1778
- return y >= 200 ? K.dateLong(I) : y >= 84 ? K.date(I) : y >= 44 ? K.dateShort(I) : "";
1779
- }, M = T.ghost, pt = (h) => `${Dt}-row-${h.key}`, Re = q(() => {
1782
+ const T = We(k.subscribe, k.getSnapshot, k.getServerSnapshot), Ge = (h, y) => {
1783
+ const A = new Date(h);
1784
+ return y >= 200 ? X.dateLong(A) : y >= 84 ? X.date(A) : y >= 44 ? X.dateShort(A) : "";
1785
+ }, M = T.ghost, pt = (h) => `${xt}-row-${encodeURIComponent(h.key)}`, Re = q(() => {
1780
1786
  const h = /* @__PURE__ */ new Map();
1781
1787
  for (const y of T.headers)
1782
- for (const I of y.within)
1783
- y.kind === "groupHead" && I === y.group || h.set(I, [...h.get(I) ?? [], pt(y)]);
1788
+ for (const A of y.within)
1789
+ y.kind === "groupHead" && A === y.group || h.set(A, [...h.get(A) ?? [], pt(y)]);
1784
1790
  return h;
1785
- }, [T.headers, Dt]), $e = q(() => new Set((M == null ? void 0 : M.refusedLanes) ?? []), [M == null ? void 0 : M.refusedLanes]), Kt = $(null), [mt, Be] = it({ x: 0, y: 0, at: "" }), gt = M === null ? "" : `${M.x}:${M.y}:${M.from}:${M.to}:${M.overlap}:${M.late}`;
1791
+ }, [T.headers, xt]), $e = q(() => new Set((M == null ? void 0 : M.refusedLanes) ?? []), [M == null ? void 0 : M.refusedLanes]), Kt = $(null), [mt, Oe] = it({ x: 0, y: 0, at: "" }), gt = M === null ? "" : `${M.x}:${M.y}:${M.from}:${M.to}:${M.overlap}:${M.late}`;
1786
1792
  vt(() => {
1787
1793
  const h = Kt.current;
1788
1794
  if (M === null || h === null) return;
1789
- const y = 4, I = M.y - h.offsetHeight - y, R = M.y + M.height + y, D = {
1795
+ const y = 4, A = M.y - h.offsetHeight - y, R = M.y + M.height + y, x = {
1790
1796
  x: Math.max(2, Math.min(M.x, T.width - h.offsetWidth - 2)),
1791
- y: I >= 2 ? I : Math.min(R, T.height - h.offsetHeight - 2),
1797
+ y: A >= 2 ? A : Math.min(R, T.height - h.offsetHeight - 2),
1792
1798
  at: gt
1793
1799
  };
1794
- Be((x) => x.x === D.x && x.y === D.y && x.at === D.at ? x : D);
1800
+ Oe((D) => D.x === x.x && D.y === x.y && D.at === x.at ? D : x);
1795
1801
  }, [M, gt, T.width, T.height]);
1796
- const Wt = $(null), [kt, Oe] = it({ x: 0, y: 0, at: "" }), O = T.tooltip, wt = O === null ? "" : `${O.x}:${O.y}:${O.target.kind}`;
1802
+ const Ut = $(null), [kt, Be] = it({ x: 0, y: 0, at: "" }), H = T.tooltip, wt = H === null ? "" : `${H.x}:${H.y}:${H.target.kind}`;
1797
1803
  return vt(() => {
1798
- const h = Wt.current;
1799
- if (O === null || h === null) return;
1800
- const y = 12, I = (D, x, Z) => {
1801
- const J = D + y, N = D - y - x, Q = J + x <= Z - 4 || N < 4 ? J : N;
1802
- return Math.max(4, Math.min(Q, Z - x - 4));
1804
+ const h = Ut.current;
1805
+ if (H === null || h === null) return;
1806
+ const y = 12, A = (x, D, J) => {
1807
+ const Q = x + y, N = x - y - D, tt = Q + D <= J - 4 || N < 4 ? Q : N;
1808
+ return Math.max(4, Math.min(tt, J - D - 4));
1803
1809
  }, R = {
1804
- x: I(O.x, h.offsetWidth, T.width),
1805
- y: I(O.y, h.offsetHeight, T.height),
1810
+ x: A(H.x, h.offsetWidth, T.width),
1811
+ y: A(H.y, h.offsetHeight, T.height),
1806
1812
  at: wt
1807
1813
  };
1808
- Oe((D) => D.x === R.x && D.y === R.y && D.at === R.at ? D : R);
1809
- }, [O, wt, T.width, T.height]), /* @__PURE__ */ H(ke.Provider, { value: k, children: [
1810
- /* @__PURE__ */ H(
1814
+ Be((x) => x.x === R.x && x.y === R.y && x.at === R.at ? x : R);
1815
+ }, [H, wt, T.width, T.height]), /* @__PURE__ */ Y(ke.Provider, { value: k, children: [
1816
+ /* @__PURE__ */ Y(
1811
1817
  "div",
1812
1818
  {
1813
- ref: xt,
1819
+ ref: Dt,
1814
1820
  role: "figure",
1815
1821
  "aria-label": s,
1816
1822
  className: Et ? `${v.root} ${Et}` : v.root,
1817
- style: { height: `${i}px`, gridTemplateColumns: `${a}px minmax(0, 1fr)`, ...Ee },
1823
+ style: { height: `${i}px`, gridTemplateColumns: `min(${a}px, 40%) minmax(0, 1fr)`, ...Ee },
1818
1824
  children: [
1819
1825
  /* @__PURE__ */ w("div", { className: v.corner }),
1820
1826
  /* @__PURE__ */ w("div", { className: v.dayBand, "aria-hidden": "true", "data-schedule-days": "", "data-schedule-clip": "day band", children: T.days.map((h) => {
1821
- const y = Math.max(0, -h.x), I = Math.min(h.x + h.width, T.width) - Math.max(h.x, 0);
1822
- return /* @__PURE__ */ w("span", { className: v.day, style: { left: `${h.x}px`, width: `${h.width}px` }, children: /* @__PURE__ */ w("span", { className: v.dayLabel, "data-schedule-overlay": "day label", style: { marginLeft: `${y}px` }, children: Ge(h.start, I) }) }, h.start);
1827
+ const y = Math.max(0, -h.x), A = Math.min(h.x + h.width, T.width) - Math.max(h.x, 0);
1828
+ return /* @__PURE__ */ w("span", { className: v.day, style: { left: `${h.x}px`, width: `${h.width}px` }, children: /* @__PURE__ */ w("span", { className: v.dayLabel, "data-schedule-overlay": "day label", style: { marginLeft: `${y}px` }, children: Ge(h.start, A) }) }, h.start);
1823
1829
  }) }),
1824
- /* @__PURE__ */ w("div", { className: v.headers, "data-schedule-headers": "", children: /* @__PURE__ */ w("div", { className: v.headerRun, style: { transform: `translateY(${-T.scrollY}px)` }, children: T.headers.map((h) => /* @__PURE__ */ H(
1830
+ /* @__PURE__ */ w("div", { className: v.headers, "data-schedule-headers": "", children: /* @__PURE__ */ w("div", { className: v.headerRun, style: { transform: `translateY(${-T.scrollY}px)` }, children: T.headers.map((h) => /* @__PURE__ */ Y(
1825
1831
  "div",
1826
1832
  {
1827
1833
  id: pt(h),
@@ -1841,18 +1847,18 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1841
1847
  "data-schedule-overlay": "fold control",
1842
1848
  "aria-expanded": h.collapsed === !1,
1843
1849
  "aria-controls": (Re.get(h.group) ?? [pt(h)]).join(" "),
1844
- "aria-label": `${h.collapsed === !0 ? W.scheduleUnfoldGroup : W.scheduleFoldGroup}: ${typeof h.label == "string" ? h.label : h.group}`,
1850
+ "aria-label": `${h.collapsed === !0 ? K.scheduleUnfoldGroup : K.scheduleFoldGroup}: ${typeof h.label == "string" ? h.label : h.group}`,
1845
1851
  onClick: () => k.toggleGroup(h.group),
1846
1852
  children: /* @__PURE__ */ w("svg", { viewBox: "0 0 10 10", width: "9", height: "9", "aria-hidden": "true", "data-open": h.collapsed === !1 ? "" : void 0, children: /* @__PURE__ */ w("path", { d: "M3.5 1.5 7 5l-3.5 3.5", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
1847
1853
  }
1848
1854
  ),
1849
1855
  /* @__PURE__ */ w("span", { className: v.headerLabel, "data-schedule-overlay": "header label", children: h.label }),
1850
- h.kind !== "lane" && /* @__PURE__ */ w("span", { className: v.headerCount, "data-schedule-overlay": "lane count", "data-lane-count": h.lanes, children: W.scheduleLaneCount(h.lanes) })
1856
+ h.kind !== "lane" && /* @__PURE__ */ w("span", { className: v.headerCount, "data-schedule-overlay": "lane count", "data-lane-count": h.lanes, children: K.scheduleLaneCount(h.lanes) })
1851
1857
  ]
1852
1858
  },
1853
1859
  h.key
1854
1860
  )) }) }),
1855
- /* @__PURE__ */ H(
1861
+ /* @__PURE__ */ Y(
1856
1862
  "div",
1857
1863
  {
1858
1864
  ref: Pt,
@@ -1902,7 +1908,7 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1902
1908
  z !== !1 && T.tooltip !== null && /* @__PURE__ */ w(
1903
1909
  "span",
1904
1910
  {
1905
- ref: Wt,
1911
+ ref: Ut,
1906
1912
  role: "tooltip",
1907
1913
  className: v.tooltip,
1908
1914
  "data-schedule-tooltip": "",
@@ -1915,7 +1921,7 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1915
1921
  children: typeof z == "function" ? z(T.tooltip.target) : /* @__PURE__ */ w(yn, { target: T.tooltip.target })
1916
1922
  }
1917
1923
  ),
1918
- M !== null && /* @__PURE__ */ H(
1924
+ M !== null && /* @__PURE__ */ Y(
1919
1925
  "span",
1920
1926
  {
1921
1927
  ref: Kt,
@@ -1930,10 +1936,10 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1930
1936
  visibility: mt.at === gt ? void 0 : "hidden"
1931
1937
  },
1932
1938
  children: [
1933
- W.scheduleGhostTimes(K.time(new Date(M.from), !1), K.time(new Date(M.to), !1)),
1934
- M.refused && /* @__PURE__ */ w("span", { className: v.refusal, children: W.scheduleLaneRefused }),
1935
- M.overlap && /* @__PURE__ */ w("span", { className: v.finding, children: W.scheduleOverlap }),
1936
- M.late && /* @__PURE__ */ w("span", { className: v.finding, children: W.scheduleLateTransport })
1939
+ K.scheduleGhostTimes(X.time(new Date(M.from), !1), X.time(new Date(M.to), !1)),
1940
+ M.refused && /* @__PURE__ */ w("span", { className: v.refusal, children: K.scheduleLaneRefused }),
1941
+ M.overlap && /* @__PURE__ */ w("span", { className: v.finding, children: K.scheduleOverlap }),
1942
+ M.late && /* @__PURE__ */ w("span", { className: v.finding, children: K.scheduleLateTransport })
1937
1943
  ]
1938
1944
  }
1939
1945
  )
@@ -1941,25 +1947,25 @@ const bn = [], ce = { min: Tt, max: 28 * st }, Mn = [], de = 20, Fn = Xe(functio
1941
1947
  }
1942
1948
  ),
1943
1949
  /* @__PURE__ */ w("div", { className: v.corner }),
1944
- /* @__PURE__ */ H("div", { className: v.tickBand, "aria-hidden": "true", "data-schedule-ticks": "", "data-schedule-clip": "time band", children: [
1950
+ /* @__PURE__ */ Y("div", { className: v.tickBand, "aria-hidden": "true", "data-schedule-ticks": "", "data-schedule-clip": "time band", children: [
1945
1951
  T.now !== null && /* @__PURE__ */ w("span", { className: v.now, "data-now": "", "data-schedule-overlay": "now mark", style: { left: `${T.now}px` } }),
1946
- T.ticks.map((h) => /* @__PURE__ */ w("span", { className: v.tick, style: { left: `${h.x}px` }, children: h.x >= de && h.x <= T.width - de && /* @__PURE__ */ w("span", { className: v.tickLabel, "data-schedule-overlay": "time label", children: T.step >= st ? K.dateShort(new Date(h.wallClock)) : K.time(new Date(h.wallClock), !1) }) }, h.wallClock))
1952
+ T.ticks.map((h) => /* @__PURE__ */ w("span", { className: v.tick, style: { left: `${h.x}px` }, children: h.x >= de && h.x <= T.width - de && /* @__PURE__ */ w("span", { className: v.tickLabel, "data-schedule-overlay": "time label", children: T.step >= st ? X.dateShort(new Date(h.wallClock)) : X.time(new Date(h.wallClock), !1) }) }, h.wallClock))
1947
1953
  ] })
1948
1954
  ]
1949
1955
  }
1950
1956
  ),
1951
- De
1957
+ xe
1952
1958
  ] });
1953
1959
  });
1954
1960
  function En({ id: n, label: t }) {
1955
1961
  const e = ve(), s = q(() => ({ id: n, label: t ?? n, ...e === null ? {} : { parent: e } }), [n, t, e]);
1956
1962
  return ts(s), null;
1957
1963
  }
1958
- function Dn({ id: n, label: t, children: e }) {
1964
+ function xn({ id: n, label: t, children: e }) {
1959
1965
  const s = ve(), o = q(() => ({ id: n, label: t ?? n, ...s === null ? {} : { parent: s } }), [n, t, s]);
1960
1966
  return es(o), /* @__PURE__ */ w(we.Provider, { value: n, children: e });
1961
1967
  }
1962
- function xn({ data: n, tasks: t }) {
1968
+ function Dn({ data: n, tasks: t }) {
1963
1969
  const e = q(() => ({ kind: "subtasks", data: n, tasks: t }), [n, t]);
1964
1970
  return ye("Subtasks", e), null;
1965
1971
  }
@@ -1983,7 +1989,7 @@ function Nn(n, t, e) {
1983
1989
  if (l.to === e.subtask) continue;
1984
1990
  const d = s.get(l.to);
1985
1991
  if (d === void 0) continue;
1986
- const p = St(l, c) + l.duration - At(l, d);
1992
+ const p = St(l, c) + l.duration - It(l, d);
1987
1993
  if (!(p > 0)) continue;
1988
1994
  const g = { kind: "move", subtask: d.id, from: d.from + p, to: d.to + p };
1989
1995
  s.set(d.id, jt(d, g)), i.set(d.id, g), r.push(d.id);
@@ -1996,20 +2002,20 @@ function Gn(n, t, e) {
1996
2002
  }
1997
2003
  export {
1998
2004
  En as Lane,
1999
- Dn as LaneGroup,
2005
+ xn as LaneGroup,
2000
2006
  Fn as Schedule,
2001
- xn as Subtasks,
2007
+ Dn as Subtasks,
2002
2008
  Pn as Transports,
2003
2009
  jt as applyIntent,
2004
- At as arrival,
2010
+ It as arrival,
2005
2011
  St as departure,
2006
2012
  _n as findings,
2007
2013
  _t as lateTransports,
2008
2014
  ut as occupied,
2009
- It as overlaps,
2015
+ At as overlaps,
2010
2016
  ht as resolveAppearance,
2011
2017
  Nn as ripple,
2012
2018
  Gn as shiftTask,
2013
- Rs as snapTime,
2014
- In as subtaskFromPlace
2019
+ Gs as snapTime,
2020
+ An as subtaskFromPlace
2015
2021
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@umriss-ui/schedule",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "The umriss schedule - subtasks on lanes over time, with transports, findings and controlled editing.",
5
5
  "license": "MIT",
6
6
  "author": "Roman Händler",
@@ -44,8 +44,8 @@
44
44
  "peerDependencies": {
45
45
  "react": ">=18",
46
46
  "react-dom": ">=18",
47
- "@umriss-ui/charts": "^0.3.1",
48
- "@umriss-ui/core": "^0.3.1"
47
+ "@umriss-ui/charts": "^0.3.2",
48
+ "@umriss-ui/core": "^0.3.2"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@fontsource/geist-mono": "^5.3.0",
@@ -59,9 +59,9 @@
59
59
  "typescript": "^5.6.3",
60
60
  "vite": "^6.0.0",
61
61
  "vite-plugin-dts": "^4.3.0",
62
- "@umriss-ui/charts": "0.3.1",
62
+ "@umriss-ui/charts": "0.3.2",
63
63
  "@umriss-ui/demo": "0.0.0",
64
- "@umriss-ui/core": "0.3.1"
64
+ "@umriss-ui/core": "0.3.2"
65
65
  },
66
66
  "scripts": {
67
67
  "props": "node --disable-warning=ExperimentalWarning --experimental-strip-types demo/props.ts",