@tensor_1/react 2.34.0 → 2.35.0

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.
@@ -39,6 +39,8 @@ const GridItem = memo(function GridItem2({ entry, segment, column, alone, name,
39
39
  ] });
40
40
  const shared = {
41
41
  className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-item",
42
+ "data-highlight": entry.emphasis === "highlight" || void 0,
43
+ "data-dim": entry.emphasis === "dim" || void 0,
42
44
  "data-band": entry.band ?? "none",
43
45
  "data-status": status,
44
46
  "data-state": entry.state,
@@ -54,6 +56,7 @@ const GridItem = memo(function GridItem2({ entry, segment, column, alone, name,
54
56
  "button",
55
57
  {
56
58
  type: "button",
59
+ tabIndex: -1,
57
60
  ...shared,
58
61
  "data-item-id": entry.id,
59
62
  "aria-label": name,
@@ -101,6 +104,9 @@ function SchedulingTimeGrid({
101
104
  const [widthCap, setWidthCap] = useState(Infinity);
102
105
  const [ghost, setGhost] = useState(null);
103
106
  const [announcement, setAnnouncement] = useState("");
107
+ const [activeDay, setActiveDay] = useState(days[0]);
108
+ const enteredFrom = useRef(null);
109
+ const tabStop = days.includes(activeDay) ? activeDay : days[0];
104
110
  const moving = canMove && onProposeMove !== void 0;
105
111
  const step = Number.isFinite(givenStep) && givenStep > 0 ? givenStep : DEFAULT_STEP;
106
112
  const laneOptions = useMemo(() => ({ crossMidnightMinutes: topLaneCrossMidnightMinutes }), [topLaneCrossMidnightMinutes]);
@@ -334,6 +340,78 @@ function SchedulingTimeGrid({
334
340
  dragRef.current = null;
335
341
  }, []);
336
342
  const gridColumns = (span) => `${span.startCol + 2} / ${span.endCol + 3}`;
343
+ const headButton = (date) => rootRef.current?.querySelector(`.uix-scheduling-calendar__tg-dayhead[data-date="${date}"] [data-calendar-date]`) ?? null;
344
+ const dayRing = (date) => {
345
+ const root = rootRef.current;
346
+ const column = days.indexOf(date);
347
+ if (!root || column === -1) return [];
348
+ const covers = (element) => {
349
+ const [from, to] = element.style.gridColumn.split("/").map((part) => Number(part.trim()));
350
+ return from !== void 0 && to !== void 0 && from <= column + 2 && column + 2 < to;
351
+ };
352
+ const all = (selector) => Array.from(root.querySelectorAll(selector));
353
+ return [
354
+ ...all(".uix-scheduling-calendar__tg-strip > button.uix-scheduling-calendar__window").filter(covers),
355
+ ...all(".uix-scheduling-calendar__tg-top > button.uix-scheduling-calendar__tg-span").filter(covers),
356
+ ...all(`[data-tg-column="${date}"] > button[data-item-id]`),
357
+ ...all(`.uix-scheduling-calendar__tg-dayhead[data-date="${date}"] > button.uix-scheduling-calendar__more`),
358
+ // "+N windows" opens one day; it is reached from that day.
359
+ ...all(`.uix-scheduling-calendar__tg-strip > button.uix-scheduling-calendar__rowmore[data-more-date="${date}"]`)
360
+ ];
361
+ };
362
+ const dayOfItem = (item) => {
363
+ if (enteredFrom.current && dayRing(enteredFrom.current).includes(item)) return enteredFrom.current;
364
+ const inColumn = item.getAttribute("data-more-date") ?? item.closest("[data-tg-column]")?.getAttribute("data-tg-column") ?? item.closest("[data-date]")?.getAttribute("data-date");
365
+ if (inColumn) return inColumn;
366
+ const from = Number(item.style.gridColumn.split("/")[0]);
367
+ return Number.isFinite(from) ? days[Math.max(0, Math.min(days.length - 1, from - 2))] ?? null : days[days.length - 1] ?? null;
368
+ };
369
+ const onHeadKeyDown = (event, date) => {
370
+ const index = days.indexOf(date);
371
+ const target = event.key === "ArrowLeft" ? index - 1 : event.key === "ArrowRight" ? index + 1 : event.key === "Home" ? 0 : event.key === "End" ? days.length - 1 : null;
372
+ if (target !== null) {
373
+ event.preventDefault();
374
+ const next = days[Math.max(0, Math.min(days.length - 1, target))];
375
+ setActiveDay(next);
376
+ headButton(next)?.focus();
377
+ } else if (event.key === "Enter") {
378
+ const [first] = dayRing(date);
379
+ if (!first) return;
380
+ event.preventDefault();
381
+ enteredFrom.current = date;
382
+ first.focus();
383
+ }
384
+ };
385
+ const onGridKeyDown = (event) => {
386
+ const item = event.target;
387
+ if (event.defaultPrevented || event.shiftKey || item.hasAttribute("data-calendar-date") || !["ArrowDown", "ArrowUp", "Home", "End", "Escape"].includes(event.key)) return;
388
+ const date = dayOfItem(item);
389
+ if (!date) return;
390
+ const ring = dayRing(date);
391
+ const index = ring.indexOf(item);
392
+ if (index === -1) return;
393
+ event.preventDefault();
394
+ const to = event.key === "Escape" ? null : ring[Math.max(0, Math.min(ring.length - 1, event.key === "Home" ? 0 : event.key === "End" ? ring.length - 1 : index + (event.key === "ArrowDown" ? 1 : -1)))];
395
+ if (to !== item && ghost?.source === "keys") {
396
+ setGhost(null);
397
+ setAnnouncement(labels.moveCancelled);
398
+ }
399
+ if (event.key === "Escape") {
400
+ event.stopPropagation();
401
+ enteredFrom.current = null;
402
+ setActiveDay(date);
403
+ headButton(date)?.focus();
404
+ return;
405
+ }
406
+ enteredFrom.current = date;
407
+ to?.focus();
408
+ };
409
+ const onGridFocus = (event) => {
410
+ const item = event.target;
411
+ if (item.hasAttribute("data-calendar-date")) return;
412
+ const date = dayOfItem(item);
413
+ if (date && dayRing(date).includes(item)) setActiveDay(date);
414
+ };
337
415
  const nowAt = now === void 0 ? null : new Date(now).getTime();
338
416
  const nowColumn = nowAt === null || Number.isNaN(nowAt) ? -1 : days.indexOf(zonedDateKey(new Date(nowAt), timeZone));
339
417
  const topHiddenOn = (date) => top.hidden.filter((id) => {
@@ -358,6 +436,8 @@ function SchedulingTimeGrid({
358
436
  role: "group",
359
437
  "aria-label": gridLabel,
360
438
  style: vars({ "--uix-scheduling-calendar-days": days.length, "--uix-scheduling-calendar-hours": maxHours }),
439
+ onKeyDown: onGridKeyDown,
440
+ onFocus: onGridFocus,
361
441
  onClickCapture: (event) => {
362
442
  if (suppressClick.current) {
363
443
  suppressClick.current = false;
@@ -374,12 +454,25 @@ function SchedulingTimeGrid({
374
454
  const more = info ? info.overflowCount : hiddenIds.length;
375
455
  const moreText = fillLabel(labels.moreSpans, { count: more });
376
456
  const moreName = fillLabel(labels.moreEntriesLabel, { count: more, date: dateText(date, "day") });
377
- const headName = info ? info.label ?? `${dateText(date, "day")}, ${fillLabel(labels.dayCount, { count: info.count })}` : dateText(date, "day");
457
+ const headName = !info ? dateText(date, "day") : info.label ? fillLabel(labels.dayName, { date: dateText(date, "day"), label: info.label }) : `${dateText(date, "day")}, ${fillLabel(labels.dayCount, { count: info.count })}`;
378
458
  return /* @__PURE__ */ jsxs("div", { className: "uix-scheduling-calendar__tg-dayhead", role: "group", "aria-label": headName, "data-date": date, children: [
379
- /* @__PURE__ */ jsx("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, "aria-label": dateText(date, "day"), onClick: onSelectDate ? () => onSelectDate(date) : void 0, children: dateText(date, "column") }),
459
+ /* @__PURE__ */ jsx(
460
+ "button",
461
+ {
462
+ type: "button",
463
+ className: "uix-scheduling-calendar__date",
464
+ "data-calendar-date": date,
465
+ tabIndex: tabStop === date ? 0 : -1,
466
+ "aria-label": info?.label ? fillLabel(labels.dayName, { date: dateText(date, "day"), label: info.label }) : dateText(date, "day"),
467
+ onFocus: () => setActiveDay(date),
468
+ onKeyDown: (event) => onHeadKeyDown(event, date),
469
+ onClick: onSelectDate ? () => onSelectDate(date) : void 0,
470
+ children: dateText(date, "column")
471
+ }
472
+ ),
380
473
  info && /* @__PURE__ */ jsx("span", { className: "uix-scheduling-calendar__count", "aria-hidden": "true", children: info.count }),
381
474
  info?.markers && info.markers.length > 0 && /* @__PURE__ */ jsx("span", { className: "uix-scheduling-calendar__markers", children: info.markers.map((marker) => /* @__PURE__ */ jsx("span", { children: renderMarker(marker, true) }, marker.id)) }),
382
- more > 0 && (onShowMore ? /* @__PURE__ */ jsx("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-label": moreName, onClick: () => onShowMore(date, hiddenIds.map((id) => entryById.get(id)).filter(Boolean)), children: moreText }) : /* @__PURE__ */ jsxs("span", { className: "uix-scheduling-calendar__more", children: [
475
+ more > 0 && (onShowMore ? /* @__PURE__ */ jsx("button", { type: "button", tabIndex: -1, className: "uix-scheduling-calendar__more", "aria-label": moreName, onClick: () => onShowMore(date, hiddenIds.map((id) => entryById.get(id)).filter(Boolean)), children: moreText }) : /* @__PURE__ */ jsxs("span", { className: "uix-scheduling-calendar__more", children: [
383
476
  /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: moreText }),
384
477
  /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: moreName })
385
478
  ] }))
@@ -394,6 +487,7 @@ function SchedulingTimeGrid({
394
487
  "button",
395
488
  {
396
489
  type: "button",
490
+ tabIndex: -1,
397
491
  className: "uix-scheduling-calendar__window",
398
492
  "data-overlay-id": overlay.id,
399
493
  "data-pattern": overlay.pattern ?? "solid",
@@ -413,7 +507,7 @@ function SchedulingTimeGrid({
413
507
  placed.id
414
508
  );
415
509
  }),
416
- moreWindows > 0 && (onShowMore ? /* @__PURE__ */ jsx("button", { type: "button", className: "uix-scheduling-calendar__rowmore", "aria-label": fillLabel(labels.moreWindowsLabel, { count: moreWindows, date: dateText(firstHiddenWindowDay, "day") }), onClick: () => onShowMore(firstHiddenWindowDay, []), children: fillLabel(labels.moreWindows, { count: moreWindows }) }) : /* @__PURE__ */ jsx("span", { className: "uix-scheduling-calendar__rowmore", children: fillLabel(labels.moreWindows, { count: moreWindows }) }))
510
+ moreWindows > 0 && (onShowMore ? /* @__PURE__ */ jsx("button", { type: "button", tabIndex: -1, className: "uix-scheduling-calendar__rowmore", "data-more-date": firstHiddenWindowDay, "aria-label": fillLabel(labels.moreWindowsLabel, { count: moreWindows, date: dateText(firstHiddenWindowDay, "day") }), onClick: () => onShowMore(firstHiddenWindowDay, []), children: fillLabel(labels.moreWindows, { count: moreWindows }) }) : /* @__PURE__ */ jsx("span", { className: "uix-scheduling-calendar__rowmore", children: fillLabel(labels.moreWindows, { count: moreWindows }) }))
417
511
  ] }),
418
512
  (topLanes > 0 || ghostSpan) && /* @__PURE__ */ jsxs("div", { className: "uix-scheduling-calendar__tg-strip uix-scheduling-calendar__tg-top", role: "group", "aria-label": labels.topLane, style: vars({ "--uix-scheduling-calendar-lanes": Math.max(topLanes, 1) }), children: [
419
513
  top.placed.map((placed) => {
@@ -425,8 +519,11 @@ function SchedulingTimeGrid({
425
519
  "button",
426
520
  {
427
521
  type: "button",
522
+ tabIndex: -1,
428
523
  className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-span",
429
524
  "data-item-id": entry.id,
525
+ "data-highlight": entry.emphasis === "highlight" || void 0,
526
+ "data-dim": entry.emphasis === "dim" || void 0,
430
527
  "data-band": entry.band ?? "none",
431
528
  "data-status": entryStatus(entry),
432
529
  "data-state": entry.state,
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
3
  import { TimelineRange, TimelineScale } from '../scheduling-timeline-model.js';
4
- import { j as SchedulingEntryState } from '../SchedulingCalendar-DSLQ6AY5.js';
4
+ import { j as SchedulingEntryState } from '../SchedulingCalendar-B6TakO2h.js';
5
5
  import '../calendar-model.js';
6
6
  import '../scheduling-calendar-model.js';
7
7