@tensor_1/react 2.32.0 → 2.33.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.
- package/README.md +17 -0
- package/dist/SchedulingCalendar-C4XVbqZr.d.ts +339 -0
- package/dist/components/SchedulingCalendar.d.ts +4 -241
- package/dist/components/SchedulingCalendar.js +73 -14
- package/dist/components/SchedulingTimeGrid.d.ts +4 -0
- package/dist/components/SchedulingTimeGrid.js +521 -0
- package/dist/components/SchedulingTimeline.d.ts +1 -1
- package/dist/index.cjs +1144 -471
- package/dist/index.d.cts +174 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +15 -1
- package/dist/labels-context.d.ts +1 -1
- package/dist/scheduling-calendar-model.d.ts +104 -1
- package/dist/scheduling-calendar-model.js +95 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -190,6 +190,7 @@ __export(src_exports, {
|
|
|
190
190
|
Switch: () => Switch,
|
|
191
191
|
TEXT_FILTER_OPERATORS: () => TEXT_FILTER_OPERATORS,
|
|
192
192
|
TOAST_LEAVE_MS: () => TOAST_LEAVE_MS,
|
|
193
|
+
TOP_LANE_CROSS_MIDNIGHT_MINUTES: () => TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
193
194
|
Tab: () => Tab,
|
|
194
195
|
TabPanel: () => TabPanel,
|
|
195
196
|
Table: () => Table,
|
|
@@ -254,10 +255,12 @@ __export(src_exports, {
|
|
|
254
255
|
isRuleGroup: () => isRuleGroup,
|
|
255
256
|
itemDaySpan: () => itemDaySpan,
|
|
256
257
|
layeredNeighbor: () => layeredNeighbor,
|
|
258
|
+
layoutDaySpans: () => layoutDaySpans,
|
|
257
259
|
layoutLane: () => layoutLane,
|
|
258
260
|
layoutLayeredGraph: () => layoutLayeredGraph,
|
|
259
261
|
layoutMonthSpans: () => layoutMonthSpans,
|
|
260
262
|
layoutRelationshipGraph: () => layoutRelationshipGraph,
|
|
263
|
+
layoutTimeGridDay: () => layoutTimeGridDay,
|
|
261
264
|
mapRuleGroup: () => mapRuleGroup,
|
|
262
265
|
matchFilter: () => matchFilter,
|
|
263
266
|
matchFilterPreset: () => matchFilterPreset,
|
|
@@ -274,6 +277,8 @@ __export(src_exports, {
|
|
|
274
277
|
partitionFiles: () => partitionFiles,
|
|
275
278
|
pixelsToMs: () => pixelsToMs,
|
|
276
279
|
placeSpan: () => placeSpan,
|
|
280
|
+
placesInTopLane: () => placesInTopLane,
|
|
281
|
+
proposeMove: () => proposeMove,
|
|
277
282
|
rankOverflow: () => rankOverflow,
|
|
278
283
|
relationshipNeighbors: () => relationshipNeighbors,
|
|
279
284
|
relativeTimeValue: () => relativeTimeValue,
|
|
@@ -8930,7 +8935,7 @@ function BuilderCanvas({
|
|
|
8930
8935
|
}
|
|
8931
8936
|
|
|
8932
8937
|
// src/components/SchedulingCalendar.tsx
|
|
8933
|
-
var
|
|
8938
|
+
var import_react59 = require("react");
|
|
8934
8939
|
|
|
8935
8940
|
// src/calendar-model.ts
|
|
8936
8941
|
function fromDateKey(value) {
|
|
@@ -9267,9 +9272,614 @@ function layoutMonthSpans(spans, days, options) {
|
|
|
9267
9272
|
}
|
|
9268
9273
|
return { placed, hiddenByRow, firstHiddenDayByRow };
|
|
9269
9274
|
}
|
|
9275
|
+
var MINUTE_MS = 6e4;
|
|
9276
|
+
var HOUR_MS = 36e5;
|
|
9277
|
+
var instantMs = (value) => new Date(value).getTime();
|
|
9278
|
+
var TOP_LANE_CROSS_MIDNIGHT_MINUTES = 360;
|
|
9279
|
+
function placesInTopLane(entry, timeZone, options = {}) {
|
|
9280
|
+
if (entry.allDay) return true;
|
|
9281
|
+
const start = instantMs(entry.start);
|
|
9282
|
+
const end = instantMs(entry.end);
|
|
9283
|
+
if (!(end > start)) return false;
|
|
9284
|
+
if (end > addZonedDays(new Date(start), 1, timeZone).instant.getTime()) return true;
|
|
9285
|
+
const firstMidnight = zonedDayBounds(zonedDateKey(new Date(start), timeZone), timeZone).end.getTime();
|
|
9286
|
+
return end > firstMidnight + (options.crossMidnightMinutes ?? TOP_LANE_CROSS_MIDNIGHT_MINUTES) * MINUTE_MS;
|
|
9287
|
+
}
|
|
9288
|
+
function layoutTimeGridDay(entries, date, timeZone, options = {}) {
|
|
9289
|
+
const bounds = zonedDayBounds(date, timeZone);
|
|
9290
|
+
const dayStart = bounds.start.getTime();
|
|
9291
|
+
const dayEnd = bounds.end.getTime();
|
|
9292
|
+
const parts = /* @__PURE__ */ new Map();
|
|
9293
|
+
for (const entry of entries) {
|
|
9294
|
+
const start = instantMs(entry.start);
|
|
9295
|
+
const end = Math.max(instantMs(entry.end), start);
|
|
9296
|
+
const touches = end > start ? start < dayEnd && end > dayStart : start >= dayStart && start < dayEnd;
|
|
9297
|
+
if (!touches || placesInTopLane(entry, timeZone, options)) continue;
|
|
9298
|
+
parts.set(entry.id, {
|
|
9299
|
+
start: Math.max(start, dayStart),
|
|
9300
|
+
end: Math.min(end, dayEnd),
|
|
9301
|
+
part: start < dayStart ? "continuation" : end > dayEnd ? "start" : "whole"
|
|
9302
|
+
});
|
|
9303
|
+
}
|
|
9304
|
+
const packed = packLanes([...parts].map(([id, part]) => ({ id, start: part.start, end: part.end })), options.maxLanes ?? Infinity);
|
|
9305
|
+
const segments = [];
|
|
9306
|
+
const hidden = [];
|
|
9307
|
+
for (const cluster of packed.clusters) {
|
|
9308
|
+
for (const id of cluster.ids) {
|
|
9309
|
+
const part = parts.get(id);
|
|
9310
|
+
const lane = packed.lanes[id].lane;
|
|
9311
|
+
if (lane === null) {
|
|
9312
|
+
hidden.push(id);
|
|
9313
|
+
continue;
|
|
9314
|
+
}
|
|
9315
|
+
segments.push({
|
|
9316
|
+
id,
|
|
9317
|
+
part: part.part,
|
|
9318
|
+
start: part.start,
|
|
9319
|
+
end: part.end,
|
|
9320
|
+
offsetHours: (part.start - dayStart) / HOUR_MS,
|
|
9321
|
+
lengthHours: (part.end - part.start) / HOUR_MS,
|
|
9322
|
+
lane,
|
|
9323
|
+
laneCount: Math.max(cluster.laneCount, 1)
|
|
9324
|
+
});
|
|
9325
|
+
}
|
|
9326
|
+
}
|
|
9327
|
+
return { date, dayStart, dayHours: (dayEnd - dayStart) / HOUR_MS, segments, hidden };
|
|
9328
|
+
}
|
|
9329
|
+
function layoutDaySpans(spans, days, options) {
|
|
9330
|
+
if (days.length === 0) throw new RangeError("layoutDaySpans: days is empty");
|
|
9331
|
+
const rowStart = days[0];
|
|
9332
|
+
const rowEnd = addCalendarDays(days[days.length - 1], 1);
|
|
9333
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9334
|
+
const inRow = spans.filter((span) => seen.has(span.id) ? false : (seen.add(span.id), true)).map((span) => ({ id: span.id, days: itemDaySpan(span.start, instantMs(span.end) < instantMs(span.start) ? span.start : span.end, options.timeZone) })).filter((span) => span.days.start < rowEnd && span.days.end > rowStart).map((span) => {
|
|
9335
|
+
const from = span.days.start > rowStart ? span.days.start : rowStart;
|
|
9336
|
+
const to = span.days.end < rowEnd ? span.days.end : rowEnd;
|
|
9337
|
+
return { span, from, startCol: days.indexOf(from), endCol: days.indexOf(addCalendarDays(to, -1)) };
|
|
9338
|
+
});
|
|
9339
|
+
const packed = packLanes(inRow.map(({ span, startCol, endCol }) => ({ id: span.id, start: startCol, end: endCol + 1 })), options.laneCap ?? Infinity, { order: "given" });
|
|
9340
|
+
const layout = { placed: [], hidden: [] };
|
|
9341
|
+
for (const { span, from, startCol, endCol } of inRow) {
|
|
9342
|
+
const lane = packed.lanes[span.id].lane;
|
|
9343
|
+
if (lane === null) {
|
|
9344
|
+
layout.hidden.push(span.id);
|
|
9345
|
+
if (layout.firstHiddenDay === void 0 || from < layout.firstHiddenDay) layout.firstHiddenDay = from;
|
|
9346
|
+
continue;
|
|
9347
|
+
}
|
|
9348
|
+
layout.placed.push({ id: span.id, lane, startCol, endCol, continuesBefore: span.days.start < rowStart, continuesAfter: span.days.end > rowEnd });
|
|
9349
|
+
}
|
|
9350
|
+
return layout;
|
|
9351
|
+
}
|
|
9352
|
+
function proposeMove(span, delta, timeZone) {
|
|
9353
|
+
const shift = (delta.minutes ?? 0) * MINUTE_MS;
|
|
9354
|
+
const start = new Date(instantMs(span.start) + shift);
|
|
9355
|
+
const end = new Date(instantMs(span.end) + shift);
|
|
9356
|
+
if (!delta.days) return { start: start.toISOString(), end: end.toISOString(), adjusted: null };
|
|
9357
|
+
const movedStart = addZonedDays(start, delta.days, timeZone);
|
|
9358
|
+
const movedEnd = addZonedDays(end, delta.days, timeZone);
|
|
9359
|
+
const length = end.getTime() - start.getTime();
|
|
9360
|
+
const collapsed = length > 0 && movedEnd.instant.getTime() <= movedStart.instant.getTime();
|
|
9361
|
+
const proposedEnd = collapsed ? new Date(movedStart.instant.getTime() + length) : movedEnd.instant;
|
|
9362
|
+
return { start: movedStart.instant.toISOString(), end: proposedEnd.toISOString(), adjusted: movedStart.adjusted ?? movedEnd.adjusted };
|
|
9363
|
+
}
|
|
9364
|
+
|
|
9365
|
+
// src/components/SchedulingTimeGrid.tsx
|
|
9366
|
+
var import_react58 = require("react");
|
|
9367
|
+
var import_jsx_runtime84 = require("react/jsx-runtime");
|
|
9368
|
+
var HOUR_MS2 = 36e5;
|
|
9369
|
+
var MINUTES_PER_HOUR = 60;
|
|
9370
|
+
var LINES_PER_HOUR = 3;
|
|
9371
|
+
var DRAG_THRESHOLD = 4;
|
|
9372
|
+
var DEFAULT_STEP = 15;
|
|
9373
|
+
var vars = (values) => values;
|
|
9374
|
+
var linesFor = (segment) => Math.max(0, Math.floor(segment.lengthHours * LINES_PER_HOUR - 0.25));
|
|
9375
|
+
var slotSignature = (slots) => slots.map((slot) => `${slot.label}${slot.offsetLabel ?? ""}`).join(" ");
|
|
9376
|
+
function uniqueById(items) {
|
|
9377
|
+
const seen = /* @__PURE__ */ new Set();
|
|
9378
|
+
return items.filter((item) => seen.has(item.id) ? false : (seen.add(item.id), true));
|
|
9379
|
+
}
|
|
9380
|
+
var GridItem = (0, import_react58.memo)(function GridItem2({ entry, segment, column, alone, name, status, movable, hintId, timeZone, continuesFrom, markers, renderEntry, renderMarker: renderMarker2, handlers }) {
|
|
9381
|
+
const lines = linesFor(segment);
|
|
9382
|
+
const continuation = segment.part === "continuation";
|
|
9383
|
+
const style = vars({
|
|
9384
|
+
"--uix-scheduling-calendar-offset": segment.offsetHours,
|
|
9385
|
+
"--uix-scheduling-calendar-length": segment.lengthHours,
|
|
9386
|
+
"--uix-scheduling-calendar-lane": segment.lane,
|
|
9387
|
+
"--uix-scheduling-calendar-lanes": segment.laneCount
|
|
9388
|
+
});
|
|
9389
|
+
const text = renderEntry?.(entry, { availableLines: lines }) ?? (lines > 0 ? /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9390
|
+
!continuation && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9391
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9392
|
+
" "
|
|
9393
|
+
] }),
|
|
9394
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9395
|
+
] }) : null);
|
|
9396
|
+
const body = /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9397
|
+
continuation && lines > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__tg-from", children: continuesFrom }),
|
|
9398
|
+
(!continuation || alone) && text != null && text !== false && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: text }),
|
|
9399
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: renderMarker2(marker) }, marker.id)) })
|
|
9400
|
+
] });
|
|
9401
|
+
const shared = {
|
|
9402
|
+
className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-item",
|
|
9403
|
+
"data-band": entry.band ?? "none",
|
|
9404
|
+
"data-status": status,
|
|
9405
|
+
"data-state": entry.state,
|
|
9406
|
+
"data-part": segment.part,
|
|
9407
|
+
"data-lines": Math.min(lines, 3),
|
|
9408
|
+
"data-movable": movable || void 0,
|
|
9409
|
+
style,
|
|
9410
|
+
onClick: () => handlers.click(entry),
|
|
9411
|
+
onPointerDown: movable ? (event) => handlers.pointerDown(event, entry, column, false) : void 0
|
|
9412
|
+
};
|
|
9413
|
+
if (continuation && !alone) return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { ...shared, "data-continuation-of": entry.id, "aria-hidden": "true", children: body });
|
|
9414
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
9415
|
+
"button",
|
|
9416
|
+
{
|
|
9417
|
+
type: "button",
|
|
9418
|
+
...shared,
|
|
9419
|
+
"data-item-id": entry.id,
|
|
9420
|
+
"aria-label": name,
|
|
9421
|
+
"aria-describedby": movable ? hintId : void 0,
|
|
9422
|
+
onKeyDown: movable ? (event) => handlers.keyDown(event, entry) : void 0,
|
|
9423
|
+
onBlur: movable ? () => handlers.blur(entry) : void 0,
|
|
9424
|
+
children: body
|
|
9425
|
+
}
|
|
9426
|
+
);
|
|
9427
|
+
}, (previous, next) => previous.entry === next.entry && previous.column === next.column && previous.alone === next.alone && previous.name === next.name && previous.status === next.status && previous.movable === next.movable && previous.hintId === next.hintId && previous.timeZone === next.timeZone && previous.continuesFrom === next.continuesFrom && previous.renderEntry === next.renderEntry && previous.segment.part === next.segment.part && previous.segment.offsetHours === next.segment.offsetHours && previous.segment.lengthHours === next.segment.lengthHours && previous.segment.lane === next.segment.lane && previous.segment.laneCount === next.segment.laneCount);
|
|
9428
|
+
function SchedulingTimeGrid({
|
|
9429
|
+
view,
|
|
9430
|
+
days,
|
|
9431
|
+
timeZone,
|
|
9432
|
+
entries: givenEntries,
|
|
9433
|
+
overlays: givenOverlays,
|
|
9434
|
+
dayInfo,
|
|
9435
|
+
labels,
|
|
9436
|
+
gridLabel,
|
|
9437
|
+
dateText,
|
|
9438
|
+
formatInstant,
|
|
9439
|
+
entryName,
|
|
9440
|
+
entryStatus,
|
|
9441
|
+
entryMarkers,
|
|
9442
|
+
overlayName,
|
|
9443
|
+
renderEntry,
|
|
9444
|
+
renderMarker: renderMarker2,
|
|
9445
|
+
onSelectEntry,
|
|
9446
|
+
onSelectOverlay,
|
|
9447
|
+
onSelectDate,
|
|
9448
|
+
onShowMore,
|
|
9449
|
+
now,
|
|
9450
|
+
canMove,
|
|
9451
|
+
step: givenStep,
|
|
9452
|
+
onProposeMove,
|
|
9453
|
+
topLaneCrossMidnightMinutes,
|
|
9454
|
+
topLaneCap,
|
|
9455
|
+
windowLaneCap,
|
|
9456
|
+
maxLanes,
|
|
9457
|
+
emptyNote,
|
|
9458
|
+
nothingToShow
|
|
9459
|
+
}) {
|
|
9460
|
+
const rootRef = (0, import_react58.useRef)(null);
|
|
9461
|
+
const hintId = (0, import_react58.useId)();
|
|
9462
|
+
const [widthCap, setWidthCap] = (0, import_react58.useState)(Infinity);
|
|
9463
|
+
const [ghost, setGhost] = (0, import_react58.useState)(null);
|
|
9464
|
+
const [announcement, setAnnouncement] = (0, import_react58.useState)("");
|
|
9465
|
+
const moving = canMove && onProposeMove !== void 0;
|
|
9466
|
+
const step = Number.isFinite(givenStep) && givenStep > 0 ? givenStep : DEFAULT_STEP;
|
|
9467
|
+
const laneOptions = (0, import_react58.useMemo)(() => ({ crossMidnightMinutes: topLaneCrossMidnightMinutes }), [topLaneCrossMidnightMinutes]);
|
|
9468
|
+
const entries = (0, import_react58.useMemo)(() => uniqueById(givenEntries), [givenEntries]);
|
|
9469
|
+
const overlays = (0, import_react58.useMemo)(() => uniqueById(givenOverlays), [givenOverlays]);
|
|
9470
|
+
(0, import_react58.useEffect)(() => {
|
|
9471
|
+
const root = rootRef.current;
|
|
9472
|
+
if (!root || typeof ResizeObserver === "undefined") return void 0;
|
|
9473
|
+
const column = root.querySelector("[data-tg-column]");
|
|
9474
|
+
const probe = root.querySelector(".uix-scheduling-calendar__tg-probe");
|
|
9475
|
+
if (!column || !probe) return void 0;
|
|
9476
|
+
let frame = 0;
|
|
9477
|
+
const measure = () => {
|
|
9478
|
+
frame = 0;
|
|
9479
|
+
if (!column.isConnected) return;
|
|
9480
|
+
const lane = probe.getBoundingClientRect().width;
|
|
9481
|
+
const width = column.getBoundingClientRect().width;
|
|
9482
|
+
setWidthCap(lane > 0 && width > 0 ? Math.max(1, Math.floor(width / lane)) : Infinity);
|
|
9483
|
+
};
|
|
9484
|
+
const observer = new ResizeObserver(() => {
|
|
9485
|
+
if (!frame) frame = requestAnimationFrame(measure);
|
|
9486
|
+
});
|
|
9487
|
+
observer.observe(column);
|
|
9488
|
+
measure();
|
|
9489
|
+
return () => {
|
|
9490
|
+
observer.disconnect();
|
|
9491
|
+
if (frame) cancelAnimationFrame(frame);
|
|
9492
|
+
};
|
|
9493
|
+
}, [days]);
|
|
9494
|
+
const lanes = Math.max(1, Math.min(maxLanes, widthCap));
|
|
9495
|
+
const entryById = (0, import_react58.useMemo)(() => new Map(entries.map((entry) => [entry.id, entry])), [entries]);
|
|
9496
|
+
const overlayById = (0, import_react58.useMemo)(() => new Map(overlays.map((overlay) => [overlay.id, overlay])), [overlays]);
|
|
9497
|
+
const columns = (0, import_react58.useMemo)(() => days.map((date) => layoutTimeGridDay(entries, date, timeZone, { ...laneOptions, maxLanes: lanes })), [days, entries, timeZone, laneOptions, lanes]);
|
|
9498
|
+
const slots = (0, import_react58.useMemo)(() => days.map((date) => zonedHourSlots(date, timeZone)), [days, timeZone]);
|
|
9499
|
+
const top = (0, import_react58.useMemo)(() => layoutDaySpans(entries.filter((entry) => placesInTopLane(entry, timeZone, laneOptions)), days, { timeZone, laneCap: Math.max(0, topLaneCap) }), [entries, days, timeZone, laneOptions, topLaneCap]);
|
|
9500
|
+
const drawable = (0, import_react58.useMemo)(() => overlays.filter((overlay) => new Date(overlay.end).getTime() >= new Date(overlay.start).getTime()), [overlays]);
|
|
9501
|
+
const strip = (0, import_react58.useMemo)(() => layoutDaySpans(drawable, days, { timeZone, laneCap: Math.max(0, windowLaneCap) }), [drawable, days, timeZone, windowLaneCap]);
|
|
9502
|
+
const shades = (0, import_react58.useMemo)(() => layoutDaySpans(drawable.filter((overlay) => overlay.global), days, { timeZone }).placed, [drawable, days, timeZone]);
|
|
9503
|
+
const lanesIn = (placed) => placed.reduce((max, span) => Math.max(max, span.lane + 1), 0);
|
|
9504
|
+
const maxHours = Math.max(...columns.map((column) => column.dayHours));
|
|
9505
|
+
const gutterIndex = (0, import_react58.useMemo)(() => {
|
|
9506
|
+
const signatures = slots.map(slotSignature);
|
|
9507
|
+
const count2 = /* @__PURE__ */ new Map();
|
|
9508
|
+
for (const signature of signatures) count2.set(signature, (count2.get(signature) ?? 0) + 1);
|
|
9509
|
+
let best = 0;
|
|
9510
|
+
signatures.forEach((signature, index) => {
|
|
9511
|
+
if ((count2.get(signature) ?? 0) > (count2.get(signatures[best]) ?? 0)) best = index;
|
|
9512
|
+
});
|
|
9513
|
+
return best;
|
|
9514
|
+
}, [slots]);
|
|
9515
|
+
const gutterSignature = slotSignature(slots[gutterIndex]);
|
|
9516
|
+
const hourLabels = (index, inline) => slots[index].map((slot) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
9517
|
+
"div",
|
|
9518
|
+
{
|
|
9519
|
+
className: inline ? "uix-scheduling-calendar__tg-hour uix-scheduling-calendar__tg-hour--inline" : "uix-scheduling-calendar__tg-hour",
|
|
9520
|
+
"data-hour": slot.label,
|
|
9521
|
+
style: vars({ "--uix-scheduling-calendar-offset": (slot.instant.getTime() - columns[index].dayStart) / HOUR_MS2 }),
|
|
9522
|
+
children: [
|
|
9523
|
+
slot.label,
|
|
9524
|
+
slot.offsetLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__tg-offset", children: slot.offsetLabel })
|
|
9525
|
+
]
|
|
9526
|
+
},
|
|
9527
|
+
slot.instant.getTime()
|
|
9528
|
+
));
|
|
9529
|
+
const movable = (entry) => moving && entry.movable !== false;
|
|
9530
|
+
const live = (0, import_react58.useRef)({ ghost, entryById, timeZone, step, onProposeMove, onSelectEntry, labels, formatInstant, days, columns, movable });
|
|
9531
|
+
live.current = { ghost, entryById, timeZone, step, onProposeMove, onSelectEntry, labels, formatInstant, days, columns, movable };
|
|
9532
|
+
const dragRef = (0, import_react58.useRef)(null);
|
|
9533
|
+
const suppressClick = (0, import_react58.useRef)(false);
|
|
9534
|
+
const refocus = (0, import_react58.useRef)(null);
|
|
9535
|
+
(0, import_react58.useEffect)(() => {
|
|
9536
|
+
if (ghost && !entryById.has(ghost.id)) setGhost(null);
|
|
9537
|
+
}, [ghost, entryById]);
|
|
9538
|
+
(0, import_react58.useEffect)(() => {
|
|
9539
|
+
const id = refocus.current;
|
|
9540
|
+
const root = rootRef.current;
|
|
9541
|
+
if (!id || !root) return;
|
|
9542
|
+
const active = document.activeElement;
|
|
9543
|
+
const lost = !active || active === document.body;
|
|
9544
|
+
if (!lost) {
|
|
9545
|
+
if (active.getAttribute("data-item-id") !== id) refocus.current = null;
|
|
9546
|
+
return;
|
|
9547
|
+
}
|
|
9548
|
+
for (const candidate of Array.from(root.querySelectorAll("[data-item-id]"))) {
|
|
9549
|
+
if (candidate.getAttribute("data-item-id") === id) {
|
|
9550
|
+
candidate.focus();
|
|
9551
|
+
break;
|
|
9552
|
+
}
|
|
9553
|
+
}
|
|
9554
|
+
});
|
|
9555
|
+
const send = (0, import_react58.useCallback)((id, delta) => {
|
|
9556
|
+
const state = live.current;
|
|
9557
|
+
const entry = state.entryById.get(id);
|
|
9558
|
+
if (!entry || !state.onProposeMove || !state.movable(entry) || delta.days === 0 && delta.minutes === 0) {
|
|
9559
|
+
setGhost(null);
|
|
9560
|
+
return;
|
|
9561
|
+
}
|
|
9562
|
+
const proposal = proposeMove(entry, delta, state.timeZone);
|
|
9563
|
+
const result = state.onProposeMove(id, proposal);
|
|
9564
|
+
if (result && typeof result.then === "function") {
|
|
9565
|
+
setGhost({ id, delta, source: "sent", proposal });
|
|
9566
|
+
const clear = () => setGhost((current) => current && current.source === "sent" && current.proposal === proposal ? null : current);
|
|
9567
|
+
result.then(clear, clear);
|
|
9568
|
+
} else setGhost(null);
|
|
9569
|
+
}, []);
|
|
9570
|
+
const handlers = (0, import_react58.useMemo)(() => ({
|
|
9571
|
+
click: (entry) => {
|
|
9572
|
+
live.current.onSelectEntry?.(entry);
|
|
9573
|
+
},
|
|
9574
|
+
keyDown: (event, entry) => {
|
|
9575
|
+
const state = live.current;
|
|
9576
|
+
const pending = state.ghost && state.ghost.id === entry.id && state.ghost.source === "keys" ? state.ghost.delta : null;
|
|
9577
|
+
if (event.key === "Enter" && pending) {
|
|
9578
|
+
event.preventDefault();
|
|
9579
|
+
refocus.current = entry.id;
|
|
9580
|
+
send(entry.id, pending);
|
|
9581
|
+
return;
|
|
9582
|
+
}
|
|
9583
|
+
if (event.key === "Escape" && pending) {
|
|
9584
|
+
event.preventDefault();
|
|
9585
|
+
event.stopPropagation();
|
|
9586
|
+
setGhost(null);
|
|
9587
|
+
setAnnouncement(state.labels.moveCancelled);
|
|
9588
|
+
return;
|
|
9589
|
+
}
|
|
9590
|
+
if (!event.shiftKey) return;
|
|
9591
|
+
const base = pending ?? { days: 0, minutes: 0 };
|
|
9592
|
+
const next = event.key === "ArrowUp" ? { ...base, minutes: base.minutes - state.step } : event.key === "ArrowDown" ? { ...base, minutes: base.minutes + state.step } : event.key === "ArrowLeft" ? { ...base, days: base.days - 1 } : event.key === "ArrowRight" ? { ...base, days: base.days + 1 } : null;
|
|
9593
|
+
if (!next) return;
|
|
9594
|
+
event.preventDefault();
|
|
9595
|
+
if (next.days === 0 && next.minutes === 0) {
|
|
9596
|
+
setGhost(null);
|
|
9597
|
+
setAnnouncement(state.labels.moveCancelled);
|
|
9598
|
+
return;
|
|
9599
|
+
}
|
|
9600
|
+
const proposal = proposeMove(entry, next, state.timeZone);
|
|
9601
|
+
setGhost({ id: entry.id, delta: next, source: "keys", proposal });
|
|
9602
|
+
const proposed = fillLabel(state.labels.moveProposed, { start: state.formatInstant(proposal.start), end: state.formatInstant(proposal.end) });
|
|
9603
|
+
setAnnouncement(proposal.adjusted ? `${fillLabel(state.labels.gapForward, { time: zonedTimeOfDay(proposal.start, state.timeZone) })} ${proposed}` : proposed);
|
|
9604
|
+
},
|
|
9605
|
+
blur: (entry) => {
|
|
9606
|
+
refocus.current = null;
|
|
9607
|
+
setGhost((current) => current && current.id === entry.id && current.source === "keys" ? null : current);
|
|
9608
|
+
},
|
|
9609
|
+
pointerDown: (event, entry, column, top2) => {
|
|
9610
|
+
if (event.button !== 0 || dragRef.current) return;
|
|
9611
|
+
const root = rootRef.current;
|
|
9612
|
+
if (!root) return;
|
|
9613
|
+
const elements = Array.from(root.querySelectorAll("[data-tg-column]"));
|
|
9614
|
+
const rects = elements.map((element) => element.getBoundingClientRect());
|
|
9615
|
+
const under = rects.findIndex((rect) => event.clientX >= rect.left && event.clientX < rect.right);
|
|
9616
|
+
const from = under === -1 ? column : under;
|
|
9617
|
+
const hours = live.current.columns[from]?.dayHours ?? 1;
|
|
9618
|
+
const finish = (commit) => {
|
|
9619
|
+
const drag = dragRef.current;
|
|
9620
|
+
if (!drag) return;
|
|
9621
|
+
drag.stop();
|
|
9622
|
+
dragRef.current = null;
|
|
9623
|
+
if (!drag.moved) return;
|
|
9624
|
+
suppressClick.current = true;
|
|
9625
|
+
setTimeout(() => {
|
|
9626
|
+
suppressClick.current = false;
|
|
9627
|
+
}, 0);
|
|
9628
|
+
if (commit && !drag.dropped) send(drag.id, drag.delta);
|
|
9629
|
+
else setGhost(null);
|
|
9630
|
+
};
|
|
9631
|
+
const onMove = (move) => {
|
|
9632
|
+
const drag = dragRef.current;
|
|
9633
|
+
if (!drag || move.pointerId !== drag.pointerId) return;
|
|
9634
|
+
if (move.buttons === 0 && move.pointerType === "mouse") {
|
|
9635
|
+
finish(false);
|
|
9636
|
+
return;
|
|
9637
|
+
}
|
|
9638
|
+
if (drag.dropped) return;
|
|
9639
|
+
const dx = move.clientX - drag.x;
|
|
9640
|
+
const dy = move.clientY - drag.y;
|
|
9641
|
+
if (!drag.moved && Math.hypot(dx, dy) < DRAG_THRESHOLD) return;
|
|
9642
|
+
drag.moved = true;
|
|
9643
|
+
const target = drag.rects.findIndex((rect) => move.clientX >= rect.left && move.clientX < rect.right);
|
|
9644
|
+
const stepMinutes = live.current.step;
|
|
9645
|
+
const delta = {
|
|
9646
|
+
days: target === -1 ? drag.delta.days : target - drag.column,
|
|
9647
|
+
minutes: drag.top || drag.hourPx <= 0 ? 0 : Math.round(dy / drag.hourPx * MINUTES_PER_HOUR / stepMinutes) * stepMinutes
|
|
9648
|
+
};
|
|
9649
|
+
if (delta.days === drag.delta.days && delta.minutes === drag.delta.minutes) return;
|
|
9650
|
+
drag.delta = delta;
|
|
9651
|
+
const dragged = live.current.entryById.get(drag.id);
|
|
9652
|
+
if (dragged) setGhost({ id: drag.id, delta, source: "pointer", proposal: proposeMove(dragged, delta, live.current.timeZone) });
|
|
9653
|
+
};
|
|
9654
|
+
const onUp = (up) => {
|
|
9655
|
+
if (up.pointerId === dragRef.current?.pointerId) finish(true);
|
|
9656
|
+
};
|
|
9657
|
+
const onCancel = (cancel) => {
|
|
9658
|
+
if (cancel.pointerId === dragRef.current?.pointerId) finish(false);
|
|
9659
|
+
};
|
|
9660
|
+
const onKey = (key) => {
|
|
9661
|
+
const drag = dragRef.current;
|
|
9662
|
+
if (key.key !== "Escape" || !drag?.moved || drag.dropped) return;
|
|
9663
|
+
key.preventDefault();
|
|
9664
|
+
key.stopPropagation();
|
|
9665
|
+
drag.dropped = true;
|
|
9666
|
+
setGhost(null);
|
|
9667
|
+
};
|
|
9668
|
+
window.addEventListener("pointermove", onMove);
|
|
9669
|
+
window.addEventListener("pointerup", onUp);
|
|
9670
|
+
window.addEventListener("pointercancel", onCancel);
|
|
9671
|
+
window.addEventListener("keydown", onKey, true);
|
|
9672
|
+
dragRef.current = {
|
|
9673
|
+
id: entry.id,
|
|
9674
|
+
pointerId: event.pointerId,
|
|
9675
|
+
x: event.clientX,
|
|
9676
|
+
y: event.clientY,
|
|
9677
|
+
column: from,
|
|
9678
|
+
top: top2,
|
|
9679
|
+
moved: false,
|
|
9680
|
+
dropped: false,
|
|
9681
|
+
rects,
|
|
9682
|
+
hourPx: (rects[from]?.height ?? 0) / hours,
|
|
9683
|
+
delta: { days: 0, minutes: 0 },
|
|
9684
|
+
stop: () => {
|
|
9685
|
+
window.removeEventListener("pointermove", onMove);
|
|
9686
|
+
window.removeEventListener("pointerup", onUp);
|
|
9687
|
+
window.removeEventListener("pointercancel", onCancel);
|
|
9688
|
+
window.removeEventListener("keydown", onKey, true);
|
|
9689
|
+
}
|
|
9690
|
+
};
|
|
9691
|
+
}
|
|
9692
|
+
}), [send]);
|
|
9693
|
+
(0, import_react58.useEffect)(() => () => {
|
|
9694
|
+
dragRef.current?.stop();
|
|
9695
|
+
dragRef.current = null;
|
|
9696
|
+
}, []);
|
|
9697
|
+
const gridColumns = (span) => `${span.startCol + 2} / ${span.endCol + 3}`;
|
|
9698
|
+
const nowAt = now === void 0 ? null : new Date(now).getTime();
|
|
9699
|
+
const nowColumn = nowAt === null || Number.isNaN(nowAt) ? -1 : days.indexOf(zonedDateKey(new Date(nowAt), timeZone));
|
|
9700
|
+
const topHiddenOn = (date) => top.hidden.filter((id) => {
|
|
9701
|
+
const entry = entryById.get(id);
|
|
9702
|
+
return entry ? layoutDaySpans([entry], [date], { timeZone }).placed.length > 0 : false;
|
|
9703
|
+
});
|
|
9704
|
+
const windowLanes = lanesIn(strip.placed);
|
|
9705
|
+
const topLanes = lanesIn(top.placed);
|
|
9706
|
+
const moreWindows = strip.hidden.length;
|
|
9707
|
+
const firstHiddenWindowDay = strip.firstHiddenDay ?? days[0];
|
|
9708
|
+
const ghostEntry = ghost ? entryById.get(ghost.id) : void 0;
|
|
9709
|
+
const ghostTop = ghostEntry ? placesInTopLane(ghostEntry, timeZone, laneOptions) : false;
|
|
9710
|
+
const ghostParts = ghost && ghostEntry && !ghostTop ? days.map((date) => layoutTimeGridDay([{ id: "ghost", start: ghost.proposal.start, end: ghost.proposal.end }], date, timeZone, { crossMidnightMinutes: Infinity }).segments) : null;
|
|
9711
|
+
const ghostSpan = ghost && ghostEntry && ghostTop ? layoutDaySpans([{ id: "ghost", start: ghost.proposal.start, end: ghost.proposal.end }], days, { timeZone }).placed[0] : void 0;
|
|
9712
|
+
const ghostLane = ghost ? top.placed.find((span) => span.id === ghost.id)?.lane ?? 0 : 0;
|
|
9713
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
9714
|
+
"div",
|
|
9715
|
+
{
|
|
9716
|
+
ref: rootRef,
|
|
9717
|
+
className: "uix-scheduling-calendar__timegrid",
|
|
9718
|
+
"data-view": view,
|
|
9719
|
+
role: "group",
|
|
9720
|
+
"aria-label": gridLabel,
|
|
9721
|
+
style: vars({ "--uix-scheduling-calendar-days": days.length, "--uix-scheduling-calendar-hours": maxHours }),
|
|
9722
|
+
onClickCapture: (event) => {
|
|
9723
|
+
if (suppressClick.current) {
|
|
9724
|
+
suppressClick.current = false;
|
|
9725
|
+
event.preventDefault();
|
|
9726
|
+
event.stopPropagation();
|
|
9727
|
+
}
|
|
9728
|
+
},
|
|
9729
|
+
children: [
|
|
9730
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__tg-head", children: [
|
|
9731
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__tg-zone", children: fillLabel(labels.timeZone, { timeZone }) }),
|
|
9732
|
+
days.map((date, index) => {
|
|
9733
|
+
const info = dayInfo?.[date];
|
|
9734
|
+
const hiddenIds = dayInfo ? [] : [...columns[index].hidden, ...topHiddenOn(date)];
|
|
9735
|
+
const more = info ? info.overflowCount : hiddenIds.length;
|
|
9736
|
+
const moreText = fillLabel(labels.moreSpans, { count: more });
|
|
9737
|
+
const moreName = fillLabel(labels.moreEntriesLabel, { count: more, date: dateText(date, "day") });
|
|
9738
|
+
const headName = info ? info.label ?? `${dateText(date, "day")}, ${fillLabel(labels.dayCount, { count: info.count })}` : dateText(date, "day");
|
|
9739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__tg-dayhead", role: "group", "aria-label": headName, "data-date": date, children: [
|
|
9740
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.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") }),
|
|
9741
|
+
info && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__count", "aria-hidden": "true", children: info.count }),
|
|
9742
|
+
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__markers", children: info.markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: renderMarker2(marker, true) }, marker.id)) }),
|
|
9743
|
+
more > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime84.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__ */ (0, import_jsx_runtime84.jsxs)("span", { className: "uix-scheduling-calendar__more", children: [
|
|
9744
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
9745
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
9746
|
+
] }))
|
|
9747
|
+
] }, date);
|
|
9748
|
+
})
|
|
9749
|
+
] }),
|
|
9750
|
+
(windowLanes > 0 || moreWindows > 0) && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__tg-strip", role: "group", "aria-label": labels.windows, style: vars({ "--uix-scheduling-calendar-lanes": Math.max(windowLanes, 1) }), children: [
|
|
9751
|
+
strip.placed.map((placed) => {
|
|
9752
|
+
const overlay = overlayById.get(placed.id);
|
|
9753
|
+
if (!overlay) return null;
|
|
9754
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
9755
|
+
"button",
|
|
9756
|
+
{
|
|
9757
|
+
type: "button",
|
|
9758
|
+
className: "uix-scheduling-calendar__window",
|
|
9759
|
+
"data-overlay-id": overlay.id,
|
|
9760
|
+
"data-pattern": overlay.pattern ?? "solid",
|
|
9761
|
+
"data-global": overlay.global || void 0,
|
|
9762
|
+
"data-kind": overlay.kind,
|
|
9763
|
+
"data-continues-before": placed.continuesBefore || void 0,
|
|
9764
|
+
"data-continues-after": placed.continuesAfter || void 0,
|
|
9765
|
+
style: { gridColumn: gridColumns(placed), ...vars({ "--uix-scheduling-calendar-lane": placed.lane }) },
|
|
9766
|
+
onClick: () => onSelectOverlay?.(overlay),
|
|
9767
|
+
"aria-label": overlayName(overlay),
|
|
9768
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("span", { className: "uix-scheduling-calendar__window-text", children: [
|
|
9769
|
+
overlay.kindLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-kind", children: overlay.kindLabel }),
|
|
9770
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-name", children: overlay.label }),
|
|
9771
|
+
overlay.scopeLabel && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__window-scope", children: overlay.scopeLabel })
|
|
9772
|
+
] })
|
|
9773
|
+
},
|
|
9774
|
+
placed.id
|
|
9775
|
+
);
|
|
9776
|
+
}),
|
|
9777
|
+
moreWindows > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime84.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__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__rowmore", children: fillLabel(labels.moreWindows, { count: moreWindows }) }))
|
|
9778
|
+
] }),
|
|
9779
|
+
(topLanes > 0 || ghostSpan) && /* @__PURE__ */ (0, import_jsx_runtime84.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: [
|
|
9780
|
+
top.placed.map((placed) => {
|
|
9781
|
+
const entry = entryById.get(placed.id);
|
|
9782
|
+
if (!entry) return null;
|
|
9783
|
+
const canDrag = movable(entry);
|
|
9784
|
+
const markers = entryMarkers(entry);
|
|
9785
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(
|
|
9786
|
+
"button",
|
|
9787
|
+
{
|
|
9788
|
+
type: "button",
|
|
9789
|
+
className: "uix-scheduling-calendar__entry uix-scheduling-calendar__tg-span",
|
|
9790
|
+
"data-item-id": entry.id,
|
|
9791
|
+
"data-band": entry.band ?? "none",
|
|
9792
|
+
"data-status": entryStatus(entry),
|
|
9793
|
+
"data-state": entry.state,
|
|
9794
|
+
"data-movable": canDrag || void 0,
|
|
9795
|
+
"data-continues-before": placed.continuesBefore || void 0,
|
|
9796
|
+
"data-continues-after": placed.continuesAfter || void 0,
|
|
9797
|
+
style: { gridColumn: gridColumns(placed), ...vars({ "--uix-scheduling-calendar-lane": placed.lane }) },
|
|
9798
|
+
"aria-label": entryName(entry),
|
|
9799
|
+
"aria-describedby": canDrag ? hintId : void 0,
|
|
9800
|
+
onClick: () => handlers.click(entry),
|
|
9801
|
+
onKeyDown: canDrag ? (event) => handlers.keyDown(event, entry) : void 0,
|
|
9802
|
+
onBlur: canDrag ? () => handlers.blur(entry) : void 0,
|
|
9803
|
+
onPointerDown: canDrag ? (event) => handlers.pointerDown(event, entry, placed.startCol, true) : void 0,
|
|
9804
|
+
children: [
|
|
9805
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: renderEntry?.(entry, { availableLines: 1 }) ?? /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9806
|
+
!placed.continuesBefore && !entry.allDay && /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)(import_jsx_runtime84.Fragment, { children: [
|
|
9807
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9808
|
+
" "
|
|
9809
|
+
] }),
|
|
9810
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9811
|
+
] }) }),
|
|
9812
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { children: renderMarker2(marker) }, marker.id)) })
|
|
9813
|
+
]
|
|
9814
|
+
},
|
|
9815
|
+
placed.id
|
|
9816
|
+
);
|
|
9817
|
+
}),
|
|
9818
|
+
ghostSpan && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__tg-ghost", "aria-hidden": "true", "data-sent": ghost?.source === "sent" || void 0, style: { gridColumn: gridColumns(ghostSpan), ...vars({ "--uix-scheduling-calendar-lane": ghostLane }) } })
|
|
9819
|
+
] }),
|
|
9820
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__tg-body", children: [
|
|
9821
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__tg-gutter", "aria-hidden": "true", children: hourLabels(gutterIndex, false) }),
|
|
9822
|
+
shades.map((placed) => {
|
|
9823
|
+
const overlay = overlayById.get(placed.id);
|
|
9824
|
+
const first = columns[placed.startCol];
|
|
9825
|
+
const last = columns[placed.endCol];
|
|
9826
|
+
const from = placed.continuesBefore ? 0 : Math.max(0, (new Date(overlay.start).getTime() - first.dayStart) / HOUR_MS2) / maxHours;
|
|
9827
|
+
const to = (placed.continuesAfter ? last.dayHours : Math.min(last.dayHours, (new Date(overlay.end).getTime() - last.dayStart) / HOUR_MS2)) / maxHours;
|
|
9828
|
+
const width = 100 / (placed.endCol - placed.startCol + 1);
|
|
9829
|
+
const percent = (value) => `${Math.round(value * 1e4) / 100}%`;
|
|
9830
|
+
const clipPath = placed.startCol === placed.endCol ? `polygon(0 ${percent(from)}, 100% ${percent(from)}, 100% ${percent(to)}, 0 ${percent(to)})` : `polygon(0 ${percent(from)}, ${width}% ${percent(from)}, ${width}% 0, 100% 0, 100% ${percent(to)}, ${100 - width}% ${percent(to)}, ${100 - width}% 100%, 0 100%)`;
|
|
9831
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__tg-shade", "aria-hidden": "true", "data-pattern": overlay.pattern ?? "solid", style: { gridColumn: gridColumns(placed), clipPath } }, `shade-${placed.id}`);
|
|
9832
|
+
}),
|
|
9833
|
+
columns.map((column, index) => /* @__PURE__ */ (0, import_jsx_runtime84.jsxs)("div", { className: "uix-scheduling-calendar__tg-column", "data-tg-column": column.date, style: { gridColumn: `${index + 2}`, ...vars({ "--uix-scheduling-calendar-hours": column.dayHours }) }, children: [
|
|
9834
|
+
slotSignature(slots[index]) !== gutterSignature && hourLabels(index, true),
|
|
9835
|
+
column.segments.map((segment) => {
|
|
9836
|
+
const entry = entryById.get(segment.id);
|
|
9837
|
+
const alone = segment.part === "continuation" && index === 0;
|
|
9838
|
+
return /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
9839
|
+
GridItem,
|
|
9840
|
+
{
|
|
9841
|
+
entry,
|
|
9842
|
+
segment,
|
|
9843
|
+
column: index,
|
|
9844
|
+
alone,
|
|
9845
|
+
name: entryName(entry),
|
|
9846
|
+
status: entryStatus(entry),
|
|
9847
|
+
movable: movable(entry),
|
|
9848
|
+
hintId,
|
|
9849
|
+
timeZone,
|
|
9850
|
+
continuesFrom: fillLabel(labels.continuesFrom, { time: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9851
|
+
markers: entryMarkers(entry),
|
|
9852
|
+
renderEntry,
|
|
9853
|
+
renderMarker: renderMarker2,
|
|
9854
|
+
handlers
|
|
9855
|
+
},
|
|
9856
|
+
`${segment.id}-${segment.part}`
|
|
9857
|
+
);
|
|
9858
|
+
}),
|
|
9859
|
+
ghostParts?.[index].map((segment) => /* @__PURE__ */ (0, import_jsx_runtime84.jsx)(
|
|
9860
|
+
"div",
|
|
9861
|
+
{
|
|
9862
|
+
className: "uix-scheduling-calendar__tg-ghost",
|
|
9863
|
+
"aria-hidden": "true",
|
|
9864
|
+
"data-sent": ghost?.source === "sent" || void 0,
|
|
9865
|
+
style: vars({ "--uix-scheduling-calendar-offset": segment.offsetHours, "--uix-scheduling-calendar-length": segment.lengthHours })
|
|
9866
|
+
},
|
|
9867
|
+
`ghost-${segment.part}`
|
|
9868
|
+
)),
|
|
9869
|
+
index === nowColumn && nowAt !== null && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__tg-now", "aria-hidden": "true", style: vars({ "--uix-scheduling-calendar-offset": (nowAt - column.dayStart) / HOUR_MS2 }) })
|
|
9870
|
+
] }, column.date))
|
|
9871
|
+
] }),
|
|
9872
|
+
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-scheduling-calendar__empty", children: emptyNote }),
|
|
9873
|
+
moving && /* @__PURE__ */ (0, import_jsx_runtime84.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.moveHint }),
|
|
9874
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("span", { className: "uix-scheduling-calendar__tg-probe", "aria-hidden": "true", children: "00:00 abcdef" }),
|
|
9875
|
+
/* @__PURE__ */ (0, import_jsx_runtime84.jsx)("div", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
9876
|
+
]
|
|
9877
|
+
}
|
|
9878
|
+
);
|
|
9879
|
+
}
|
|
9270
9880
|
|
|
9271
9881
|
// src/components/SchedulingCalendar.tsx
|
|
9272
|
-
var
|
|
9882
|
+
var import_jsx_runtime85 = require("react/jsx-runtime");
|
|
9273
9883
|
var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
9274
9884
|
region: "Scheduling calendar in {timeZone}",
|
|
9275
9885
|
previous: "Previous",
|
|
@@ -9278,9 +9888,12 @@ var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
|
9278
9888
|
nextMonth: "Next month",
|
|
9279
9889
|
previousWeek: "Previous week",
|
|
9280
9890
|
nextWeek: "Next week",
|
|
9891
|
+
previousDay: "Previous day",
|
|
9892
|
+
nextDay: "Next day",
|
|
9281
9893
|
viewGroup: "Calendar view",
|
|
9282
9894
|
viewMonth: "Month",
|
|
9283
9895
|
viewWeek: "Week",
|
|
9896
|
+
viewDay: "Day",
|
|
9284
9897
|
viewAgenda: "Agenda",
|
|
9285
9898
|
loading: "Loading schedule\u2026",
|
|
9286
9899
|
retry: "Try again",
|
|
@@ -9297,14 +9910,25 @@ var DEFAULT_SCHEDULING_CALENDAR_LABELS = {
|
|
|
9297
9910
|
moreSpansLabel: "{count} more spanning this week, from {date}",
|
|
9298
9911
|
dayCount: "{count} entries",
|
|
9299
9912
|
states: { scheduled: "Scheduled", conflicted: "Conflicted", "in-progress": "In progress", "blackout-violation": "Blackout violation" },
|
|
9300
|
-
statuses: { tentative: "Tentative", committed: "Scheduled", live: "In progress", done: "Done", dead: "Cancelled" }
|
|
9913
|
+
statuses: { tentative: "Tentative", committed: "Scheduled", live: "In progress", done: "Done", dead: "Cancelled" },
|
|
9914
|
+
timeZone: "{timeZone}",
|
|
9915
|
+
windows: "Windows",
|
|
9916
|
+
moreWindows: "+{count} windows",
|
|
9917
|
+
moreWindowsLabel: "{count} more windows, from {date}",
|
|
9918
|
+
topLane: "All-day and longer entries",
|
|
9919
|
+
continuesFrom: "from {time}",
|
|
9920
|
+
moveHint: "Hold Shift and press an arrow key to move it. Enter confirms, Escape cancels.",
|
|
9921
|
+
moveProposed: "Move to {start} \u2013 {end}. Enter confirms, Escape cancels.",
|
|
9922
|
+
moveCancelled: "Move cancelled.",
|
|
9923
|
+
gapForward: "That time does not exist on this day. Moved forward to {time}."
|
|
9301
9924
|
};
|
|
9302
9925
|
var stateTone = (state) => state === "scheduled" ? "info" : state === "in-progress" ? "success" : "danger";
|
|
9303
9926
|
var utcDate = (date) => /* @__PURE__ */ new Date(`${date}T00:00:00Z`);
|
|
9304
9927
|
var INTL_PARTS = {
|
|
9305
9928
|
day: { dateStyle: "full", timeZone: "UTC" },
|
|
9306
9929
|
weekday: { weekday: "short", timeZone: "UTC" },
|
|
9307
|
-
month: { month: "long", year: "numeric", timeZone: "UTC" }
|
|
9930
|
+
month: { month: "long", year: "numeric", timeZone: "UTC" },
|
|
9931
|
+
column: { weekday: "short", day: "2-digit", month: "2-digit", timeZone: "UTC" }
|
|
9308
9932
|
};
|
|
9309
9933
|
var EMPTY_OVERLAYS = [];
|
|
9310
9934
|
var EMPTY_ENTRIES = [];
|
|
@@ -9317,13 +9941,14 @@ function coveredDays(start, end, timeZone) {
|
|
|
9317
9941
|
return itemDaySpan(start, start, timeZone);
|
|
9318
9942
|
}
|
|
9319
9943
|
}
|
|
9320
|
-
function Marker({ marker }) {
|
|
9944
|
+
function Marker({ marker, showLabel }) {
|
|
9321
9945
|
const emphasis = marker.emphasis ?? "neutral";
|
|
9322
|
-
return /* @__PURE__ */ (0,
|
|
9323
|
-
marker.icon != null && /* @__PURE__ */ (0,
|
|
9324
|
-
/* @__PURE__ */ (0,
|
|
9946
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__marker", "data-emphasis": emphasis, "data-glyph": marker.icon == null ? emphasis : void 0, children: [
|
|
9947
|
+
marker.icon != null && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__marker-icon", "aria-hidden": "true", children: marker.icon }),
|
|
9948
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: showLabel ? "uix-scheduling-calendar__marker-label" : "uix-visually-hidden", children: marker.label })
|
|
9325
9949
|
] });
|
|
9326
9950
|
}
|
|
9951
|
+
var renderMarker = (marker, showLabel) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Marker, { marker, showLabel });
|
|
9327
9952
|
function SchedulingCalendar({
|
|
9328
9953
|
entries,
|
|
9329
9954
|
anchorDate,
|
|
@@ -9354,6 +9979,14 @@ function SchedulingCalendar({
|
|
|
9354
9979
|
notice,
|
|
9355
9980
|
emptyNote,
|
|
9356
9981
|
onSelectDate,
|
|
9982
|
+
timeGrid = false,
|
|
9983
|
+
now,
|
|
9984
|
+
canMove = false,
|
|
9985
|
+
step = 15,
|
|
9986
|
+
onProposeMove,
|
|
9987
|
+
topLaneCrossMidnightMinutes = TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
9988
|
+
topLaneCap = 3,
|
|
9989
|
+
maxLanes = 4,
|
|
9357
9990
|
loading,
|
|
9358
9991
|
error,
|
|
9359
9992
|
onRetry,
|
|
@@ -9369,26 +10002,27 @@ function SchedulingCalendar({
|
|
|
9369
10002
|
statuses: { ...DEFAULT_SCHEDULING_CALENDAR_LABELS.statuses, ...uixLabels.schedulingCalendar?.statuses, ...labelOverrides?.statuses }
|
|
9370
10003
|
};
|
|
9371
10004
|
const stateLabel = labels.states;
|
|
9372
|
-
const viewLabel = { month: labels.viewMonth, week: labels.viewWeek, agenda: labels.viewAgenda };
|
|
9373
|
-
const [internalView, setInternalView] = (0,
|
|
10005
|
+
const viewLabel = { month: labels.viewMonth, week: labels.viewWeek, day: labels.viewDay, agenda: labels.viewAgenda };
|
|
10006
|
+
const [internalView, setInternalView] = (0, import_react59.useState)("month");
|
|
9374
10007
|
const view = controlledView ?? internalView;
|
|
9375
|
-
const [activeDate, setActiveDate] = (0,
|
|
9376
|
-
const [expandedDates, setExpandedDates] = (0,
|
|
10008
|
+
const [activeDate, setActiveDate] = (0, import_react59.useState)(anchorDate);
|
|
10009
|
+
const [expandedDates, setExpandedDates] = (0, import_react59.useState)(() => /* @__PURE__ */ new Set());
|
|
9377
10010
|
const dateText = (date, part) => formatDate?.(date, part) ?? cachedDateTimeFormat(locale, INTL_PARTS[part]).format(utcDate(date));
|
|
9378
10011
|
const formatInstant = (instant) => formatInstantProp?.(instant) ?? `${dateText(zonedDateKey(instant, timeZone), "day")} ${zonedTimeOfDay(instant, timeZone)}`;
|
|
9379
|
-
const gridRef = (0,
|
|
10012
|
+
const gridRef = (0, import_react59.useRef)(null);
|
|
9380
10013
|
const picksGiven = dayEntries !== void 0;
|
|
9381
10014
|
const controlled = picksGiven || dayInfo !== void 0;
|
|
9382
10015
|
const fixed = controlled || maxEntriesPerDay !== void 0 && onShowMore !== void 0;
|
|
9383
10016
|
const windowCap = Math.max(0, windowLaneCap ?? (fixed ? DEFAULT_LANE_CAP2 : Infinity));
|
|
9384
10017
|
const spanCap = Math.max(0, spanLaneCap ?? (fixed ? DEFAULT_LANE_CAP2 : Infinity));
|
|
9385
|
-
const visibleEntries = (0,
|
|
9386
|
-
const monthDays = (0,
|
|
10018
|
+
const visibleEntries = (0, import_react59.useMemo)(() => entries.filter((entry) => filter?.(entry) ?? true), [entries, filter]);
|
|
10019
|
+
const monthDays = (0, import_react59.useMemo)(() => buildMonthGrid(startOfMonth(anchorDate), weekStartsOn), [anchorDate, weekStartsOn]);
|
|
9387
10020
|
const weekday = (utcDate(anchorDate).getUTCDay() - weekStartsOn + 7) % 7;
|
|
9388
10021
|
const weekStart = addCalendarDays(anchorDate, -weekday);
|
|
9389
|
-
const weekDays = (0,
|
|
9390
|
-
const days = (0,
|
|
9391
|
-
const
|
|
10022
|
+
const weekDays = (0, import_react59.useMemo)(() => Array.from({ length: 7 }, (_, index) => addCalendarDays(weekStart, index)), [weekStart]);
|
|
10023
|
+
const days = (0, import_react59.useMemo)(() => view === "month" ? monthDays.map((day) => day.date) : view === "day" ? [anchorDate] : weekDays, [view, monthDays, weekDays, anchorDate]);
|
|
10024
|
+
const timeGridView = view === "day" || view === "week" && timeGrid;
|
|
10025
|
+
const { singles, multiDay, coverage } = (0, import_react59.useMemo)(() => {
|
|
9392
10026
|
const byDay = /* @__PURE__ */ new Map();
|
|
9393
10027
|
const spans = [];
|
|
9394
10028
|
const every = [];
|
|
@@ -9403,11 +10037,11 @@ function SchedulingCalendar({
|
|
|
9403
10037
|
}
|
|
9404
10038
|
return { singles: byDay, multiDay: spans, coverage: every };
|
|
9405
10039
|
}, [visibleEntries, timeZone]);
|
|
9406
|
-
const entryById = (0,
|
|
9407
|
-
const overlayById = (0,
|
|
9408
|
-
const layout = (0,
|
|
10040
|
+
const entryById = (0, import_react59.useMemo)(() => new Map([...multiDay].reverse().map(({ entry }) => [entry.id, entry])), [multiDay]);
|
|
10041
|
+
const overlayById = (0, import_react59.useMemo)(() => new Map([...overlays].reverse().map((overlay) => [overlay.id, overlay])), [overlays]);
|
|
10042
|
+
const layout = (0, import_react59.useMemo)(() => {
|
|
9409
10043
|
if (spanLayout) return spanLayout;
|
|
9410
|
-
if (view === "agenda") return { placed: [], hiddenByRow: {}, firstHiddenDayByRow: {} };
|
|
10044
|
+
if (view === "agenda" || timeGridView) return { placed: [], hiddenByRow: {}, firstHiddenDayByRow: {} };
|
|
9411
10045
|
const inputs = [];
|
|
9412
10046
|
const windowIds = /* @__PURE__ */ new Set();
|
|
9413
10047
|
const itemIds = /* @__PURE__ */ new Set();
|
|
@@ -9422,8 +10056,8 @@ function SchedulingCalendar({
|
|
|
9422
10056
|
inputs.push({ id: entry.id, start: entry.start, end: entry.end, group: "item" });
|
|
9423
10057
|
}
|
|
9424
10058
|
return layoutMonthSpans(inputs, days, { timeZone, laneCap: { window: windowCap, item: spanCap } });
|
|
9425
|
-
}, [spanLayout, view, overlays, multiDay, days, timeZone, windowCap, spanCap]);
|
|
9426
|
-
const placedByRow = (0,
|
|
10059
|
+
}, [spanLayout, view, timeGridView, overlays, multiDay, days, timeZone, windowCap, spanCap]);
|
|
10060
|
+
const placedByRow = (0, import_react59.useMemo)(() => {
|
|
9427
10061
|
const rows = /* @__PURE__ */ new Map();
|
|
9428
10062
|
for (const placed of layout.placed) {
|
|
9429
10063
|
const row = rows.get(placed.weekRow);
|
|
@@ -9434,16 +10068,16 @@ function SchedulingCalendar({
|
|
|
9434
10068
|
}, [layout]);
|
|
9435
10069
|
const lanesUsed = (row, group) => (placedByRow.get(row) ?? []).reduce((max, placed) => placed.group === group ? Math.max(max, placed.lane + 1) : max, 0);
|
|
9436
10070
|
const lanesUsedAnywhere = (group) => layout.placed.reduce((max, placed) => placed.group === group ? Math.max(max, placed.lane + 1) : max, 0);
|
|
9437
|
-
(0,
|
|
10071
|
+
(0, import_react59.useEffect)(() => {
|
|
9438
10072
|
if (view !== "agenda" && !days.includes(activeDate)) setActiveDate(days[0]);
|
|
9439
10073
|
}, [activeDate, days, view]);
|
|
9440
10074
|
const setView = (next) => {
|
|
9441
10075
|
if (controlledView === void 0) setInternalView(next);
|
|
9442
10076
|
onViewChange?.(next);
|
|
9443
10077
|
};
|
|
9444
|
-
const movePeriod = (direction) => onAnchorDateChange?.(view === "month" ? addCalendarMonths(anchorDate, direction) : addCalendarDays(anchorDate, direction * 7));
|
|
10078
|
+
const movePeriod = (direction) => onAnchorDateChange?.(view === "month" ? addCalendarMonths(anchorDate, direction) : addCalendarDays(anchorDate, view === "day" ? direction : direction * 7));
|
|
9445
10079
|
const periodLabel = (direction) => {
|
|
9446
|
-
const key = `${direction}${view === "month" ? "Month" : "Week"}`;
|
|
10080
|
+
const key = `${direction}${view === "month" ? "Month" : view === "day" ? "Day" : "Week"}`;
|
|
9447
10081
|
return overrides[key] ?? overrides[direction] ?? labels[key];
|
|
9448
10082
|
};
|
|
9449
10083
|
const focusDate = (date) => {
|
|
@@ -9495,15 +10129,15 @@ function SchedulingCalendar({
|
|
|
9495
10129
|
});
|
|
9496
10130
|
const entryContent = (entry, withTime = true) => {
|
|
9497
10131
|
const markers = markersOf(entry);
|
|
9498
|
-
return /* @__PURE__ */ (0,
|
|
9499
|
-
/* @__PURE__ */ (0,
|
|
9500
|
-
withTime && /* @__PURE__ */ (0,
|
|
9501
|
-
/* @__PURE__ */ (0,
|
|
10132
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
10133
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__entry-text", children: renderEntry?.(entry) ?? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
10134
|
+
withTime && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)(import_jsx_runtime85.Fragment, { children: [
|
|
10135
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__time", children: zonedTimeOfDay(entry.start, timeZone) }),
|
|
9502
10136
|
" "
|
|
9503
10137
|
] }),
|
|
9504
|
-
/* @__PURE__ */ (0,
|
|
10138
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__title", children: entry.title })
|
|
9505
10139
|
] }) }),
|
|
9506
|
-
markers.length > 0 && /* @__PURE__ */ (0,
|
|
10140
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Marker, { marker }, marker.id)) })
|
|
9507
10141
|
] });
|
|
9508
10142
|
};
|
|
9509
10143
|
const laneStyle = (placed, windowLanes) => ({
|
|
@@ -9522,25 +10156,25 @@ function SchedulingCalendar({
|
|
|
9522
10156
|
const onDay = picksGiven ? all : entriesOn(date);
|
|
9523
10157
|
const badge = renderDayBadge?.(date, onDay);
|
|
9524
10158
|
const hasBadge = badge != null && badge !== false;
|
|
9525
|
-
const dateButton = /* @__PURE__ */ (0,
|
|
10159
|
+
const dateButton = /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, tabIndex: activeDate === date ? 0 : -1, onFocus: () => setActiveDate(date), onKeyDown: (event) => onDayKeyDown(event, date), onClick: onSelectDate ? () => onSelectDate(date) : void 0, "aria-label": dateText(date, "day"), children: Number(date.slice(-2)) });
|
|
9526
10160
|
const moreText = fillLabel(labels.moreEntries, { count: hiddenCount });
|
|
9527
10161
|
const moreName = fillLabel(labels.moreEntriesLabel, { count: hiddenCount, date: dateText(date, "day") });
|
|
9528
|
-
return /* @__PURE__ */ (0,
|
|
9529
|
-
hasBadge || info ? /* @__PURE__ */ (0,
|
|
9530
|
-
hasBadge && /* @__PURE__ */ (0,
|
|
9531
|
-
info && /* @__PURE__ */ (0,
|
|
9532
|
-
/* @__PURE__ */ (0,
|
|
9533
|
-
/* @__PURE__ */ (0,
|
|
10162
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__day", "data-outside": view === "month" && !monthDays[index].inMonth || void 0, children: [
|
|
10163
|
+
hasBadge || info ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__dayhead", children: [
|
|
10164
|
+
hasBadge && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__badge", children: badge }),
|
|
10165
|
+
info && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__count", children: [
|
|
10166
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { "aria-hidden": "true", children: info.count }),
|
|
10167
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-visually-hidden", children: info.label ?? fillLabel(labels.dayCount, { count: info.count }) })
|
|
9534
10168
|
] }),
|
|
9535
|
-
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0,
|
|
10169
|
+
info?.markers && info.markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: info.markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Marker, { marker }, marker.id)) }),
|
|
9536
10170
|
dateButton
|
|
9537
10171
|
] }) : dateButton,
|
|
9538
|
-
/* @__PURE__ */ (0,
|
|
9539
|
-
shown.map((entry) => /* @__PURE__ */ (0,
|
|
9540
|
-
controlled ? hiddenCount > 0 && (onShowMore ? /* @__PURE__ */ (0,
|
|
9541
|
-
/* @__PURE__ */ (0,
|
|
9542
|
-
/* @__PURE__ */ (0,
|
|
9543
|
-
] })) : overflowing && /* @__PURE__ */ (0,
|
|
10172
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__entries", children: [
|
|
10173
|
+
shown.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { className: "uix-scheduling-calendar__entry", ...entryProps(entry), children: entryContent(entry) }, entry.id)),
|
|
10174
|
+
controlled ? hiddenCount > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-label": moreName, onClick: () => onShowMore(date, onDay), children: moreText }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__more", children: [
|
|
10175
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
10176
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
10177
|
+
] })) : overflowing && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__more", "aria-expanded": onShowMore ? void 0 : !collapsed, "aria-label": collapsed ? moreName : void 0, onClick: () => toggleMore(date, onDay), children: collapsed ? moreText : labels.fewerEntries })
|
|
9544
10178
|
] })
|
|
9545
10179
|
] }, date);
|
|
9546
10180
|
};
|
|
@@ -9553,26 +10187,26 @@ function SchedulingCalendar({
|
|
|
9553
10187
|
const moreText = fillLabel(labels.moreSpans, { count: hidden });
|
|
9554
10188
|
const moreName = fillLabel(labels.moreSpansLabel, { count: hidden, date: dateText(firstHiddenDay, "day") });
|
|
9555
10189
|
const style = { ["--uix-scheduling-calendar-lanes"]: Math.max(windowLanes + spanLanes, hidden > 0 ? 1 : 0) };
|
|
9556
|
-
return /* @__PURE__ */ (0,
|
|
10190
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__week", style, children: [
|
|
9557
10191
|
rowDays.map((date, column) => renderDay(date, row * 7 + column)),
|
|
9558
10192
|
(placedByRow.get(row) ?? []).map((placed) => {
|
|
9559
10193
|
const continues = { "data-continues-before": placed.continuesBefore || void 0, "data-continues-after": placed.continuesAfter || void 0 };
|
|
9560
10194
|
if (placed.group === "window") {
|
|
9561
10195
|
const overlay = overlayById.get(placed.id);
|
|
9562
10196
|
if (!overlay) return null;
|
|
9563
|
-
return /* @__PURE__ */ (0,
|
|
9564
|
-
overlay.kindLabel && /* @__PURE__ */ (0,
|
|
9565
|
-
/* @__PURE__ */ (0,
|
|
9566
|
-
overlay.scopeLabel && /* @__PURE__ */ (0,
|
|
10197
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__window", "data-overlay-id": overlay.id, "data-pattern": overlay.pattern ?? "solid", "data-global": overlay.global || void 0, "data-kind": overlay.kind, ...continues, style: laneStyle(placed, windowLanes), onClick: () => onSelectOverlay?.(overlay), "aria-label": overlayName(overlay), children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__window-text", children: [
|
|
10198
|
+
overlay.kindLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-kind", children: overlay.kindLabel }),
|
|
10199
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-name", children: overlay.label }),
|
|
10200
|
+
overlay.scopeLabel && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__window-scope", children: overlay.scopeLabel })
|
|
9567
10201
|
] }) }, `window-${placed.id}`);
|
|
9568
10202
|
}
|
|
9569
10203
|
const entry = entryById.get(placed.id);
|
|
9570
10204
|
if (!entry) return null;
|
|
9571
|
-
return /* @__PURE__ */ (0,
|
|
10205
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { className: "uix-scheduling-calendar__entry uix-scheduling-calendar__span", ...entryProps(entry), ...continues, style: laneStyle(placed, windowLanes), children: entryContent(entry, !placed.continuesBefore) }, `span-${placed.id}`);
|
|
9572
10206
|
}),
|
|
9573
|
-
hidden > 0 && (onShowMore ? /* @__PURE__ */ (0,
|
|
9574
|
-
/* @__PURE__ */ (0,
|
|
9575
|
-
/* @__PURE__ */ (0,
|
|
10207
|
+
hidden > 0 && (onShowMore ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-scheduling-calendar__rowmore", "aria-label": moreName, onClick: () => onShowMore(firstHiddenDay, picksGiven ? dayEntries[firstHiddenDay] ?? EMPTY_ENTRIES : entriesOn(firstHiddenDay)), children: moreText }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { className: "uix-scheduling-calendar__rowmore", children: [
|
|
10208
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { "aria-hidden": "true", children: moreText }),
|
|
10209
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-visually-hidden", children: moreName })
|
|
9576
10210
|
] }))
|
|
9577
10211
|
] }, rowDays[0]);
|
|
9578
10212
|
};
|
|
@@ -9583,54 +10217,88 @@ function SchedulingCalendar({
|
|
|
9583
10217
|
Object.keys(layout.hiddenByRow ?? {}).length > 0 ? 1 : 0
|
|
9584
10218
|
)
|
|
9585
10219
|
} : void 0;
|
|
9586
|
-
return /* @__PURE__ */ (0,
|
|
9587
|
-
showHeader && /* @__PURE__ */ (0,
|
|
9588
|
-
/* @__PURE__ */ (0,
|
|
9589
|
-
/* @__PURE__ */ (0,
|
|
9590
|
-
/* @__PURE__ */ (0,
|
|
10220
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("section", { className: cx("uix-scheduling-calendar", className), "aria-label": fillLabel(labels.region, { timeZone }), children: [
|
|
10221
|
+
showHeader && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__header", children: [
|
|
10222
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { children: [
|
|
10223
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(-1), disabled: !onAnchorDateChange, children: periodLabel("previous") }),
|
|
10224
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(1), disabled: !onAnchorDateChange, children: periodLabel("next") })
|
|
9591
10225
|
] }),
|
|
9592
|
-
/* @__PURE__ */ (0,
|
|
9593
|
-
/* @__PURE__ */ (0,
|
|
10226
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: view === "month" ? dateText(startOfMonth(anchorDate), "month") : view === "day" ? dateText(anchorDate, "day") : `${dateText(weekStart, "day")} \u2013 ${dateText(weekDays[weekDays.length - 1], "day")}` }),
|
|
10227
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-segmented", role: "group", "aria-label": labels.viewGroup, children: (timeGrid || view === "day" ? ["month", "week", "day", "agenda"] : ["month", "week", "agenda"]).map((option) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-segmented__option", "aria-pressed": view === option, "data-selected": view === option || void 0, onClick: () => setView(option), children: viewLabel[option] }, option)) })
|
|
9594
10228
|
] }),
|
|
9595
|
-
notice != null && notice !== false && /* @__PURE__ */ (0,
|
|
9596
|
-
loading ? /* @__PURE__ */ (0,
|
|
9597
|
-
/* @__PURE__ */ (0,
|
|
9598
|
-
onRetry && /* @__PURE__ */ (0,
|
|
9599
|
-
] }) : view === "agenda" ? /* @__PURE__ */ (0,
|
|
10229
|
+
notice != null && notice !== false && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__notice", children: notice }),
|
|
10230
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__state", role: "status", children: labels.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__state", role: "alert", children: [
|
|
10231
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { children: error }),
|
|
10232
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
10233
|
+
] }) : view === "agenda" ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": labels.agenda, children: visibleEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { children: labels.agendaEmpty }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("ol", { children: [...visibleEntries].sort((a, b) => a.start.localeCompare(b.start)).map((entry) => {
|
|
9600
10234
|
const markers = markersOf(entry);
|
|
9601
|
-
return /* @__PURE__ */ (0,
|
|
9602
|
-
/* @__PURE__ */ (0,
|
|
9603
|
-
/* @__PURE__ */ (0,
|
|
9604
|
-
/* @__PURE__ */ (0,
|
|
10235
|
+
return /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("button", { type: "button", "data-item-id": entry.id, "data-band": entry.band ?? "none", "data-status": statusOf(entry), "data-state": entry.state, onClick: () => onSelectEntry?.(entry), children: [
|
|
10236
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
|
|
10237
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("strong", { children: renderEntry?.(entry) ?? entry.title }),
|
|
10238
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("span", { children: [
|
|
9605
10239
|
formatInstant(entry.start),
|
|
9606
10240
|
" \u2013 ",
|
|
9607
10241
|
formatInstant(entry.end)
|
|
9608
10242
|
] }),
|
|
9609
|
-
entry.meta && /* @__PURE__ */ (0,
|
|
10243
|
+
entry.meta && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { children: entry.meta })
|
|
9610
10244
|
] }),
|
|
9611
|
-
markers.length > 0 && /* @__PURE__ */ (0,
|
|
9612
|
-
entry.state ? /* @__PURE__ */ (0,
|
|
10245
|
+
markers.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__markers", children: markers.map((marker) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(Marker, { marker }, marker.id)) }),
|
|
10246
|
+
entry.state ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(StatusPill, { tone: stateTone(entry.state), children: stateLabel[entry.state] }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__status", children: stateText(entry) })
|
|
9613
10247
|
] }) }, entry.id);
|
|
9614
|
-
}) }) }) : /* @__PURE__ */ (0,
|
|
9615
|
-
|
|
10248
|
+
}) }) }) : timeGridView ? /* @__PURE__ */ (0, import_jsx_runtime85.jsx)(
|
|
10249
|
+
SchedulingTimeGrid,
|
|
10250
|
+
{
|
|
10251
|
+
view: view === "day" ? "day" : "week",
|
|
10252
|
+
days,
|
|
10253
|
+
timeZone,
|
|
10254
|
+
entries: visibleEntries,
|
|
10255
|
+
overlays,
|
|
10256
|
+
dayInfo,
|
|
10257
|
+
labels,
|
|
10258
|
+
gridLabel: fillLabel(labels.grid, { view: viewLabel[view] }),
|
|
10259
|
+
dateText,
|
|
10260
|
+
formatInstant,
|
|
10261
|
+
entryName,
|
|
10262
|
+
entryStatus: statusOf,
|
|
10263
|
+
entryMarkers: markersOf,
|
|
10264
|
+
overlayName,
|
|
10265
|
+
renderEntry,
|
|
10266
|
+
renderMarker,
|
|
10267
|
+
onSelectEntry,
|
|
10268
|
+
onSelectOverlay,
|
|
10269
|
+
onSelectDate,
|
|
10270
|
+
onShowMore,
|
|
10271
|
+
now,
|
|
10272
|
+
canMove,
|
|
10273
|
+
step,
|
|
10274
|
+
onProposeMove,
|
|
10275
|
+
topLaneCrossMidnightMinutes,
|
|
10276
|
+
topLaneCap,
|
|
10277
|
+
windowLaneCap: windowLaneCap ?? DEFAULT_LANE_CAP2,
|
|
10278
|
+
maxLanes,
|
|
10279
|
+
emptyNote,
|
|
10280
|
+
nothingToShow
|
|
10281
|
+
}
|
|
10282
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { ref: gridRef, className: cx("uix-scheduling-calendar__grid", view === "week" && "uix-scheduling-calendar__grid--week"), "data-fixed": fixed || void 0, style: gridStyle, role: "group", "aria-label": fillLabel(labels.grid, { view: viewLabel[view] }), children: [
|
|
10283
|
+
days.slice(0, 7).map((date) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__weekday", "aria-hidden": "true", children: dateText(date, "weekday") }, `weekday-${date}`)),
|
|
9616
10284
|
Array.from({ length: days.length / 7 }, (_, row) => renderWeek(row)),
|
|
9617
|
-
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0,
|
|
10285
|
+
emptyNote != null && emptyNote !== false && nothingToShow && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("div", { className: "uix-scheduling-calendar__empty", children: emptyNote })
|
|
9618
10286
|
] }),
|
|
9619
|
-
legend ? (legend.length > 0 || legendCaption != null && legendCaption !== false) && /* @__PURE__ */ (0,
|
|
9620
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
9621
|
-
/* @__PURE__ */ (0,
|
|
10287
|
+
legend ? (legend.length > 0 || legendCaption != null && legendCaption !== false) && /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__legend", role: "group", "aria-label": labels.legend, children: [
|
|
10288
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("ul", { className: "uix-scheduling-calendar__legend-list", children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("li", { "data-legend-id": item.id, children: [
|
|
10289
|
+
/* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { className: "uix-scheduling-calendar__swatch", "aria-hidden": "true", "data-band": item.swatch.band, "data-status": item.swatch.status, "data-pattern": item.swatch.pattern, children: item.swatch.icon }),
|
|
9622
10290
|
item.label
|
|
9623
10291
|
] }, item.id)) }),
|
|
9624
|
-
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0,
|
|
9625
|
-
] }) : /* @__PURE__ */ (0,
|
|
9626
|
-
["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0,
|
|
9627
|
-
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0,
|
|
10292
|
+
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { className: "uix-scheduling-calendar__legend-caption", children: legendCaption })
|
|
10293
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime85.jsxs)("div", { className: "uix-scheduling-calendar__legend", role: "group", "aria-label": labels.legend, children: [
|
|
10294
|
+
["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("span", { "data-state": state, children: stateLabel[state] }, state)),
|
|
10295
|
+
legendCaption != null && legendCaption !== false && /* @__PURE__ */ (0, import_jsx_runtime85.jsx)("p", { className: "uix-scheduling-calendar__legend-caption", children: legendCaption })
|
|
9628
10296
|
] })
|
|
9629
10297
|
] });
|
|
9630
10298
|
}
|
|
9631
10299
|
|
|
9632
10300
|
// src/components/SchedulingTimeline.tsx
|
|
9633
|
-
var
|
|
10301
|
+
var import_react60 = require("react");
|
|
9634
10302
|
|
|
9635
10303
|
// src/scheduling-timeline-model.ts
|
|
9636
10304
|
var HOUR = 36e5;
|
|
@@ -9732,7 +10400,7 @@ function pixelsToMs(px, trackWidth, range, step) {
|
|
|
9732
10400
|
}
|
|
9733
10401
|
|
|
9734
10402
|
// src/components/SchedulingTimeline.tsx
|
|
9735
|
-
var
|
|
10403
|
+
var import_jsx_runtime86 = require("react/jsx-runtime");
|
|
9736
10404
|
var DEFAULT_SCHEDULING_TIMELINE_LABELS = {
|
|
9737
10405
|
region: "Schedule timeline in {timeZone}",
|
|
9738
10406
|
lanes: "Lanes",
|
|
@@ -9788,20 +10456,20 @@ function SchedulingTimeline({
|
|
|
9788
10456
|
states: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.states, ...uixLabels.schedulingTimeline?.states, ...labelOverrides?.states },
|
|
9789
10457
|
overlays: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.overlays, ...uixLabels.schedulingTimeline?.overlays, ...labelOverrides?.overlays }
|
|
9790
10458
|
};
|
|
9791
|
-
const id = (0,
|
|
10459
|
+
const id = (0, import_react60.useId)();
|
|
9792
10460
|
const step = stepProp ?? defaultTimelineStep(scale);
|
|
9793
|
-
const ticks = (0,
|
|
9794
|
-
const laneLayouts = (0,
|
|
10461
|
+
const ticks = (0, import_react60.useMemo)(() => timelineTicks(range, scale, timeZone, weekStartsOn), [range.start, range.end, scale, timeZone, weekStartsOn]);
|
|
10462
|
+
const laneLayouts = (0, import_react60.useMemo)(
|
|
9795
10463
|
() => lanes.map((lane) => ({ lane, placed: layoutLane(items.filter((item) => item.laneId === lane.id), range) })),
|
|
9796
10464
|
[lanes, items, range.start, range.end]
|
|
9797
10465
|
// eslint-disable-line react-hooks/exhaustive-deps
|
|
9798
10466
|
);
|
|
9799
|
-
const ordered = (0,
|
|
9800
|
-
const [activeId, setActiveId] = (0,
|
|
10467
|
+
const ordered = (0, import_react60.useMemo)(() => laneLayouts.flatMap((l) => l.placed.map((p) => p.item.id)), [laneLayouts]);
|
|
10468
|
+
const [activeId, setActiveId] = (0, import_react60.useState)();
|
|
9801
10469
|
const focusId = activeId && ordered.includes(activeId) ? activeId : ordered[0];
|
|
9802
|
-
const [drag, setDrag] = (0,
|
|
9803
|
-
const [announcement, setAnnouncement] = (0,
|
|
9804
|
-
const rootRef = (0,
|
|
10470
|
+
const [drag, setDrag] = (0, import_react60.useState)(null);
|
|
10471
|
+
const [announcement, setAnnouncement] = (0, import_react60.useState)("");
|
|
10472
|
+
const rootRef = (0, import_react60.useRef)(null);
|
|
9805
10473
|
const fmtInstant = (instant) => formatInstantProp?.(instant) ?? new Intl.DateTimeFormat(locale, { timeZone, dateStyle: "medium", timeStyle: "short" }).format(new Date(instant));
|
|
9806
10474
|
const fmtTick = (at) => formatTick?.(new Date(at), scale) ?? new Intl.DateTimeFormat(locale, { timeZone, ...TICK_FORMAT[scale] }).format(new Date(at));
|
|
9807
10475
|
const movable = (item) => !!onMoveItem && item.movable !== false;
|
|
@@ -9872,17 +10540,17 @@ function SchedulingTimeline({
|
|
|
9872
10540
|
const trackStyle = { minWidth: `calc(${Math.max(ticks.length - 1, 1)} * ${tickWidth ?? TICK_WIDTH[scale]})` };
|
|
9873
10541
|
const band = (o, showLabel) => {
|
|
9874
10542
|
const pos = placeSpan(o, range);
|
|
9875
|
-
return pos && /* @__PURE__ */ (0,
|
|
9876
|
-
};
|
|
9877
|
-
return /* @__PURE__ */ (0,
|
|
9878
|
-
loading ? /* @__PURE__ */ (0,
|
|
9879
|
-
/* @__PURE__ */ (0,
|
|
9880
|
-
onRetry && /* @__PURE__ */ (0,
|
|
9881
|
-
] }) : /* @__PURE__ */ (0,
|
|
9882
|
-
(overlays.length > 0 || markers.length > 0) && /* @__PURE__ */ (0,
|
|
9883
|
-
/* @__PURE__ */ (0,
|
|
9884
|
-
/* @__PURE__ */ (0,
|
|
9885
|
-
overlays.map((o) => /* @__PURE__ */ (0,
|
|
10543
|
+
return pos && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__overlay", "data-kind": o.kind, style: { left: `${pos.left}%`, width: `${pos.width}%` }, children: showLabel && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__overlay-label", children: o.label }) }, o.id);
|
|
10544
|
+
};
|
|
10545
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("section", { ref: rootRef, className: cx("uix-scheduling-timeline", className), "aria-label": fillLabel(labels.region, { timeZone }), children: [
|
|
10546
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-timeline__state", role: "status", children: labels.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__state", role: "alert", children: [
|
|
10547
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { children: error }),
|
|
10548
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
10549
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(import_jsx_runtime86.Fragment, { children: [
|
|
10550
|
+
(overlays.length > 0 || markers.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-visually-hidden", children: [
|
|
10551
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { id: `${id}-windows`, children: labels.windows }),
|
|
10552
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("ul", { "aria-labelledby": `${id}-windows`, children: [
|
|
10553
|
+
overlays.map((o) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("li", { children: [
|
|
9886
10554
|
labels.overlays[o.kind],
|
|
9887
10555
|
": ",
|
|
9888
10556
|
o.label,
|
|
@@ -9891,40 +10559,40 @@ function SchedulingTimeline({
|
|
|
9891
10559
|
" \u2013 ",
|
|
9892
10560
|
fmtInstant(o.end)
|
|
9893
10561
|
] }, o.id)),
|
|
9894
|
-
markers.map((m) => /* @__PURE__ */ (0,
|
|
10562
|
+
markers.map((m) => /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("li", { children: [
|
|
9895
10563
|
m.label,
|
|
9896
10564
|
", ",
|
|
9897
10565
|
fmtInstant(m.at)
|
|
9898
10566
|
] }, m.id))
|
|
9899
10567
|
] })
|
|
9900
10568
|
] }),
|
|
9901
|
-
/* @__PURE__ */ (0,
|
|
9902
|
-
/* @__PURE__ */ (0,
|
|
9903
|
-
/* @__PURE__ */ (0,
|
|
9904
|
-
/* @__PURE__ */ (0,
|
|
10569
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-timeline__scroller", children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__grid", children: [
|
|
10570
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__row uix-scheduling-timeline__row--axis", "aria-hidden": "true", children: [
|
|
10571
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-timeline__lane-label", children: labels.lanes }),
|
|
10572
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("div", { className: "uix-scheduling-timeline__track uix-scheduling-timeline__axis", style: trackStyle, children: ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__tick", "data-major": tick.major || void 0, style: { left: `${tick.offset}%` }, children: tick.offset < 100 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__tick-label", children: fmtTick(tick.at) }) }, tick.at)) })
|
|
9905
10573
|
] }),
|
|
9906
10574
|
laneLayouts.map(({ lane, placed }, laneIndex) => {
|
|
9907
10575
|
const rows = placed.reduce((max, p) => Math.max(max, p.row + 1), 1);
|
|
9908
10576
|
const laneLabelId = `${id}-lane-${laneIndex}`;
|
|
9909
|
-
return /* @__PURE__ */ (0,
|
|
9910
|
-
/* @__PURE__ */ (0,
|
|
9911
|
-
/* @__PURE__ */ (0,
|
|
9912
|
-
lane.meta != null && /* @__PURE__ */ (0,
|
|
10577
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__row", style: { "--uix-timeline-rows": rows }, children: [
|
|
10578
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__lane-label", id: laneLabelId, children: [
|
|
10579
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__lane-name", children: lane.label }),
|
|
10580
|
+
lane.meta != null && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__lane-meta", children: lane.meta })
|
|
9913
10581
|
] }),
|
|
9914
|
-
/* @__PURE__ */ (0,
|
|
9915
|
-
ticks.map((tick) => /* @__PURE__ */ (0,
|
|
9916
|
-
/* @__PURE__ */ (0,
|
|
9917
|
-
nowPos && /* @__PURE__ */ (0,
|
|
10582
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsxs)("div", { className: "uix-scheduling-timeline__track", style: trackStyle, children: [
|
|
10583
|
+
ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__gridline", "data-major": tick.major || void 0, style: { left: `${tick.offset}%` }, "aria-hidden": "true" }, tick.at)),
|
|
10584
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { "aria-hidden": "true", children: overlaysFor(lane.id).map((o) => band(o, laneIndex === 0 || !!o.laneId)) }),
|
|
10585
|
+
nowPos && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__now", style: { left: `${nowPos.left}%` }, "aria-hidden": "true", children: laneIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__now-label", children: labels.now }) }),
|
|
9918
10586
|
markersFor(lane.id).map((m) => {
|
|
9919
10587
|
const pos = placeSpan({ start: m.at, end: m.at }, range);
|
|
9920
|
-
return pos && /* @__PURE__ */ (0,
|
|
10588
|
+
return pos && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__marker", style: { left: `${pos.left}%` }, title: m.label, "aria-hidden": "true" }, m.id);
|
|
9921
10589
|
}),
|
|
9922
|
-
/* @__PURE__ */ (0,
|
|
10590
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("ul", { className: "uix-scheduling-timeline__items", "aria-labelledby": laneLabelId, children: placed.map((p, index) => {
|
|
9923
10591
|
const item = p.item;
|
|
9924
10592
|
const state = item.state ?? "scheduled";
|
|
9925
10593
|
const dragging = drag?.id === item.id && drag.moved;
|
|
9926
10594
|
const shown = dragging && drag ? placeSpan(shiftSpan(item, drag.delta, "move", step), range) ?? p : p;
|
|
9927
|
-
return /* @__PURE__ */ (0,
|
|
10595
|
+
return /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("li", { className: "uix-scheduling-timeline__slot", style: { left: `${shown.left}%`, width: `${shown.width}%`, "--uix-timeline-row": p.row }, children: /* @__PURE__ */ (0, import_jsx_runtime86.jsxs)(
|
|
9928
10596
|
"button",
|
|
9929
10597
|
{
|
|
9930
10598
|
type: "button",
|
|
@@ -9951,8 +10619,8 @@ function SchedulingTimeline({
|
|
|
9951
10619
|
onSelectItem?.(item);
|
|
9952
10620
|
},
|
|
9953
10621
|
children: [
|
|
9954
|
-
/* @__PURE__ */ (0,
|
|
9955
|
-
item.meta && /* @__PURE__ */ (0,
|
|
10622
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__item-title", children: renderItem?.(item) ?? item.title }),
|
|
10623
|
+
item.meta && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-scheduling-timeline__item-meta", children: item.meta })
|
|
9956
10624
|
]
|
|
9957
10625
|
}
|
|
9958
10626
|
) }, item.id);
|
|
@@ -9961,16 +10629,16 @@ function SchedulingTimeline({
|
|
|
9961
10629
|
] }, lane.id);
|
|
9962
10630
|
})
|
|
9963
10631
|
] }) }),
|
|
9964
|
-
ordered.length === 0 && /* @__PURE__ */ (0,
|
|
10632
|
+
ordered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("p", { className: "uix-scheduling-timeline__empty", children: labels.empty })
|
|
9965
10633
|
] }),
|
|
9966
|
-
onMoveItem && /* @__PURE__ */ (0,
|
|
9967
|
-
/* @__PURE__ */ (0,
|
|
10634
|
+
onMoveItem && /* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { id: `${id}-hint`, className: "uix-visually-hidden", children: labels.moveHint }),
|
|
10635
|
+
/* @__PURE__ */ (0, import_jsx_runtime86.jsx)("span", { className: "uix-visually-hidden", role: "status", "aria-live": "polite", children: announcement })
|
|
9968
10636
|
] });
|
|
9969
10637
|
}
|
|
9970
10638
|
|
|
9971
10639
|
// src/components/DateRangePicker.tsx
|
|
9972
|
-
var
|
|
9973
|
-
var
|
|
10640
|
+
var import_react61 = require("react");
|
|
10641
|
+
var import_jsx_runtime87 = require("react/jsx-runtime");
|
|
9974
10642
|
var DEFAULT_DATE_RANGE_PICKER_LABELS = {
|
|
9975
10643
|
previous: "Previous",
|
|
9976
10644
|
previousMonth: "Show previous month",
|
|
@@ -10008,29 +10676,29 @@ function DateRangePicker({
|
|
|
10008
10676
|
labels: labelOverrides,
|
|
10009
10677
|
today
|
|
10010
10678
|
}) {
|
|
10011
|
-
const id = (0,
|
|
10679
|
+
const id = (0, import_react61.useId)();
|
|
10012
10680
|
const uixLabels = useUixLabels();
|
|
10013
10681
|
const labels = { ...DEFAULT_DATE_RANGE_PICKER_LABELS, ...uixLabels.dateRangePicker, ...labelOverrides };
|
|
10014
|
-
const weekdays = (0,
|
|
10015
|
-
const [internalMonth, setInternalMonth] = (0,
|
|
10682
|
+
const weekdays = (0, import_react61.useMemo)(() => weekdayNames(locale), [locale]);
|
|
10683
|
+
const [internalMonth, setInternalMonth] = (0, import_react61.useState)(() => startOfMonth(controlledMonth ?? value.start ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)));
|
|
10016
10684
|
const visibleMonth = startOfMonth(controlledMonth ?? internalMonth);
|
|
10017
|
-
const [activeDate, setActiveDate] = (0,
|
|
10018
|
-
const rootRef = (0,
|
|
10019
|
-
const pendingFocus = (0,
|
|
10685
|
+
const [activeDate, setActiveDate] = (0, import_react61.useState)(value.end ?? value.start ?? visibleMonth);
|
|
10686
|
+
const rootRef = (0, import_react61.useRef)(null);
|
|
10687
|
+
const pendingFocus = (0, import_react61.useRef)(false);
|
|
10020
10688
|
const count2 = Math.max(1, Math.min(3, months));
|
|
10021
|
-
const calendars = (0,
|
|
10689
|
+
const calendars = (0, import_react61.useMemo)(() => Array.from({ length: count2 }, (_, index) => {
|
|
10022
10690
|
const month = startOfMonth(addCalendarMonths(visibleMonth, index));
|
|
10023
10691
|
return { month, days: buildMonthGrid(month).filter((day) => day.inMonth) };
|
|
10024
10692
|
}), [visibleMonth, count2]);
|
|
10025
10693
|
const todayDate = today === void 0 ? localDateKey() : today;
|
|
10026
10694
|
const rangeInvalid = invalid || !!value.start && !!value.end && value.start > value.end;
|
|
10027
|
-
(0,
|
|
10695
|
+
(0, import_react61.useEffect)(() => {
|
|
10028
10696
|
const first = calendars[0]?.days[0]?.date;
|
|
10029
10697
|
const finalDays = calendars[calendars.length - 1]?.days;
|
|
10030
10698
|
const last = finalDays?.[finalDays.length - 1]?.date;
|
|
10031
10699
|
if (first && last && (activeDate < first || activeDate > last)) setActiveDate(first);
|
|
10032
10700
|
}, [activeDate, calendars]);
|
|
10033
|
-
(0,
|
|
10701
|
+
(0, import_react61.useEffect)(() => {
|
|
10034
10702
|
if (!pendingFocus.current) return;
|
|
10035
10703
|
rootRef.current?.querySelector(`[data-date="${activeDate}"]`)?.focus();
|
|
10036
10704
|
pendingFocus.current = false;
|
|
@@ -10068,23 +10736,23 @@ function DateRangePicker({
|
|
|
10068
10736
|
}
|
|
10069
10737
|
};
|
|
10070
10738
|
const announcement = !value.start ? labels.noneSelected : !value.end ? labels.startSelected.replace("{start}", dateLabel(value.start, locale)) : labels.rangeSelected.replace("{start}", dateLabel(value.start, locale)).replace("{end}", dateLabel(value.end, locale));
|
|
10071
|
-
return /* @__PURE__ */ (0,
|
|
10072
|
-
/* @__PURE__ */ (0,
|
|
10073
|
-
/* @__PURE__ */ (0,
|
|
10074
|
-
/* @__PURE__ */ (0,
|
|
10075
|
-
/* @__PURE__ */ (0,
|
|
10076
|
-
/* @__PURE__ */ (0,
|
|
10739
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
|
|
10740
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-date-range-picker__header", children: [
|
|
10741
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h3", { id: `${id}-label`, children: label }),
|
|
10742
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { children: [
|
|
10743
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, -1)), "aria-label": labels.previousMonth, children: labels.previous }),
|
|
10744
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, 1)), "aria-label": labels.nextMonth, children: labels.next })
|
|
10077
10745
|
] })
|
|
10078
10746
|
] }),
|
|
10079
|
-
/* @__PURE__ */ (0,
|
|
10080
|
-
/* @__PURE__ */ (0,
|
|
10081
|
-
/* @__PURE__ */ (0,
|
|
10082
|
-
/* @__PURE__ */ (0,
|
|
10083
|
-
Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0,
|
|
10747
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-date-range-picker__month", children: [
|
|
10748
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("h4", { children: monthLabel(month, locale) }),
|
|
10749
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: weekdays.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { children: day }, index)) }),
|
|
10750
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
|
|
10751
|
+
Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
|
|
10084
10752
|
days.map((day) => {
|
|
10085
10753
|
const unavailable = disabled || isDateUnavailable(day.date, { min, max, isDisabled: isDateDisabled });
|
|
10086
10754
|
const edge = day.date === value.start ? "start" : day.date === value.end ? "end" : void 0;
|
|
10087
|
-
return /* @__PURE__ */ (0,
|
|
10755
|
+
return /* @__PURE__ */ (0, import_jsx_runtime87.jsx)(
|
|
10088
10756
|
"button",
|
|
10089
10757
|
{
|
|
10090
10758
|
type: "button",
|
|
@@ -10106,13 +10774,13 @@ function DateRangePicker({
|
|
|
10106
10774
|
})
|
|
10107
10775
|
] })
|
|
10108
10776
|
] }, month)) }),
|
|
10109
|
-
/* @__PURE__ */ (0,
|
|
10110
|
-
rangeInvalid && /* @__PURE__ */ (0,
|
|
10777
|
+
/* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
|
|
10778
|
+
rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime87.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
|
|
10111
10779
|
] });
|
|
10112
10780
|
}
|
|
10113
10781
|
|
|
10114
10782
|
// src/components/RelationshipGraph.tsx
|
|
10115
|
-
var
|
|
10783
|
+
var import_react63 = require("react");
|
|
10116
10784
|
|
|
10117
10785
|
// src/relationship-graph-model.ts
|
|
10118
10786
|
function boundRelationshipGraph(nodes, edges, maxNodes = 40) {
|
|
@@ -10593,10 +11261,10 @@ function layeredNeighbor(layout, currentId, key) {
|
|
|
10593
11261
|
}
|
|
10594
11262
|
|
|
10595
11263
|
// src/components/RelationshipGraphLayered.tsx
|
|
10596
|
-
var
|
|
11264
|
+
var import_react62 = require("react");
|
|
10597
11265
|
|
|
10598
11266
|
// src/components/RelationshipGraphList.tsx
|
|
10599
|
-
var
|
|
11267
|
+
var import_jsx_runtime88 = require("react/jsx-runtime");
|
|
10600
11268
|
function EquivalentRelationshipList({
|
|
10601
11269
|
nodes,
|
|
10602
11270
|
edges,
|
|
@@ -10607,19 +11275,19 @@ function EquivalentRelationshipList({
|
|
|
10607
11275
|
onOpenDetails
|
|
10608
11276
|
}) {
|
|
10609
11277
|
const labelById = new Map(nodes.map((node) => [node.id, node.label]));
|
|
10610
|
-
return /* @__PURE__ */ (0,
|
|
10611
|
-
/* @__PURE__ */ (0,
|
|
10612
|
-
/* @__PURE__ */ (0,
|
|
11278
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
|
|
11279
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("h3", { children: labels.listHeading }),
|
|
11280
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("ul", { children: nodes.map((node) => {
|
|
10613
11281
|
const neighbors = relationshipNeighbors(node.id, edges).map((id) => labelById.get(id) ?? id);
|
|
10614
|
-
return /* @__PURE__ */ (0,
|
|
10615
|
-
/* @__PURE__ */ (0,
|
|
10616
|
-
/* @__PURE__ */ (0,
|
|
10617
|
-
node.type && /* @__PURE__ */ (0,
|
|
10618
|
-
/* @__PURE__ */ (0,
|
|
11282
|
+
return /* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
|
|
11283
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
|
|
11284
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("strong", { children: node.label }),
|
|
11285
|
+
node.type && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { children: node.type }),
|
|
11286
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsx)("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
|
|
10619
11287
|
] }),
|
|
10620
|
-
/* @__PURE__ */ (0,
|
|
10621
|
-
onExpandNeighbors && /* @__PURE__ */ (0,
|
|
10622
|
-
onOpenDetails && /* @__PURE__ */ (0,
|
|
11288
|
+
/* @__PURE__ */ (0, import_jsx_runtime88.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
|
|
11289
|
+
onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
|
|
11290
|
+
onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime88.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: labels.openDetails })
|
|
10623
11291
|
] })
|
|
10624
11292
|
] }, node.id);
|
|
10625
11293
|
}) })
|
|
@@ -10627,7 +11295,7 @@ function EquivalentRelationshipList({
|
|
|
10627
11295
|
}
|
|
10628
11296
|
|
|
10629
11297
|
// src/components/RelationshipGraphLayered.tsx
|
|
10630
|
-
var
|
|
11298
|
+
var import_jsx_runtime89 = require("react/jsx-runtime");
|
|
10631
11299
|
var EMPTY_IDS = /* @__PURE__ */ new Set();
|
|
10632
11300
|
var MIN_ZOOM = 0.4;
|
|
10633
11301
|
var MAX_ZOOM = 1.5;
|
|
@@ -10680,11 +11348,11 @@ function LayeredRelationshipGraph({
|
|
|
10680
11348
|
focusId,
|
|
10681
11349
|
onFocusChange
|
|
10682
11350
|
}) {
|
|
10683
|
-
const hintId = (0,
|
|
10684
|
-
const bounded = (0,
|
|
10685
|
-
const [localExpanded, setLocalExpanded] = (0,
|
|
11351
|
+
const hintId = (0, import_react62.useId)();
|
|
11352
|
+
const bounded = (0, import_react62.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
|
|
11353
|
+
const [localExpanded, setLocalExpanded] = (0, import_react62.useState)(EMPTY_IDS);
|
|
10686
11354
|
const expanded = expandedClusterIds ?? localExpanded;
|
|
10687
|
-
const layout = (0,
|
|
11355
|
+
const layout = (0, import_react62.useMemo)(
|
|
10688
11356
|
() => layoutLayeredGraph(bounded.nodes, bounded.edges, {
|
|
10689
11357
|
...rootId !== void 0 ? { rootId } : {},
|
|
10690
11358
|
...clusterThreshold !== void 0 ? { clusterThreshold } : {},
|
|
@@ -10693,29 +11361,29 @@ function LayeredRelationshipGraph({
|
|
|
10693
11361
|
}),
|
|
10694
11362
|
[bounded, rootId, clusterThreshold, expanded, density]
|
|
10695
11363
|
);
|
|
10696
|
-
const itemById = (0,
|
|
10697
|
-
const viewportRef = (0,
|
|
10698
|
-
const itemRefs = (0,
|
|
10699
|
-
const [size, setSize] = (0,
|
|
10700
|
-
const [view, setView] = (0,
|
|
10701
|
-
const [animate, setAnimate] = (0,
|
|
10702
|
-
const [localFocus, setLocalFocus] = (0,
|
|
10703
|
-
const [hoverId, setHoverId] = (0,
|
|
10704
|
-
const viewRef = (0,
|
|
11364
|
+
const itemById = (0, import_react62.useMemo)(() => new Map(layout.items.map((item) => [item.id, item])), [layout]);
|
|
11365
|
+
const viewportRef = (0, import_react62.useRef)(null);
|
|
11366
|
+
const itemRefs = (0, import_react62.useRef)(/* @__PURE__ */ new Map());
|
|
11367
|
+
const [size, setSize] = (0, import_react62.useState)({ width: 0, height: 0 });
|
|
11368
|
+
const [view, setView] = (0, import_react62.useState)({ x: 0, y: 0, zoom: 1 });
|
|
11369
|
+
const [animate, setAnimate] = (0, import_react62.useState)(false);
|
|
11370
|
+
const [localFocus, setLocalFocus] = (0, import_react62.useState)(void 0);
|
|
11371
|
+
const [hoverId, setHoverId] = (0, import_react62.useState)(void 0);
|
|
11372
|
+
const viewRef = (0, import_react62.useRef)(view);
|
|
10705
11373
|
viewRef.current = view;
|
|
10706
|
-
const layoutRef = (0,
|
|
11374
|
+
const layoutRef = (0, import_react62.useRef)(layout);
|
|
10707
11375
|
layoutRef.current = layout;
|
|
10708
|
-
const pendingFocus = (0,
|
|
10709
|
-
const initialisedFor = (0,
|
|
11376
|
+
const pendingFocus = (0, import_react62.useRef)(void 0);
|
|
11377
|
+
const initialisedFor = (0, import_react62.useRef)(void 0);
|
|
10710
11378
|
const rootItemId = layout.rootId !== void 0 ? layout.itemOf[layout.rootId] : layout.items[0]?.id;
|
|
10711
11379
|
const requestedFocus = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : localFocus;
|
|
10712
11380
|
const focusedId = requestedFocus !== void 0 && itemById.has(requestedFocus) ? requestedFocus : rootItemId;
|
|
10713
11381
|
const selectedItemId = selectedId !== void 0 ? layout.itemOf[selectedId] : void 0;
|
|
10714
|
-
const activeIds = (0,
|
|
11382
|
+
const activeIds = (0, import_react62.useMemo)(
|
|
10715
11383
|
() => new Set([hoverId, selectedItemId].filter((id) => id !== void 0)),
|
|
10716
11384
|
[hoverId, selectedItemId]
|
|
10717
11385
|
);
|
|
10718
|
-
(0,
|
|
11386
|
+
(0, import_react62.useEffect)(() => {
|
|
10719
11387
|
const element = viewportRef.current;
|
|
10720
11388
|
if (!element) return;
|
|
10721
11389
|
const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
|
|
@@ -10725,18 +11393,18 @@ function LayeredRelationshipGraph({
|
|
|
10725
11393
|
observer.observe(element);
|
|
10726
11394
|
return () => observer.disconnect();
|
|
10727
11395
|
}, []);
|
|
10728
|
-
(0,
|
|
11396
|
+
(0, import_react62.useEffect)(() => {
|
|
10729
11397
|
if (size.width === 0) return;
|
|
10730
11398
|
const key = `${layout.rootId ?? ""}`;
|
|
10731
11399
|
if (initialisedFor.current === key) return;
|
|
10732
11400
|
initialisedFor.current = key;
|
|
10733
11401
|
setView(initialView(layout, size));
|
|
10734
11402
|
}, [layout, size]);
|
|
10735
|
-
const moveView = (0,
|
|
11403
|
+
const moveView = (0, import_react62.useCallback)((next, smooth) => {
|
|
10736
11404
|
setAnimate(smooth);
|
|
10737
11405
|
setView(next);
|
|
10738
11406
|
}, []);
|
|
10739
|
-
const ensureVisible = (0,
|
|
11407
|
+
const ensureVisible = (0, import_react62.useCallback)((id, smooth) => {
|
|
10740
11408
|
const element = viewportRef.current;
|
|
10741
11409
|
const item = layoutRef.current.items.find((candidate) => candidate.id === id);
|
|
10742
11410
|
if (!element || !item) return;
|
|
@@ -10755,7 +11423,7 @@ function LayeredRelationshipGraph({
|
|
|
10755
11423
|
else if (bottom > heightPx - FOCUS_MARGIN) nextY -= bottom - (heightPx - FOCUS_MARGIN);
|
|
10756
11424
|
if (nextX !== x || nextY !== y) moveView({ x: nextX, y: nextY, zoom }, smooth);
|
|
10757
11425
|
}, [moveView]);
|
|
10758
|
-
const focusItem = (0,
|
|
11426
|
+
const focusItem = (0, import_react62.useCallback)((id) => {
|
|
10759
11427
|
setLocalFocus(id);
|
|
10760
11428
|
onFocusChange?.(id);
|
|
10761
11429
|
requestAnimationFrame(() => {
|
|
@@ -10763,7 +11431,7 @@ function LayeredRelationshipGraph({
|
|
|
10763
11431
|
ensureVisible(id, true);
|
|
10764
11432
|
});
|
|
10765
11433
|
}, [ensureVisible, onFocusChange]);
|
|
10766
|
-
(0,
|
|
11434
|
+
(0, import_react62.useEffect)(() => {
|
|
10767
11435
|
const wanted = pendingFocus.current;
|
|
10768
11436
|
if (wanted !== void 0 && itemById.has(wanted)) {
|
|
10769
11437
|
pendingFocus.current = void 0;
|
|
@@ -10773,8 +11441,8 @@ function LayeredRelationshipGraph({
|
|
|
10773
11441
|
const controlledTarget = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : void 0;
|
|
10774
11442
|
const controlledPresent = controlledTarget !== void 0 && itemById.has(controlledTarget);
|
|
10775
11443
|
const controlledKey = `${controlledTarget ?? ""}|${controlledPresent}`;
|
|
10776
|
-
const lastControlledKey = (0,
|
|
10777
|
-
(0,
|
|
11444
|
+
const lastControlledKey = (0, import_react62.useRef)(controlledKey);
|
|
11445
|
+
(0, import_react62.useEffect)(() => {
|
|
10778
11446
|
if (lastControlledKey.current === controlledKey) return;
|
|
10779
11447
|
lastControlledKey.current = controlledKey;
|
|
10780
11448
|
if (!controlledPresent || controlledTarget === void 0) return;
|
|
@@ -10783,7 +11451,7 @@ function LayeredRelationshipGraph({
|
|
|
10783
11451
|
ensureVisible(controlledTarget, true);
|
|
10784
11452
|
});
|
|
10785
11453
|
}, [controlledKey, controlledTarget, controlledPresent, ensureVisible]);
|
|
10786
|
-
(0,
|
|
11454
|
+
(0, import_react62.useEffect)(() => {
|
|
10787
11455
|
const element = viewportRef.current;
|
|
10788
11456
|
if (!element) return;
|
|
10789
11457
|
const onWheel = (event) => {
|
|
@@ -10801,8 +11469,8 @@ function LayeredRelationshipGraph({
|
|
|
10801
11469
|
element.addEventListener("wheel", onWheel, { passive: false });
|
|
10802
11470
|
return () => element.removeEventListener("wheel", onWheel);
|
|
10803
11471
|
}, []);
|
|
10804
|
-
const pointers = (0,
|
|
10805
|
-
const pinchDistance = (0,
|
|
11472
|
+
const pointers = (0, import_react62.useRef)(/* @__PURE__ */ new Map());
|
|
11473
|
+
const pinchDistance = (0, import_react62.useRef)(void 0);
|
|
10806
11474
|
const onPointerDown = (event) => {
|
|
10807
11475
|
if (event.target.closest("button")) return;
|
|
10808
11476
|
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
@@ -10900,21 +11568,21 @@ function LayeredRelationshipGraph({
|
|
|
10900
11568
|
height: layout.height,
|
|
10901
11569
|
transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`
|
|
10902
11570
|
};
|
|
10903
|
-
return /* @__PURE__ */ (0,
|
|
10904
|
-
/* @__PURE__ */ (0,
|
|
10905
|
-
/* @__PURE__ */ (0,
|
|
10906
|
-
/* @__PURE__ */ (0,
|
|
10907
|
-
/* @__PURE__ */ (0,
|
|
10908
|
-
/* @__PURE__ */ (0,
|
|
10909
|
-
/* @__PURE__ */ (0,
|
|
10910
|
-
/* @__PURE__ */ (0,
|
|
10911
|
-
/* @__PURE__ */ (0,
|
|
10912
|
-
/* @__PURE__ */ (0,
|
|
10913
|
-
/* @__PURE__ */ (0,
|
|
11571
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("section", { className: cx("uix-relationship-graph", "uix-relationship-graph--layered", density === "compact" && "uix-relationship-graph--compact", className), "aria-label": labels.graph, children: [
|
|
11572
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "uix-relationship-graph__toolbar", role: "group", "aria-label": labels.controls, children: [
|
|
11573
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => zoomBy(ZOOM_STEP), disabled: view.zoom >= MAX_ZOOM, children: labels.zoomIn }),
|
|
11574
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => zoomBy(1 / ZOOM_STEP), disabled: view.zoom <= MIN_ZOOM, children: labels.zoomOut }),
|
|
11575
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => moveView(fitView(layout, size), true), children: labels.fit }),
|
|
11576
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => moveView(initialView(layout, size), true), children: labels.reset }),
|
|
11577
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => panBy(PAN_STEP, 0), "aria-label": labels.panLeft, children: labels.left }),
|
|
11578
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => panBy(0, PAN_STEP), "aria-label": labels.panUp, children: labels.up }),
|
|
11579
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => panBy(0, -PAN_STEP), "aria-label": labels.panDown, children: labels.down }),
|
|
11580
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("button", { type: "button", onClick: () => panBy(-PAN_STEP, 0), "aria-label": labels.panRight, children: labels.right }),
|
|
11581
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(view.zoom * 100)) })
|
|
10914
11582
|
] }),
|
|
10915
|
-
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0,
|
|
10916
|
-
/* @__PURE__ */ (0,
|
|
10917
|
-
/* @__PURE__ */ (0,
|
|
11583
|
+
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
|
|
11584
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.keyboardHint }),
|
|
11585
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
10918
11586
|
"div",
|
|
10919
11587
|
{
|
|
10920
11588
|
ref: viewportRef,
|
|
@@ -10924,11 +11592,11 @@ function LayeredRelationshipGraph({
|
|
|
10924
11592
|
onPointerMove,
|
|
10925
11593
|
onPointerUp: onPointerEnd,
|
|
10926
11594
|
onPointerCancel: onPointerEnd,
|
|
10927
|
-
children: /* @__PURE__ */ (0,
|
|
10928
|
-
/* @__PURE__ */ (0,
|
|
11595
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
|
|
11596
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
|
|
10929
11597
|
const active = activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id));
|
|
10930
11598
|
const angle = edge.arrowAngle * 180 / Math.PI;
|
|
10931
|
-
return /* @__PURE__ */ (0,
|
|
11599
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
10932
11600
|
"g",
|
|
10933
11601
|
{
|
|
10934
11602
|
className: "uix-relationship-graph__link",
|
|
@@ -10938,15 +11606,15 @@ function LayeredRelationshipGraph({
|
|
|
10938
11606
|
"data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
|
|
10939
11607
|
"data-dimmed": dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0,
|
|
10940
11608
|
children: [
|
|
10941
|
-
/* @__PURE__ */ (0,
|
|
10942
|
-
edge.arrow !== "none" && /* @__PURE__ */ (0,
|
|
10943
|
-
showLabel(edge) && /* @__PURE__ */ (0,
|
|
11609
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("path", { d: edge.path }),
|
|
11610
|
+
edge.arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
|
|
11611
|
+
showLabel(edge) && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("text", { x: edge.labelX, y: edge.labelY, textAnchor: "middle", dominantBaseline: "middle", children: (edge.kind === "cycle" ? [...edge.labelLines, labels.cycle] : edge.labelLines).map((line, index, lines) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
|
|
10944
11612
|
]
|
|
10945
11613
|
},
|
|
10946
11614
|
edge.id
|
|
10947
11615
|
);
|
|
10948
11616
|
}) }),
|
|
10949
|
-
layout.columns.map((column) => /* @__PURE__ */ (0,
|
|
11617
|
+
layout.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
10950
11618
|
"div",
|
|
10951
11619
|
{
|
|
10952
11620
|
className: "uix-relationship-graph__column",
|
|
@@ -10956,17 +11624,17 @@ function LayeredRelationshipGraph({
|
|
|
10956
11624
|
},
|
|
10957
11625
|
column.depth
|
|
10958
11626
|
)),
|
|
10959
|
-
/* @__PURE__ */ (0,
|
|
11627
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("div", { role: "group", "aria-roledescription": labels.roleDescription, "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), "aria-describedby": hintId, children: layout.items.map((item) => {
|
|
10960
11628
|
const selected = item.id === selectedItemId;
|
|
10961
11629
|
const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
|
|
10962
|
-
const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0,
|
|
10963
|
-
/* @__PURE__ */ (0,
|
|
10964
|
-
/* @__PURE__ */ (0,
|
|
10965
|
-
] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0,
|
|
10966
|
-
/* @__PURE__ */ (0,
|
|
10967
|
-
(item.node.type || item.node.description) && /* @__PURE__ */ (0,
|
|
11630
|
+
const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, { children: [
|
|
11631
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
|
|
11632
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
|
|
11633
|
+
] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(import_jsx_runtime89.Fragment, { children: [
|
|
11634
|
+
/* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
|
|
11635
|
+
(item.node.type || item.node.description) && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
|
|
10968
11636
|
] });
|
|
10969
|
-
return /* @__PURE__ */ (0,
|
|
11637
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsxs)(
|
|
10970
11638
|
"button",
|
|
10971
11639
|
{
|
|
10972
11640
|
ref: (element) => {
|
|
@@ -10997,7 +11665,7 @@ function LayeredRelationshipGraph({
|
|
|
10997
11665
|
onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
|
|
10998
11666
|
children: [
|
|
10999
11667
|
body,
|
|
11000
|
-
item.inCycle && /* @__PURE__ */ (0,
|
|
11668
|
+
item.inCycle && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
|
|
11001
11669
|
]
|
|
11002
11670
|
},
|
|
11003
11671
|
item.id
|
|
@@ -11005,7 +11673,7 @@ function LayeredRelationshipGraph({
|
|
|
11005
11673
|
}) }),
|
|
11006
11674
|
layout.items.filter((item) => item.expandedGroup).map((item) => {
|
|
11007
11675
|
const group = item.expandedGroup;
|
|
11008
|
-
return /* @__PURE__ */ (0,
|
|
11676
|
+
return /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
11009
11677
|
"button",
|
|
11010
11678
|
{
|
|
11011
11679
|
type: "button",
|
|
@@ -11021,8 +11689,8 @@ function LayeredRelationshipGraph({
|
|
|
11021
11689
|
] })
|
|
11022
11690
|
}
|
|
11023
11691
|
),
|
|
11024
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
11025
|
-
showList && /* @__PURE__ */ (0,
|
|
11692
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime89.jsx)("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
|
|
11693
|
+
showList && /* @__PURE__ */ (0, import_jsx_runtime89.jsx)(
|
|
11026
11694
|
EquivalentRelationshipList,
|
|
11027
11695
|
{
|
|
11028
11696
|
nodes: bounded.nodes,
|
|
@@ -11041,7 +11709,7 @@ function LayeredRelationshipGraph({
|
|
|
11041
11709
|
}
|
|
11042
11710
|
|
|
11043
11711
|
// src/components/RelationshipGraph.tsx
|
|
11044
|
-
var
|
|
11712
|
+
var import_jsx_runtime90 = require("react/jsx-runtime");
|
|
11045
11713
|
var DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
|
|
11046
11714
|
graph: "Relationship graph",
|
|
11047
11715
|
controls: "Graph view controls",
|
|
@@ -11103,21 +11771,21 @@ function radialViewBox(nodes) {
|
|
|
11103
11771
|
return `${round(minX)} ${round(minY)} ${width} ${height}`;
|
|
11104
11772
|
}
|
|
11105
11773
|
function RelationshipGraph(props) {
|
|
11106
|
-
const labels = (0,
|
|
11774
|
+
const labels = (0, import_react63.useMemo)(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
|
|
11107
11775
|
const stateClass = cx("uix-relationship-graph uix-relationship-graph--state", props.className);
|
|
11108
|
-
if (props.loading) return /* @__PURE__ */ (0,
|
|
11776
|
+
if (props.loading) return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: stateClass, role: "status", children: labels.loading });
|
|
11109
11777
|
if (props.error) {
|
|
11110
|
-
return /* @__PURE__ */ (0,
|
|
11111
|
-
/* @__PURE__ */ (0,
|
|
11112
|
-
props.onRetry && /* @__PURE__ */ (0,
|
|
11778
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: stateClass, role: "alert", children: [
|
|
11779
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { children: props.error }),
|
|
11780
|
+
props.onRetry && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
|
|
11113
11781
|
] });
|
|
11114
11782
|
}
|
|
11115
|
-
if (props.nodes.length === 0) return /* @__PURE__ */ (0,
|
|
11116
|
-
/* @__PURE__ */ (0,
|
|
11117
|
-
/* @__PURE__ */ (0,
|
|
11783
|
+
if (props.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: stateClass, children: [
|
|
11784
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { children: labels.emptyTitle }),
|
|
11785
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { children: labels.emptyHint })
|
|
11118
11786
|
] });
|
|
11119
|
-
if (props.layout === "layered") return /* @__PURE__ */ (0,
|
|
11120
|
-
return /* @__PURE__ */ (0,
|
|
11787
|
+
if (props.layout === "layered") return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(LayeredRelationshipGraph, { ...props, labels });
|
|
11788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(RadialRelationshipGraph, { ...props, labels });
|
|
11121
11789
|
}
|
|
11122
11790
|
function RadialRelationshipGraph({
|
|
11123
11791
|
nodes,
|
|
@@ -11137,17 +11805,17 @@ function RadialRelationshipGraph({
|
|
|
11137
11805
|
labels,
|
|
11138
11806
|
showList = true
|
|
11139
11807
|
}) {
|
|
11140
|
-
const bounded = (0,
|
|
11141
|
-
const positioned = (0,
|
|
11142
|
-
const typeColor = (0,
|
|
11808
|
+
const bounded = (0, import_react63.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
|
|
11809
|
+
const positioned = (0, import_react63.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
|
|
11810
|
+
const typeColor = (0, import_react63.useMemo)(
|
|
11143
11811
|
() => new Map(legend.map((item, index) => [item.id, `var(--uix-chart-${index % 8 + 1})`])),
|
|
11144
11812
|
[legend]
|
|
11145
11813
|
);
|
|
11146
|
-
const positionedById = (0,
|
|
11147
|
-
const [zoom, setZoom] = (0,
|
|
11148
|
-
const [pan, setPan] = (0,
|
|
11149
|
-
const [focusedId, setFocusedId] = (0,
|
|
11150
|
-
const svgRef = (0,
|
|
11814
|
+
const positionedById = (0, import_react63.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
|
|
11815
|
+
const [zoom, setZoom] = (0, import_react63.useState)(1);
|
|
11816
|
+
const [pan, setPan] = (0, import_react63.useState)({ x: 0, y: 0 });
|
|
11817
|
+
const [focusedId, setFocusedId] = (0, import_react63.useState)(selectedId ?? positioned[0]?.id);
|
|
11818
|
+
const svgRef = (0, import_react63.useRef)(null);
|
|
11151
11819
|
const select = (id) => {
|
|
11152
11820
|
const node = bounded.nodes.find((item) => item.id === id);
|
|
11153
11821
|
if (node) onSelect?.(node);
|
|
@@ -11170,25 +11838,25 @@ function RadialRelationshipGraph({
|
|
|
11170
11838
|
setZoom(1);
|
|
11171
11839
|
setPan({ x: 0, y: 0 });
|
|
11172
11840
|
};
|
|
11173
|
-
return /* @__PURE__ */ (0,
|
|
11174
|
-
/* @__PURE__ */ (0,
|
|
11175
|
-
/* @__PURE__ */ (0,
|
|
11176
|
-
/* @__PURE__ */ (0,
|
|
11177
|
-
/* @__PURE__ */ (0,
|
|
11178
|
-
/* @__PURE__ */ (0,
|
|
11179
|
-
/* @__PURE__ */ (0,
|
|
11180
|
-
/* @__PURE__ */ (0,
|
|
11181
|
-
/* @__PURE__ */ (0,
|
|
11182
|
-
/* @__PURE__ */ (0,
|
|
11841
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
|
|
11842
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
|
|
11843
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
|
|
11844
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
|
|
11845
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
|
|
11846
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
|
|
11847
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
|
|
11848
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
|
|
11849
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("button", { type: "button", onClick: reset, children: labels.reset }),
|
|
11850
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
|
|
11183
11851
|
] }),
|
|
11184
|
-
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0,
|
|
11185
|
-
/* @__PURE__ */ (0,
|
|
11852
|
+
bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
|
|
11853
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("svg", { ref: svgRef, viewBox: radialViewBox(positioned), role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
|
|
11186
11854
|
bounded.edges.map((edge) => {
|
|
11187
11855
|
const source = positionedById.get(edge.source);
|
|
11188
11856
|
const target = positionedById.get(edge.target);
|
|
11189
|
-
return /* @__PURE__ */ (0,
|
|
11857
|
+
return /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("line", { x1: source.x * RADIAL_SCALE_X, y1: source.y * RADIAL_SCALE_Y, x2: target.x * RADIAL_SCALE_X, y2: target.y * RADIAL_SCALE_Y, className: "uix-relationship-graph__edge", "data-typed": edge.type != null && typeColor.has(edge.type) || void 0, style: edge.type != null && typeColor.has(edge.type) ? { "--uix-graph-type-color": typeColor.get(edge.type) } : void 0, "data-highlighted": highlightedEdgeIds.has(edge.id) || void 0, "data-conflicted": conflictedEdgeIds.has(edge.id) || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
|
|
11190
11858
|
}),
|
|
11191
|
-
positioned.map((node) => /* @__PURE__ */ (0,
|
|
11859
|
+
positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime90.jsxs)(
|
|
11192
11860
|
"g",
|
|
11193
11861
|
{
|
|
11194
11862
|
transform: `translate(${node.x * RADIAL_SCALE_X} ${node.y * RADIAL_SCALE_Y})`,
|
|
@@ -11204,22 +11872,22 @@ function RadialRelationshipGraph({
|
|
|
11204
11872
|
onKeyDown: (event) => onNodeKeyDown(event, node.id),
|
|
11205
11873
|
onClick: () => select(node.id),
|
|
11206
11874
|
children: [
|
|
11207
|
-
/* @__PURE__ */ (0,
|
|
11208
|
-
/* @__PURE__ */ (0,
|
|
11209
|
-
/* @__PURE__ */ (0,
|
|
11875
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("title", { children: node.label }),
|
|
11876
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("rect", { x: -RADIAL_NODE_HALF_W, y: -RADIAL_NODE_HALF_H, width: RADIAL_NODE_HALF_W * 2, height: RADIAL_NODE_HALF_H * 2, rx: "8" }),
|
|
11877
|
+
/* @__PURE__ */ (0, import_jsx_runtime90.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
|
|
11210
11878
|
]
|
|
11211
11879
|
},
|
|
11212
11880
|
node.id
|
|
11213
11881
|
))
|
|
11214
11882
|
] }) }) }),
|
|
11215
|
-
legend.length > 0 && /* @__PURE__ */ (0,
|
|
11216
|
-
showList && /* @__PURE__ */ (0,
|
|
11883
|
+
legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime90.jsx)("li", { "data-type": item.id, style: { "--uix-graph-type-color": typeColor.get(item.id) }, children: item.label }, item.id)) }),
|
|
11884
|
+
showList && /* @__PURE__ */ (0, import_jsx_runtime90.jsx)(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
|
|
11217
11885
|
] });
|
|
11218
11886
|
}
|
|
11219
11887
|
|
|
11220
11888
|
// src/components/MatchReview.tsx
|
|
11221
|
-
var
|
|
11222
|
-
var
|
|
11889
|
+
var import_react64 = require("react");
|
|
11890
|
+
var import_jsx_runtime91 = require("react/jsx-runtime");
|
|
11223
11891
|
var DEFAULT_MATCH_REVIEW_LABELS = {
|
|
11224
11892
|
region: "Match review",
|
|
11225
11893
|
loading: "Loading match candidates\u2026",
|
|
@@ -11281,11 +11949,11 @@ function MatchReview({
|
|
|
11281
11949
|
const plural = (n, one, many) => fillLabel(n === 1 ? one : many, { count: n });
|
|
11282
11950
|
const decisionLabel = { accepted: labels.decisionAccepted, dismissed: labels.decisionDismissed, split: labels.decisionSplit, other: labels.decisionOther };
|
|
11283
11951
|
const actionLabel = { accept: labels.accept, dismiss: labels.dismiss, split: labels.split, "pick-other": labels.pickOther };
|
|
11284
|
-
const [internalSelection, setInternalSelection] = (0,
|
|
11285
|
-
const [announcement, setAnnouncement] = (0,
|
|
11286
|
-
const [bulkPending, setBulkPending] = (0,
|
|
11952
|
+
const [internalSelection, setInternalSelection] = (0, import_react64.useState)(/* @__PURE__ */ new Set());
|
|
11953
|
+
const [announcement, setAnnouncement] = (0, import_react64.useState)("");
|
|
11954
|
+
const [bulkPending, setBulkPending] = (0, import_react64.useState)(false);
|
|
11287
11955
|
const selection = selectedIds ?? internalSelection;
|
|
11288
|
-
const pending = (0,
|
|
11956
|
+
const pending = (0, import_react64.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
|
|
11289
11957
|
const setSelection = (next) => {
|
|
11290
11958
|
if (selectedIds === void 0) setInternalSelection(next);
|
|
11291
11959
|
onSelectionChange?.(next);
|
|
@@ -11314,48 +11982,48 @@ function MatchReview({
|
|
|
11314
11982
|
setBulkPending(false);
|
|
11315
11983
|
}
|
|
11316
11984
|
};
|
|
11317
|
-
if (loading) return /* @__PURE__ */ (0,
|
|
11318
|
-
if (error) return /* @__PURE__ */ (0,
|
|
11319
|
-
/* @__PURE__ */ (0,
|
|
11320
|
-
onRetry && /* @__PURE__ */ (0,
|
|
11985
|
+
if (loading) return /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: labels.loading });
|
|
11986
|
+
if (error) return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
|
|
11987
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: error }),
|
|
11988
|
+
onRetry && /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
|
|
11321
11989
|
] });
|
|
11322
|
-
if (candidates.length === 0) return /* @__PURE__ */ (0,
|
|
11323
|
-
/* @__PURE__ */ (0,
|
|
11324
|
-
/* @__PURE__ */ (0,
|
|
11990
|
+
if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
|
|
11991
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: labels.empty }),
|
|
11992
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { children: labels.emptyDetail })
|
|
11325
11993
|
] });
|
|
11326
|
-
return /* @__PURE__ */ (0,
|
|
11327
|
-
/* @__PURE__ */ (0,
|
|
11328
|
-
/* @__PURE__ */ (0,
|
|
11329
|
-
/* @__PURE__ */ (0,
|
|
11330
|
-
/* @__PURE__ */ (0,
|
|
11994
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": labels.region, children: [
|
|
11995
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "uix-match-review__summary", children: [
|
|
11996
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { children: [
|
|
11997
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("strong", { children: incomingLabel }),
|
|
11998
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { children: fillLabel(labels.pendingOf, { pending: pending.length, total: candidates.length }) })
|
|
11331
11999
|
] }),
|
|
11332
|
-
/* @__PURE__ */ (0,
|
|
11333
|
-
/* @__PURE__ */ (0,
|
|
12000
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("span", { children: [
|
|
12001
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("b", { children: field.label }),
|
|
11334
12002
|
field.render?.(incoming[field.id], incoming) ?? valueText(incoming[field.id])
|
|
11335
12003
|
] }, field.id)) })
|
|
11336
12004
|
] }),
|
|
11337
|
-
onBulkDecision && /* @__PURE__ */ (0,
|
|
11338
|
-
/* @__PURE__ */ (0,
|
|
11339
|
-
/* @__PURE__ */ (0,
|
|
11340
|
-
/* @__PURE__ */ (0,
|
|
12005
|
+
onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": labels.bulk, children: [
|
|
12006
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { children: fillLabel(labels.selectedCount, { count: selection.size }) }),
|
|
12007
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("accept"), children: bulkPending ? labels.applying : labels.acceptSelected }),
|
|
12008
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("dismiss"), children: bulkPending ? labels.applying : labels.dismissSelected })
|
|
11341
12009
|
] }),
|
|
11342
|
-
/* @__PURE__ */ (0,
|
|
11343
|
-
/* @__PURE__ */ (0,
|
|
11344
|
-
/* @__PURE__ */ (0,
|
|
11345
|
-
/* @__PURE__ */ (0,
|
|
11346
|
-
/* @__PURE__ */ (0,
|
|
11347
|
-
fields.map((field) => /* @__PURE__ */ (0,
|
|
11348
|
-
/* @__PURE__ */ (0,
|
|
11349
|
-
/* @__PURE__ */ (0,
|
|
12010
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
|
|
12011
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("caption", { className: "uix-visually-hidden", children: labels.caption }),
|
|
12012
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("tr", { children: [
|
|
12013
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "uix-visually-hidden", children: labels.select }) }),
|
|
12014
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("th", { scope: "col", children: labels.confidence }),
|
|
12015
|
+
fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("th", { scope: "col", children: field.label }, field.id)),
|
|
12016
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("th", { scope: "col", children: labels.status }),
|
|
12017
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("th", { scope: "col", children: labels.actions })
|
|
11350
12018
|
] }) }),
|
|
11351
|
-
/* @__PURE__ */ (0,
|
|
12019
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("tbody", { children: candidates.map((candidate) => {
|
|
11352
12020
|
const resolved = candidate.status === "resolved";
|
|
11353
|
-
return /* @__PURE__ */ (0,
|
|
11354
|
-
/* @__PURE__ */ (0,
|
|
11355
|
-
/* @__PURE__ */ (0,
|
|
11356
|
-
fields.map((field) => /* @__PURE__ */ (0,
|
|
11357
|
-
/* @__PURE__ */ (0,
|
|
11358
|
-
/* @__PURE__ */ (0,
|
|
12021
|
+
return /* @__PURE__ */ (0, import_jsx_runtime91.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
|
|
12022
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": fillLabel(labels.selectCandidate, { id: candidate.id }) }) }),
|
|
12023
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? labels.notScored : `${Math.round(candidate.confidence * 100)}%` }) }),
|
|
12024
|
+
fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
|
|
12025
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ? decisionLabel[candidate.decision] : labels.resolved : labels.pending }) }),
|
|
12026
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime91.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime91.jsx)(
|
|
11359
12027
|
"button",
|
|
11360
12028
|
{
|
|
11361
12029
|
type: "button",
|
|
@@ -11369,12 +12037,12 @@ function MatchReview({
|
|
|
11369
12037
|
] }, candidate.id);
|
|
11370
12038
|
}) })
|
|
11371
12039
|
] }) }),
|
|
11372
|
-
/* @__PURE__ */ (0,
|
|
12040
|
+
/* @__PURE__ */ (0, import_jsx_runtime91.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
11373
12041
|
] });
|
|
11374
12042
|
}
|
|
11375
12043
|
|
|
11376
12044
|
// src/components/MetricInput.tsx
|
|
11377
|
-
var
|
|
12045
|
+
var import_react65 = require("react");
|
|
11378
12046
|
|
|
11379
12047
|
// src/metric-model.ts
|
|
11380
12048
|
function decimals(value) {
|
|
@@ -11399,7 +12067,7 @@ function parseMetricValue(value) {
|
|
|
11399
12067
|
}
|
|
11400
12068
|
|
|
11401
12069
|
// src/components/MetricInput.tsx
|
|
11402
|
-
var
|
|
12070
|
+
var import_jsx_runtime92 = require("react/jsx-runtime");
|
|
11403
12071
|
var defaultMetricFormat = (input) => input == null ? "" : String(input);
|
|
11404
12072
|
function MetricInput({
|
|
11405
12073
|
value,
|
|
@@ -11418,11 +12086,11 @@ function MetricInput({
|
|
|
11418
12086
|
className,
|
|
11419
12087
|
id: providedId
|
|
11420
12088
|
}) {
|
|
11421
|
-
const generatedId = (0,
|
|
12089
|
+
const generatedId = (0, import_react65.useId)();
|
|
11422
12090
|
const id = providedId ?? generatedId;
|
|
11423
12091
|
const errorId = `${id}-error`;
|
|
11424
|
-
const [text, setText] = (0,
|
|
11425
|
-
(0,
|
|
12092
|
+
const [text, setText] = (0, import_react65.useState)(() => format(value));
|
|
12093
|
+
(0, import_react65.useEffect)(() => setText(format(value)), [value, format]);
|
|
11426
12094
|
const commit = (input) => {
|
|
11427
12095
|
const parsed = parse(input);
|
|
11428
12096
|
if (input.trim() === "" || parsed !== null) {
|
|
@@ -11448,10 +12116,10 @@ function MetricInput({
|
|
|
11448
12116
|
const parsed = parse(event.currentTarget.value);
|
|
11449
12117
|
setText(parsed === null && event.currentTarget.value.trim() !== "" ? format(value) : format(parsed));
|
|
11450
12118
|
};
|
|
11451
|
-
return /* @__PURE__ */ (0,
|
|
11452
|
-
/* @__PURE__ */ (0,
|
|
11453
|
-
/* @__PURE__ */ (0,
|
|
11454
|
-
/* @__PURE__ */ (0,
|
|
12119
|
+
return /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
|
|
12120
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
|
|
12121
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("div", { className: "uix-metric-input__control", children: [
|
|
12122
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)(
|
|
11455
12123
|
Input,
|
|
11456
12124
|
{
|
|
11457
12125
|
id,
|
|
@@ -11470,22 +12138,22 @@ function MetricInput({
|
|
|
11470
12138
|
readOnly
|
|
11471
12139
|
}
|
|
11472
12140
|
),
|
|
11473
|
-
unit && /* @__PURE__ */ (0,
|
|
11474
|
-
/* @__PURE__ */ (0,
|
|
11475
|
-
/* @__PURE__ */ (0,
|
|
11476
|
-
/* @__PURE__ */ (0,
|
|
12141
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
|
|
12142
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("span", { className: "uix-metric-input__steps", children: [
|
|
12143
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
|
|
12144
|
+
/* @__PURE__ */ (0, import_jsx_runtime92.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
|
|
11477
12145
|
] })
|
|
11478
12146
|
] }),
|
|
11479
|
-
unit && /* @__PURE__ */ (0,
|
|
12147
|
+
unit && /* @__PURE__ */ (0, import_jsx_runtime92.jsxs)("span", { className: "uix-visually-hidden", children: [
|
|
11480
12148
|
"Unit: ",
|
|
11481
12149
|
unit
|
|
11482
12150
|
] }),
|
|
11483
|
-
invalid && errorMessage && /* @__PURE__ */ (0,
|
|
12151
|
+
invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime92.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
|
|
11484
12152
|
] });
|
|
11485
12153
|
}
|
|
11486
12154
|
|
|
11487
12155
|
// src/components/LicensePositionBar.tsx
|
|
11488
|
-
var
|
|
12156
|
+
var import_jsx_runtime93 = require("react/jsx-runtime");
|
|
11489
12157
|
var defaultCapacityFormat = (value) => new Intl.NumberFormat().format(value);
|
|
11490
12158
|
function LicensePositionBar({
|
|
11491
12159
|
consumed,
|
|
@@ -11506,18 +12174,18 @@ function LicensePositionBar({
|
|
|
11506
12174
|
const percent = safeEntitled === 0 ? safeConsumed > 0 ? 100 : 0 : safeConsumed / safeEntitled * 100;
|
|
11507
12175
|
const format = (value) => `${formatValue(value)}${unit ? ` ${unit}` : ""}`;
|
|
11508
12176
|
const summary = `${consumedLabel}: ${format(safeConsumed)}. ${entitledLabel}: ${format(safeEntitled)}. ${over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}`}.`;
|
|
11509
|
-
return /* @__PURE__ */ (0,
|
|
11510
|
-
/* @__PURE__ */ (0,
|
|
11511
|
-
/* @__PURE__ */ (0,
|
|
12177
|
+
return /* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
|
|
12178
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "uix-license-position__header", children: [
|
|
12179
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("span", { className: "uix-license-position__value", children: [
|
|
11512
12180
|
format(safeConsumed),
|
|
11513
12181
|
" / ",
|
|
11514
12182
|
format(safeEntitled)
|
|
11515
12183
|
] }),
|
|
11516
|
-
/* @__PURE__ */ (0,
|
|
12184
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
|
|
11517
12185
|
] }),
|
|
11518
|
-
/* @__PURE__ */ (0,
|
|
11519
|
-
/* @__PURE__ */ (0,
|
|
11520
|
-
over > 0 && /* @__PURE__ */ (0,
|
|
12186
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsxs)("div", { className: "uix-license-position__track", children: [
|
|
12187
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
|
|
12188
|
+
over > 0 && /* @__PURE__ */ (0, import_jsx_runtime93.jsx)(
|
|
11521
12189
|
"span",
|
|
11522
12190
|
{
|
|
11523
12191
|
className: "uix-license-position__overflow",
|
|
@@ -11526,12 +12194,12 @@ function LicensePositionBar({
|
|
|
11526
12194
|
}
|
|
11527
12195
|
)
|
|
11528
12196
|
] }),
|
|
11529
|
-
/* @__PURE__ */ (0,
|
|
12197
|
+
/* @__PURE__ */ (0, import_jsx_runtime93.jsx)("span", { className: "uix-visually-hidden", children: summary })
|
|
11530
12198
|
] });
|
|
11531
12199
|
}
|
|
11532
12200
|
|
|
11533
12201
|
// src/components/BrandProfiles.tsx
|
|
11534
|
-
var
|
|
12202
|
+
var import_react67 = require("react");
|
|
11535
12203
|
|
|
11536
12204
|
// src/color-model.ts
|
|
11537
12205
|
var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
|
|
@@ -11600,8 +12268,8 @@ function meetsContrast(background, foreground, minimum = 4.5) {
|
|
|
11600
12268
|
}
|
|
11601
12269
|
|
|
11602
12270
|
// src/components/ColorPicker.tsx
|
|
11603
|
-
var
|
|
11604
|
-
var
|
|
12271
|
+
var import_react66 = require("react");
|
|
12272
|
+
var import_jsx_runtime94 = require("react/jsx-runtime");
|
|
11605
12273
|
var DEFAULT_COLOR_PICKER_LABELS = {
|
|
11606
12274
|
trigger: "{label}: {color}",
|
|
11607
12275
|
sample: "Aa",
|
|
@@ -11632,17 +12300,17 @@ function ColorPicker({
|
|
|
11632
12300
|
labels: labelOverrides
|
|
11633
12301
|
}) {
|
|
11634
12302
|
const labels = { ...DEFAULT_COLOR_PICKER_LABELS, ...labelOverrides };
|
|
11635
|
-
const id = (0,
|
|
11636
|
-
const triggerRef = (0,
|
|
11637
|
-
const dialogRef = (0,
|
|
11638
|
-
const [open, setOpen] = (0,
|
|
12303
|
+
const id = (0, import_react66.useId)();
|
|
12304
|
+
const triggerRef = (0, import_react66.useRef)(null);
|
|
12305
|
+
const dialogRef = (0, import_react66.useRef)(null);
|
|
12306
|
+
const [open, setOpen] = (0, import_react66.useState)(false);
|
|
11639
12307
|
const normalized = normalizeHex(value) ?? "#000000";
|
|
11640
|
-
const [hexText, setHexText] = (0,
|
|
11641
|
-
const hsv = (0,
|
|
12308
|
+
const [hexText, setHexText] = (0, import_react66.useState)(normalized);
|
|
12309
|
+
const hsv = (0, import_react66.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
|
|
11642
12310
|
const ratio = contrastRatio(normalized, foreground) ?? 0;
|
|
11643
12311
|
const passes = ratio >= minimumContrast;
|
|
11644
|
-
(0,
|
|
11645
|
-
(0,
|
|
12312
|
+
(0, import_react66.useEffect)(() => setHexText(normalized), [normalized]);
|
|
12313
|
+
(0, import_react66.useEffect)(() => {
|
|
11646
12314
|
if (!open) return;
|
|
11647
12315
|
const dialog = dialogRef.current;
|
|
11648
12316
|
dialog?.querySelector("input,button")?.focus();
|
|
@@ -11685,8 +12353,8 @@ function ColorPicker({
|
|
|
11685
12353
|
if (next) onChange(next);
|
|
11686
12354
|
};
|
|
11687
12355
|
const sampleStyle = { backgroundColor: normalized };
|
|
11688
|
-
return /* @__PURE__ */ (0,
|
|
11689
|
-
/* @__PURE__ */ (0,
|
|
12356
|
+
return /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: cx("uix-color-picker", className), children: [
|
|
12357
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(
|
|
11690
12358
|
"button",
|
|
11691
12359
|
{
|
|
11692
12360
|
ref: triggerRef,
|
|
@@ -11698,12 +12366,12 @@ function ColorPicker({
|
|
|
11698
12366
|
onClick: () => setOpen((current) => !current),
|
|
11699
12367
|
disabled,
|
|
11700
12368
|
children: [
|
|
11701
|
-
/* @__PURE__ */ (0,
|
|
11702
|
-
/* @__PURE__ */ (0,
|
|
12369
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
|
|
12370
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { children: normalized })
|
|
11703
12371
|
]
|
|
11704
12372
|
}
|
|
11705
12373
|
),
|
|
11706
|
-
open && /* @__PURE__ */ (0,
|
|
12374
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)(
|
|
11707
12375
|
"div",
|
|
11708
12376
|
{
|
|
11709
12377
|
ref: dialogRef,
|
|
@@ -11714,55 +12382,55 @@ function ColorPicker({
|
|
|
11714
12382
|
className: "uix-color-picker__popover",
|
|
11715
12383
|
onKeyDown: onDialogKeyDown,
|
|
11716
12384
|
children: [
|
|
11717
|
-
/* @__PURE__ */ (0,
|
|
11718
|
-
/* @__PURE__ */ (0,
|
|
12385
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("span", { style: { color: foreground }, children: labels.sample }) }),
|
|
12386
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11719
12387
|
labels.hue,
|
|
11720
12388
|
" ",
|
|
11721
|
-
/* @__PURE__ */ (0,
|
|
12389
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { children: [
|
|
11722
12390
|
Math.round(hsv.h),
|
|
11723
12391
|
"\xB0"
|
|
11724
12392
|
] }),
|
|
11725
|
-
/* @__PURE__ */ (0,
|
|
12393
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
|
|
11726
12394
|
] }),
|
|
11727
|
-
/* @__PURE__ */ (0,
|
|
12395
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11728
12396
|
labels.saturation,
|
|
11729
12397
|
" ",
|
|
11730
|
-
/* @__PURE__ */ (0,
|
|
12398
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { children: [
|
|
11731
12399
|
Math.round(hsv.s * 100),
|
|
11732
12400
|
"%"
|
|
11733
12401
|
] }),
|
|
11734
|
-
/* @__PURE__ */ (0,
|
|
12402
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
|
|
11735
12403
|
] }),
|
|
11736
|
-
/* @__PURE__ */ (0,
|
|
12404
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("label", { className: "uix-color-picker__range", children: [
|
|
11737
12405
|
labels.brightness,
|
|
11738
12406
|
" ",
|
|
11739
|
-
/* @__PURE__ */ (0,
|
|
12407
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { children: [
|
|
11740
12408
|
Math.round(hsv.v * 100),
|
|
11741
12409
|
"%"
|
|
11742
12410
|
] }),
|
|
11743
|
-
/* @__PURE__ */ (0,
|
|
12411
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
|
|
11744
12412
|
] }),
|
|
11745
|
-
/* @__PURE__ */ (0,
|
|
12413
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("label", { className: "uix-color-picker__hex", children: [
|
|
11746
12414
|
labels.hex,
|
|
11747
|
-
/* @__PURE__ */ (0,
|
|
11748
|
-
/* @__PURE__ */ (0,
|
|
12415
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
|
|
12416
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
|
|
11749
12417
|
if (event.key === "Enter") commitHex();
|
|
11750
12418
|
}, "aria-invalid": !normalizeHex(hexText) }),
|
|
11751
|
-
/* @__PURE__ */ (0,
|
|
12419
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: labels.set })
|
|
11752
12420
|
] })
|
|
11753
12421
|
] }),
|
|
11754
|
-
(presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0,
|
|
11755
|
-
presets.length > 0 && /* @__PURE__ */ (0,
|
|
11756
|
-
/* @__PURE__ */ (0,
|
|
11757
|
-
/* @__PURE__ */ (0,
|
|
12422
|
+
(presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("div", { className: "uix-color-picker__palettes", children: [
|
|
12423
|
+
presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("fieldset", { children: [
|
|
12424
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("legend", { children: labels.presets }),
|
|
12425
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.usePreset, { color }) }, color)) })
|
|
11758
12426
|
] }),
|
|
11759
|
-
recent.length > 0 && /* @__PURE__ */ (0,
|
|
11760
|
-
/* @__PURE__ */ (0,
|
|
11761
|
-
/* @__PURE__ */ (0,
|
|
12427
|
+
recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime94.jsxs)("fieldset", { children: [
|
|
12428
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("legend", { children: labels.recent }),
|
|
12429
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.useRecent, { color }) }, color)) })
|
|
11762
12430
|
] })
|
|
11763
12431
|
] }),
|
|
11764
|
-
/* @__PURE__ */ (0,
|
|
11765
|
-
/* @__PURE__ */ (0,
|
|
12432
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("p", { className: cx("uix-color-picker__contrast", passes ? "uix-color-picker__contrast--pass" : "uix-color-picker__contrast--fail"), role: "status", "aria-live": "polite", children: fillLabel(passes ? labels.contrastPasses : labels.contrastFails, { ratio: ratio.toFixed(2), minimum: minimumContrast }) }),
|
|
12433
|
+
/* @__PURE__ */ (0, import_jsx_runtime94.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: labels.done })
|
|
11766
12434
|
]
|
|
11767
12435
|
}
|
|
11768
12436
|
)
|
|
@@ -11770,7 +12438,7 @@ function ColorPicker({
|
|
|
11770
12438
|
}
|
|
11771
12439
|
|
|
11772
12440
|
// src/components/BrandProfiles.tsx
|
|
11773
|
-
var
|
|
12441
|
+
var import_jsx_runtime95 = require("react/jsx-runtime");
|
|
11774
12442
|
var PROFILE_PROPERTIES = {
|
|
11775
12443
|
brand: "--uix-brand",
|
|
11776
12444
|
brandForeground: "--uix-brand-fg",
|
|
@@ -11862,7 +12530,7 @@ function BrandProfileEditor({
|
|
|
11862
12530
|
labels: labelOverrides
|
|
11863
12531
|
}) {
|
|
11864
12532
|
const labels = { ...DEFAULT_BRAND_PROFILE_EDITOR_LABELS, ...labelOverrides };
|
|
11865
|
-
const [announcement, setAnnouncement] = (0,
|
|
12533
|
+
const [announcement, setAnnouncement] = (0, import_react67.useState)("");
|
|
11866
12534
|
const update = (patch) => onChange({ ...value, ...patch });
|
|
11867
12535
|
const apply = () => {
|
|
11868
12536
|
if (applyTarget !== null) applyBrandProfile(value, applyTarget);
|
|
@@ -11879,54 +12547,54 @@ function BrandProfileEditor({
|
|
|
11879
12547
|
...value.typography?.sans ? { "--uix-font-sans": value.typography.sans } : {},
|
|
11880
12548
|
...value.typography?.heading ? { "--uix-font-heading": value.typography.heading } : {}
|
|
11881
12549
|
};
|
|
11882
|
-
return /* @__PURE__ */ (0,
|
|
11883
|
-
/* @__PURE__ */ (0,
|
|
11884
|
-
profiles.length > 0 && /* @__PURE__ */ (0,
|
|
12550
|
+
return /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": labels.region, children: [
|
|
12551
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-brand-profiles__form", children: [
|
|
12552
|
+
profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-field__label", children: [
|
|
11885
12553
|
labels.profile,
|
|
11886
|
-
/* @__PURE__ */ (0,
|
|
12554
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
|
|
11887
12555
|
const selected = profiles.find((profile) => profile.id === event.currentTarget.value);
|
|
11888
12556
|
if (selected) onSelectProfile?.(selected);
|
|
11889
|
-
}, children: profiles.map((profile) => /* @__PURE__ */ (0,
|
|
12557
|
+
}, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
|
|
11890
12558
|
] }),
|
|
11891
|
-
/* @__PURE__ */ (0,
|
|
12559
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-field__label", children: [
|
|
11892
12560
|
labels.name,
|
|
11893
|
-
/* @__PURE__ */ (0,
|
|
12561
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
|
|
11894
12562
|
] }),
|
|
11895
|
-
/* @__PURE__ */ (0,
|
|
11896
|
-
/* @__PURE__ */ (0,
|
|
12563
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
|
|
12564
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { children: [
|
|
11897
12565
|
labels.brand,
|
|
11898
|
-
/* @__PURE__ */ (0,
|
|
12566
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(ColorPicker, { label: labels.brandColor, value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
|
|
11899
12567
|
] }),
|
|
11900
|
-
/* @__PURE__ */ (0,
|
|
12568
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { children: [
|
|
11901
12569
|
labels.onBrand,
|
|
11902
|
-
/* @__PURE__ */ (0,
|
|
12570
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)(ColorPicker, { label: labels.onBrandColor, value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
|
|
11903
12571
|
] })
|
|
11904
12572
|
] }),
|
|
11905
|
-
/* @__PURE__ */ (0,
|
|
12573
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-field__label", children: [
|
|
11906
12574
|
labels.bodyFont,
|
|
11907
|
-
/* @__PURE__ */ (0,
|
|
12575
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
|
|
11908
12576
|
] }),
|
|
11909
|
-
/* @__PURE__ */ (0,
|
|
12577
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-field__label", children: [
|
|
11910
12578
|
labels.headingFont,
|
|
11911
|
-
/* @__PURE__ */ (0,
|
|
12579
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
|
|
11912
12580
|
] }),
|
|
11913
|
-
/* @__PURE__ */ (0,
|
|
12581
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
|
|
11914
12582
|
labels.logoFile,
|
|
11915
|
-
/* @__PURE__ */ (0,
|
|
12583
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
|
|
11916
12584
|
] }),
|
|
11917
|
-
/* @__PURE__ */ (0,
|
|
11918
|
-
/* @__PURE__ */ (0,
|
|
12585
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: labels.apply }),
|
|
12586
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
|
|
11919
12587
|
] }),
|
|
11920
|
-
/* @__PURE__ */ (0,
|
|
11921
|
-
/* @__PURE__ */ (0,
|
|
11922
|
-
value.logo ? /* @__PURE__ */ (0,
|
|
11923
|
-
/* @__PURE__ */ (0,
|
|
12588
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": fillLabel(labels.preview, { name: value.name }), children: [
|
|
12589
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
|
|
12590
|
+
value.logo ? /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime95.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: labels.logoPlaceholder }),
|
|
12591
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("strong", { children: value.name || labels.previewTitleFallback })
|
|
11924
12592
|
] }),
|
|
11925
|
-
/* @__PURE__ */ (0,
|
|
11926
|
-
/* @__PURE__ */ (0,
|
|
11927
|
-
/* @__PURE__ */ (0,
|
|
11928
|
-
/* @__PURE__ */ (0,
|
|
11929
|
-
/* @__PURE__ */ (0,
|
|
12593
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
|
|
12594
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("h3", { children: labels.previewHeading }),
|
|
12595
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("p", { children: labels.previewBody }),
|
|
12596
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: labels.previewPrimary }),
|
|
12597
|
+
/* @__PURE__ */ (0, import_jsx_runtime95.jsx)("a", { href: "#brand-profile-preview", children: labels.previewLink })
|
|
11930
12598
|
] })
|
|
11931
12599
|
] })
|
|
11932
12600
|
] });
|
|
@@ -11934,7 +12602,7 @@ function BrandProfileEditor({
|
|
|
11934
12602
|
var BrandProfiles = BrandProfileEditor;
|
|
11935
12603
|
|
|
11936
12604
|
// src/components/DiffViewer.tsx
|
|
11937
|
-
var
|
|
12605
|
+
var import_react68 = require("react");
|
|
11938
12606
|
|
|
11939
12607
|
// src/diff-model.ts
|
|
11940
12608
|
function isJsonObject(value) {
|
|
@@ -11985,7 +12653,7 @@ function summarizeDiff(entries, resolutions = {}) {
|
|
|
11985
12653
|
}
|
|
11986
12654
|
|
|
11987
12655
|
// src/components/DiffViewer.tsx
|
|
11988
|
-
var
|
|
12656
|
+
var import_jsx_runtime96 = require("react/jsx-runtime");
|
|
11989
12657
|
var DEFAULT_DIFF_VIEWER_LABELS = {
|
|
11990
12658
|
base: "Base",
|
|
11991
12659
|
current: "Current",
|
|
@@ -12030,33 +12698,33 @@ function DiffViewer({
|
|
|
12030
12698
|
const labels = { ...DEFAULT_DIFF_VIEWER_LABELS, ...labelOverrides };
|
|
12031
12699
|
const resolutionLabel = { accept: labels.resolutionAccept, skip: labels.resolutionSkip, pending: labels.resolutionPending };
|
|
12032
12700
|
const buttonSize = controlSize === "md" ? void 0 : `uix-btn--${controlSize}`;
|
|
12033
|
-
const id = (0,
|
|
12034
|
-
const entries = (0,
|
|
12035
|
-
const [internalResolutions, setInternalResolutions] = (0,
|
|
12701
|
+
const id = (0, import_react68.useId)();
|
|
12702
|
+
const entries = (0, import_react68.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
|
|
12703
|
+
const [internalResolutions, setInternalResolutions] = (0, import_react68.useState)({});
|
|
12036
12704
|
const resolutions = controlledResolutions ?? internalResolutions;
|
|
12037
12705
|
const summary = summarizeDiff(entries, resolutions);
|
|
12038
12706
|
const resolve = (path, resolution) => {
|
|
12039
12707
|
if (controlledResolutions === void 0) setInternalResolutions((currentState) => ({ ...currentState, [path]: resolution }));
|
|
12040
12708
|
onResolutionChange?.(path, resolution);
|
|
12041
12709
|
};
|
|
12042
|
-
if (entries.length === 0) return /* @__PURE__ */ (0,
|
|
12043
|
-
/* @__PURE__ */ (0,
|
|
12044
|
-
/* @__PURE__ */ (0,
|
|
12710
|
+
if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": labels.region, children: [
|
|
12711
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("h3", { children: labels.noDifferences }),
|
|
12712
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { children: labels.noDifferencesDetail })
|
|
12045
12713
|
] });
|
|
12046
|
-
return /* @__PURE__ */ (0,
|
|
12047
|
-
/* @__PURE__ */ (0,
|
|
12048
|
-
GROUPS.map((kind) => /* @__PURE__ */ (0,
|
|
12049
|
-
/* @__PURE__ */ (0,
|
|
12714
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": labels.region, "data-control-size": controlSize, children: [
|
|
12715
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-diff-viewer__summary", role: "group", "aria-label": labels.summary, children: [
|
|
12716
|
+
GROUPS.map((kind) => /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("span", { children: [
|
|
12717
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("b", { children: summary[kind] }),
|
|
12050
12718
|
" ",
|
|
12051
12719
|
labels[kind].toLowerCase()
|
|
12052
12720
|
] }, kind)),
|
|
12053
|
-
/* @__PURE__ */ (0,
|
|
12054
|
-
/* @__PURE__ */ (0,
|
|
12721
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("span", { children: [
|
|
12722
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("b", { children: summary.resolved }),
|
|
12055
12723
|
" ",
|
|
12056
12724
|
labels.resolved
|
|
12057
12725
|
] }),
|
|
12058
|
-
/* @__PURE__ */ (0,
|
|
12059
|
-
/* @__PURE__ */ (0,
|
|
12726
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("span", { children: [
|
|
12727
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("b", { children: summary.pending }),
|
|
12060
12728
|
" ",
|
|
12061
12729
|
labels.pending
|
|
12062
12730
|
] })
|
|
@@ -12064,38 +12732,38 @@ function DiffViewer({
|
|
|
12064
12732
|
GROUPS.map((kind) => {
|
|
12065
12733
|
const grouped = entries.filter((entry) => entry.kind === kind);
|
|
12066
12734
|
if (!grouped.length) return null;
|
|
12067
|
-
return /* @__PURE__ */ (0,
|
|
12068
|
-
/* @__PURE__ */ (0,
|
|
12735
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${kind}`, children: [
|
|
12736
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("h3", { id: `${id}-${kind}`, children: [
|
|
12069
12737
|
labels[kind],
|
|
12070
12738
|
" ",
|
|
12071
|
-
/* @__PURE__ */ (0,
|
|
12739
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("span", { children: grouped.length })
|
|
12072
12740
|
] }),
|
|
12073
12741
|
grouped.map((entry) => {
|
|
12074
12742
|
const resolution = resolutions[entry.path] ?? "pending";
|
|
12075
|
-
return /* @__PURE__ */ (0,
|
|
12076
|
-
/* @__PURE__ */ (0,
|
|
12077
|
-
/* @__PURE__ */ (0,
|
|
12078
|
-
/* @__PURE__ */ (0,
|
|
12743
|
+
return /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
|
|
12744
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("summary", { children: [
|
|
12745
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("code", { children: entry.path }),
|
|
12746
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolutionLabel[resolution] })
|
|
12079
12747
|
] }),
|
|
12080
|
-
/* @__PURE__ */ (0,
|
|
12081
|
-
/* @__PURE__ */ (0,
|
|
12082
|
-
/* @__PURE__ */ (0,
|
|
12748
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { role: "region", "aria-label": fillLabel(labels.valueFor, { version: labels[version], path: entry.path }), children: [
|
|
12749
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("strong", { children: labels[version] }),
|
|
12750
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("pre", { children: renderValue(entry[version], labels.notPresent) })
|
|
12083
12751
|
] }, version)) }),
|
|
12084
|
-
/* @__PURE__ */ (0,
|
|
12085
|
-
/* @__PURE__ */ (0,
|
|
12086
|
-
/* @__PURE__ */ (0,
|
|
12087
|
-
/* @__PURE__ */ (0,
|
|
12752
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsxs)("div", { className: "uix-diff-viewer__actions", role: "group", "aria-label": fillLabel(labels.resolve, { path: entry.path }), children: [
|
|
12753
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--primary", buttonSize), "aria-label": fillLabel(labels.acceptIncomingFor, { path: entry.path }), "aria-pressed": resolution === "accept", onClick: () => resolve(entry.path, "accept"), children: labels.acceptIncoming }),
|
|
12754
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--secondary", buttonSize), "aria-label": fillLabel(labels.keepCurrentFor, { path: entry.path }), "aria-pressed": resolution === "skip", onClick: () => resolve(entry.path, "skip"), children: labels.keepCurrent }),
|
|
12755
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("button", { type: "button", className: cx("uix-btn uix-btn--ghost", buttonSize), "aria-label": fillLabel(labels.markPendingFor, { path: entry.path }), "aria-pressed": resolution === "pending", onClick: () => resolve(entry.path, "pending"), children: labels.markPending })
|
|
12088
12756
|
] })
|
|
12089
12757
|
] }, entry.path);
|
|
12090
12758
|
})
|
|
12091
12759
|
] }, kind);
|
|
12092
12760
|
}),
|
|
12093
|
-
/* @__PURE__ */ (0,
|
|
12761
|
+
/* @__PURE__ */ (0, import_jsx_runtime96.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: fillLabel(labels.progress, { resolved: summary.resolved, total: entries.length }) })
|
|
12094
12762
|
] });
|
|
12095
12763
|
}
|
|
12096
12764
|
|
|
12097
12765
|
// src/components/TextDiff.tsx
|
|
12098
|
-
var
|
|
12766
|
+
var import_react69 = require("react");
|
|
12099
12767
|
|
|
12100
12768
|
// src/text-diff-model.ts
|
|
12101
12769
|
var WORD_TOKENS = /\s+|[\p{L}\p{M}\p{N}_]+|[^\s\p{L}\p{M}\p{N}_]/gu;
|
|
@@ -12355,7 +13023,7 @@ function textDiffRows(result, { context } = {}) {
|
|
|
12355
13023
|
}
|
|
12356
13024
|
|
|
12357
13025
|
// src/components/TextDiff.tsx
|
|
12358
|
-
var
|
|
13026
|
+
var import_jsx_runtime97 = require("react/jsx-runtime");
|
|
12359
13027
|
var DEFAULT_TEXT_DIFF_LABELS = {
|
|
12360
13028
|
before: "Before",
|
|
12361
13029
|
after: "After",
|
|
@@ -12368,47 +13036,47 @@ var DEFAULT_TEXT_DIFF_LABELS = {
|
|
|
12368
13036
|
};
|
|
12369
13037
|
function Marked({ segments, side, labels, whole }) {
|
|
12370
13038
|
const Tag = side === "before" ? "del" : "ins";
|
|
12371
|
-
return /* @__PURE__ */ (0,
|
|
12372
|
-
/* @__PURE__ */ (0,
|
|
13039
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_jsx_runtime97.Fragment, { children: segments.map((segment, i) => segment.changed ? /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(Tag, { "data-whole": whole || void 0, children: [
|
|
13040
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { className: "uix-visually-hidden", children: [
|
|
12373
13041
|
side === "before" ? labels.removed : labels.added,
|
|
12374
13042
|
": "
|
|
12375
13043
|
] }),
|
|
12376
13044
|
segment.text
|
|
12377
|
-
] }, i) : /* @__PURE__ */ (0,
|
|
13045
|
+
] }, i) : /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_react69.Fragment, { children: segment.text }, i)) });
|
|
12378
13046
|
}
|
|
12379
13047
|
function Cell({ line, side, kind, labels }) {
|
|
12380
|
-
if (!line) return /* @__PURE__ */ (0,
|
|
13048
|
+
if (!line) return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__cell", "data-side": side, "data-empty": "", "aria-hidden": "true" });
|
|
12381
13049
|
const changed = kind !== "equal";
|
|
12382
|
-
return /* @__PURE__ */ (0,
|
|
12383
|
-
/* @__PURE__ */ (0,
|
|
12384
|
-
/* @__PURE__ */ (0,
|
|
12385
|
-
/* @__PURE__ */ (0,
|
|
13050
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-text-diff__cell", "data-side": side, "data-kind": changed ? side === "before" ? "delete" : "insert" : "equal", children: [
|
|
13051
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "uix-text-diff__num", "aria-hidden": "true", children: line.number }),
|
|
13052
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "uix-text-diff__sign", "aria-hidden": "true", children: changed ? side === "before" ? "\u2212" : "+" : "" }),
|
|
13053
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { className: "uix-text-diff__text", children: line.segments.length === 1 && line.segments[0].text === "" ? "\u200B" : /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Marked, { segments: line.segments, side, labels, whole: line.segments.length === 1 }) })
|
|
12386
13054
|
] });
|
|
12387
13055
|
}
|
|
12388
13056
|
function Rows({ rows, view, labels, focusFirst }) {
|
|
12389
|
-
const [open, setOpen] = (0,
|
|
12390
|
-
const first = (0,
|
|
12391
|
-
(0,
|
|
13057
|
+
const [open, setOpen] = (0, import_react69.useState)(() => /* @__PURE__ */ new Set());
|
|
13058
|
+
const first = (0, import_react69.useRef)(null);
|
|
13059
|
+
(0, import_react69.useEffect)(() => {
|
|
12392
13060
|
if (focusFirst) first.current?.focus();
|
|
12393
13061
|
}, [focusFirst]);
|
|
12394
13062
|
const firstProps = (index) => focusFirst && index === 0 ? { ref: first, tabIndex: -1 } : {};
|
|
12395
|
-
return /* @__PURE__ */ (0,
|
|
13063
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_jsx_runtime97.Fragment, { children: rows.map((row, index) => {
|
|
12396
13064
|
if (row.kind === "fold") {
|
|
12397
|
-
if (open.has(index)) return /* @__PURE__ */ (0,
|
|
12398
|
-
return /* @__PURE__ */ (0,
|
|
13065
|
+
if (open.has(index)) return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Rows, { rows: row.rows, view, labels, focusFirst: true }, index);
|
|
13066
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__row", "data-kind": "fold", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("button", { type: "button", className: "uix-text-diff__fold", onClick: () => setOpen((s) => new Set(s).add(index)), children: fillLabel(labels.showUnchanged, { count: row.count }) }) }, index);
|
|
12399
13067
|
}
|
|
12400
13068
|
const before = row.kind === "insert" ? void 0 : row.before;
|
|
12401
13069
|
const after = row.kind === "delete" ? void 0 : row.after;
|
|
12402
13070
|
if (view === "unified") {
|
|
12403
|
-
if (row.kind === "equal") return /* @__PURE__ */ (0,
|
|
12404
|
-
return /* @__PURE__ */ (0,
|
|
12405
|
-
before && /* @__PURE__ */ (0,
|
|
12406
|
-
after && /* @__PURE__ */ (0,
|
|
13071
|
+
if (row.kind === "equal") return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__row", "data-kind": "equal", ...firstProps(index), children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Cell, { line: after, side: "after", kind: "equal", labels }) }, index);
|
|
13072
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)(import_react69.Fragment, { children: [
|
|
13073
|
+
before && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__row", "data-kind": "delete", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Cell, { line: before, side: "before", kind: row.kind, labels }) }),
|
|
13074
|
+
after && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__row", "data-kind": "insert", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Cell, { line: after, side: "after", kind: row.kind, labels }) })
|
|
12407
13075
|
] }, index);
|
|
12408
13076
|
}
|
|
12409
|
-
return /* @__PURE__ */ (0,
|
|
12410
|
-
/* @__PURE__ */ (0,
|
|
12411
|
-
/* @__PURE__ */ (0,
|
|
13077
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-text-diff__row", "data-kind": row.kind, ...firstProps(index), children: [
|
|
13078
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Cell, { line: before, side: "before", kind: row.kind, labels }),
|
|
13079
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Cell, { line: after, side: "after", kind: row.kind, labels })
|
|
12412
13080
|
] }, index);
|
|
12413
13081
|
}) });
|
|
12414
13082
|
}
|
|
@@ -12430,41 +13098,41 @@ function TextDiff({
|
|
|
12430
13098
|
}) {
|
|
12431
13099
|
const uixLabels = useUixLabels();
|
|
12432
13100
|
const labels = { ...DEFAULT_TEXT_DIFF_LABELS, ...uixLabels.textDiff, ...labelOverrides };
|
|
12433
|
-
const result = (0,
|
|
12434
|
-
const rows = (0,
|
|
12435
|
-
const heads = /* @__PURE__ */ (0,
|
|
12436
|
-
/* @__PURE__ */ (0,
|
|
12437
|
-
view === "unified" && /* @__PURE__ */ (0,
|
|
13101
|
+
const result = (0, import_react69.useMemo)(() => diffText(before, after, { granularity, maxTokens, maxEdits }), [before, after, granularity, maxTokens, maxEdits]);
|
|
13102
|
+
const rows = (0, import_react69.useMemo)(() => granularity === "line" && result.status === "ok" ? textDiffRows(result, { context }) : [], [result, granularity, context]);
|
|
13103
|
+
const heads = /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-text-diff__heads", "aria-hidden": view === "unified" || void 0, children: [
|
|
13104
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { className: "uix-text-diff__head", "data-side": "before", children: [
|
|
13105
|
+
view === "unified" && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { "aria-hidden": "true", children: "\u2212 " }),
|
|
12438
13106
|
beforeLabel ?? labels.before
|
|
12439
13107
|
] }),
|
|
12440
|
-
/* @__PURE__ */ (0,
|
|
12441
|
-
view === "unified" && /* @__PURE__ */ (0,
|
|
13108
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("span", { className: "uix-text-diff__head", "data-side": "after", children: [
|
|
13109
|
+
view === "unified" && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("span", { "aria-hidden": "true", children: "+ " }),
|
|
12442
13110
|
afterLabel ?? labels.after
|
|
12443
13111
|
] })
|
|
12444
13112
|
] });
|
|
12445
13113
|
const unchanged = result.status === "ok" && result.added === 0 && result.removed === 0 && result.ops.every((op) => op.type === "equal");
|
|
12446
13114
|
let body;
|
|
12447
|
-
if (result.status === "too-large") body = /* @__PURE__ */ (0,
|
|
12448
|
-
else if (granularity === "line") body = /* @__PURE__ */ (0,
|
|
13115
|
+
if (result.status === "too-large") body = /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__note", children: labels.tooLarge });
|
|
13116
|
+
else if (granularity === "line") body = /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__body", children: /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Rows, { rows, view, labels }) });
|
|
12449
13117
|
else {
|
|
12450
|
-
const prose = (side2) => /* @__PURE__ */ (0,
|
|
13118
|
+
const prose = (side2) => /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__prose", "data-side": side2, children: result.ops.map((op, i) => {
|
|
12451
13119
|
const text = op.tokens.join("");
|
|
12452
|
-
if (op.type === "equal") return /* @__PURE__ */ (0,
|
|
13120
|
+
if (op.type === "equal") return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(import_react69.Fragment, { children: text }, i);
|
|
12453
13121
|
if (op.type === "delete" && side2 === "after") return null;
|
|
12454
13122
|
if (op.type === "insert" && side2 === "before") return null;
|
|
12455
|
-
return /* @__PURE__ */ (0,
|
|
13123
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsx)(Marked, { segments: [{ text, changed: true }], side: op.type === "delete" ? "before" : "after", labels }, i);
|
|
12456
13124
|
}) });
|
|
12457
|
-
const side = (which) => /* @__PURE__ */ (0,
|
|
12458
|
-
/* @__PURE__ */ (0,
|
|
13125
|
+
const side = (which) => /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-text-diff__side", children: [
|
|
13126
|
+
/* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__head", children: which === "before" ? beforeLabel ?? labels.before : afterLabel ?? labels.after }),
|
|
12459
13127
|
prose(which)
|
|
12460
13128
|
] });
|
|
12461
|
-
body = /* @__PURE__ */ (0,
|
|
13129
|
+
body = /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__body", children: view === "unified" ? prose("both") : /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { className: "uix-text-diff__row", "data-kind": "prose", children: [
|
|
12462
13130
|
side("before"),
|
|
12463
13131
|
side("after")
|
|
12464
13132
|
] }) });
|
|
12465
13133
|
}
|
|
12466
|
-
return /* @__PURE__ */ (0,
|
|
12467
|
-
!hideSummary && result.status === "ok" && /* @__PURE__ */ (0,
|
|
13134
|
+
return /* @__PURE__ */ (0, import_jsx_runtime97.jsxs)("div", { role: "group", "aria-label": label, className: cx("uix-text-diff", className), "data-view": view, "data-granularity": granularity, ...props, children: [
|
|
13135
|
+
!hideSummary && result.status === "ok" && /* @__PURE__ */ (0, import_jsx_runtime97.jsx)("div", { className: "uix-text-diff__summary", children: unchanged ? labels.noChanges : fillLabel(labels.summary, { added: result.added, removed: result.removed }) }),
|
|
12468
13136
|
!(granularity === "word" && view === "split" && result.status === "ok") && heads,
|
|
12469
13137
|
body
|
|
12470
13138
|
] });
|
|
@@ -12641,6 +13309,7 @@ function TextDiff({
|
|
|
12641
13309
|
Switch,
|
|
12642
13310
|
TEXT_FILTER_OPERATORS,
|
|
12643
13311
|
TOAST_LEAVE_MS,
|
|
13312
|
+
TOP_LANE_CROSS_MIDNIGHT_MINUTES,
|
|
12644
13313
|
Tab,
|
|
12645
13314
|
TabPanel,
|
|
12646
13315
|
Table,
|
|
@@ -12705,10 +13374,12 @@ function TextDiff({
|
|
|
12705
13374
|
isRuleGroup,
|
|
12706
13375
|
itemDaySpan,
|
|
12707
13376
|
layeredNeighbor,
|
|
13377
|
+
layoutDaySpans,
|
|
12708
13378
|
layoutLane,
|
|
12709
13379
|
layoutLayeredGraph,
|
|
12710
13380
|
layoutMonthSpans,
|
|
12711
13381
|
layoutRelationshipGraph,
|
|
13382
|
+
layoutTimeGridDay,
|
|
12712
13383
|
mapRuleGroup,
|
|
12713
13384
|
matchFilter,
|
|
12714
13385
|
matchFilterPreset,
|
|
@@ -12725,6 +13396,8 @@ function TextDiff({
|
|
|
12725
13396
|
partitionFiles,
|
|
12726
13397
|
pixelsToMs,
|
|
12727
13398
|
placeSpan,
|
|
13399
|
+
placesInTopLane,
|
|
13400
|
+
proposeMove,
|
|
12728
13401
|
rankOverflow,
|
|
12729
13402
|
relationshipNeighbors,
|
|
12730
13403
|
relativeTimeValue,
|