@tensor_1/react 2.29.0 → 2.30.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/dist/index.cjs CHANGED
@@ -54,6 +54,7 @@ __export(src_exports, {
54
54
  ContentList: () => ContentList,
55
55
  ContentListItem: () => ContentListItem,
56
56
  CopyButton: () => CopyButton,
57
+ DAY: () => DAY,
57
58
  DEFAULT_BRAND_PROFILE_EDITOR_LABELS: () => DEFAULT_BRAND_PROFILE_EDITOR_LABELS,
58
59
  DEFAULT_BUILDER_CANVAS_LABELS: () => DEFAULT_BUILDER_CANVAS_LABELS,
59
60
  DEFAULT_COLOR_PICKER_LABELS: () => DEFAULT_COLOR_PICKER_LABELS,
@@ -65,6 +66,7 @@ __export(src_exports, {
65
66
  DEFAULT_RULE_BUILDER_LABELS: () => DEFAULT_RULE_BUILDER_LABELS,
66
67
  DEFAULT_SAVE_STATUS_LABELS: () => DEFAULT_SAVE_STATUS_LABELS,
67
68
  DEFAULT_SCHEDULING_CALENDAR_LABELS: () => DEFAULT_SCHEDULING_CALENDAR_LABELS,
69
+ DEFAULT_SCHEDULING_TIMELINE_LABELS: () => DEFAULT_SCHEDULING_TIMELINE_LABELS,
68
70
  DEFAULT_STEP_STATE_LABELS: () => DEFAULT_STEP_STATE_LABELS,
69
71
  DateRangePicker: () => DateRangePicker,
70
72
  DescriptionItem: () => DescriptionItem,
@@ -86,6 +88,7 @@ __export(src_exports, {
86
88
  Flow: () => Flow,
87
89
  FlowNode: () => FlowNode,
88
90
  ForbiddenState: () => ForbiddenState,
91
+ HOUR: () => HOUR,
89
92
  Highlighted: () => Highlighted,
90
93
  Inbox: () => Inbox,
91
94
  InboxDetail: () => InboxDetail,
@@ -143,6 +146,7 @@ __export(src_exports, {
143
146
  SaveStatus: () => SaveStatus,
144
147
  SavedViewMenu: () => SavedViewMenu,
145
148
  SchedulingCalendar: () => SchedulingCalendar,
149
+ SchedulingTimeline: () => SchedulingTimeline,
146
150
  SearchSuggest: () => SearchSuggest,
147
151
  SectionHead: () => SectionHead,
148
152
  Segmented: () => Segmented,
@@ -198,6 +202,7 @@ __export(src_exports, {
198
202
  createToastApi: () => createToastApi,
199
203
  createToastStore: () => createToastStore,
200
204
  cx: () => cx,
205
+ defaultTimelineStep: () => defaultTimelineStep,
201
206
  enumerateDateSpan: () => enumerateDateSpan,
202
207
  filterComboboxOptions: () => filterComboboxOptions,
203
208
  findRuleNodeDepth: () => findRuleNodeDepth,
@@ -211,6 +216,7 @@ __export(src_exports, {
211
216
  isDateUnavailable: () => isDateUnavailable,
212
217
  isRuleGroup: () => isRuleGroup,
213
218
  layeredNeighbor: () => layeredNeighbor,
219
+ layoutLane: () => layoutLane,
214
220
  layoutLayeredGraph: () => layoutLayeredGraph,
215
221
  layoutRelationshipGraph: () => layoutRelationshipGraph,
216
222
  mapRuleGroup: () => mapRuleGroup,
@@ -224,6 +230,8 @@ __export(src_exports, {
224
230
  parseDateValue: () => parseDateValue,
225
231
  parseMetricValue: () => parseMetricValue,
226
232
  parseView: () => parseView,
233
+ pixelsToMs: () => pixelsToMs,
234
+ placeSpan: () => placeSpan,
227
235
  relationshipNeighbors: () => relationshipNeighbors,
228
236
  relativeTimeValue: () => relativeTimeValue,
229
237
  removeRuleNode: () => removeRuleNode,
@@ -238,11 +246,14 @@ __export(src_exports, {
238
246
  selectAllState: () => selectAllState,
239
247
  selectRangeDate: () => selectRangeDate,
240
248
  serializeView: () => serializeView,
249
+ shiftSpan: () => shiftSpan,
241
250
  shouldVirtualize: () => shouldVirtualize,
251
+ snapToStep: () => snapToStep,
242
252
  startOfMonth: () => startOfMonth,
243
253
  stepMetricValue: () => stepMetricValue,
244
254
  summarizeDiff: () => summarizeDiff,
245
255
  summarizeRule: () => summarizeRule,
256
+ timelineTicks: () => timelineTicks,
246
257
  toDateKey: () => toDateKey,
247
258
  toast: () => toast,
248
259
  toggleId: () => toggleId,
@@ -6743,9 +6754,348 @@ function SchedulingCalendar({
6743
6754
  ] });
6744
6755
  }
6745
6756
 
6746
- // src/components/DateRangePicker.tsx
6757
+ // src/components/SchedulingTimeline.tsx
6747
6758
  var import_react50 = require("react");
6759
+
6760
+ // src/scheduling-timeline-model.ts
6761
+ var HOUR = 36e5;
6762
+ var DAY = 24 * HOUR;
6763
+ var toMs = (value) => {
6764
+ const ms = typeof value === "number" ? value : Date.parse(value);
6765
+ if (Number.isNaN(ms)) throw new TypeError(`Invalid instant: ${String(value)}`);
6766
+ return ms;
6767
+ };
6768
+ var defaultTimelineStep = (scale) => scale === "hour" ? 15 * 6e4 : scale === "day" ? HOUR : DAY;
6769
+ function zonedParts(ms, timeZone) {
6770
+ const parts = new Intl.DateTimeFormat("en-US", {
6771
+ timeZone,
6772
+ hourCycle: "h23",
6773
+ year: "numeric",
6774
+ month: "numeric",
6775
+ day: "numeric",
6776
+ hour: "numeric",
6777
+ minute: "numeric",
6778
+ weekday: "short"
6779
+ }).formatToParts(new Date(ms));
6780
+ const get = (type) => parts.find((p) => p.type === type)?.value ?? "";
6781
+ return { year: +get("year"), month: +get("month"), day: +get("day"), hour: +get("hour"), minute: +get("minute"), weekday: get("weekday") };
6782
+ }
6783
+ function timelineTicks(range, scale, timeZone, weekStartsOn = 1) {
6784
+ const start = toMs(range.start);
6785
+ const end = toMs(range.end);
6786
+ if (end <= start) return [];
6787
+ const span = end - start;
6788
+ const ticks = [];
6789
+ const weekdays = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
6790
+ const step = scale === "hour" ? 15 * 6e4 : HOUR;
6791
+ let prev = zonedParts(start - step, timeZone);
6792
+ for (let at = Math.ceil(start / step) * step; at <= end && ticks.length < 500; at += step) {
6793
+ const p = zonedParts(at, timeZone);
6794
+ const newHour = p.minute === 0 && (p.hour !== prev.hour || prev.minute !== 0);
6795
+ const newDay = p.day !== prev.day && p.minute === 0;
6796
+ const newMonth = newDay && p.day === 1;
6797
+ const newWeek = newDay && weekdays.indexOf(p.weekday) === weekStartsOn;
6798
+ const isTick = scale === "hour" ? newHour : scale === "day" ? newDay : scale === "week" ? newWeek : newMonth;
6799
+ if (isTick) {
6800
+ const major = scale === "hour" ? newDay : scale === "day" ? newWeek : scale === "week" ? newMonth : p.month === 1;
6801
+ ticks.push({ at, offset: (at - start) / span * 100, major });
6802
+ }
6803
+ prev = p;
6804
+ }
6805
+ return ticks;
6806
+ }
6807
+ function placeSpan(span, range) {
6808
+ const start = toMs(range.start);
6809
+ const end = toMs(range.end);
6810
+ const s = toMs(span.start);
6811
+ const e = Math.max(toMs(span.end), s);
6812
+ if (e < start || s > end || end <= start) return null;
6813
+ const total = end - start;
6814
+ const left = (Math.max(s, start) - start) / total * 100;
6815
+ const right = (Math.min(e, end) - start) / total * 100;
6816
+ return { left, width: Math.max(right - left, 0), clippedStart: s < start, clippedEnd: e > end };
6817
+ }
6818
+ function layoutLane(items, range) {
6819
+ const sorted = [...items].sort((a, b) => toMs(a.start) - toMs(b.start) || toMs(a.end) - toMs(b.end));
6820
+ const rowEnds = [];
6821
+ const placed = [];
6822
+ for (const item of sorted) {
6823
+ const pos = placeSpan(item, range);
6824
+ if (!pos) continue;
6825
+ const s = toMs(item.start);
6826
+ let row = rowEnds.findIndex((end) => end <= s);
6827
+ if (row === -1) {
6828
+ row = rowEnds.length;
6829
+ rowEnds.push(0);
6830
+ }
6831
+ rowEnds[row] = Math.max(toMs(item.end), s);
6832
+ placed.push({ item, ...pos, row, conflict: false });
6833
+ }
6834
+ for (let i = 0; i < placed.length; i++) {
6835
+ for (let j = i + 1; j < placed.length; j++) {
6836
+ const a = placed[i].item;
6837
+ const b = placed[j].item;
6838
+ if (toMs(b.start) >= toMs(a.end)) continue;
6839
+ if (toMs(a.start) < toMs(b.end)) {
6840
+ placed[i].conflict = true;
6841
+ placed[j].conflict = true;
6842
+ }
6843
+ }
6844
+ }
6845
+ return placed;
6846
+ }
6847
+ var snapToStep = (ms, step) => Math.round(ms / step) * step;
6848
+ function shiftSpan(span, delta, mode, step) {
6849
+ const s = toMs(span.start);
6850
+ const e = toMs(span.end);
6851
+ if (mode === "move") return { start: new Date(s + delta).toISOString(), end: new Date(e + delta).toISOString() };
6852
+ return { start: new Date(s).toISOString(), end: new Date(Math.max(e + delta, s + step)).toISOString() };
6853
+ }
6854
+ function pixelsToMs(px, trackWidth, range, step) {
6855
+ if (trackWidth <= 0) return 0;
6856
+ return snapToStep(px / trackWidth * (toMs(range.end) - toMs(range.start)), step);
6857
+ }
6858
+
6859
+ // src/components/SchedulingTimeline.tsx
6748
6860
  var import_jsx_runtime73 = require("react/jsx-runtime");
6861
+ var DEFAULT_SCHEDULING_TIMELINE_LABELS = {
6862
+ region: "Schedule timeline in {timeZone}",
6863
+ lanes: "Lanes",
6864
+ item: "{title}, {state}, {start} to {end}{conflict}",
6865
+ conflict: ", overlaps another entry",
6866
+ moveHint: "Shift and an arrow key moves it; Alt, Shift and an arrow key changes when it ends.",
6867
+ moved: "Moved {title} to {start} \u2013 {end}",
6868
+ resized: "{title} now ends {end}",
6869
+ loading: "Loading schedule\u2026",
6870
+ retry: "Try again",
6871
+ empty: "Nothing is scheduled in this range.",
6872
+ windows: "Windows and markers in this range",
6873
+ now: "Now",
6874
+ states: { scheduled: "Scheduled", conflicted: "Conflicted", "in-progress": "In progress", "blackout-violation": "Blackout violation" },
6875
+ overlays: { freeze: "Change freeze", maintenance: "Maintenance window", blackout: "Blackout" }
6876
+ };
6877
+ var TICK_WIDTH = { hour: "3.5rem", day: "7rem", week: "6rem", month: "8rem" };
6878
+ var TICK_FORMAT = {
6879
+ hour: { hour: "2-digit", minute: "2-digit" },
6880
+ day: { weekday: "short", day: "numeric" },
6881
+ week: { day: "numeric", month: "short" },
6882
+ month: { month: "short", year: "numeric" }
6883
+ };
6884
+ function SchedulingTimeline({
6885
+ lanes,
6886
+ items,
6887
+ range,
6888
+ scale = "day",
6889
+ timeZone,
6890
+ locale,
6891
+ overlays = [],
6892
+ markers = [],
6893
+ now,
6894
+ weekStartsOn = 1,
6895
+ tickWidth,
6896
+ step: stepProp,
6897
+ formatTick,
6898
+ formatInstant: formatInstantProp,
6899
+ renderItem,
6900
+ onSelectItem,
6901
+ onMoveItem,
6902
+ loading,
6903
+ error,
6904
+ onRetry,
6905
+ labels: labelOverrides,
6906
+ className
6907
+ }) {
6908
+ const uixLabels = useUixLabels();
6909
+ const labels = {
6910
+ ...DEFAULT_SCHEDULING_TIMELINE_LABELS,
6911
+ ...uixLabels.schedulingTimeline,
6912
+ ...labelOverrides,
6913
+ states: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.states, ...uixLabels.schedulingTimeline?.states, ...labelOverrides?.states },
6914
+ overlays: { ...DEFAULT_SCHEDULING_TIMELINE_LABELS.overlays, ...uixLabels.schedulingTimeline?.overlays, ...labelOverrides?.overlays }
6915
+ };
6916
+ const id = (0, import_react50.useId)();
6917
+ const step = stepProp ?? defaultTimelineStep(scale);
6918
+ const ticks = (0, import_react50.useMemo)(() => timelineTicks(range, scale, timeZone, weekStartsOn), [range.start, range.end, scale, timeZone, weekStartsOn]);
6919
+ const laneLayouts = (0, import_react50.useMemo)(
6920
+ () => lanes.map((lane) => ({ lane, placed: layoutLane(items.filter((item) => item.laneId === lane.id), range) })),
6921
+ [lanes, items, range.start, range.end]
6922
+ // eslint-disable-line react-hooks/exhaustive-deps
6923
+ );
6924
+ const ordered = (0, import_react50.useMemo)(() => laneLayouts.flatMap((l) => l.placed.map((p) => p.item.id)), [laneLayouts]);
6925
+ const [activeId, setActiveId] = (0, import_react50.useState)();
6926
+ const focusId = activeId && ordered.includes(activeId) ? activeId : ordered[0];
6927
+ const [drag, setDrag] = (0, import_react50.useState)(null);
6928
+ const [announcement, setAnnouncement] = (0, import_react50.useState)("");
6929
+ const rootRef = (0, import_react50.useRef)(null);
6930
+ const fmtInstant = (instant) => formatInstantProp?.(instant) ?? new Intl.DateTimeFormat(locale, { timeZone, dateStyle: "medium", timeStyle: "short" }).format(new Date(instant));
6931
+ const fmtTick = (at) => formatTick?.(new Date(at), scale) ?? new Intl.DateTimeFormat(locale, { timeZone, ...TICK_FORMAT[scale] }).format(new Date(at));
6932
+ const movable = (item) => !!onMoveItem && item.movable !== false;
6933
+ const focusItem = (itemId) => {
6934
+ if (!itemId) return;
6935
+ setActiveId(itemId);
6936
+ requestAnimationFrame(() => rootRef.current?.querySelector(`[data-timeline-item="${CSS.escape(itemId)}"]`)?.focus());
6937
+ };
6938
+ const commit = (item, delta, mode) => {
6939
+ if (!onMoveItem || delta === 0) return;
6940
+ const next = shiftSpan(item, delta, mode, step);
6941
+ onMoveItem(item.id, next);
6942
+ setAnnouncement(mode === "move" ? fillLabel(labels.moved, { title: item.title, start: fmtInstant(next.start), end: fmtInstant(next.end) }) : fillLabel(labels.resized, { title: item.title, end: fmtInstant(next.end) }));
6943
+ };
6944
+ const onItemKeyDown = (event, laneIndex, placed, index) => {
6945
+ const item = placed[index].item;
6946
+ const horizontal = event.key === "ArrowLeft" ? -1 : event.key === "ArrowRight" ? 1 : 0;
6947
+ if (horizontal && event.shiftKey && movable(item)) {
6948
+ event.preventDefault();
6949
+ commit(item, horizontal * step, event.altKey ? "resize" : "move");
6950
+ return;
6951
+ }
6952
+ if (horizontal) {
6953
+ event.preventDefault();
6954
+ focusItem(placed[index + horizontal]?.item.id);
6955
+ return;
6956
+ }
6957
+ if (event.key === "Home" || event.key === "End") {
6958
+ event.preventDefault();
6959
+ focusItem((event.key === "Home" ? placed[0] : placed[placed.length - 1])?.item.id);
6960
+ return;
6961
+ }
6962
+ const vertical = event.key === "ArrowUp" ? -1 : event.key === "ArrowDown" ? 1 : 0;
6963
+ if (vertical) {
6964
+ event.preventDefault();
6965
+ const start = Date.parse(item.start);
6966
+ for (let l = laneIndex + vertical; l >= 0 && l < laneLayouts.length; l += vertical) {
6967
+ const candidates = laneLayouts[l].placed;
6968
+ if (candidates.length === 0) continue;
6969
+ const nearest = candidates.reduce((best, p) => Math.abs(Date.parse(p.item.start) - start) < Math.abs(Date.parse(best.item.start) - start) ? p : best);
6970
+ focusItem(nearest.item.id);
6971
+ return;
6972
+ }
6973
+ }
6974
+ };
6975
+ const onPointerDown = (event, item) => {
6976
+ if (!movable(item) || event.button !== 0) return;
6977
+ const track = event.currentTarget.closest(".uix-scheduling-timeline__track");
6978
+ if (!track) return;
6979
+ event.currentTarget.setPointerCapture?.(event.pointerId);
6980
+ setDrag({ id: item.id, x: event.clientX, width: track.getBoundingClientRect().width, delta: 0, moved: false });
6981
+ };
6982
+ const onPointerMove = (event) => {
6983
+ if (!drag) return;
6984
+ const dx = event.clientX - drag.x;
6985
+ const delta = pixelsToMs(dx, drag.width, range, step);
6986
+ if (delta !== drag.delta || !drag.moved && Math.abs(dx) > 3) setDrag({ ...drag, delta, moved: drag.moved || Math.abs(dx) > 3 });
6987
+ };
6988
+ const onPointerUp = (item) => {
6989
+ if (!drag || drag.id !== item.id) return;
6990
+ if (drag.moved) commit(item, drag.delta, "move");
6991
+ setDrag(drag.moved ? { ...drag, delta: 0 } : null);
6992
+ if (drag.moved) window.setTimeout(() => setDrag(null), 0);
6993
+ };
6994
+ const nowPos = now ? placeSpan({ start: now, end: now }, range) : null;
6995
+ const overlaysFor = (laneId) => overlays.filter((o) => !o.laneId || o.laneId === laneId);
6996
+ const markersFor = (laneId) => markers.filter((m) => !m.laneId || m.laneId === laneId);
6997
+ const trackStyle = { minWidth: `calc(${Math.max(ticks.length - 1, 1)} * ${tickWidth ?? TICK_WIDTH[scale]})` };
6998
+ const band = (o, showLabel) => {
6999
+ const pos = placeSpan(o, range);
7000
+ return pos && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__overlay", "data-kind": o.kind, style: { left: `${pos.left}%`, width: `${pos.width}%` }, children: showLabel && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__overlay-label", children: o.label }) }, o.id);
7001
+ };
7002
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("section", { ref: rootRef, className: cx("uix-scheduling-timeline", className), "aria-label": fillLabel(labels.region, { timeZone }), children: [
7003
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uix-scheduling-timeline__state", role: "status", children: labels.loading }) : error ? /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__state", role: "alert", children: [
7004
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { children: error }),
7005
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
7006
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(import_jsx_runtime73.Fragment, { children: [
7007
+ (overlays.length > 0 || markers.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-visually-hidden", children: [
7008
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { id: `${id}-windows`, children: labels.windows }),
7009
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("ul", { "aria-labelledby": `${id}-windows`, children: [
7010
+ overlays.map((o) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("li", { children: [
7011
+ labels.overlays[o.kind],
7012
+ ": ",
7013
+ o.label,
7014
+ ", ",
7015
+ fmtInstant(o.start),
7016
+ " \u2013 ",
7017
+ fmtInstant(o.end)
7018
+ ] }, o.id)),
7019
+ markers.map((m) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("li", { children: [
7020
+ m.label,
7021
+ ", ",
7022
+ fmtInstant(m.at)
7023
+ ] }, m.id))
7024
+ ] })
7025
+ ] }),
7026
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uix-scheduling-timeline__scroller", children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__grid", children: [
7027
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__row uix-scheduling-timeline__row--axis", "aria-hidden": "true", children: [
7028
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uix-scheduling-timeline__lane-label", children: labels.lanes }),
7029
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uix-scheduling-timeline__track uix-scheduling-timeline__axis", style: trackStyle, children: ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime73.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_runtime73.jsx)("span", { className: "uix-scheduling-timeline__tick-label", children: fmtTick(tick.at) }) }, tick.at)) })
7030
+ ] }),
7031
+ laneLayouts.map(({ lane, placed }, laneIndex) => {
7032
+ const rows = placed.reduce((max, p) => Math.max(max, p.row + 1), 1);
7033
+ const laneLabelId = `${id}-lane-${laneIndex}`;
7034
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__row", style: { "--uix-timeline-rows": rows }, children: [
7035
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__lane-label", id: laneLabelId, children: [
7036
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__lane-name", children: lane.label }),
7037
+ lane.meta != null && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__lane-meta", children: lane.meta })
7038
+ ] }),
7039
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-scheduling-timeline__track", style: trackStyle, children: [
7040
+ ticks.map((tick) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__gridline", "data-major": tick.major || void 0, style: { left: `${tick.offset}%` }, "aria-hidden": "true" }, tick.at)),
7041
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { "aria-hidden": "true", children: overlaysFor(lane.id).map((o) => band(o, laneIndex === 0 || !!o.laneId)) }),
7042
+ nowPos && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__now", style: { left: `${nowPos.left}%` }, "aria-hidden": "true", children: laneIndex === 0 && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__now-label", children: labels.now }) }),
7043
+ markersFor(lane.id).map((m) => {
7044
+ const pos = placeSpan({ start: m.at, end: m.at }, range);
7045
+ return pos && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__marker", style: { left: `${pos.left}%` }, title: m.label, "aria-hidden": "true" }, m.id);
7046
+ }),
7047
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("ul", { className: "uix-scheduling-timeline__items", "aria-labelledby": laneLabelId, children: placed.map((p, index) => {
7048
+ const item = p.item;
7049
+ const state = item.state ?? "scheduled";
7050
+ const dragging = drag?.id === item.id && drag.moved;
7051
+ const shown = dragging && drag ? placeSpan(shiftSpan(item, drag.delta, "move", step), range) ?? p : p;
7052
+ return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("li", { className: "uix-scheduling-timeline__slot", style: { left: `${shown.left}%`, width: `${shown.width}%`, "--uix-timeline-row": p.row }, children: /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)(
7053
+ "button",
7054
+ {
7055
+ type: "button",
7056
+ className: "uix-scheduling-timeline__item",
7057
+ "data-timeline-item": item.id,
7058
+ title: item.title,
7059
+ "data-state": state,
7060
+ "data-conflict": p.conflict || void 0,
7061
+ "data-clipped-start": p.clippedStart || void 0,
7062
+ "data-clipped-end": p.clippedEnd || void 0,
7063
+ "data-movable": movable(item) || void 0,
7064
+ "data-dragging": dragging || void 0,
7065
+ tabIndex: focusId === item.id ? 0 : -1,
7066
+ "aria-label": fillLabel(labels.item, { title: item.title, state: labels.states[state], start: fmtInstant(item.start), end: fmtInstant(item.end), conflict: p.conflict ? labels.conflict : "" }),
7067
+ "aria-describedby": movable(item) ? `${id}-hint` : void 0,
7068
+ onFocus: () => setActiveId(item.id),
7069
+ onKeyDown: (event) => onItemKeyDown(event, laneIndex, placed, index),
7070
+ onPointerDown: (event) => onPointerDown(event, item),
7071
+ onPointerMove,
7072
+ onPointerUp: () => onPointerUp(item),
7073
+ onPointerCancel: () => setDrag(null),
7074
+ onClick: () => {
7075
+ if (drag?.moved) return;
7076
+ onSelectItem?.(item);
7077
+ },
7078
+ children: [
7079
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__item-title", children: renderItem?.(item) ?? item.title }),
7080
+ item.meta && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-scheduling-timeline__item-meta", children: item.meta })
7081
+ ]
7082
+ }
7083
+ ) }, item.id);
7084
+ }) })
7085
+ ] })
7086
+ ] }, lane.id);
7087
+ })
7088
+ ] }) }),
7089
+ ordered.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "uix-scheduling-timeline__empty", children: labels.empty })
7090
+ ] }),
7091
+ onMoveItem && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { id: `${id}-hint`, className: "uix-visually-hidden", children: labels.moveHint }),
7092
+ /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { className: "uix-visually-hidden", role: "status", "aria-live": "polite", children: announcement })
7093
+ ] });
7094
+ }
7095
+
7096
+ // src/components/DateRangePicker.tsx
7097
+ var import_react51 = require("react");
7098
+ var import_jsx_runtime74 = require("react/jsx-runtime");
6749
7099
  var DEFAULT_DATE_RANGE_PICKER_LABELS = {
6750
7100
  previous: "Previous",
6751
7101
  previousMonth: "Show previous month",
@@ -6781,28 +7131,28 @@ function DateRangePicker({
6781
7131
  className,
6782
7132
  labels: labelOverrides
6783
7133
  }) {
6784
- const id = (0, import_react50.useId)();
7134
+ const id = (0, import_react51.useId)();
6785
7135
  const uixLabels = useUixLabels();
6786
7136
  const labels = { ...DEFAULT_DATE_RANGE_PICKER_LABELS, ...uixLabels.dateRangePicker, ...labelOverrides };
6787
- const weekdays = (0, import_react50.useMemo)(() => weekdayNames(locale), [locale]);
6788
- const [internalMonth, setInternalMonth] = (0, import_react50.useState)(() => startOfMonth(controlledMonth ?? value.start ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)));
7137
+ const weekdays = (0, import_react51.useMemo)(() => weekdayNames(locale), [locale]);
7138
+ const [internalMonth, setInternalMonth] = (0, import_react51.useState)(() => startOfMonth(controlledMonth ?? value.start ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10)));
6789
7139
  const visibleMonth = startOfMonth(controlledMonth ?? internalMonth);
6790
- const [activeDate, setActiveDate] = (0, import_react50.useState)(value.end ?? value.start ?? visibleMonth);
6791
- const rootRef = (0, import_react50.useRef)(null);
6792
- const pendingFocus = (0, import_react50.useRef)(false);
7140
+ const [activeDate, setActiveDate] = (0, import_react51.useState)(value.end ?? value.start ?? visibleMonth);
7141
+ const rootRef = (0, import_react51.useRef)(null);
7142
+ const pendingFocus = (0, import_react51.useRef)(false);
6793
7143
  const count = Math.max(1, Math.min(3, months));
6794
- const calendars = (0, import_react50.useMemo)(() => Array.from({ length: count }, (_, index) => {
7144
+ const calendars = (0, import_react51.useMemo)(() => Array.from({ length: count }, (_, index) => {
6795
7145
  const month = startOfMonth(addCalendarMonths(visibleMonth, index));
6796
7146
  return { month, days: buildMonthGrid(month).filter((day) => day.inMonth) };
6797
7147
  }), [visibleMonth, count]);
6798
7148
  const rangeInvalid = invalid || !!value.start && !!value.end && value.start > value.end;
6799
- (0, import_react50.useEffect)(() => {
7149
+ (0, import_react51.useEffect)(() => {
6800
7150
  const first = calendars[0]?.days[0]?.date;
6801
7151
  const finalDays = calendars[calendars.length - 1]?.days;
6802
7152
  const last = finalDays?.[finalDays.length - 1]?.date;
6803
7153
  if (first && last && (activeDate < first || activeDate > last)) setActiveDate(first);
6804
7154
  }, [activeDate, calendars]);
6805
- (0, import_react50.useEffect)(() => {
7155
+ (0, import_react51.useEffect)(() => {
6806
7156
  if (!pendingFocus.current) return;
6807
7157
  rootRef.current?.querySelector(`[data-date="${activeDate}"]`)?.focus();
6808
7158
  pendingFocus.current = false;
@@ -6840,23 +7190,23 @@ function DateRangePicker({
6840
7190
  }
6841
7191
  };
6842
7192
  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));
6843
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
6844
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-date-range-picker__header", children: [
6845
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("h3", { id: `${id}-label`, children: label }),
6846
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { children: [
6847
- /* @__PURE__ */ (0, import_jsx_runtime73.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 }),
6848
- /* @__PURE__ */ (0, import_jsx_runtime73.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 })
7193
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
7194
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uix-date-range-picker__header", children: [
7195
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("h3", { id: `${id}-label`, children: label }),
7196
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { children: [
7197
+ /* @__PURE__ */ (0, import_jsx_runtime74.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 }),
7198
+ /* @__PURE__ */ (0, import_jsx_runtime74.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 })
6849
7199
  ] })
6850
7200
  ] }),
6851
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-date-range-picker__month", children: [
6852
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("h4", { children: monthLabel(month, locale) }),
6853
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: weekdays.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { children: day }, index)) }),
6854
- /* @__PURE__ */ (0, import_jsx_runtime73.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
6855
- Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
7201
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uix-date-range-picker__month", children: [
7202
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("h4", { children: monthLabel(month, locale) }),
7203
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: weekdays.map((day, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { children: day }, index)) }),
7204
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
7205
+ Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
6856
7206
  days.map((day) => {
6857
7207
  const unavailable = disabled || isDateUnavailable(day.date, { min, max, isDisabled: isDateDisabled });
6858
7208
  const edge = day.date === value.start ? "start" : day.date === value.end ? "end" : void 0;
6859
- return /* @__PURE__ */ (0, import_jsx_runtime73.jsx)(
7209
+ return /* @__PURE__ */ (0, import_jsx_runtime74.jsx)(
6860
7210
  "button",
6861
7211
  {
6862
7212
  type: "button",
@@ -6877,13 +7227,13 @@ function DateRangePicker({
6877
7227
  })
6878
7228
  ] })
6879
7229
  ] }, month)) }),
6880
- /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
6881
- rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime73.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
7230
+ /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
7231
+ rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
6882
7232
  ] });
6883
7233
  }
6884
7234
 
6885
7235
  // src/components/RelationshipGraph.tsx
6886
- var import_react52 = require("react");
7236
+ var import_react53 = require("react");
6887
7237
 
6888
7238
  // src/relationship-graph-model.ts
6889
7239
  function boundRelationshipGraph(nodes, edges, maxNodes = 40) {
@@ -7364,10 +7714,10 @@ function layeredNeighbor(layout, currentId, key) {
7364
7714
  }
7365
7715
 
7366
7716
  // src/components/RelationshipGraphLayered.tsx
7367
- var import_react51 = require("react");
7717
+ var import_react52 = require("react");
7368
7718
 
7369
7719
  // src/components/RelationshipGraphList.tsx
7370
- var import_jsx_runtime74 = require("react/jsx-runtime");
7720
+ var import_jsx_runtime75 = require("react/jsx-runtime");
7371
7721
  function EquivalentRelationshipList({
7372
7722
  nodes,
7373
7723
  edges,
@@ -7378,19 +7728,19 @@ function EquivalentRelationshipList({
7378
7728
  onOpenDetails
7379
7729
  }) {
7380
7730
  const labelById = new Map(nodes.map((node) => [node.id, node.label]));
7381
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
7382
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("h3", { children: labels.listHeading }),
7383
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("ul", { children: nodes.map((node) => {
7731
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
7732
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("h3", { children: labels.listHeading }),
7733
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("ul", { children: nodes.map((node) => {
7384
7734
  const neighbors = relationshipNeighbors(node.id, edges).map((id) => labelById.get(id) ?? id);
7385
- return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
7386
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
7387
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("strong", { children: node.label }),
7388
- node.type && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { children: node.type }),
7389
- /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
7735
+ return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
7736
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
7737
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("strong", { children: node.label }),
7738
+ node.type && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: node.type }),
7739
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
7390
7740
  ] }),
7391
- /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
7392
- onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
7393
- onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime74.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: labels.openDetails })
7741
+ /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
7742
+ onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
7743
+ onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: labels.openDetails })
7394
7744
  ] })
7395
7745
  ] }, node.id);
7396
7746
  }) })
@@ -7398,7 +7748,7 @@ function EquivalentRelationshipList({
7398
7748
  }
7399
7749
 
7400
7750
  // src/components/RelationshipGraphLayered.tsx
7401
- var import_jsx_runtime75 = require("react/jsx-runtime");
7751
+ var import_jsx_runtime76 = require("react/jsx-runtime");
7402
7752
  var EMPTY_IDS = /* @__PURE__ */ new Set();
7403
7753
  var MIN_ZOOM = 0.4;
7404
7754
  var MAX_ZOOM = 1.5;
@@ -7451,11 +7801,11 @@ function LayeredRelationshipGraph({
7451
7801
  focusId,
7452
7802
  onFocusChange
7453
7803
  }) {
7454
- const hintId = (0, import_react51.useId)();
7455
- const bounded = (0, import_react51.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
7456
- const [localExpanded, setLocalExpanded] = (0, import_react51.useState)(EMPTY_IDS);
7804
+ const hintId = (0, import_react52.useId)();
7805
+ const bounded = (0, import_react52.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
7806
+ const [localExpanded, setLocalExpanded] = (0, import_react52.useState)(EMPTY_IDS);
7457
7807
  const expanded = expandedClusterIds ?? localExpanded;
7458
- const layout = (0, import_react51.useMemo)(
7808
+ const layout = (0, import_react52.useMemo)(
7459
7809
  () => layoutLayeredGraph(bounded.nodes, bounded.edges, {
7460
7810
  ...rootId !== void 0 ? { rootId } : {},
7461
7811
  ...clusterThreshold !== void 0 ? { clusterThreshold } : {},
@@ -7464,29 +7814,29 @@ function LayeredRelationshipGraph({
7464
7814
  }),
7465
7815
  [bounded, rootId, clusterThreshold, expanded, density]
7466
7816
  );
7467
- const itemById = (0, import_react51.useMemo)(() => new Map(layout.items.map((item) => [item.id, item])), [layout]);
7468
- const viewportRef = (0, import_react51.useRef)(null);
7469
- const itemRefs = (0, import_react51.useRef)(/* @__PURE__ */ new Map());
7470
- const [size, setSize] = (0, import_react51.useState)({ width: 0, height: 0 });
7471
- const [view, setView] = (0, import_react51.useState)({ x: 0, y: 0, zoom: 1 });
7472
- const [animate, setAnimate] = (0, import_react51.useState)(false);
7473
- const [localFocus, setLocalFocus] = (0, import_react51.useState)(void 0);
7474
- const [hoverId, setHoverId] = (0, import_react51.useState)(void 0);
7475
- const viewRef = (0, import_react51.useRef)(view);
7817
+ const itemById = (0, import_react52.useMemo)(() => new Map(layout.items.map((item) => [item.id, item])), [layout]);
7818
+ const viewportRef = (0, import_react52.useRef)(null);
7819
+ const itemRefs = (0, import_react52.useRef)(/* @__PURE__ */ new Map());
7820
+ const [size, setSize] = (0, import_react52.useState)({ width: 0, height: 0 });
7821
+ const [view, setView] = (0, import_react52.useState)({ x: 0, y: 0, zoom: 1 });
7822
+ const [animate, setAnimate] = (0, import_react52.useState)(false);
7823
+ const [localFocus, setLocalFocus] = (0, import_react52.useState)(void 0);
7824
+ const [hoverId, setHoverId] = (0, import_react52.useState)(void 0);
7825
+ const viewRef = (0, import_react52.useRef)(view);
7476
7826
  viewRef.current = view;
7477
- const layoutRef = (0, import_react51.useRef)(layout);
7827
+ const layoutRef = (0, import_react52.useRef)(layout);
7478
7828
  layoutRef.current = layout;
7479
- const pendingFocus = (0, import_react51.useRef)(void 0);
7480
- const initialisedFor = (0, import_react51.useRef)(void 0);
7829
+ const pendingFocus = (0, import_react52.useRef)(void 0);
7830
+ const initialisedFor = (0, import_react52.useRef)(void 0);
7481
7831
  const rootItemId = layout.rootId !== void 0 ? layout.itemOf[layout.rootId] : layout.items[0]?.id;
7482
7832
  const requestedFocus = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : localFocus;
7483
7833
  const focusedId = requestedFocus !== void 0 && itemById.has(requestedFocus) ? requestedFocus : rootItemId;
7484
7834
  const selectedItemId = selectedId !== void 0 ? layout.itemOf[selectedId] : void 0;
7485
- const activeIds = (0, import_react51.useMemo)(
7835
+ const activeIds = (0, import_react52.useMemo)(
7486
7836
  () => new Set([hoverId, selectedItemId].filter((id) => id !== void 0)),
7487
7837
  [hoverId, selectedItemId]
7488
7838
  );
7489
- (0, import_react51.useEffect)(() => {
7839
+ (0, import_react52.useEffect)(() => {
7490
7840
  const element = viewportRef.current;
7491
7841
  if (!element) return;
7492
7842
  const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
@@ -7496,18 +7846,18 @@ function LayeredRelationshipGraph({
7496
7846
  observer.observe(element);
7497
7847
  return () => observer.disconnect();
7498
7848
  }, []);
7499
- (0, import_react51.useEffect)(() => {
7849
+ (0, import_react52.useEffect)(() => {
7500
7850
  if (size.width === 0) return;
7501
7851
  const key = `${layout.rootId ?? ""}`;
7502
7852
  if (initialisedFor.current === key) return;
7503
7853
  initialisedFor.current = key;
7504
7854
  setView(initialView(layout, size));
7505
7855
  }, [layout, size]);
7506
- const moveView = (0, import_react51.useCallback)((next, smooth) => {
7856
+ const moveView = (0, import_react52.useCallback)((next, smooth) => {
7507
7857
  setAnimate(smooth);
7508
7858
  setView(next);
7509
7859
  }, []);
7510
- const ensureVisible = (0, import_react51.useCallback)((id, smooth) => {
7860
+ const ensureVisible = (0, import_react52.useCallback)((id, smooth) => {
7511
7861
  const element = viewportRef.current;
7512
7862
  const item = layoutRef.current.items.find((candidate) => candidate.id === id);
7513
7863
  if (!element || !item) return;
@@ -7526,7 +7876,7 @@ function LayeredRelationshipGraph({
7526
7876
  else if (bottom > heightPx - FOCUS_MARGIN) nextY -= bottom - (heightPx - FOCUS_MARGIN);
7527
7877
  if (nextX !== x || nextY !== y) moveView({ x: nextX, y: nextY, zoom }, smooth);
7528
7878
  }, [moveView]);
7529
- const focusItem = (0, import_react51.useCallback)((id) => {
7879
+ const focusItem = (0, import_react52.useCallback)((id) => {
7530
7880
  setLocalFocus(id);
7531
7881
  onFocusChange?.(id);
7532
7882
  requestAnimationFrame(() => {
@@ -7534,7 +7884,7 @@ function LayeredRelationshipGraph({
7534
7884
  ensureVisible(id, true);
7535
7885
  });
7536
7886
  }, [ensureVisible, onFocusChange]);
7537
- (0, import_react51.useEffect)(() => {
7887
+ (0, import_react52.useEffect)(() => {
7538
7888
  const wanted = pendingFocus.current;
7539
7889
  if (wanted !== void 0 && itemById.has(wanted)) {
7540
7890
  pendingFocus.current = void 0;
@@ -7544,8 +7894,8 @@ function LayeredRelationshipGraph({
7544
7894
  const controlledTarget = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : void 0;
7545
7895
  const controlledPresent = controlledTarget !== void 0 && itemById.has(controlledTarget);
7546
7896
  const controlledKey = `${controlledTarget ?? ""}|${controlledPresent}`;
7547
- const lastControlledKey = (0, import_react51.useRef)(controlledKey);
7548
- (0, import_react51.useEffect)(() => {
7897
+ const lastControlledKey = (0, import_react52.useRef)(controlledKey);
7898
+ (0, import_react52.useEffect)(() => {
7549
7899
  if (lastControlledKey.current === controlledKey) return;
7550
7900
  lastControlledKey.current = controlledKey;
7551
7901
  if (!controlledPresent || controlledTarget === void 0) return;
@@ -7554,7 +7904,7 @@ function LayeredRelationshipGraph({
7554
7904
  ensureVisible(controlledTarget, true);
7555
7905
  });
7556
7906
  }, [controlledKey, controlledTarget, controlledPresent, ensureVisible]);
7557
- (0, import_react51.useEffect)(() => {
7907
+ (0, import_react52.useEffect)(() => {
7558
7908
  const element = viewportRef.current;
7559
7909
  if (!element) return;
7560
7910
  const onWheel = (event) => {
@@ -7572,8 +7922,8 @@ function LayeredRelationshipGraph({
7572
7922
  element.addEventListener("wheel", onWheel, { passive: false });
7573
7923
  return () => element.removeEventListener("wheel", onWheel);
7574
7924
  }, []);
7575
- const pointers = (0, import_react51.useRef)(/* @__PURE__ */ new Map());
7576
- const pinchDistance = (0, import_react51.useRef)(void 0);
7925
+ const pointers = (0, import_react52.useRef)(/* @__PURE__ */ new Map());
7926
+ const pinchDistance = (0, import_react52.useRef)(void 0);
7577
7927
  const onPointerDown = (event) => {
7578
7928
  if (event.target.closest("button")) return;
7579
7929
  event.currentTarget.setPointerCapture?.(event.pointerId);
@@ -7671,21 +8021,21 @@ function LayeredRelationshipGraph({
7671
8021
  height: layout.height,
7672
8022
  transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`
7673
8023
  };
7674
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("section", { className: cx("uix-relationship-graph", "uix-relationship-graph--layered", density === "compact" && "uix-relationship-graph--compact", className), "aria-label": labels.graph, children: [
7675
- /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uix-relationship-graph__toolbar", role: "group", "aria-label": labels.controls, children: [
7676
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => zoomBy(ZOOM_STEP), disabled: view.zoom >= MAX_ZOOM, children: labels.zoomIn }),
7677
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => zoomBy(1 / ZOOM_STEP), disabled: view.zoom <= MIN_ZOOM, children: labels.zoomOut }),
7678
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => moveView(fitView(layout, size), true), children: labels.fit }),
7679
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => moveView(initialView(layout, size), true), children: labels.reset }),
7680
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => panBy(PAN_STEP, 0), "aria-label": labels.panLeft, children: labels.left }),
7681
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => panBy(0, PAN_STEP), "aria-label": labels.panUp, children: labels.up }),
7682
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => panBy(0, -PAN_STEP), "aria-label": labels.panDown, children: labels.down }),
7683
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("button", { type: "button", onClick: () => panBy(-PAN_STEP, 0), "aria-label": labels.panRight, children: labels.right }),
7684
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(view.zoom * 100)) })
8024
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("section", { className: cx("uix-relationship-graph", "uix-relationship-graph--layered", density === "compact" && "uix-relationship-graph--compact", className), "aria-label": labels.graph, children: [
8025
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "uix-relationship-graph__toolbar", role: "group", "aria-label": labels.controls, children: [
8026
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => zoomBy(ZOOM_STEP), disabled: view.zoom >= MAX_ZOOM, children: labels.zoomIn }),
8027
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => zoomBy(1 / ZOOM_STEP), disabled: view.zoom <= MIN_ZOOM, children: labels.zoomOut }),
8028
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => moveView(fitView(layout, size), true), children: labels.fit }),
8029
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => moveView(initialView(layout, size), true), children: labels.reset }),
8030
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => panBy(PAN_STEP, 0), "aria-label": labels.panLeft, children: labels.left }),
8031
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => panBy(0, PAN_STEP), "aria-label": labels.panUp, children: labels.up }),
8032
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => panBy(0, -PAN_STEP), "aria-label": labels.panDown, children: labels.down }),
8033
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => panBy(-PAN_STEP, 0), "aria-label": labels.panRight, children: labels.right }),
8034
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(view.zoom * 100)) })
7685
8035
  ] }),
7686
- bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
7687
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.keyboardHint }),
7688
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
8036
+ bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
8037
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.keyboardHint }),
8038
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7689
8039
  "div",
7690
8040
  {
7691
8041
  ref: viewportRef,
@@ -7695,11 +8045,11 @@ function LayeredRelationshipGraph({
7695
8045
  onPointerMove,
7696
8046
  onPointerUp: onPointerEnd,
7697
8047
  onPointerCancel: onPointerEnd,
7698
- children: /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
7699
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
8048
+ children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
8049
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
7700
8050
  const active = activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id));
7701
8051
  const angle = edge.arrowAngle * 180 / Math.PI;
7702
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
8052
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
7703
8053
  "g",
7704
8054
  {
7705
8055
  className: "uix-relationship-graph__link",
@@ -7709,15 +8059,15 @@ function LayeredRelationshipGraph({
7709
8059
  "data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
7710
8060
  "data-dimmed": dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0,
7711
8061
  children: [
7712
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("path", { d: edge.path }),
7713
- edge.arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
7714
- showLabel(edge) && /* @__PURE__ */ (0, import_jsx_runtime75.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_runtime75.jsx)("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
8062
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("path", { d: edge.path }),
8063
+ edge.arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
8064
+ showLabel(edge) && /* @__PURE__ */ (0, import_jsx_runtime76.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_runtime76.jsx)("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
7715
8065
  ]
7716
8066
  },
7717
8067
  edge.id
7718
8068
  );
7719
8069
  }) }),
7720
- layout.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
8070
+ layout.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7721
8071
  "div",
7722
8072
  {
7723
8073
  className: "uix-relationship-graph__column",
@@ -7727,17 +8077,17 @@ function LayeredRelationshipGraph({
7727
8077
  },
7728
8078
  column.depth
7729
8079
  )),
7730
- /* @__PURE__ */ (0, import_jsx_runtime75.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) => {
8080
+ /* @__PURE__ */ (0, import_jsx_runtime76.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) => {
7731
8081
  const selected = item.id === selectedItemId;
7732
8082
  const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
7733
- const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
7734
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
7735
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
7736
- ] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(import_jsx_runtime75.Fragment, { children: [
7737
- /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
7738
- (item.node.type || item.node.description) && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
8083
+ const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
8084
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
8085
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
8086
+ ] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(import_jsx_runtime76.Fragment, { children: [
8087
+ /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
8088
+ (item.node.type || item.node.description) && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
7739
8089
  ] });
7740
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsxs)(
8090
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
7741
8091
  "button",
7742
8092
  {
7743
8093
  ref: (element) => {
@@ -7768,7 +8118,7 @@ function LayeredRelationshipGraph({
7768
8118
  onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
7769
8119
  children: [
7770
8120
  body,
7771
- item.inCycle && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
8121
+ item.inCycle && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
7772
8122
  ]
7773
8123
  },
7774
8124
  item.id
@@ -7776,7 +8126,7 @@ function LayeredRelationshipGraph({
7776
8126
  }) }),
7777
8127
  layout.items.filter((item) => item.expandedGroup).map((item) => {
7778
8128
  const group = item.expandedGroup;
7779
- return /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
8129
+ return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7780
8130
  "button",
7781
8131
  {
7782
8132
  type: "button",
@@ -7792,8 +8142,8 @@ function LayeredRelationshipGraph({
7792
8142
  ] })
7793
8143
  }
7794
8144
  ),
7795
- legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime75.jsx)("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
7796
- showList && /* @__PURE__ */ (0, import_jsx_runtime75.jsx)(
8145
+ legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
8146
+ showList && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(
7797
8147
  EquivalentRelationshipList,
7798
8148
  {
7799
8149
  nodes: bounded.nodes,
@@ -7812,7 +8162,7 @@ function LayeredRelationshipGraph({
7812
8162
  }
7813
8163
 
7814
8164
  // src/components/RelationshipGraph.tsx
7815
- var import_jsx_runtime76 = require("react/jsx-runtime");
8165
+ var import_jsx_runtime77 = require("react/jsx-runtime");
7816
8166
  var DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
7817
8167
  graph: "Relationship graph",
7818
8168
  controls: "Graph view controls",
@@ -7874,21 +8224,21 @@ function radialViewBox(nodes) {
7874
8224
  return `${round(minX)} ${round(minY)} ${width} ${height}`;
7875
8225
  }
7876
8226
  function RelationshipGraph(props) {
7877
- const labels = (0, import_react52.useMemo)(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
8227
+ const labels = (0, import_react53.useMemo)(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
7878
8228
  const stateClass = cx("uix-relationship-graph uix-relationship-graph--state", props.className);
7879
- if (props.loading) return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: stateClass, role: "status", children: labels.loading });
8229
+ if (props.loading) return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: stateClass, role: "status", children: labels.loading });
7880
8230
  if (props.error) {
7881
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: stateClass, role: "alert", children: [
7882
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { children: props.error }),
7883
- props.onRetry && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
8231
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: stateClass, role: "alert", children: [
8232
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: props.error }),
8233
+ props.onRetry && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
7884
8234
  ] });
7885
8235
  }
7886
- if (props.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: stateClass, children: [
7887
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { children: labels.emptyTitle }),
7888
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { children: labels.emptyHint })
8236
+ if (props.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: stateClass, children: [
8237
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: labels.emptyTitle }),
8238
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: labels.emptyHint })
7889
8239
  ] });
7890
- if (props.layout === "layered") return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(LayeredRelationshipGraph, { ...props, labels });
7891
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(RadialRelationshipGraph, { ...props, labels });
8240
+ if (props.layout === "layered") return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(LayeredRelationshipGraph, { ...props, labels });
8241
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(RadialRelationshipGraph, { ...props, labels });
7892
8242
  }
7893
8243
  function RadialRelationshipGraph({
7894
8244
  nodes,
@@ -7908,17 +8258,17 @@ function RadialRelationshipGraph({
7908
8258
  labels,
7909
8259
  showList = true
7910
8260
  }) {
7911
- const bounded = (0, import_react52.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
7912
- const positioned = (0, import_react52.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
7913
- const typeColor = (0, import_react52.useMemo)(
8261
+ const bounded = (0, import_react53.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
8262
+ const positioned = (0, import_react53.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
8263
+ const typeColor = (0, import_react53.useMemo)(
7914
8264
  () => new Map(legend.map((item, index) => [item.id, `var(--uix-chart-${index % 8 + 1})`])),
7915
8265
  [legend]
7916
8266
  );
7917
- const positionedById = (0, import_react52.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
7918
- const [zoom, setZoom] = (0, import_react52.useState)(1);
7919
- const [pan, setPan] = (0, import_react52.useState)({ x: 0, y: 0 });
7920
- const [focusedId, setFocusedId] = (0, import_react52.useState)(selectedId ?? positioned[0]?.id);
7921
- const svgRef = (0, import_react52.useRef)(null);
8267
+ const positionedById = (0, import_react53.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
8268
+ const [zoom, setZoom] = (0, import_react53.useState)(1);
8269
+ const [pan, setPan] = (0, import_react53.useState)({ x: 0, y: 0 });
8270
+ const [focusedId, setFocusedId] = (0, import_react53.useState)(selectedId ?? positioned[0]?.id);
8271
+ const svgRef = (0, import_react53.useRef)(null);
7922
8272
  const select = (id) => {
7923
8273
  const node = bounded.nodes.find((item) => item.id === id);
7924
8274
  if (node) onSelect?.(node);
@@ -7941,25 +8291,25 @@ function RadialRelationshipGraph({
7941
8291
  setZoom(1);
7942
8292
  setPan({ x: 0, y: 0 });
7943
8293
  };
7944
- return /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
7945
- /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
7946
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
7947
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
7948
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
7949
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
7950
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
7951
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
7952
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("button", { type: "button", onClick: reset, children: labels.reset }),
7953
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
8294
+ return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
8295
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
8296
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
8297
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
8298
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
8299
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
8300
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
8301
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
8302
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", onClick: reset, children: labels.reset }),
8303
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
7954
8304
  ] }),
7955
- bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
7956
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("svg", { ref: svgRef, viewBox: radialViewBox(positioned), role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
8305
+ bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
8306
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("svg", { ref: svgRef, viewBox: radialViewBox(positioned), role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
7957
8307
  bounded.edges.map((edge) => {
7958
8308
  const source = positionedById.get(edge.source);
7959
8309
  const target = positionedById.get(edge.target);
7960
- return /* @__PURE__ */ (0, import_jsx_runtime76.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_runtime76.jsx)("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
8310
+ return /* @__PURE__ */ (0, import_jsx_runtime77.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_runtime77.jsx)("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
7961
8311
  }),
7962
- positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime76.jsxs)(
8312
+ positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)(
7963
8313
  "g",
7964
8314
  {
7965
8315
  transform: `translate(${node.x * RADIAL_SCALE_X} ${node.y * RADIAL_SCALE_Y})`,
@@ -7975,22 +8325,22 @@ function RadialRelationshipGraph({
7975
8325
  onKeyDown: (event) => onNodeKeyDown(event, node.id),
7976
8326
  onClick: () => select(node.id),
7977
8327
  children: [
7978
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("title", { children: node.label }),
7979
- /* @__PURE__ */ (0, import_jsx_runtime76.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" }),
7980
- /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
8328
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("title", { children: node.label }),
8329
+ /* @__PURE__ */ (0, import_jsx_runtime77.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" }),
8330
+ /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
7981
8331
  ]
7982
8332
  },
7983
8333
  node.id
7984
8334
  ))
7985
8335
  ] }) }) }),
7986
- legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime76.jsx)("li", { "data-type": item.id, style: { "--uix-graph-type-color": typeColor.get(item.id) }, children: item.label }, item.id)) }),
7987
- showList && /* @__PURE__ */ (0, import_jsx_runtime76.jsx)(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
8336
+ legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("li", { "data-type": item.id, style: { "--uix-graph-type-color": typeColor.get(item.id) }, children: item.label }, item.id)) }),
8337
+ showList && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
7988
8338
  ] });
7989
8339
  }
7990
8340
 
7991
8341
  // src/components/MatchReview.tsx
7992
- var import_react53 = require("react");
7993
- var import_jsx_runtime77 = require("react/jsx-runtime");
8342
+ var import_react54 = require("react");
8343
+ var import_jsx_runtime78 = require("react/jsx-runtime");
7994
8344
  var DEFAULT_MATCH_REVIEW_LABELS = {
7995
8345
  region: "Match review",
7996
8346
  loading: "Loading match candidates\u2026",
@@ -8052,11 +8402,11 @@ function MatchReview({
8052
8402
  const plural = (n, one, many) => fillLabel(n === 1 ? one : many, { count: n });
8053
8403
  const decisionLabel = { accepted: labels.decisionAccepted, dismissed: labels.decisionDismissed, split: labels.decisionSplit, other: labels.decisionOther };
8054
8404
  const actionLabel = { accept: labels.accept, dismiss: labels.dismiss, split: labels.split, "pick-other": labels.pickOther };
8055
- const [internalSelection, setInternalSelection] = (0, import_react53.useState)(/* @__PURE__ */ new Set());
8056
- const [announcement, setAnnouncement] = (0, import_react53.useState)("");
8057
- const [bulkPending, setBulkPending] = (0, import_react53.useState)(false);
8405
+ const [internalSelection, setInternalSelection] = (0, import_react54.useState)(/* @__PURE__ */ new Set());
8406
+ const [announcement, setAnnouncement] = (0, import_react54.useState)("");
8407
+ const [bulkPending, setBulkPending] = (0, import_react54.useState)(false);
8058
8408
  const selection = selectedIds ?? internalSelection;
8059
- const pending = (0, import_react53.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
8409
+ const pending = (0, import_react54.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
8060
8410
  const setSelection = (next) => {
8061
8411
  if (selectedIds === void 0) setInternalSelection(next);
8062
8412
  onSelectionChange?.(next);
@@ -8085,48 +8435,48 @@ function MatchReview({
8085
8435
  setBulkPending(false);
8086
8436
  }
8087
8437
  };
8088
- if (loading) return /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: labels.loading });
8089
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
8090
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: error }),
8091
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
8438
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: labels.loading });
8439
+ if (error) return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
8440
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { children: error }),
8441
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: labels.retry })
8092
8442
  ] });
8093
- if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
8094
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: labels.empty }),
8095
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { children: labels.emptyDetail })
8443
+ if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
8444
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { children: labels.empty }),
8445
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { children: labels.emptyDetail })
8096
8446
  ] });
8097
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": labels.region, children: [
8098
- /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "uix-match-review__summary", children: [
8099
- /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { children: [
8100
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("strong", { children: incomingLabel }),
8101
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { children: fillLabel(labels.pendingOf, { pending: pending.length, total: candidates.length }) })
8447
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": labels.region, children: [
8448
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "uix-match-review__summary", children: [
8449
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { children: [
8450
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("strong", { children: incomingLabel }),
8451
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { children: fillLabel(labels.pendingOf, { pending: pending.length, total: candidates.length }) })
8102
8452
  ] }),
8103
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("span", { children: [
8104
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("b", { children: field.label }),
8453
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { children: [
8454
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("b", { children: field.label }),
8105
8455
  field.render?.(incoming[field.id], incoming) ?? valueText(incoming[field.id])
8106
8456
  ] }, field.id)) })
8107
8457
  ] }),
8108
- onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": labels.bulk, children: [
8109
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { children: fillLabel(labels.selectedCount, { count: selection.size }) }),
8110
- /* @__PURE__ */ (0, import_jsx_runtime77.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 }),
8111
- /* @__PURE__ */ (0, import_jsx_runtime77.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 })
8458
+ onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": labels.bulk, children: [
8459
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { children: fillLabel(labels.selectedCount, { count: selection.size }) }),
8460
+ /* @__PURE__ */ (0, import_jsx_runtime78.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 }),
8461
+ /* @__PURE__ */ (0, import_jsx_runtime78.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 })
8112
8462
  ] }),
8113
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
8114
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("caption", { className: "uix-visually-hidden", children: labels.caption }),
8115
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("tr", { children: [
8116
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "uix-visually-hidden", children: labels.select }) }),
8117
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("th", { scope: "col", children: labels.confidence }),
8118
- fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("th", { scope: "col", children: field.label }, field.id)),
8119
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("th", { scope: "col", children: labels.status }),
8120
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("th", { scope: "col", children: labels.actions })
8463
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
8464
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("caption", { className: "uix-visually-hidden", children: labels.caption }),
8465
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("tr", { children: [
8466
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "uix-visually-hidden", children: labels.select }) }),
8467
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { scope: "col", children: labels.confidence }),
8468
+ fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { scope: "col", children: field.label }, field.id)),
8469
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { scope: "col", children: labels.status }),
8470
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("th", { scope: "col", children: labels.actions })
8121
8471
  ] }) }),
8122
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("tbody", { children: candidates.map((candidate) => {
8472
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("tbody", { children: candidates.map((candidate) => {
8123
8473
  const resolved = candidate.status === "resolved";
8124
- return /* @__PURE__ */ (0, import_jsx_runtime77.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
8125
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": fillLabel(labels.selectCandidate, { id: candidate.id }) }) }),
8126
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? labels.notScored : `${Math.round(candidate.confidence * 100)}%` }) }),
8127
- fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
8128
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ? decisionLabel[candidate.decision] : labels.resolved : labels.pending }) }),
8129
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime77.jsx)(
8474
+ return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
8475
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": fillLabel(labels.selectCandidate, { id: candidate.id }) }) }),
8476
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? labels.notScored : `${Math.round(candidate.confidence * 100)}%` }) }),
8477
+ fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
8478
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ? decisionLabel[candidate.decision] : labels.resolved : labels.pending }) }),
8479
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
8130
8480
  "button",
8131
8481
  {
8132
8482
  type: "button",
@@ -8140,12 +8490,12 @@ function MatchReview({
8140
8490
  ] }, candidate.id);
8141
8491
  }) })
8142
8492
  ] }) }),
8143
- /* @__PURE__ */ (0, import_jsx_runtime77.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
8493
+ /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
8144
8494
  ] });
8145
8495
  }
8146
8496
 
8147
8497
  // src/components/MetricInput.tsx
8148
- var import_react54 = require("react");
8498
+ var import_react55 = require("react");
8149
8499
 
8150
8500
  // src/metric-model.ts
8151
8501
  function decimals(value) {
@@ -8170,7 +8520,7 @@ function parseMetricValue(value) {
8170
8520
  }
8171
8521
 
8172
8522
  // src/components/MetricInput.tsx
8173
- var import_jsx_runtime78 = require("react/jsx-runtime");
8523
+ var import_jsx_runtime79 = require("react/jsx-runtime");
8174
8524
  var defaultMetricFormat = (input) => input == null ? "" : String(input);
8175
8525
  function MetricInput({
8176
8526
  value,
@@ -8189,11 +8539,11 @@ function MetricInput({
8189
8539
  className,
8190
8540
  id: providedId
8191
8541
  }) {
8192
- const generatedId = (0, import_react54.useId)();
8542
+ const generatedId = (0, import_react55.useId)();
8193
8543
  const id = providedId ?? generatedId;
8194
8544
  const errorId = `${id}-error`;
8195
- const [text, setText] = (0, import_react54.useState)(() => format(value));
8196
- (0, import_react54.useEffect)(() => setText(format(value)), [value, format]);
8545
+ const [text, setText] = (0, import_react55.useState)(() => format(value));
8546
+ (0, import_react55.useEffect)(() => setText(format(value)), [value, format]);
8197
8547
  const commit = (input) => {
8198
8548
  const parsed = parse(input);
8199
8549
  if (input.trim() === "" || parsed !== null) {
@@ -8219,10 +8569,10 @@ function MetricInput({
8219
8569
  const parsed = parse(event.currentTarget.value);
8220
8570
  setText(parsed === null && event.currentTarget.value.trim() !== "" ? format(value) : format(parsed));
8221
8571
  };
8222
- return /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
8223
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
8224
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("div", { className: "uix-metric-input__control", children: [
8225
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)(
8572
+ return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
8573
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
8574
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "uix-metric-input__control", children: [
8575
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
8226
8576
  Input,
8227
8577
  {
8228
8578
  id,
@@ -8241,22 +8591,22 @@ function MetricInput({
8241
8591
  readOnly
8242
8592
  }
8243
8593
  ),
8244
- unit && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
8245
- /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "uix-metric-input__steps", children: [
8246
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
8247
- /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
8594
+ unit && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
8595
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("span", { className: "uix-metric-input__steps", children: [
8596
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
8597
+ /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
8248
8598
  ] })
8249
8599
  ] }),
8250
- unit && /* @__PURE__ */ (0, import_jsx_runtime78.jsxs)("span", { className: "uix-visually-hidden", children: [
8600
+ unit && /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("span", { className: "uix-visually-hidden", children: [
8251
8601
  "Unit: ",
8252
8602
  unit
8253
8603
  ] }),
8254
- invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime78.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
8604
+ invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
8255
8605
  ] });
8256
8606
  }
8257
8607
 
8258
8608
  // src/components/LicensePositionBar.tsx
8259
- var import_jsx_runtime79 = require("react/jsx-runtime");
8609
+ var import_jsx_runtime80 = require("react/jsx-runtime");
8260
8610
  var defaultCapacityFormat = (value) => new Intl.NumberFormat().format(value);
8261
8611
  function LicensePositionBar({
8262
8612
  consumed,
@@ -8277,18 +8627,18 @@ function LicensePositionBar({
8277
8627
  const percent = safeEntitled === 0 ? safeConsumed > 0 ? 100 : 0 : safeConsumed / safeEntitled * 100;
8278
8628
  const format = (value) => `${formatValue(value)}${unit ? ` ${unit}` : ""}`;
8279
8629
  const summary = `${consumedLabel}: ${format(safeConsumed)}. ${entitledLabel}: ${format(safeEntitled)}. ${over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}`}.`;
8280
- return /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
8281
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "uix-license-position__header", children: [
8282
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("span", { className: "uix-license-position__value", children: [
8630
+ return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
8631
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "uix-license-position__header", children: [
8632
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { className: "uix-license-position__value", children: [
8283
8633
  format(safeConsumed),
8284
8634
  " / ",
8285
8635
  format(safeEntitled)
8286
8636
  ] }),
8287
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
8637
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
8288
8638
  ] }),
8289
- /* @__PURE__ */ (0, import_jsx_runtime79.jsxs)("div", { className: "uix-license-position__track", children: [
8290
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
8291
- over > 0 && /* @__PURE__ */ (0, import_jsx_runtime79.jsx)(
8639
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "uix-license-position__track", children: [
8640
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
8641
+ over > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsx)(
8292
8642
  "span",
8293
8643
  {
8294
8644
  className: "uix-license-position__overflow",
@@ -8297,12 +8647,12 @@ function LicensePositionBar({
8297
8647
  }
8298
8648
  )
8299
8649
  ] }),
8300
- /* @__PURE__ */ (0, import_jsx_runtime79.jsx)("span", { className: "uix-visually-hidden", children: summary })
8650
+ /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "uix-visually-hidden", children: summary })
8301
8651
  ] });
8302
8652
  }
8303
8653
 
8304
8654
  // src/components/BrandProfiles.tsx
8305
- var import_react56 = require("react");
8655
+ var import_react57 = require("react");
8306
8656
 
8307
8657
  // src/color-model.ts
8308
8658
  var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
@@ -8371,8 +8721,8 @@ function meetsContrast(background, foreground, minimum = 4.5) {
8371
8721
  }
8372
8722
 
8373
8723
  // src/components/ColorPicker.tsx
8374
- var import_react55 = require("react");
8375
- var import_jsx_runtime80 = require("react/jsx-runtime");
8724
+ var import_react56 = require("react");
8725
+ var import_jsx_runtime81 = require("react/jsx-runtime");
8376
8726
  var DEFAULT_COLOR_PICKER_LABELS = {
8377
8727
  trigger: "{label}: {color}",
8378
8728
  sample: "Aa",
@@ -8403,17 +8753,17 @@ function ColorPicker({
8403
8753
  labels: labelOverrides
8404
8754
  }) {
8405
8755
  const labels = { ...DEFAULT_COLOR_PICKER_LABELS, ...labelOverrides };
8406
- const id = (0, import_react55.useId)();
8407
- const triggerRef = (0, import_react55.useRef)(null);
8408
- const dialogRef = (0, import_react55.useRef)(null);
8409
- const [open, setOpen] = (0, import_react55.useState)(false);
8756
+ const id = (0, import_react56.useId)();
8757
+ const triggerRef = (0, import_react56.useRef)(null);
8758
+ const dialogRef = (0, import_react56.useRef)(null);
8759
+ const [open, setOpen] = (0, import_react56.useState)(false);
8410
8760
  const normalized = normalizeHex(value) ?? "#000000";
8411
- const [hexText, setHexText] = (0, import_react55.useState)(normalized);
8412
- const hsv = (0, import_react55.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
8761
+ const [hexText, setHexText] = (0, import_react56.useState)(normalized);
8762
+ const hsv = (0, import_react56.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
8413
8763
  const ratio = contrastRatio(normalized, foreground) ?? 0;
8414
8764
  const passes = ratio >= minimumContrast;
8415
- (0, import_react55.useEffect)(() => setHexText(normalized), [normalized]);
8416
- (0, import_react55.useEffect)(() => {
8765
+ (0, import_react56.useEffect)(() => setHexText(normalized), [normalized]);
8766
+ (0, import_react56.useEffect)(() => {
8417
8767
  if (!open) return;
8418
8768
  const dialog = dialogRef.current;
8419
8769
  dialog?.querySelector("input,button")?.focus();
@@ -8456,8 +8806,8 @@ function ColorPicker({
8456
8806
  if (next) onChange(next);
8457
8807
  };
8458
8808
  const sampleStyle = { backgroundColor: normalized };
8459
- return /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: cx("uix-color-picker", className), children: [
8460
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
8809
+ return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: cx("uix-color-picker", className), children: [
8810
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
8461
8811
  "button",
8462
8812
  {
8463
8813
  ref: triggerRef,
@@ -8469,12 +8819,12 @@ function ColorPicker({
8469
8819
  onClick: () => setOpen((current) => !current),
8470
8820
  disabled,
8471
8821
  children: [
8472
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
8473
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { children: normalized })
8822
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
8823
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { children: normalized })
8474
8824
  ]
8475
8825
  }
8476
8826
  ),
8477
- open && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)(
8827
+ open && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)(
8478
8828
  "div",
8479
8829
  {
8480
8830
  ref: dialogRef,
@@ -8485,55 +8835,55 @@ function ColorPicker({
8485
8835
  className: "uix-color-picker__popover",
8486
8836
  onKeyDown: onDialogKeyDown,
8487
8837
  children: [
8488
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("span", { style: { color: foreground }, children: labels.sample }) }),
8489
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("label", { className: "uix-color-picker__range", children: [
8838
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { style: { color: foreground }, children: labels.sample }) }),
8839
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-color-picker__range", children: [
8490
8840
  labels.hue,
8491
8841
  " ",
8492
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { children: [
8842
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("span", { children: [
8493
8843
  Math.round(hsv.h),
8494
8844
  "\xB0"
8495
8845
  ] }),
8496
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
8846
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
8497
8847
  ] }),
8498
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("label", { className: "uix-color-picker__range", children: [
8848
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-color-picker__range", children: [
8499
8849
  labels.saturation,
8500
8850
  " ",
8501
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { children: [
8851
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("span", { children: [
8502
8852
  Math.round(hsv.s * 100),
8503
8853
  "%"
8504
8854
  ] }),
8505
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
8855
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
8506
8856
  ] }),
8507
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("label", { className: "uix-color-picker__range", children: [
8857
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-color-picker__range", children: [
8508
8858
  labels.brightness,
8509
8859
  " ",
8510
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { children: [
8860
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("span", { children: [
8511
8861
  Math.round(hsv.v * 100),
8512
8862
  "%"
8513
8863
  ] }),
8514
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
8864
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
8515
8865
  ] }),
8516
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("label", { className: "uix-color-picker__hex", children: [
8866
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-color-picker__hex", children: [
8517
8867
  labels.hex,
8518
- /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
8519
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
8868
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
8869
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
8520
8870
  if (event.key === "Enter") commitHex();
8521
8871
  }, "aria-invalid": !normalizeHex(hexText) }),
8522
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: labels.set })
8872
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: labels.set })
8523
8873
  ] })
8524
8874
  ] }),
8525
- (presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("div", { className: "uix-color-picker__palettes", children: [
8526
- presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("fieldset", { children: [
8527
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("legend", { children: labels.presets }),
8528
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.usePreset, { color }) }, color)) })
8875
+ (presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-color-picker__palettes", children: [
8876
+ presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("fieldset", { children: [
8877
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("legend", { children: labels.presets }),
8878
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.usePreset, { color }) }, color)) })
8529
8879
  ] }),
8530
- recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime80.jsxs)("fieldset", { children: [
8531
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("legend", { children: labels.recent }),
8532
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.useRecent, { color }) }, color)) })
8880
+ recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("fieldset", { children: [
8881
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("legend", { children: labels.recent }),
8882
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": fillLabel(labels.useRecent, { color }) }, color)) })
8533
8883
  ] })
8534
8884
  ] }),
8535
- /* @__PURE__ */ (0, import_jsx_runtime80.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 }) }),
8536
- /* @__PURE__ */ (0, import_jsx_runtime80.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: labels.done })
8885
+ /* @__PURE__ */ (0, import_jsx_runtime81.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 }) }),
8886
+ /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: labels.done })
8537
8887
  ]
8538
8888
  }
8539
8889
  )
@@ -8541,7 +8891,7 @@ function ColorPicker({
8541
8891
  }
8542
8892
 
8543
8893
  // src/components/BrandProfiles.tsx
8544
- var import_jsx_runtime81 = require("react/jsx-runtime");
8894
+ var import_jsx_runtime82 = require("react/jsx-runtime");
8545
8895
  var PROFILE_PROPERTIES = {
8546
8896
  brand: "--uix-brand",
8547
8897
  brandForeground: "--uix-brand-fg",
@@ -8633,7 +8983,7 @@ function BrandProfileEditor({
8633
8983
  labels: labelOverrides
8634
8984
  }) {
8635
8985
  const labels = { ...DEFAULT_BRAND_PROFILE_EDITOR_LABELS, ...labelOverrides };
8636
- const [announcement, setAnnouncement] = (0, import_react56.useState)("");
8986
+ const [announcement, setAnnouncement] = (0, import_react57.useState)("");
8637
8987
  const update = (patch) => onChange({ ...value, ...patch });
8638
8988
  const apply = () => {
8639
8989
  if (applyTarget !== null) applyBrandProfile(value, applyTarget);
@@ -8650,54 +9000,54 @@ function BrandProfileEditor({
8650
9000
  ...value.typography?.sans ? { "--uix-font-sans": value.typography.sans } : {},
8651
9001
  ...value.typography?.heading ? { "--uix-font-heading": value.typography.heading } : {}
8652
9002
  };
8653
- return /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": labels.region, children: [
8654
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-brand-profiles__form", children: [
8655
- profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-field__label", children: [
9003
+ return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": labels.region, children: [
9004
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-brand-profiles__form", children: [
9005
+ profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: "uix-field__label", children: [
8656
9006
  labels.profile,
8657
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
9007
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
8658
9008
  const selected = profiles.find((profile) => profile.id === event.currentTarget.value);
8659
9009
  if (selected) onSelectProfile?.(selected);
8660
- }, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
9010
+ }, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
8661
9011
  ] }),
8662
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-field__label", children: [
9012
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: "uix-field__label", children: [
8663
9013
  labels.name,
8664
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
9014
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
8665
9015
  ] }),
8666
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
8667
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { children: [
9016
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
9017
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { children: [
8668
9018
  labels.brand,
8669
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ColorPicker, { label: labels.brandColor, value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
9019
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ColorPicker, { label: labels.brandColor, value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
8670
9020
  ] }),
8671
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { children: [
9021
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { children: [
8672
9022
  labels.onBrand,
8673
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)(ColorPicker, { label: labels.onBrandColor, value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
9023
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(ColorPicker, { label: labels.onBrandColor, value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
8674
9024
  ] })
8675
9025
  ] }),
8676
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-field__label", children: [
9026
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: "uix-field__label", children: [
8677
9027
  labels.bodyFont,
8678
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
9028
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
8679
9029
  ] }),
8680
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-field__label", children: [
9030
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: "uix-field__label", children: [
8681
9031
  labels.headingFont,
8682
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
9032
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
8683
9033
  ] }),
8684
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
9034
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
8685
9035
  labels.logoFile,
8686
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
9036
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
8687
9037
  ] }),
8688
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: labels.apply }),
8689
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
9038
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: labels.apply }),
9039
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
8690
9040
  ] }),
8691
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": fillLabel(labels.preview, { name: value.name }), children: [
8692
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
8693
- value.logo ? /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: labels.logoPlaceholder }),
8694
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("strong", { children: value.name || labels.previewTitleFallback })
9041
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": fillLabel(labels.preview, { name: value.name }), children: [
9042
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
9043
+ value.logo ? /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: labels.logoPlaceholder }),
9044
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("strong", { children: value.name || labels.previewTitleFallback })
8695
9045
  ] }),
8696
- /* @__PURE__ */ (0, import_jsx_runtime81.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
8697
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("h3", { children: labels.previewHeading }),
8698
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("p", { children: labels.previewBody }),
8699
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: labels.previewPrimary }),
8700
- /* @__PURE__ */ (0, import_jsx_runtime81.jsx)("a", { href: "#brand-profile-preview", children: labels.previewLink })
9046
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
9047
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { children: labels.previewHeading }),
9048
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { children: labels.previewBody }),
9049
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: labels.previewPrimary }),
9050
+ /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("a", { href: "#brand-profile-preview", children: labels.previewLink })
8701
9051
  ] })
8702
9052
  ] })
8703
9053
  ] });
@@ -8705,7 +9055,7 @@ function BrandProfileEditor({
8705
9055
  var BrandProfiles = BrandProfileEditor;
8706
9056
 
8707
9057
  // src/components/DiffViewer.tsx
8708
- var import_react57 = require("react");
9058
+ var import_react58 = require("react");
8709
9059
 
8710
9060
  // src/diff-model.ts
8711
9061
  function isJsonObject(value) {
@@ -8756,7 +9106,7 @@ function summarizeDiff(entries, resolutions = {}) {
8756
9106
  }
8757
9107
 
8758
9108
  // src/components/DiffViewer.tsx
8759
- var import_jsx_runtime82 = require("react/jsx-runtime");
9109
+ var import_jsx_runtime83 = require("react/jsx-runtime");
8760
9110
  var DEFAULT_DIFF_VIEWER_LABELS = {
8761
9111
  base: "Base",
8762
9112
  current: "Current",
@@ -8801,33 +9151,33 @@ function DiffViewer({
8801
9151
  const labels = { ...DEFAULT_DIFF_VIEWER_LABELS, ...labelOverrides };
8802
9152
  const resolutionLabel = { accept: labels.resolutionAccept, skip: labels.resolutionSkip, pending: labels.resolutionPending };
8803
9153
  const buttonSize = controlSize === "md" ? void 0 : `uix-btn--${controlSize}`;
8804
- const id = (0, import_react57.useId)();
8805
- const entries = (0, import_react57.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
8806
- const [internalResolutions, setInternalResolutions] = (0, import_react57.useState)({});
9154
+ const id = (0, import_react58.useId)();
9155
+ const entries = (0, import_react58.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
9156
+ const [internalResolutions, setInternalResolutions] = (0, import_react58.useState)({});
8807
9157
  const resolutions = controlledResolutions ?? internalResolutions;
8808
9158
  const summary = summarizeDiff(entries, resolutions);
8809
9159
  const resolve = (path, resolution) => {
8810
9160
  if (controlledResolutions === void 0) setInternalResolutions((currentState) => ({ ...currentState, [path]: resolution }));
8811
9161
  onResolutionChange?.(path, resolution);
8812
9162
  };
8813
- if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": labels.region, children: [
8814
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("h3", { children: labels.noDifferences }),
8815
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { children: labels.noDifferencesDetail })
9163
+ if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": labels.region, children: [
9164
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("h3", { children: labels.noDifferences }),
9165
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { children: labels.noDifferencesDetail })
8816
9166
  ] });
8817
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": labels.region, "data-control-size": controlSize, children: [
8818
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-diff-viewer__summary", role: "group", "aria-label": labels.summary, children: [
8819
- GROUPS.map((kind) => /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("span", { children: [
8820
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("b", { children: summary[kind] }),
9167
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": labels.region, "data-control-size": controlSize, children: [
9168
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uix-diff-viewer__summary", role: "group", "aria-label": labels.summary, children: [
9169
+ GROUPS.map((kind) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("span", { children: [
9170
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("b", { children: summary[kind] }),
8821
9171
  " ",
8822
9172
  labels[kind].toLowerCase()
8823
9173
  ] }, kind)),
8824
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("span", { children: [
8825
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("b", { children: summary.resolved }),
9174
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("span", { children: [
9175
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("b", { children: summary.resolved }),
8826
9176
  " ",
8827
9177
  labels.resolved
8828
9178
  ] }),
8829
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("span", { children: [
8830
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("b", { children: summary.pending }),
9179
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("span", { children: [
9180
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("b", { children: summary.pending }),
8831
9181
  " ",
8832
9182
  labels.pending
8833
9183
  ] })
@@ -8835,33 +9185,33 @@ function DiffViewer({
8835
9185
  GROUPS.map((kind) => {
8836
9186
  const grouped = entries.filter((entry) => entry.kind === kind);
8837
9187
  if (!grouped.length) return null;
8838
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${kind}`, children: [
8839
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("h3", { id: `${id}-${kind}`, children: [
9188
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${kind}`, children: [
9189
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("h3", { id: `${id}-${kind}`, children: [
8840
9190
  labels[kind],
8841
9191
  " ",
8842
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("span", { children: grouped.length })
9192
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("span", { children: grouped.length })
8843
9193
  ] }),
8844
9194
  grouped.map((entry) => {
8845
9195
  const resolution = resolutions[entry.path] ?? "pending";
8846
- return /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
8847
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("summary", { children: [
8848
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("code", { children: entry.path }),
8849
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolutionLabel[resolution] })
9196
+ return /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
9197
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("summary", { children: [
9198
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("code", { children: entry.path }),
9199
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolutionLabel[resolution] })
8850
9200
  ] }),
8851
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { role: "region", "aria-label": fillLabel(labels.valueFor, { version: labels[version], path: entry.path }), children: [
8852
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("strong", { children: labels[version] }),
8853
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("pre", { children: renderValue(entry[version], labels.notPresent) })
9201
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { role: "region", "aria-label": fillLabel(labels.valueFor, { version: labels[version], path: entry.path }), children: [
9202
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("strong", { children: labels[version] }),
9203
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("pre", { children: renderValue(entry[version], labels.notPresent) })
8854
9204
  ] }, version)) }),
8855
- /* @__PURE__ */ (0, import_jsx_runtime82.jsxs)("div", { className: "uix-diff-viewer__actions", role: "group", "aria-label": fillLabel(labels.resolve, { path: entry.path }), children: [
8856
- /* @__PURE__ */ (0, import_jsx_runtime82.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 }),
8857
- /* @__PURE__ */ (0, import_jsx_runtime82.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 }),
8858
- /* @__PURE__ */ (0, import_jsx_runtime82.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 })
9205
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsxs)("div", { className: "uix-diff-viewer__actions", role: "group", "aria-label": fillLabel(labels.resolve, { path: entry.path }), children: [
9206
+ /* @__PURE__ */ (0, import_jsx_runtime83.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 }),
9207
+ /* @__PURE__ */ (0, import_jsx_runtime83.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 }),
9208
+ /* @__PURE__ */ (0, import_jsx_runtime83.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 })
8859
9209
  ] })
8860
9210
  ] }, entry.path);
8861
9211
  })
8862
9212
  ] }, kind);
8863
9213
  }),
8864
- /* @__PURE__ */ (0, import_jsx_runtime82.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: fillLabel(labels.progress, { resolved: summary.resolved, total: entries.length }) })
9214
+ /* @__PURE__ */ (0, import_jsx_runtime83.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: fillLabel(labels.progress, { resolved: summary.resolved, total: entries.length }) })
8865
9215
  ] });
8866
9216
  }
8867
9217
  // Annotate the CommonJS export names for ESM import in node:
@@ -8900,6 +9250,7 @@ function DiffViewer({
8900
9250
  ContentList,
8901
9251
  ContentListItem,
8902
9252
  CopyButton,
9253
+ DAY,
8903
9254
  DEFAULT_BRAND_PROFILE_EDITOR_LABELS,
8904
9255
  DEFAULT_BUILDER_CANVAS_LABELS,
8905
9256
  DEFAULT_COLOR_PICKER_LABELS,
@@ -8911,6 +9262,7 @@ function DiffViewer({
8911
9262
  DEFAULT_RULE_BUILDER_LABELS,
8912
9263
  DEFAULT_SAVE_STATUS_LABELS,
8913
9264
  DEFAULT_SCHEDULING_CALENDAR_LABELS,
9265
+ DEFAULT_SCHEDULING_TIMELINE_LABELS,
8914
9266
  DEFAULT_STEP_STATE_LABELS,
8915
9267
  DateRangePicker,
8916
9268
  DescriptionItem,
@@ -8932,6 +9284,7 @@ function DiffViewer({
8932
9284
  Flow,
8933
9285
  FlowNode,
8934
9286
  ForbiddenState,
9287
+ HOUR,
8935
9288
  Highlighted,
8936
9289
  Inbox,
8937
9290
  InboxDetail,
@@ -8989,6 +9342,7 @@ function DiffViewer({
8989
9342
  SaveStatus,
8990
9343
  SavedViewMenu,
8991
9344
  SchedulingCalendar,
9345
+ SchedulingTimeline,
8992
9346
  SearchSuggest,
8993
9347
  SectionHead,
8994
9348
  Segmented,
@@ -9044,6 +9398,7 @@ function DiffViewer({
9044
9398
  createToastApi,
9045
9399
  createToastStore,
9046
9400
  cx,
9401
+ defaultTimelineStep,
9047
9402
  enumerateDateSpan,
9048
9403
  filterComboboxOptions,
9049
9404
  findRuleNodeDepth,
@@ -9057,6 +9412,7 @@ function DiffViewer({
9057
9412
  isDateUnavailable,
9058
9413
  isRuleGroup,
9059
9414
  layeredNeighbor,
9415
+ layoutLane,
9060
9416
  layoutLayeredGraph,
9061
9417
  layoutRelationshipGraph,
9062
9418
  mapRuleGroup,
@@ -9070,6 +9426,8 @@ function DiffViewer({
9070
9426
  parseDateValue,
9071
9427
  parseMetricValue,
9072
9428
  parseView,
9429
+ pixelsToMs,
9430
+ placeSpan,
9073
9431
  relationshipNeighbors,
9074
9432
  relativeTimeValue,
9075
9433
  removeRuleNode,
@@ -9084,11 +9442,14 @@ function DiffViewer({
9084
9442
  selectAllState,
9085
9443
  selectRangeDate,
9086
9444
  serializeView,
9445
+ shiftSpan,
9087
9446
  shouldVirtualize,
9447
+ snapToStep,
9088
9448
  startOfMonth,
9089
9449
  stepMetricValue,
9090
9450
  summarizeDiff,
9091
9451
  summarizeRule,
9452
+ timelineTicks,
9092
9453
  toDateKey,
9093
9454
  toast,
9094
9455
  toggleId,