@tensor_1/react 2.17.0 → 2.19.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.
Files changed (60) hide show
  1. package/README.md +131 -1
  2. package/dist/components/Comments.d.ts +18 -2
  3. package/dist/components/Comments.js +37 -12
  4. package/dist/components/EditorIcons.d.ts +39 -0
  5. package/dist/components/EditorIcons.js +51 -0
  6. package/dist/components/EmojiGlyph.d.ts +10 -0
  7. package/dist/components/EmojiGlyph.js +18 -0
  8. package/dist/components/EmojiPicker.d.ts +60 -0
  9. package/dist/components/EmojiPicker.js +277 -0
  10. package/dist/components/Markdown.d.ts +36 -0
  11. package/dist/components/Markdown.js +104 -0
  12. package/dist/components/ReactionBar.d.ts +57 -0
  13. package/dist/components/ReactionBar.js +81 -0
  14. package/dist/components/RelationshipGraph.d.ts +81 -3
  15. package/dist/components/RelationshipGraph.js +102 -59
  16. package/dist/components/RelationshipGraphLayered.d.ts +8 -0
  17. package/dist/components/RelationshipGraphLayered.js +420 -0
  18. package/dist/components/RelationshipGraphList.d.ts +16 -0
  19. package/dist/components/RelationshipGraphList.js +33 -0
  20. package/dist/components/RichTextEditor.d.ts +128 -0
  21. package/dist/components/RichTextEditor.js +954 -0
  22. package/dist/components/SaveStatus.d.ts +32 -0
  23. package/dist/components/SaveStatus.js +21 -0
  24. package/dist/components/Tabs.d.ts +10 -3
  25. package/dist/components/Tabs.js +5 -3
  26. package/dist/emoji-image-WQLh8ZQP.d.cts +128 -0
  27. package/dist/emoji-image.d.ts +25 -0
  28. package/dist/emoji-image.js +80 -0
  29. package/dist/emoji-model.d.ts +66 -0
  30. package/dist/emoji-model.js +108 -0
  31. package/dist/emoji.cjs +871 -0
  32. package/dist/emoji.d.cts +57 -0
  33. package/dist/emoji.d.ts +6 -0
  34. package/dist/emoji.js +18 -0
  35. package/dist/index.cjs +1503 -540
  36. package/dist/index.d.cts +245 -65
  37. package/dist/index.d.ts +3 -2
  38. package/dist/index.js +11 -2
  39. package/dist/markdown-model.d.ts +75 -0
  40. package/dist/markdown-model.js +438 -0
  41. package/dist/markdown.cjs +585 -0
  42. package/dist/markdown.d.cts +115 -0
  43. package/dist/markdown.d.ts +4 -0
  44. package/dist/markdown.js +9 -0
  45. package/dist/overlay-position-CEGSz6Z2.d.cts +59 -0
  46. package/dist/relationship-graph-model.d.ts +112 -1
  47. package/dist/relationship-graph-model.js +420 -1
  48. package/dist/rich-text/emoji-items.d.ts +14 -0
  49. package/dist/rich-text/emoji-items.js +7 -0
  50. package/dist/rich-text/pipeline.d.ts +91 -0
  51. package/dist/rich-text/pipeline.js +379 -0
  52. package/dist/rich-text/round-trip.d.ts +24 -0
  53. package/dist/rich-text/round-trip.js +11 -0
  54. package/dist/rich-text.cjs +2578 -0
  55. package/dist/rich-text.d.cts +148 -0
  56. package/dist/rich-text.d.ts +8 -0
  57. package/dist/rich-text.js +10 -0
  58. package/dist/url-policy.d.ts +9 -0
  59. package/dist/url-policy.js +11 -0
  60. package/package.json +82 -1
package/dist/index.cjs CHANGED
@@ -50,6 +50,8 @@ __export(src_exports, {
50
50
  ConfirmDialog: () => ConfirmDialog,
51
51
  ContentList: () => ContentList,
52
52
  ContentListItem: () => ContentListItem,
53
+ DEFAULT_RELATIONSHIP_GRAPH_LABELS: () => DEFAULT_RELATIONSHIP_GRAPH_LABELS,
54
+ DEFAULT_SAVE_STATUS_LABELS: () => DEFAULT_SAVE_STATUS_LABELS,
53
55
  DateRangePicker: () => DateRangePicker,
54
56
  DescriptionItem: () => DescriptionItem,
55
57
  DescriptionList: () => DescriptionList,
@@ -116,6 +118,7 @@ __export(src_exports, {
116
118
  RowAction: () => RowAction,
117
119
  RowActions: () => RowActions,
118
120
  RuleBuilder: () => RuleBuilder,
121
+ SaveStatus: () => SaveStatus,
119
122
  SavedViewMenu: () => SavedViewMenu,
120
123
  SchedulingCalendar: () => SchedulingCalendar,
121
124
  SectionHead: () => SectionHead,
@@ -161,6 +164,8 @@ __export(src_exports, {
161
164
  buildThreeWayDiff: () => buildThreeWayDiff,
162
165
  clampMetricValue: () => clampMetricValue,
163
166
  clampWidth: () => clampWidth,
167
+ classifyLayeredEdges: () => classifyLayeredEdges,
168
+ clusterIdFor: () => clusterIdFor,
164
169
  computePosition: () => computePosition,
165
170
  contrastRatio: () => contrastRatio,
166
171
  cx: () => cx,
@@ -175,6 +180,8 @@ __export(src_exports, {
175
180
  isDateInRange: () => isDateInRange,
176
181
  isDateUnavailable: () => isDateUnavailable,
177
182
  isRuleGroup: () => isRuleGroup,
183
+ layeredNeighbor: () => layeredNeighbor,
184
+ layoutLayeredGraph: () => layoutLayeredGraph,
178
185
  layoutRelationshipGraph: () => layoutRelationshipGraph,
179
186
  mapRuleGroup: () => mapRuleGroup,
180
187
  matchFilter: () => matchFilter,
@@ -216,6 +223,7 @@ __export(src_exports, {
216
223
  useVirtualRows: () => useVirtualRows,
217
224
  validateRuleDefinition: () => validateRuleDefinition,
218
225
  virtualWindow: () => virtualWindow,
226
+ wrapEdgeLabel: () => wrapEdgeLabel,
219
227
  zonedDateKey: () => zonedDateKey,
220
228
  zonedDateSpan: () => zonedDateSpan
221
229
  });
@@ -1460,16 +1468,18 @@ function Tab({ value, children, disabled, className, onClick, ...props }) {
1460
1468
  }
1461
1469
  );
1462
1470
  }
1463
- function TabPanel({ value, children, ...props }) {
1471
+ function TabPanel({ value, children, keepMounted, ...props }) {
1464
1472
  const ctx = (0, import_react20.useContext)(TabsCtx);
1465
- if (ctx.value !== value) return null;
1473
+ const selected = ctx.value === value;
1474
+ if (!selected && !keepMounted) return null;
1466
1475
  return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
1467
1476
  "div",
1468
1477
  {
1469
1478
  role: "tabpanel",
1470
1479
  id: ctx.baseId ? `${ctx.baseId}-panel-${value}` : void 0,
1471
1480
  "aria-labelledby": ctx.baseId ? `${ctx.baseId}-tab-${value}` : void 0,
1472
- tabIndex: 0,
1481
+ hidden: !selected || void 0,
1482
+ tabIndex: selected ? 0 : -1,
1473
1483
  ...props,
1474
1484
  children
1475
1485
  }
@@ -2600,41 +2610,84 @@ var import_jsx_runtime44 = require("react/jsx-runtime");
2600
2610
  function Comments({ children, className, ...props }) {
2601
2611
  return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { role: "log", className: cx("uix-comments", className), ...props, children });
2602
2612
  }
2603
- function Comment({ avatar, author, meta, children, className, ...props }) {
2604
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: cx("uix-comment", className), ...props, children: [
2605
- avatar ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "aria-hidden": "true" }),
2606
- /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "uix-comment__body", children: [
2607
- (author != null || meta != null) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "uix-comment__meta", children: [
2608
- author != null && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "uix-comment__author", children: author }),
2609
- author != null && meta != null ? " \xB7 " : null,
2610
- meta
2611
- ] }),
2612
- children
2613
- ] })
2613
+ function Comment({
2614
+ avatar,
2615
+ author,
2616
+ meta,
2617
+ children,
2618
+ className,
2619
+ variant = "person",
2620
+ systemLabel = "System",
2621
+ replyTo,
2622
+ replyToLabel = "In reply to",
2623
+ ...props
2624
+ }) {
2625
+ const system = variant === "system";
2626
+ const byline = author ?? (system ? systemLabel : void 0);
2627
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2628
+ "div",
2629
+ {
2630
+ className: cx("uix-comment", system && "uix-comment--system", className),
2631
+ "data-variant": system ? "system" : void 0,
2632
+ ...props,
2633
+ children: [
2634
+ avatar ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { "aria-hidden": "true" }),
2635
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "uix-comment__body", children: [
2636
+ (byline != null || meta != null) && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "uix-comment__meta", children: [
2637
+ byline != null && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "uix-comment__author", children: byline }),
2638
+ byline != null && meta != null ? " \xB7 " : null,
2639
+ meta
2640
+ ] }),
2641
+ replyTo != null && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("blockquote", { className: "uix-comment__reply", children: [
2642
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "uix-comment__reply-label", children: replyToLabel }),
2643
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "uix-comment__reply-body", children: replyTo })
2644
+ ] }),
2645
+ children
2646
+ ] })
2647
+ ]
2648
+ }
2649
+ );
2650
+ }
2651
+
2652
+ // src/components/SaveStatus.tsx
2653
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2654
+ var DEFAULT_SAVE_STATUS_LABELS = {
2655
+ saving: "Saving\u2026",
2656
+ saved: "Saved",
2657
+ failed: "Could not save",
2658
+ retry: "Try again"
2659
+ };
2660
+ function SaveStatus({ state, labels, onRetry, className, ...props }) {
2661
+ const text = { ...DEFAULT_SAVE_STATUS_LABELS, ...labels };
2662
+ const message = state === "idle" ? "" : text[state];
2663
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: cx("uix-save-status", className), "data-state": state, ...props, children: [
2664
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "uix-save-status__icon", "aria-hidden": "true" }),
2665
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "uix-save-status__text", role: "status", "aria-live": "polite", children: message }),
2666
+ state === "failed" && onRetry && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("button", { type: "button", className: "uix-btn uix-btn--link uix-btn--sm uix-save-status__retry", onClick: onRetry, children: text.retry })
2614
2667
  ] });
2615
2668
  }
2616
2669
 
2617
2670
  // src/components/Composer.tsx
2618
2671
  var import_react28 = require("react");
2619
- var import_jsx_runtime45 = require("react/jsx-runtime");
2672
+ var import_jsx_runtime46 = require("react/jsx-runtime");
2620
2673
  function Composer({ children, className, label = "Add a comment", ...props }) {
2621
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cx("uix-composer", className), ...props, children: import_react28.Children.map(children, (child) => {
2674
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cx("uix-composer", className), ...props, children: import_react28.Children.map(children, (child) => {
2622
2675
  if (!(0, import_react28.isValidElement)(child) || child.type !== "textarea") return child;
2623
2676
  const p = child.props;
2624
2677
  return p["aria-label"] || p["aria-labelledby"] || p.id ? child : (0, import_react28.cloneElement)(child, { "aria-label": label });
2625
2678
  }) });
2626
2679
  }
2627
2680
  function ComposerBar({ children, className, ...props }) {
2628
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: cx("uix-composer__bar", className), ...props, children });
2681
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: cx("uix-composer__bar", className), ...props, children });
2629
2682
  }
2630
2683
 
2631
2684
  // src/components/Segmented.tsx
2632
2685
  var import_react29 = require("react");
2633
- var import_jsx_runtime46 = require("react/jsx-runtime");
2686
+ var import_jsx_runtime47 = require("react/jsx-runtime");
2634
2687
  var SegmentedCtx = (0, import_react29.createContext)({});
2635
2688
  function Segmented({ value, onChange, children, className, ...props }) {
2636
2689
  const contextValue = (0, import_react29.useMemo)(() => ({ value, onChange }), [value, onChange]);
2637
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(SegmentedCtx.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { role: "group", className: cx("uix-segmented", className), ...props, children }) });
2690
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SegmentedCtx.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { role: "group", className: cx("uix-segmented", className), ...props, children }) });
2638
2691
  }
2639
2692
  function SegmentedOption({
2640
2693
  value,
@@ -2645,7 +2698,7 @@ function SegmentedOption({
2645
2698
  }) {
2646
2699
  const ctx = (0, import_react29.useContext)(SegmentedCtx);
2647
2700
  const selected = ctx.value === value;
2648
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
2701
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
2649
2702
  "button",
2650
2703
  {
2651
2704
  type: "button",
@@ -2663,69 +2716,69 @@ function SegmentedOption({
2663
2716
 
2664
2717
  // src/components/TableControls.tsx
2665
2718
  var import_react30 = require("react");
2666
- var import_jsx_runtime47 = require("react/jsx-runtime");
2719
+ var import_jsx_runtime48 = require("react/jsx-runtime");
2667
2720
  function ViewMenu({ density, densityLabel, densityOptions, onDensityChange, zebra, freeze, columns, columnsLabel, onColumnVisibilityChange }) {
2668
2721
  const densityLabelId = (0, import_react30.useId)();
2669
2722
  const zebraLabelId = (0, import_react30.useId)();
2670
2723
  const freezeLabelId = (0, import_react30.useId)();
2671
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu", children: [
2672
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu__group", children: [
2673
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { id: densityLabelId, className: "uix-view-menu__label", children: densityLabel }),
2674
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Segmented, { value: density, onChange: onDensityChange, "aria-labelledby": densityLabelId, children: densityOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(SegmentedOption, { value: option.value, children: option.label }, option.value)) })
2724
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu", children: [
2725
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu__group", children: [
2726
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { id: densityLabelId, className: "uix-view-menu__label", children: densityLabel }),
2727
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Segmented, { value: density, onChange: onDensityChange, "aria-labelledby": densityLabelId, children: densityOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(SegmentedOption, { value: option.value, children: option.label }, option.value)) })
2675
2728
  ] }),
2676
- (zebra || freeze) && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu__group", children: [
2677
- zebra && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu__row", children: [
2678
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { id: zebraLabelId, children: zebra.label }),
2679
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Switch, { checked: zebra.checked, "aria-labelledby": zebraLabelId, onChange: (event) => zebra.onChange(event.currentTarget.checked) })
2729
+ (zebra || freeze) && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu__group", children: [
2730
+ zebra && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu__row", children: [
2731
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { id: zebraLabelId, children: zebra.label }),
2732
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Switch, { checked: zebra.checked, "aria-labelledby": zebraLabelId, onChange: (event) => zebra.onChange(event.currentTarget.checked) })
2680
2733
  ] }),
2681
- freeze && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu__row", children: [
2682
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { id: freezeLabelId, children: freeze.label }),
2683
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Switch, { checked: freeze.checked, "aria-labelledby": freezeLabelId, onChange: (event) => freeze.onChange(event.currentTarget.checked) })
2734
+ freeze && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu__row", children: [
2735
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { id: freezeLabelId, children: freeze.label }),
2736
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Switch, { checked: freeze.checked, "aria-labelledby": freezeLabelId, onChange: (event) => freeze.onChange(event.currentTarget.checked) })
2684
2737
  ] })
2685
2738
  ] }),
2686
- columns && columns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-view-menu__group", children: [
2687
- columnsLabel != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "uix-view-menu__label", children: columnsLabel }),
2688
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("div", { className: "uix-view-menu__cols", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Checkbox, { label: column.label, checked: column.visible, disabled: column.disabled, onChange: (event) => onColumnVisibilityChange?.(column.id, event.currentTarget.checked) }, column.id)) })
2739
+ columns && columns.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-view-menu__group", children: [
2740
+ columnsLabel != null && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "uix-view-menu__label", children: columnsLabel }),
2741
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "uix-view-menu__cols", children: columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Checkbox, { label: column.label, checked: column.visible, disabled: column.disabled, onChange: (event) => onColumnVisibilityChange?.(column.id, event.currentTarget.checked) }, column.id)) })
2689
2742
  ] })
2690
2743
  ] });
2691
2744
  }
2692
2745
  function FilterPopover({ label, type = "text", value, onValueChange, options, applyLabel, clearLabel, onApply, onClear, placeholder }) {
2693
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-filter-popover", children: [
2694
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("label", { className: "uix-label", children: [
2695
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { children: label }),
2696
- type === "select" || type === "enum" || type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("select", { className: "uix-select", value, onChange: (event) => onValueChange(event.currentTarget.value), children: options?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("option", { value: option.value, children: option.label }, option.value)) }) : /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Input, { type, value, placeholder, onChange: (event) => onValueChange(event.currentTarget.value) })
2746
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-filter-popover", children: [
2747
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("label", { className: "uix-label", children: [
2748
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { children: label }),
2749
+ type === "select" || type === "enum" || type === "boolean" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("select", { className: "uix-select", value, onChange: (event) => onValueChange(event.currentTarget.value), children: options?.map((option) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("option", { value: option.value, children: option.label }, option.value)) }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Input, { type, value, placeholder, onChange: (event) => onValueChange(event.currentTarget.value) })
2697
2750
  ] }),
2698
- /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "uix-filter-popover__actions", children: [
2699
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Button, { type: "button", onClick: onClear, children: clearLabel }),
2700
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(Button, { type: "button", variant: "primary", onClick: onApply, children: applyLabel })
2751
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-filter-popover__actions", children: [
2752
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Button, { type: "button", onClick: onClear, children: clearLabel }),
2753
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(Button, { type: "button", variant: "primary", onClick: onApply, children: applyLabel })
2701
2754
  ] })
2702
2755
  ] });
2703
2756
  }
2704
2757
  function SavedViewMenu({ items, onSelect, onPinChange, pinLabel, unpinLabel, emptyLabel, actions, footer }) {
2705
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("ul", { className: "uix-menu uix-saved-views", children: [
2706
- items.length === 0 && emptyLabel != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("li", { className: "uix-menu__label", children: emptyLabel }),
2707
- items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("li", { className: "uix-saved-views__row", children: [
2708
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: "uix-menu__item", "data-active": item.active || void 0, onClick: () => onSelect(item.id), children: item.label }),
2709
- onPinChange && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("button", { type: "button", className: "uix-saved-views__pin", "aria-label": item.pinned ? unpinLabel : pinLabel, "data-on": item.pinned || void 0, onClick: () => onPinChange(item.id, !item.pinned), children: "\u2605" }),
2758
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("ul", { className: "uix-menu uix-saved-views", children: [
2759
+ items.length === 0 && emptyLabel != null && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("li", { className: "uix-menu__label", children: emptyLabel }),
2760
+ items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("li", { className: "uix-saved-views__row", children: [
2761
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "uix-menu__item", "data-active": item.active || void 0, onClick: () => onSelect(item.id), children: item.label }),
2762
+ onPinChange && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("button", { type: "button", className: "uix-saved-views__pin", "aria-label": item.pinned ? unpinLabel : pinLabel, "data-on": item.pinned || void 0, onClick: () => onPinChange(item.id, !item.pinned), children: "\u2605" }),
2710
2763
  actions?.(item)
2711
2764
  ] }, item.id)),
2712
- footer != null && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("li", { className: "uix-saved-views__footer", children: footer })
2765
+ footer != null && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("li", { className: "uix-saved-views__footer", children: footer })
2713
2766
  ] });
2714
2767
  }
2715
2768
 
2716
2769
  // src/components/Timeline.tsx
2717
- var import_jsx_runtime48 = require("react/jsx-runtime");
2770
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2718
2771
  function Timeline({ children, className, ...props }) {
2719
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("ol", { className: cx("uix-timeline", className), ...props, children });
2772
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("ol", { className: cx("uix-timeline", className), ...props, children });
2720
2773
  }
2721
2774
  function TimelineItem({ node, meta, children, className, ...props }) {
2722
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("li", { className: cx("uix-timeline__item", className), ...props, children: [
2723
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-timeline__rail", "aria-hidden": "true", children: [
2724
- node ?? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "uix-timeline__node" }),
2725
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { className: "uix-timeline__line" })
2775
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("li", { className: cx("uix-timeline__item", className), ...props, children: [
2776
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "uix-timeline__rail", "aria-hidden": "true", children: [
2777
+ node ?? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "uix-timeline__node" }),
2778
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "uix-timeline__line" })
2726
2779
  ] }),
2727
- /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: "uix-timeline__body", children: [
2728
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "uix-timeline__meta", children: meta }),
2780
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "uix-timeline__body", children: [
2781
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "uix-timeline__meta", children: meta }),
2729
2782
  children
2730
2783
  ] })
2731
2784
  ] });
@@ -2733,10 +2786,10 @@ function TimelineItem({ node, meta, children, className, ...props }) {
2733
2786
 
2734
2787
  // src/components/Pipeline.tsx
2735
2788
  var import_react31 = require("react");
2736
- var import_jsx_runtime49 = require("react/jsx-runtime");
2789
+ var import_jsx_runtime50 = require("react/jsx-runtime");
2737
2790
  function Pipeline({ detailed = false, children, className, tabIndex, ...props }) {
2738
2791
  const stages = detailed ? import_react31.Children.map(children, (child) => (0, import_react31.isValidElement)(child) && child.type === PipelineStage ? (0, import_react31.cloneElement)(child, { detailed: child.props.detailed ?? true }) : child) : children;
2739
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
2792
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2740
2793
  "ol",
2741
2794
  {
2742
2795
  className: cx("uix-pipeline", detailed && "uix-pipeline--detailed", className),
@@ -2773,20 +2826,20 @@ function PipelineStage({
2773
2826
  const current = currentProp ?? (state === "active" || state === "current" || state === "running");
2774
2827
  const resolvedStateLabel = stateLabel2 ?? DEFAULT_STATE_LABELS[state];
2775
2828
  const showDetails = detailed || description != null || meta != null || marker != null;
2776
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
2829
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2777
2830
  "li",
2778
2831
  {
2779
2832
  className: cx("uix-pipeline__stage", className),
2780
2833
  "data-state": state,
2781
2834
  "aria-current": current ? "step" : void 0,
2782
2835
  ...props,
2783
- children: showDetails ? /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(import_jsx_runtime49.Fragment, { children: [
2784
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "uix-pipeline__marker", "aria-hidden": "true", children: marker }),
2785
- /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "uix-pipeline__content", children: [
2786
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "uix-pipeline__eyebrow", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "uix-pipeline__state", children: resolvedStateLabel }) }),
2787
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "uix-pipeline__title", children: label }),
2788
- description != null && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "uix-pipeline__description", children: description }),
2789
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "uix-pipeline__meta", children: meta })
2836
+ children: showDetails ? /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)(import_jsx_runtime50.Fragment, { children: [
2837
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "uix-pipeline__marker", "aria-hidden": "true", children: marker }),
2838
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "uix-pipeline__content", children: [
2839
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-pipeline__eyebrow", children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "uix-pipeline__state", children: resolvedStateLabel }) }),
2840
+ /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-pipeline__title", children: label }),
2841
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-pipeline__description", children: description }),
2842
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-pipeline__meta", children: meta })
2790
2843
  ] })
2791
2844
  ] }) : label
2792
2845
  }
@@ -2794,9 +2847,9 @@ function PipelineStage({
2794
2847
  }
2795
2848
 
2796
2849
  // src/components/Flow.tsx
2797
- var import_jsx_runtime50 = require("react/jsx-runtime");
2850
+ var import_jsx_runtime51 = require("react/jsx-runtime");
2798
2851
  function Flow({ variant = "linear", panel = false, children, className, role = "group", ...props }) {
2799
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2852
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
2800
2853
  "div",
2801
2854
  {
2802
2855
  className: cx("uix-flow", `uix-flow--${variant}`, panel && "uix-flow--panel", className),
@@ -2826,33 +2879,33 @@ function FlowNode({
2826
2879
  ...props
2827
2880
  }) {
2828
2881
  const resolvedStateLabel = stateLabel2 ?? FLOW_STATE_LABELS[state];
2829
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: cx("uix-node", `uix-node--${state}`, icon == null && "uix-node--no-icon", wide && "uix-node--wide", className), ...props, children: [
2830
- icon != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("span", { className: "uix-node__icon", "aria-hidden": "true", children: icon }),
2831
- /* @__PURE__ */ (0, import_jsx_runtime50.jsxs)("div", { className: "uix-node__body", children: [
2832
- eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-node__eyebrow", children: eyebrow }),
2833
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-node__title", children: title }),
2834
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-node__meta", children: meta }),
2835
- /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-node__status", children: resolvedStateLabel })
2882
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: cx("uix-node", `uix-node--${state}`, icon == null && "uix-node--no-icon", wide && "uix-node--wide", className), ...props, children: [
2883
+ icon != null && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("span", { className: "uix-node__icon", "aria-hidden": "true", children: icon }),
2884
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: "uix-node__body", children: [
2885
+ eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-node__eyebrow", children: eyebrow }),
2886
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-node__title", children: title }),
2887
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-node__meta", children: meta }),
2888
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-node__status", children: resolvedStateLabel })
2836
2889
  ] }),
2837
- footer != null && /* @__PURE__ */ (0, import_jsx_runtime50.jsx)("div", { className: "uix-node__footer", children: footer })
2890
+ footer != null && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-node__footer", children: footer })
2838
2891
  ] });
2839
2892
  }
2840
2893
 
2841
2894
  // src/components/Prose.tsx
2842
- var import_jsx_runtime51 = require("react/jsx-runtime");
2895
+ var import_jsx_runtime52 = require("react/jsx-runtime");
2843
2896
  function Prose({ children, className, ...props }) {
2844
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: cx("uix-prose", className), ...props, children });
2897
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: cx("uix-prose", className), ...props, children });
2845
2898
  }
2846
2899
  function Note({ tone, icon, children, className, ...props }) {
2847
- return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { className: cx("uix-note", tone && `uix-note--${tone}`, className), ...props, children: [
2848
- icon != null && /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-note__icon", children: icon }),
2849
- /* @__PURE__ */ (0, import_jsx_runtime51.jsx)("div", { className: "uix-note__body", children })
2900
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { className: cx("uix-note", tone && `uix-note--${tone}`, className), ...props, children: [
2901
+ icon != null && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uix-note__icon", children: icon }),
2902
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { className: "uix-note__body", children })
2850
2903
  ] });
2851
2904
  }
2852
2905
 
2853
2906
  // src/components/Popover.tsx
2854
2907
  var import_react32 = require("react");
2855
- var import_jsx_runtime52 = require("react/jsx-runtime");
2908
+ var import_jsx_runtime53 = require("react/jsx-runtime");
2856
2909
  function Popover({
2857
2910
  popover = "auto",
2858
2911
  anchor,
@@ -2881,12 +2934,12 @@ function Popover({
2881
2934
  el.addEventListener("toggle", sync);
2882
2935
  return () => el.removeEventListener("toggle", sync);
2883
2936
  }, [anchor, reposition]);
2884
- return /* @__PURE__ */ (0, import_jsx_runtime52.jsx)("div", { ref, className: cx("uix-popover", className), ...popoverAttr, ...props, children });
2937
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { ref, className: cx("uix-popover", className), ...popoverAttr, ...props, children });
2885
2938
  }
2886
2939
 
2887
2940
  // src/components/CommandPalette.tsx
2888
2941
  var import_react33 = require("react");
2889
- var import_jsx_runtime53 = require("react/jsx-runtime");
2942
+ var import_jsx_runtime54 = require("react/jsx-runtime");
2890
2943
  var CmdkContext = (0, import_react33.createContext)(null);
2891
2944
  function CommandPalette({ inputProps, children, className, ...props }) {
2892
2945
  const listId = (0, import_react33.useId)();
@@ -2905,8 +2958,8 @@ function CommandPalette({ inputProps, children, className, ...props }) {
2905
2958
  return () => clearTimeout(t);
2906
2959
  }, [count]);
2907
2960
  const ctx = (0, import_react33.useMemo)(() => ({ listId, setActive, registerItem }), [listId, setActive, registerItem]);
2908
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(CmdkContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { className: cx("uix-cmdk", className), ...props, children: [
2909
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
2961
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(CmdkContext.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { className: cx("uix-cmdk", className), ...props, children: [
2962
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
2910
2963
  "input",
2911
2964
  {
2912
2965
  className: "uix-cmdk__input",
@@ -2919,14 +2972,14 @@ function CommandPalette({ inputProps, children, className, ...props }) {
2919
2972
  ...inputProps
2920
2973
  }
2921
2974
  ),
2922
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "uix-cmdk__list", role: "listbox", id: listId, children }),
2923
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { className: "uix-visually-hidden", role: "status", children: announced })
2975
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uix-cmdk__list", role: "listbox", id: listId, children }),
2976
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { className: "uix-visually-hidden", role: "status", children: announced })
2924
2977
  ] }) });
2925
2978
  }
2926
2979
  function CommandGroup({ label, children }) {
2927
2980
  const labelId = (0, import_react33.useId)();
2928
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { role: "group", "aria-labelledby": label != null ? labelId : void 0, children: [
2929
- label != null && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("div", { className: "uix-cmdk__group", id: labelId, children: label }),
2981
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)("div", { role: "group", "aria-labelledby": label != null ? labelId : void 0, children: [
2982
+ label != null && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uix-cmdk__group", id: labelId, children: label }),
2930
2983
  children
2931
2984
  ] });
2932
2985
  }
@@ -2940,7 +2993,7 @@ function CommandItem({ icon, shortcut, active, children, className, id, ...props
2940
2993
  ctx.setActive(itemId, true);
2941
2994
  return () => ctx.setActive(itemId, false);
2942
2995
  }, [ctx, itemId, active]);
2943
- return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)(
2996
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
2944
2997
  "div",
2945
2998
  {
2946
2999
  className: cx("uix-cmdk__item", className),
@@ -2951,7 +3004,7 @@ function CommandItem({ icon, shortcut, active, children, className, id, ...props
2951
3004
  ...props,
2952
3005
  children: [
2953
3006
  icon,
2954
- /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { children }),
3007
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("span", { children }),
2955
3008
  shortcut
2956
3009
  ]
2957
3010
  }
@@ -2960,9 +3013,9 @@ function CommandItem({ icon, shortcut, active, children, className, id, ...props
2960
3013
 
2961
3014
  // src/components/Inbox.tsx
2962
3015
  var import_react34 = require("react");
2963
- var import_jsx_runtime54 = require("react/jsx-runtime");
3016
+ var import_jsx_runtime55 = require("react/jsx-runtime");
2964
3017
  function Inbox({ view, children, className, ...props }) {
2965
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: cx("uix-inbox", className), "data-view": view, ...props, children });
3018
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: cx("uix-inbox", className), "data-view": view, ...props, children });
2966
3019
  }
2967
3020
  var InboxListCtx = (0, import_react34.createContext)({});
2968
3021
  function InboxList({ children, className, ...props }) {
@@ -3003,7 +3056,7 @@ function InboxList({ children, className, ...props }) {
3003
3056
  setActiveId(el.id);
3004
3057
  el.scrollIntoView({ block: "nearest" });
3005
3058
  };
3006
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(InboxListCtx.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
3059
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(InboxListCtx.Provider, { value: ctx, children: /* @__PURE__ */ (0, import_jsx_runtime55.jsx)(
3007
3060
  "div",
3008
3061
  {
3009
3062
  ref: listRef,
@@ -3032,7 +3085,7 @@ function InboxItem({
3032
3085
  const autoId = (0, import_react34.useId)();
3033
3086
  const itemId = id ?? autoId;
3034
3087
  const { activeId } = (0, import_react34.useContext)(InboxListCtx);
3035
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(
3088
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
3036
3089
  "div",
3037
3090
  {
3038
3091
  role: "option",
@@ -3044,35 +3097,35 @@ function InboxItem({
3044
3097
  ...props,
3045
3098
  children: [
3046
3099
  leading,
3047
- subject != null && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uix-inbox__subject", children: subject }),
3048
- preview != null && /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: "uix-inbox__preview", children: preview }),
3100
+ subject != null && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uix-inbox__subject", children: subject }),
3101
+ preview != null && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uix-inbox__preview", children: preview }),
3049
3102
  children
3050
3103
  ]
3051
3104
  }
3052
3105
  );
3053
3106
  }
3054
3107
  function InboxDetail({ children, className, ...props }) {
3055
- return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)("div", { className: cx("uix-inbox__detail", className), ...props, children });
3108
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: cx("uix-inbox__detail", className), ...props, children });
3056
3109
  }
3057
3110
 
3058
3111
  // src/components/Kanban.tsx
3059
3112
  var import_react35 = require("react");
3060
- var import_jsx_runtime55 = require("react/jsx-runtime");
3113
+ var import_jsx_runtime56 = require("react/jsx-runtime");
3061
3114
  function Kanban({ announcement, children, className, ...props }) {
3062
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: cx("uix-kanban", className), ...props, children: [
3063
- announcement != null && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { role: "status", className: "uix-visually-hidden", children: announcement }),
3115
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cx("uix-kanban", className), ...props, children: [
3116
+ announcement != null && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { role: "status", className: "uix-visually-hidden", children: announcement }),
3064
3117
  children
3065
3118
  ] });
3066
3119
  }
3067
3120
  function KanbanColumn({ title, count, children, className, ...props }) {
3068
3121
  const headId = (0, import_react35.useId)();
3069
3122
  const hasHead = title != null || count != null;
3070
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: cx("uix-kanban__col", className), ...props, children: [
3071
- hasHead && /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { className: "uix-kanban__head", id: headId, children: [
3123
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: cx("uix-kanban__col", className), ...props, children: [
3124
+ hasHead && /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("div", { className: "uix-kanban__head", id: headId, children: [
3072
3125
  title,
3073
- count != null && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { className: "uix-kanban__count", children: count })
3126
+ count != null && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "uix-kanban__count", children: count })
3074
3127
  ] }),
3075
- /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uix-kanban__body", role: "list", "aria-labelledby": hasHead ? headId : void 0, children })
3128
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "uix-kanban__body", role: "list", "aria-labelledby": hasHead ? headId : void 0, children })
3076
3129
  ] });
3077
3130
  }
3078
3131
  var MOVE_KEYS = {
@@ -3091,7 +3144,7 @@ function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...pr
3091
3144
  onMove(dir);
3092
3145
  }
3093
3146
  };
3094
- return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)(
3147
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
3095
3148
  "div",
3096
3149
  {
3097
3150
  role: "listitem",
@@ -3100,8 +3153,8 @@ function KanbanCard({ title, meta, children, className, onMove, onKeyDown, ...pr
3100
3153
  onKeyDown: handleKeyDown,
3101
3154
  ...props,
3102
3155
  children: [
3103
- title && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uix-kanban__card-title", children: title }),
3104
- meta && /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { className: "uix-kanban__card-meta", children: meta }),
3156
+ title && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "uix-kanban__card-title", children: title }),
3157
+ meta && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("div", { className: "uix-kanban__card-meta", children: meta }),
3105
3158
  children
3106
3159
  ]
3107
3160
  }
@@ -3167,12 +3220,12 @@ function treeNav(flat, currentId, key) {
3167
3220
  }
3168
3221
 
3169
3222
  // src/components/Tree.tsx
3170
- var import_jsx_runtime56 = require("react/jsx-runtime");
3171
- var ChevronIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("path", { d: "M2 4l4 4 4-4" }) });
3223
+ var import_jsx_runtime57 = require("react/jsx-runtime");
3224
+ var ChevronIcon2 = () => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("svg", { viewBox: "0 0 12 12", fill: "none", stroke: "currentColor", strokeWidth: 1.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("path", { d: "M2 4l4 4 4-4" }) });
3172
3225
  function TreeNode({ node, expanded, selected, selectable, tabbableId, onToggle, onSelect, onFocusNode, level = 1 }) {
3173
3226
  const hasChildren = Array.isArray(node.children) && node.children.length > 0;
3174
3227
  const isExpanded = expanded.has(node.id);
3175
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
3228
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
3176
3229
  "li",
3177
3230
  {
3178
3231
  role: "treeitem",
@@ -3192,12 +3245,12 @@ function TreeNode({ node, expanded, selected, selectable, tabbableId, onToggle,
3192
3245
  onFocusNode(node.id);
3193
3246
  },
3194
3247
  children: [
3195
- /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "uix-tree__row", children: [
3196
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "uix-tree__toggle", children: hasChildren && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ChevronIcon2, {}) }),
3197
- node.icon && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { "aria-hidden": "true", children: node.icon }),
3198
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "uix-tree__label", children: node.label })
3248
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "uix-tree__row", children: [
3249
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-tree__toggle", children: hasChildren && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ChevronIcon2, {}) }),
3250
+ node.icon && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { "aria-hidden": "true", children: node.icon }),
3251
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-tree__label", children: node.label })
3199
3252
  ] }),
3200
- hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("ul", { role: "group", className: "uix-tree__group", children: node.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3253
+ hasChildren && isExpanded && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("ul", { role: "group", className: "uix-tree__group", children: node.children.map((child) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3201
3254
  TreeNode,
3202
3255
  {
3203
3256
  node: child,
@@ -3249,7 +3302,7 @@ function Tree({
3249
3302
  const useVirtual = virtualize ?? shouldVirtualize(flat.length);
3250
3303
  const tabbableId = focusedId ?? selected ?? nodes[0]?.id;
3251
3304
  if (useVirtual) {
3252
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3305
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3253
3306
  VirtualTreeView,
3254
3307
  {
3255
3308
  flat,
@@ -3326,7 +3379,7 @@ function Tree({
3326
3379
  break;
3327
3380
  }
3328
3381
  };
3329
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("ul", { ref: rootRef, className: cx("uix-tree", className), role: "tree", onKeyDown, ...props, children: nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3382
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("ul", { ref: rootRef, className: cx("uix-tree", className), role: "tree", onKeyDown, ...props, children: nodes.map((node) => /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3330
3383
  TreeNode,
3331
3384
  {
3332
3385
  node,
@@ -3406,7 +3459,7 @@ function VirtualTreeView({
3406
3459
  }
3407
3460
  if (act.focusId !== void 0) moveTo(act.focusId);
3408
3461
  };
3409
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)(
3462
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
3410
3463
  "ul",
3411
3464
  {
3412
3465
  ref: scrollRef,
@@ -3424,10 +3477,10 @@ function VirtualTreeView({
3424
3477
  },
3425
3478
  ...props,
3426
3479
  children: [
3427
- win.padTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("li", { role: "presentation", "aria-hidden": "true", style: { height: win.padTop } }),
3480
+ win.padTop > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("li", { role: "presentation", "aria-hidden": "true", style: { height: win.padTop } }),
3428
3481
  rows.map((f, i) => {
3429
3482
  const rowStyle = { height: rowHeight, paddingLeft: `calc(${f.level - 1} * var(--uix-space-5))` };
3430
- return /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
3483
+ return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3431
3484
  "li",
3432
3485
  {
3433
3486
  role: "treeitem",
@@ -3448,23 +3501,23 @@ function VirtualTreeView({
3448
3501
  onSelect?.(f.node.id);
3449
3502
  setFocusedId(f.node.id);
3450
3503
  },
3451
- children: /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("span", { className: "uix-tree__row", style: rowStyle, children: [
3452
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "uix-tree__toggle", children: f.hasChildren && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(ChevronIcon2, {}) }),
3453
- f.node.icon && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { "aria-hidden": "true", children: f.node.icon }),
3454
- /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("span", { className: "uix-tree__label", children: f.node.label })
3504
+ children: /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { className: "uix-tree__row", style: rowStyle, children: [
3505
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-tree__toggle", children: f.hasChildren && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(ChevronIcon2, {}) }),
3506
+ f.node.icon && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { "aria-hidden": "true", children: f.node.icon }),
3507
+ /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-tree__label", children: f.node.label })
3455
3508
  ] })
3456
3509
  },
3457
3510
  f.node.id
3458
3511
  );
3459
3512
  }),
3460
- win.padBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime56.jsx)("li", { role: "presentation", "aria-hidden": "true", style: { height: win.padBottom } })
3513
+ win.padBottom > 0 && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("li", { role: "presentation", "aria-hidden": "true", style: { height: win.padBottom } })
3461
3514
  ]
3462
3515
  }
3463
3516
  );
3464
3517
  }
3465
3518
 
3466
3519
  // src/components/EditorialHome.tsx
3467
- var import_jsx_runtime57 = require("react/jsx-runtime");
3520
+ var import_jsx_runtime58 = require("react/jsx-runtime");
3468
3521
  function PageIntro({
3469
3522
  kicker,
3470
3523
  title,
@@ -3477,39 +3530,39 @@ function PageIntro({
3477
3530
  children,
3478
3531
  ...props
3479
3532
  }) {
3480
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("section", { className: cx("uix-page-intro", className), ...props, children: [
3481
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
3482
- kicker != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-page-kicker", children: kicker }),
3483
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h1", { className: "uix-page-title", children: title }),
3484
- lede != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-page-lede", children: lede })
3533
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: cx("uix-page-intro", className), ...props, children: [
3534
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
3535
+ kicker != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-page-kicker", children: kicker }),
3536
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h1", { className: "uix-page-title", children: title }),
3537
+ lede != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-page-lede", children: lede })
3485
3538
  ] }),
3486
- search != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
3487
- searchLabel != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-intro-search__label", children: searchLabel }),
3539
+ search != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
3540
+ searchLabel != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-intro-search__label", children: searchLabel }),
3488
3541
  search
3489
3542
  ] }),
3490
- shortcuts != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uix-shortcut-grid", "aria-label": shortcutsLabel, children: shortcuts }),
3543
+ shortcuts != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "uix-shortcut-grid", "aria-label": shortcutsLabel, children: shortcuts }),
3491
3544
  children
3492
3545
  ] });
3493
3546
  }
3494
3547
  function SectionHead({ title, titleId, action, className, ...props }) {
3495
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cx("uix-section-head", className), ...props, children: [
3496
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h2", { className: "uix-section-title", id: titleId, children: title }),
3548
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: cx("uix-section-head", className), ...props, children: [
3549
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "uix-section-title", id: titleId, children: title }),
3497
3550
  action
3498
3551
  ] });
3499
3552
  }
3500
3553
  function NoticeQueue({ icon, title, summary, meta, position, actions, className, ...props }) {
3501
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("section", { className: cx("uix-notice", className), ...props, children: [
3554
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: cx("uix-notice", className), ...props, children: [
3502
3555
  icon,
3503
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-notice__content", "aria-live": "polite", children: [
3504
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "uix-notice__copy", children: [
3505
- title != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("strong", { children: title }),
3556
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-notice__content", "aria-live": "polite", children: [
3557
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("p", { className: "uix-notice__copy", children: [
3558
+ title != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("strong", { children: title }),
3506
3559
  title != null && summary != null && " ",
3507
3560
  summary
3508
3561
  ] }),
3509
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-notice__meta", children: meta })
3562
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-notice__meta", children: meta })
3510
3563
  ] }),
3511
- (position != null || actions != null) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-notice__actions", children: [
3512
- position != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-notice__position", children: position }),
3564
+ (position != null || actions != null) && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-notice__actions", children: [
3565
+ position != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-notice__position", children: position }),
3513
3566
  actions
3514
3567
  ] })
3515
3568
  ] });
@@ -3527,8 +3580,8 @@ function FeaturedStage({
3527
3580
  className,
3528
3581
  ...props
3529
3582
  }) {
3530
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("article", { className: cx("uix-featured__stage", className), ...props, children: [
3531
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)(
3583
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("article", { className: cx("uix-featured__stage", className), ...props, children: [
3584
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3532
3585
  "div",
3533
3586
  {
3534
3587
  className: "uix-featured__visual",
@@ -3538,32 +3591,32 @@ function FeaturedStage({
3538
3591
  children: visual
3539
3592
  }
3540
3593
  ),
3541
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-featured__content", "aria-live": "polite", children: [
3542
- (eyebrow != null || ordinal != null) && /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("p", { className: "uix-featured__eyebrow", children: [
3543
- ordinal != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-featured__now", children: ordinal }),
3594
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-featured__content", "aria-live": "polite", children: [
3595
+ (eyebrow != null || ordinal != null) && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("p", { className: "uix-featured__eyebrow", children: [
3596
+ ordinal != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-featured__now", children: ordinal }),
3544
3597
  eyebrow
3545
3598
  ] }),
3546
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h2", { className: "uix-featured__title", id: titleId, children: title }),
3547
- description != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-featured__description", children: description }),
3548
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-featured__meta", children: meta }),
3599
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "uix-featured__title", id: titleId, children: title }),
3600
+ description != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-featured__description", children: description }),
3601
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-featured__meta", children: meta }),
3549
3602
  action
3550
3603
  ] })
3551
3604
  ] });
3552
3605
  }
3553
3606
  function FeaturedRundown({ eyebrow, title, titleId, meta, children, className, ...props }) {
3554
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("aside", { className: cx("uix-rundown", className), ...props, children: [
3555
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-rundown__head", children: [
3556
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
3557
- eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-rundown__eyebrow", children: eyebrow }),
3558
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h2", { className: "uix-rundown__title", id: titleId, children: title })
3607
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("aside", { className: cx("uix-rundown", className), ...props, children: [
3608
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-rundown__head", children: [
3609
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
3610
+ eyebrow != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-rundown__eyebrow", children: eyebrow }),
3611
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h2", { className: "uix-rundown__title", id: titleId, children: title })
3559
3612
  ] }),
3560
3613
  meta
3561
3614
  ] }),
3562
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: "uix-rundown__items", children })
3615
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "uix-rundown__items", children })
3563
3616
  ] });
3564
3617
  }
3565
3618
  function FeaturedRundownItem({ number, topic, title, selected = false, className, ...props }) {
3566
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)(
3619
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(
3567
3620
  "button",
3568
3621
  {
3569
3622
  type: "button",
@@ -3572,63 +3625,63 @@ function FeaturedRundownItem({ number, topic, title, selected = false, className
3572
3625
  "data-selected": selected ? "true" : "false",
3573
3626
  ...props,
3574
3627
  children: [
3575
- number != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-rundown__number", children: number }),
3576
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("span", { children: [
3577
- topic != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-rundown__topic", children: topic }),
3578
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-rundown__item-title", children: title })
3628
+ number != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-rundown__number", children: number }),
3629
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { children: [
3630
+ topic != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-rundown__topic", children: topic }),
3631
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-rundown__item-title", children: title })
3579
3632
  ] })
3580
3633
  ]
3581
3634
  }
3582
3635
  );
3583
3636
  }
3584
3637
  function NewsLead({ meta, title, summary, className, ...props }) {
3585
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("article", { className: cx("uix-news-lead", className), ...props, children: [
3586
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-news-lead__meta", children: meta }),
3587
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("h3", { className: "uix-news-lead__title", children: title }),
3588
- summary != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-news-lead__summary", children: summary })
3638
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("article", { className: cx("uix-news-lead", className), ...props, children: [
3639
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-news-lead__meta", children: meta }),
3640
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("h3", { className: "uix-news-lead__title", children: title }),
3641
+ summary != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-news-lead__summary", children: summary })
3589
3642
  ] });
3590
3643
  }
3591
3644
  function ContentList({ children, className, ...props }) {
3592
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("ul", { className: cx("uix-content-list", className), ...props, children });
3645
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("ul", { className: cx("uix-content-list", className), ...props, children });
3593
3646
  }
3594
3647
  function ContentListItem({ title, meta, trailing, className, ...props }) {
3595
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("li", { className: cx("uix-content-list__item", className), ...props, children: [
3596
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
3597
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-content-list__title", children: title }),
3598
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-content-list__meta", children: meta })
3648
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("li", { className: cx("uix-content-list__item", className), ...props, children: [
3649
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
3650
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-content-list__title", children: title }),
3651
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-content-list__meta", children: meta })
3599
3652
  ] }),
3600
3653
  trailing
3601
3654
  ] });
3602
3655
  }
3603
3656
  function ResourceGrid({ children, className, ...props }) {
3604
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("div", { className: cx("uix-resource-grid", className), ...props, children });
3657
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: cx("uix-resource-grid", className), ...props, children });
3605
3658
  }
3606
3659
  function StatLine({ items, children, className, ...props }) {
3607
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cx("uix-stat-line", className), ...props, children: [
3608
- items?.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-stat-line__item", children: [
3609
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-stat-line__value", children: item.value }),
3610
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-stat-line__label", children: item.label })
3660
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: cx("uix-stat-line", className), ...props, children: [
3661
+ items?.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-stat-line__item", children: [
3662
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-stat-line__value", children: item.value }),
3663
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-stat-line__label", children: item.label })
3611
3664
  ] }, item.id ?? i)),
3612
3665
  children
3613
3666
  ] });
3614
3667
  }
3615
3668
  function EventRow({ month, day, title, meta, className, ...props }) {
3616
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cx("uix-event-row", className), ...props, children: [
3617
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: "uix-event-date", children: [
3618
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-event-date__month", children: month }),
3619
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-event-date__day", children: day })
3669
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: cx("uix-event-row", className), ...props, children: [
3670
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-event-date", children: [
3671
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-event-date__month", children: month }),
3672
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-event-date__day", children: day })
3620
3673
  ] }),
3621
- /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { children: [
3622
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-event-row__title", children: title }),
3623
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("p", { className: "uix-event-row__meta", children: meta })
3674
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { children: [
3675
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-event-row__title", children: title }),
3676
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { className: "uix-event-row__meta", children: meta })
3624
3677
  ] })
3625
3678
  ] });
3626
3679
  }
3627
3680
  function StatusRow({ indicator, name, meta, className, ...props }) {
3628
- return /* @__PURE__ */ (0, import_jsx_runtime57.jsxs)("div", { className: cx("uix-status-row", className), ...props, children: [
3681
+ return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: cx("uix-status-row", className), ...props, children: [
3629
3682
  indicator,
3630
- /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-status-row__name", children: name }),
3631
- meta != null && /* @__PURE__ */ (0, import_jsx_runtime57.jsx)("span", { className: "uix-list-meta", children: meta })
3683
+ /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-status-row__name", children: name }),
3684
+ meta != null && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-list-meta", children: meta })
3632
3685
  ] });
3633
3686
  }
3634
3687
 
@@ -3725,7 +3778,7 @@ function summarizeRule(value, labels = {}) {
3725
3778
  }
3726
3779
 
3727
3780
  // src/components/RuleBuilder.tsx
3728
- var import_jsx_runtime58 = require("react/jsx-runtime");
3781
+ var import_jsx_runtime59 = require("react/jsx-runtime");
3729
3782
  var ruleId = 0;
3730
3783
  var nextId = (prefix) => `${prefix}-${Date.now().toString(36)}-${(++ruleId).toString(36)}`;
3731
3784
  function defaultCondition(fields, operators) {
@@ -3741,21 +3794,21 @@ function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disa
3741
3794
  combinator: "and",
3742
3795
  conditions: [defaultCondition(fields, operators)]
3743
3796
  }, maxDepth));
3744
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("fieldset", { className: "uix-rule-builder__group", "data-depth": depth, children: [
3745
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("legend", { className: "uix-rule-builder__group-heading", children: [
3746
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { children: depth === 1 ? "When" : "Group" }),
3747
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { children: [
3797
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("fieldset", { className: "uix-rule-builder__group", "data-depth": depth, children: [
3798
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("legend", { className: "uix-rule-builder__group-heading", children: [
3799
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: depth === 1 ? "When" : "Group" }),
3800
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { children: [
3748
3801
  "Match",
3749
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("select", { className: "uix-select uix-select--sm", value: group.combinator, disabled, onChange: (event) => updateNode(group.id, (node) => ({ ...node, combinator: event.currentTarget.value })), children: [
3750
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("option", { value: "and", children: "all (AND)" }),
3751
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("option", { value: "or", children: "any (OR)" })
3802
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("select", { className: "uix-select uix-select--sm", value: group.combinator, disabled, onChange: (event) => updateNode(group.id, (node) => ({ ...node, combinator: event.currentTarget.value })), children: [
3803
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("option", { value: "and", children: "all (AND)" }),
3804
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("option", { value: "or", children: "any (OR)" })
3752
3805
  ] })
3753
3806
  ] })
3754
3807
  ] }),
3755
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "uix-rule-builder__rows", children: group.conditions.map((node, index) => isRuleGroup(node) ? /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-rule-builder__nested", children: [
3756
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(RuleGroupEditor, { ...{ group: node, depth: depth + 1, root, fields, operators, maxDepth, disabled, onRootChange, labels } }),
3757
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(RowControls, { label: "group", first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
3758
- ] }, node.id) : /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3808
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "uix-rule-builder__rows", children: group.conditions.map((node, index) => isRuleGroup(node) ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-rule-builder__nested", children: [
3809
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RuleGroupEditor, { ...{ group: node, depth: depth + 1, root, fields, operators, maxDepth, disabled, onRootChange, labels } }),
3810
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RowControls, { label: "group", first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
3811
+ ] }, node.id) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
3759
3812
  ConditionRow,
3760
3813
  {
3761
3814
  condition: node,
@@ -3763,13 +3816,13 @@ function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disa
3763
3816
  operators,
3764
3817
  disabled,
3765
3818
  onChange: (condition) => updateNode(node.id, () => condition),
3766
- controls: /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(RowControls, { label: "condition", first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
3819
+ controls: /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RowControls, { label: "condition", first: index === 0, last: index === group.conditions.length - 1, disabled, onUp: () => onRootChange(moveRuleNode(root, node.id, -1)), onDown: () => onRootChange(moveRuleNode(root, node.id, 1)), onRemove: () => onRootChange(removeRuleNode(root, node.id)) })
3767
3820
  },
3768
3821
  node.id
3769
3822
  )) }),
3770
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-rule-builder__add", children: [
3771
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: addCondition, disabled: disabled || fields.length === 0 || operators.length === 0, children: labels.addCondition }),
3772
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: addGroup, disabled: disabled || depth >= maxDepth, children: labels.addGroup })
3823
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-rule-builder__add", children: [
3824
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: addCondition, disabled: disabled || fields.length === 0 || operators.length === 0, children: labels.addCondition }),
3825
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: addGroup, disabled: disabled || depth >= maxDepth, children: labels.addGroup })
3773
3826
  ] })
3774
3827
  ] });
3775
3828
  }
@@ -3782,24 +3835,24 @@ function ConditionRow({ condition, fields, operators, disabled, onChange, contro
3782
3835
  const nextOperator = operators.find((item) => nextField?.operators?.includes(item.id)) ?? availableOperators[0] ?? operators[0];
3783
3836
  onChange({ ...condition, field: id, operator: nextOperator?.id ?? "" });
3784
3837
  };
3785
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-rule-builder__condition", children: [
3786
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { children: [
3787
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-visually-hidden", children: "Field" }),
3788
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("select", { className: "uix-select", value: condition.field, onChange: (event) => setField(event.currentTarget.value), disabled, children: fields.map((item) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("option", { value: item.id, children: item.label }, item.id)) })
3838
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-rule-builder__condition", children: [
3839
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { children: [
3840
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "uix-visually-hidden", children: "Field" }),
3841
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("select", { className: "uix-select", value: condition.field, onChange: (event) => setField(event.currentTarget.value), disabled, children: fields.map((item) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("option", { value: item.id, children: item.label }, item.id)) })
3789
3842
  ] }),
3790
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("label", { children: [
3791
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { className: "uix-visually-hidden", children: "Operator" }),
3792
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("select", { className: "uix-select", value: condition.operator, onChange: (event) => onChange({ ...condition, operator: event.currentTarget.value }), disabled, children: availableOperators.map((item) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("option", { value: item.id, children: item.label }, item.id)) })
3843
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("label", { children: [
3844
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { className: "uix-visually-hidden", children: "Operator" }),
3845
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("select", { className: "uix-select", value: condition.operator, onChange: (event) => onChange({ ...condition, operator: event.currentTarget.value }), disabled, children: availableOperators.map((item) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("option", { value: item.id, children: item.label }, item.id)) })
3793
3846
  ] }),
3794
- operator?.requiresValue !== false && /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "uix-rule-builder__value", children: field?.renderValueEditor?.({ condition, onChange: (value) => onChange({ ...condition, value }), disabled }) ?? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("input", { className: "uix-input", value: typeof condition.value === "string" || typeof condition.value === "number" ? condition.value : condition.value == null ? "" : JSON.stringify(condition.value), onChange: (event) => onChange({ ...condition, value: event.currentTarget.value }), disabled, "aria-label": `Value for ${field?.label ?? "condition"}` }) }),
3847
+ operator?.requiresValue !== false && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "uix-rule-builder__value", children: field?.renderValueEditor?.({ condition, onChange: (value) => onChange({ ...condition, value }), disabled }) ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("input", { className: "uix-input", value: typeof condition.value === "string" || typeof condition.value === "number" ? condition.value : condition.value == null ? "" : JSON.stringify(condition.value), onChange: (event) => onChange({ ...condition, value: event.currentTarget.value }), disabled, "aria-label": `Value for ${field?.label ?? "condition"}` }) }),
3795
3848
  controls
3796
3849
  ] });
3797
3850
  }
3798
3851
  function RowControls({ label, first, last, disabled, onUp, onDown, onRemove }) {
3799
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("span", { className: "uix-rule-builder__row-actions", children: [
3800
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onUp, disabled: disabled || first, "aria-label": `Move ${label} up`, children: "Up" }),
3801
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onDown, disabled: disabled || last, "aria-label": `Move ${label} down`, children: "Down" }),
3802
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onRemove, disabled, "aria-label": `Remove ${label}`, children: "Remove" })
3852
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "uix-rule-builder__row-actions", children: [
3853
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onUp, disabled: disabled || first, "aria-label": `Move ${label} up`, children: "Up" }),
3854
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onDown, disabled: disabled || last, "aria-label": `Move ${label} down`, children: "Down" }),
3855
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: onRemove, disabled, "aria-label": `Remove ${label}`, children: "Remove" })
3803
3856
  ] });
3804
3857
  }
3805
3858
  function RuleBuilder({
@@ -3820,9 +3873,9 @@ function RuleBuilder({
3820
3873
  const fieldLabels = Object.fromEntries(fields.map((field) => [field.id, field.label]));
3821
3874
  const operatorLabels = Object.fromEntries(operators.map((operator) => [operator.id, operator.label]));
3822
3875
  const actionLabels = Object.fromEntries(actions.map((action) => [action.id, action.label]));
3823
- if (readOnly) return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: cx("uix-rule-builder uix-rule-builder--summary", className), "aria-label": "Rule summary", children: [
3824
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("p", { children: summarizeRule(value, { fields: fieldLabels, operators: operatorLabels, actions: actionLabels }) }),
3825
- issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("p", { className: "uix-rule-builder__invalid", children: [
3876
+ if (readOnly) return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("section", { className: cx("uix-rule-builder uix-rule-builder--summary", className), "aria-label": "Rule summary", children: [
3877
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: summarizeRule(value, { fields: fieldLabels, operators: operatorLabels, actions: actionLabels }) }),
3878
+ issues.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("p", { className: "uix-rule-builder__invalid", children: [
3826
3879
  "Rule has ",
3827
3880
  issues.length,
3828
3881
  " validation issue",
@@ -3831,16 +3884,16 @@ function RuleBuilder({
3831
3884
  ] })
3832
3885
  ] });
3833
3886
  const updateActions = (next) => onChange({ ...value, then: next });
3834
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("section", { className: cx("uix-rule-builder", className), "aria-label": "Rule builder", children: [
3835
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(RuleGroupEditor, { group: value.when, depth: 1, root: value.when, fields, operators, maxDepth, disabled: readOnly, onRootChange: (when) => onChange({ ...value, when }), labels: { addCondition: addConditionLabel, addGroup: addGroupLabel } }),
3836
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("fieldset", { className: "uix-rule-builder__actions", children: [
3837
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("legend", { children: "Then" }),
3887
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("section", { className: cx("uix-rule-builder", className), "aria-label": "Rule builder", children: [
3888
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(RuleGroupEditor, { group: value.when, depth: 1, root: value.when, fields, operators, maxDepth, disabled: readOnly, onRootChange: (when) => onChange({ ...value, when }), labels: { addCondition: addConditionLabel, addGroup: addGroupLabel } }),
3889
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("fieldset", { className: "uix-rule-builder__actions", children: [
3890
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("legend", { children: "Then" }),
3838
3891
  value.then.map((action, index) => {
3839
3892
  const definition = actions.find((item) => item.id === action.type);
3840
- return /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("div", { className: "uix-rule-builder__action", children: [
3841
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("select", { className: "uix-select", value: action.type, onChange: (event) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: event.currentTarget.value } : item)), "aria-label": "Action type", children: actions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("option", { value: item.id, children: item.label }, item.id)) }),
3893
+ return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-rule-builder__action", children: [
3894
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("select", { className: "uix-select", value: action.type, onChange: (event) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: event.currentTarget.value } : item)), "aria-label": "Action type", children: actions.map((item) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("option", { value: item.id, children: item.label }, item.id)) }),
3842
3895
  definition?.renderParameters?.(action, (parameters) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, parameters } : item)), false),
3843
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)(
3896
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)(
3844
3897
  RowControls,
3845
3898
  {
3846
3899
  label: "action",
@@ -3862,22 +3915,22 @@ function RuleBuilder({
3862
3915
  )
3863
3916
  ] }, action.id);
3864
3917
  }),
3865
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: actions.length === 0, onClick: () => updateActions([...value.then, { id: nextId("action"), type: actions[0]?.id ?? "", parameters: {} }]), children: addActionLabel })
3918
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: actions.length === 0, onClick: () => updateActions([...value.then, { id: nextId("action"), type: actions[0]?.id ?? "", parameters: {} }]), children: addActionLabel })
3866
3919
  ] }),
3867
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("div", { className: "uix-rule-builder__validation", "aria-live": "polite", children: issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("span", { children: "Rule is valid." }) : /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)(import_jsx_runtime58.Fragment, { children: [
3868
- /* @__PURE__ */ (0, import_jsx_runtime58.jsxs)("strong", { children: [
3920
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "uix-rule-builder__validation", "aria-live": "polite", children: issues.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: "Rule is valid." }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
3921
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("strong", { children: [
3869
3922
  issues.length,
3870
3923
  " validation issue",
3871
3924
  issues.length === 1 ? "" : "s"
3872
3925
  ] }),
3873
- /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("ul", { children: issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime58.jsx)("li", { children: issue.message }, `${issue.path}-${index}`)) })
3926
+ /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ul", { children: issues.map((issue, index) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { children: issue.message }, `${issue.path}-${index}`)) })
3874
3927
  ] }) })
3875
3928
  ] });
3876
3929
  }
3877
3930
 
3878
3931
  // src/components/BuilderCanvas.tsx
3879
3932
  var import_react37 = require("react");
3880
- var import_jsx_runtime59 = require("react/jsx-runtime");
3933
+ var import_jsx_runtime60 = require("react/jsx-runtime");
3881
3934
  function BuilderCanvas({
3882
3935
  items,
3883
3936
  onItemsChange,
@@ -3932,27 +3985,27 @@ function BuilderCanvas({
3932
3985
  if (from >= 0 && to >= 0) onItemsChange(reorder(items, from, to));
3933
3986
  setDraggedId(void 0);
3934
3987
  };
3935
- return /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("section", { className: cx("uix-builder-canvas", className), "aria-label": "Builder canvas", children: [
3936
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("aside", { className: "uix-builder-canvas__palette", "aria-label": "Item palette", children: [
3937
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { children: "Palette" }),
3938
- palette.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "No item types available." }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ul", { children: palette.map((item) => /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("button", { type: "button", onClick: () => add(item), children: [
3939
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { children: item.label }),
3940
- item.description && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: item.description }),
3941
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { "aria-hidden": "true", children: "Add" })
3988
+ return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { className: cx("uix-builder-canvas", className), "aria-label": "Builder canvas", children: [
3989
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("aside", { className: "uix-builder-canvas__palette", "aria-label": "Item palette", children: [
3990
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { children: "Palette" }),
3991
+ palette.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: "No item types available." }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("ul", { children: palette.map((item) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", onClick: () => add(item), children: [
3992
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("strong", { children: item.label }),
3993
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: item.description }),
3994
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { "aria-hidden": "true", children: "Add" })
3942
3995
  ] }) }, item.id)) })
3943
3996
  ] }),
3944
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-builder-canvas__workspace", children: [
3945
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { children: "Canvas" }),
3946
- loading ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("div", { className: "uix-builder-canvas__state", role: "status", children: "Loading canvas\u2026" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-builder-canvas__state", role: "alert", children: [
3947
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: error }),
3948
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
3949
- ] }) : items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("div", { className: "uix-builder-canvas__state", children: [
3950
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: emptyMessage }),
3951
- palette[0] && /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: () => add(palette[0]), children: [
3997
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-builder-canvas__workspace", children: [
3998
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { children: "Canvas" }),
3999
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-builder-canvas__state", role: "status", children: "Loading canvas\u2026" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-builder-canvas__state", role: "alert", children: [
4000
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: error }),
4001
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
4002
+ ] }) : items.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-builder-canvas__state", children: [
4003
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: emptyMessage }),
4004
+ palette[0] && /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: () => add(palette[0]), children: [
3952
4005
  "Add ",
3953
4006
  palette[0].label
3954
4007
  ] })
3955
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("ol", { className: "uix-builder-canvas__items", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(
4008
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("ol", { className: "uix-builder-canvas__items", children: items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(
3956
4009
  "li",
3957
4010
  {
3958
4011
  draggable: true,
@@ -3962,27 +4015,27 @@ function BuilderCanvas({
3962
4015
  onDrop: (event) => drop(event, item.id),
3963
4016
  className: cx("uix-builder-canvas__item", selectedId === item.id && "uix-builder-canvas__item--selected"),
3964
4017
  children: [
3965
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", className: "uix-builder-canvas__item-main", "aria-pressed": selectedId === item.id, onClick: () => select(item.id), children: renderItem?.(item, selectedId === item.id) ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)(import_jsx_runtime59.Fragment, { children: [
3966
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("strong", { children: item.label }),
3967
- item.description && /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("span", { children: item.description })
4018
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-builder-canvas__item-main", "aria-pressed": selectedId === item.id, onClick: () => select(item.id), children: renderItem?.(item, selectedId === item.id) ?? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)(import_jsx_runtime60.Fragment, { children: [
4019
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("strong", { children: item.label }),
4020
+ item.description && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: item.description })
3968
4021
  ] }) }),
3969
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("span", { className: "uix-builder-canvas__item-actions", children: [
3970
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", onClick: () => move(item.id, -1), disabled: index === 0, "aria-label": `Move ${item.label} up`, children: "Up" }),
3971
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", onClick: () => move(item.id, 1), disabled: index === items.length - 1, "aria-label": `Move ${item.label} down`, children: "Down" }),
3972
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("button", { type: "button", onClick: () => remove(item.id), "aria-label": `Remove ${item.label}`, children: "Remove" })
4022
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { className: "uix-builder-canvas__item-actions", children: [
4023
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => move(item.id, -1), disabled: index === 0, "aria-label": `Move ${item.label} up`, children: "Up" }),
4024
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => move(item.id, 1), disabled: index === items.length - 1, "aria-label": `Move ${item.label} down`, children: "Down" }),
4025
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", onClick: () => remove(item.id), "aria-label": `Remove ${item.label}`, children: "Remove" })
3973
4026
  ] })
3974
4027
  ]
3975
4028
  },
3976
4029
  item.id
3977
4030
  )) })
3978
4031
  ] }),
3979
- /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("aside", { className: "uix-builder-canvas__properties", "aria-label": "Item properties", children: [
3980
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("h3", { ref: propertyHeadingRef, tabIndex: -1, children: "Properties" }),
3981
- !selected ? /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("p", { children: "Select a canvas item to edit its properties." }) : renderProperties?.(selected, (updated) => onItemsChange(items.map((item) => item.id === updated.id ? updated : item))) ?? /* @__PURE__ */ (0, import_jsx_runtime59.jsxs)("dl", { children: [
3982
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("dt", { children: "Type" }),
3983
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("dd", { children: selected.type }),
3984
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("dt", { children: "Label" }),
3985
- /* @__PURE__ */ (0, import_jsx_runtime59.jsx)("dd", { children: selected.label })
4032
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("aside", { className: "uix-builder-canvas__properties", "aria-label": "Item properties", children: [
4033
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("h3", { ref: propertyHeadingRef, tabIndex: -1, children: "Properties" }),
4034
+ !selected ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: "Select a canvas item to edit its properties." }) : renderProperties?.(selected, (updated) => onItemsChange(items.map((item) => item.id === updated.id ? updated : item))) ?? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("dl", { children: [
4035
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("dt", { children: "Type" }),
4036
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("dd", { children: selected.type }),
4037
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("dt", { children: "Label" }),
4038
+ /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("dd", { children: selected.label })
3986
4039
  ] })
3987
4040
  ] })
3988
4041
  ] });
@@ -4070,7 +4123,7 @@ function isDateUnavailable(date, options) {
4070
4123
  }
4071
4124
 
4072
4125
  // src/components/SchedulingCalendar.tsx
4073
- var import_jsx_runtime60 = require("react/jsx-runtime");
4126
+ var import_jsx_runtime61 = require("react/jsx-runtime");
4074
4127
  var stateLabel = { scheduled: "Scheduled", conflicted: "Conflicted", "in-progress": "In progress", "blackout-violation": "Blackout violation" };
4075
4128
  var stateTone = (state) => state === "scheduled" ? "info" : state === "in-progress" ? "success" : "danger";
4076
4129
  var dateLabel = (date, locale) => new Intl.DateTimeFormat(locale, { dateStyle: "full", timeZone: "UTC" }).format(/* @__PURE__ */ new Date(`${date}T00:00:00Z`));
@@ -4138,58 +4191,58 @@ function SchedulingCalendar({
4138
4191
  return date >= span.start && date <= span.end;
4139
4192
  });
4140
4193
  const formatInstant = (instant) => new Intl.DateTimeFormat(locale, { timeZone, dateStyle: "medium", timeStyle: "short" }).format(new Date(instant));
4141
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("section", { className: cx("uix-scheduling-calendar", className), "aria-label": `Scheduling calendar in ${timeZone}`, children: [
4142
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-scheduling-calendar__header", children: [
4143
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { children: [
4144
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(-1), disabled: !onAnchorDateChange, children: "Previous" }),
4145
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(1), disabled: !onAnchorDateChange, children: "Next" })
4194
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { className: cx("uix-scheduling-calendar", className), "aria-label": `Scheduling calendar in ${timeZone}`, children: [
4195
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-scheduling-calendar__header", children: [
4196
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
4197
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(-1), disabled: !onAnchorDateChange, children: "Previous" }),
4198
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => movePeriod(1), disabled: !onAnchorDateChange, children: "Next" })
4146
4199
  ] }),
4147
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("strong", { children: view === "month" ? new Intl.DateTimeFormat(locale, { month: "long", year: "numeric", timeZone: "UTC" }).format(/* @__PURE__ */ new Date(`${anchorDate}T00:00:00Z`)) : `${dateLabel(weekStart, locale)} \u2013 ${dateLabel(weekDays[weekDays.length - 1], locale)}` }),
4148
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-segmented", role: "group", "aria-label": "Calendar view", children: ["month", "week", "agenda"].map((option) => /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", className: "uix-segmented__option", "aria-pressed": view === option, "data-selected": view === option || void 0, onClick: () => setView(option), children: [
4200
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("strong", { children: view === "month" ? new Intl.DateTimeFormat(locale, { month: "long", year: "numeric", timeZone: "UTC" }).format(/* @__PURE__ */ new Date(`${anchorDate}T00:00:00Z`)) : `${dateLabel(weekStart, locale)} \u2013 ${dateLabel(weekDays[weekDays.length - 1], locale)}` }),
4201
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-segmented", role: "group", "aria-label": "Calendar view", children: ["month", "week", "agenda"].map((option) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", className: "uix-segmented__option", "aria-pressed": view === option, "data-selected": view === option || void 0, onClick: () => setView(option), children: [
4149
4202
  option[0].toUpperCase(),
4150
4203
  option.slice(1)
4151
4204
  ] }, option)) })
4152
4205
  ] }),
4153
- loading ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-scheduling-calendar__state", role: "status", children: "Loading schedule\u2026" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-scheduling-calendar__state", role: "alert", children: [
4154
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: error }),
4155
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
4156
- ] }) : view === "agenda" ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": "Schedule agenda", children: visibleEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("p", { children: "No scheduled entries match the current filters." }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("ol", { children: [...visibleEntries].sort((a, b) => a.start.localeCompare(b.start)).map((entry) => {
4206
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-scheduling-calendar__state", role: "status", children: "Loading schedule\u2026" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-scheduling-calendar__state", role: "alert", children: [
4207
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: error }),
4208
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
4209
+ ] }) : view === "agenda" ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-scheduling-calendar__agenda", role: "region", "aria-label": "Schedule agenda", children: visibleEntries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { children: "No scheduled entries match the current filters." }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("ol", { children: [...visibleEntries].sort((a, b) => a.start.localeCompare(b.start)).map((entry) => {
4157
4210
  const state = entry.state ?? "scheduled";
4158
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", onClick: () => onSelectEntry?.(entry), children: [
4159
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { children: [
4160
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("strong", { children: renderEntry?.(entry) ?? entry.title }),
4161
- /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("span", { children: [
4211
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("li", { children: /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", onClick: () => onSelectEntry?.(entry), children: [
4212
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { children: [
4213
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("strong", { children: renderEntry?.(entry) ?? entry.title }),
4214
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("span", { children: [
4162
4215
  formatInstant(entry.start),
4163
4216
  " \u2013 ",
4164
4217
  formatInstant(entry.end)
4165
4218
  ] }),
4166
- entry.meta && /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: entry.meta })
4219
+ entry.meta && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { children: entry.meta })
4167
4220
  ] }),
4168
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)(StatusPill, { tone: stateTone(state), children: stateLabel[state] })
4221
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(StatusPill, { tone: stateTone(state), children: stateLabel[state] })
4169
4222
  ] }) }, entry.id);
4170
- }) }) }) : /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { ref: gridRef, className: cx("uix-scheduling-calendar__grid", view === "week" && "uix-scheduling-calendar__grid--week"), role: "group", "aria-label": `${view} schedule`, children: days.map((date, index) => {
4223
+ }) }) }) : /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { ref: gridRef, className: cx("uix-scheduling-calendar__grid", view === "week" && "uix-scheduling-calendar__grid--week"), role: "group", "aria-label": `${view} schedule`, children: days.map((date, index) => {
4171
4224
  const dayEntries = entriesFor(date);
4172
4225
  const dayOverlays = overlaysFor(date);
4173
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("div", { className: "uix-scheduling-calendar__day", "data-outside": view === "month" && !monthDays[index].inMonth || void 0, children: [
4174
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, tabIndex: activeDate === date ? 0 : -1, onFocus: () => setActiveDate(date), onKeyDown: (event) => onDayKeyDown(event, date), "aria-label": dateLabel(date, locale), children: Number(date.slice(-2)) }),
4175
- dayOverlays.map((overlay) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "uix-scheduling-calendar__overlay", "data-kind": overlay.kind, children: overlay.label }, overlay.id)),
4176
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-scheduling-calendar__entries", children: dayEntries.map((entry) => {
4226
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-scheduling-calendar__day", "data-outside": view === "month" && !monthDays[index].inMonth || void 0, children: [
4227
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-scheduling-calendar__date", "data-calendar-date": date, tabIndex: activeDate === date ? 0 : -1, onFocus: () => setActiveDate(date), onKeyDown: (event) => onDayKeyDown(event, date), "aria-label": dateLabel(date, locale), children: Number(date.slice(-2)) }),
4228
+ dayOverlays.map((overlay) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "uix-scheduling-calendar__overlay", "data-kind": overlay.kind, children: overlay.label }, overlay.id)),
4229
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-scheduling-calendar__entries", children: dayEntries.map((entry) => {
4177
4230
  const span = entrySpans.get(entry.id);
4178
4231
  const state = entry.state ?? "scheduled";
4179
- return /* @__PURE__ */ (0, import_jsx_runtime60.jsxs)("button", { type: "button", className: "uix-scheduling-calendar__entry", "data-state": state, "data-range-start": date === span.start || void 0, "data-range-end": date === span.end || void 0, onClick: () => onSelectEntry?.(entry), "aria-label": `${entry.title}, ${stateLabel[state]}, ${formatInstant(entry.start)} to ${formatInstant(entry.end)}`, children: [
4180
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { children: renderEntry?.(entry) ?? entry.title }),
4181
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { className: "uix-visually-hidden", children: stateLabel[state] })
4232
+ return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("button", { type: "button", className: "uix-scheduling-calendar__entry", "data-state": state, "data-range-start": date === span.start || void 0, "data-range-end": date === span.end || void 0, onClick: () => onSelectEntry?.(entry), "aria-label": `${entry.title}, ${stateLabel[state]}, ${formatInstant(entry.start)} to ${formatInstant(entry.end)}`, children: [
4233
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { children: renderEntry?.(entry) ?? entry.title }),
4234
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { className: "uix-visually-hidden", children: stateLabel[state] })
4182
4235
  ] }, entry.id);
4183
4236
  }) })
4184
4237
  ] }, date);
4185
4238
  }) }),
4186
- /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("div", { className: "uix-scheduling-calendar__legend", "aria-label": "Schedule state legend", children: ["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime60.jsx)("span", { "data-state": state, children: stateLabel[state] }, state)) })
4239
+ /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-scheduling-calendar__legend", "aria-label": "Schedule state legend", children: ["scheduled", "conflicted", "in-progress", "blackout-violation"].map((state) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { "data-state": state, children: stateLabel[state] }, state)) })
4187
4240
  ] });
4188
4241
  }
4189
4242
 
4190
4243
  // src/components/DateRangePicker.tsx
4191
4244
  var import_react39 = require("react");
4192
- var import_jsx_runtime61 = require("react/jsx-runtime");
4245
+ var import_jsx_runtime62 = require("react/jsx-runtime");
4193
4246
  var monthLabel = (date, locale) => new Intl.DateTimeFormat(locale, { month: "long", year: "numeric", timeZone: "UTC" }).format(/* @__PURE__ */ new Date(`${date}T00:00:00Z`));
4194
4247
  var dateLabel2 = (date, locale) => new Intl.DateTimeFormat(locale, { dateStyle: "full", timeZone: "UTC" }).format(/* @__PURE__ */ new Date(`${date}T00:00:00Z`));
4195
4248
  function DateRangePicker({
@@ -4264,23 +4317,23 @@ function DateRangePicker({
4264
4317
  }
4265
4318
  };
4266
4319
  const announcement = !value.start ? "No date range selected." : !value.end ? `Start date ${dateLabel2(value.start, locale)} selected. Choose an end date.` : `${dateLabel2(value.start, locale)} to ${dateLabel2(value.end, locale)} selected.`;
4267
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
4268
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-date-range-picker__header", children: [
4269
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h3", { id: `${id}-label`, children: label }),
4270
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { children: [
4271
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, -1)), "aria-label": "Show previous month", children: "Previous" }),
4272
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, 1)), "aria-label": "Show next month", children: "Next" })
4320
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("section", { className: cx("uix-date-range-picker", rangeInvalid && "uix-date-range-picker--invalid", className), "aria-labelledby": `${id}-label`, children: [
4321
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uix-date-range-picker__header", children: [
4322
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("h3", { id: `${id}-label`, children: label }),
4323
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { children: [
4324
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, -1)), "aria-label": "Show previous month", children: "Previous" }),
4325
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", onClick: () => setMonth(addCalendarMonths(visibleMonth, 1)), "aria-label": "Show next month", children: "Next" })
4273
4326
  ] })
4274
4327
  ] }),
4275
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-date-range-picker__month", children: [
4276
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("h4", { children: monthLabel(month, locale) }),
4277
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { children: day }, day)) }),
4278
- /* @__PURE__ */ (0, import_jsx_runtime61.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
4279
- Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
4328
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { ref: rootRef, className: "uix-date-range-picker__months", children: calendars.map(({ month, days }) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uix-date-range-picker__month", children: [
4329
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("h4", { children: monthLabel(month, locale) }),
4330
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uix-date-range-picker__weekdays", "aria-hidden": "true", children: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"].map((day) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: day }, day)) }),
4331
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uix-date-range-picker__grid", role: "group", "aria-label": monthLabel(month, locale), children: [
4332
+ Array.from({ length: ((/* @__PURE__ */ new Date(`${month}T00:00:00Z`)).getUTCDay() + 6) % 7 }, (_, index) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { "aria-hidden": "true" }, `blank-${index}`)),
4280
4333
  days.map((day) => {
4281
4334
  const unavailable = disabled || isDateUnavailable(day.date, { min, max, isDisabled: isDateDisabled });
4282
4335
  const edge = day.date === value.start ? "start" : day.date === value.end ? "end" : void 0;
4283
- return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(
4336
+ return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)(
4284
4337
  "button",
4285
4338
  {
4286
4339
  type: "button",
@@ -4301,13 +4354,13 @@ function DateRangePicker({
4301
4354
  })
4302
4355
  ] })
4303
4356
  ] }, month)) }),
4304
- /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
4305
- rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime61.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
4357
+ /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "uix-date-range-picker__selection", "aria-live": "polite", children: announcement }),
4358
+ rangeInvalid && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { className: "uix-field__error", role: "alert", children: invalidMessage })
4306
4359
  ] });
4307
4360
  }
4308
4361
 
4309
4362
  // src/components/RelationshipGraph.tsx
4310
- var import_react40 = require("react");
4363
+ var import_react41 = require("react");
4311
4364
 
4312
4365
  // src/relationship-graph-model.ts
4313
4366
  function boundRelationshipGraph(nodes, edges, maxNodes = 40) {
@@ -4372,37 +4425,973 @@ function traverseRelationshipNode(nodes, currentId, direction) {
4372
4425
  const current = Math.max(0, nodes.findIndex((node) => node.id === currentId));
4373
4426
  return nodes[(current + direction + nodes.length) % nodes.length]?.id;
4374
4427
  }
4428
+ var LAYERED_GEOMETRY = {
4429
+ standard: { nodeWidth: 176, nodeHeight: 76, columnGap: 96, rowGap: 12 },
4430
+ compact: { nodeWidth: 160, nodeHeight: 60, columnGap: 80, rowGap: 8 }
4431
+ };
4432
+ var LAYERED_PADDING = 16;
4433
+ var LAYERED_HEADER = 28;
4434
+ var GROUP_HEADER = 28;
4435
+ var AUTO_LABEL_MAX_FANOUT = 4;
4436
+ var LABEL_CHAR_WIDTH = 5.6;
4437
+ var LABEL_MAX_LINES = 2;
4438
+ function wrapEdgeLabel(label, width) {
4439
+ const max = Math.max(4, Math.floor(width / LABEL_CHAR_WIDTH));
4440
+ const clip = (word) => word.length > max ? `${word.slice(0, max - 1)}\u2026` : word;
4441
+ const lines = [];
4442
+ let current = "";
4443
+ for (const word of label.split(/\s+/).filter(Boolean)) {
4444
+ const next = current ? `${current} ${word}` : word;
4445
+ if (next.length <= max) {
4446
+ current = next;
4447
+ continue;
4448
+ }
4449
+ if (current) lines.push(current);
4450
+ current = clip(word);
4451
+ if (lines.length === LABEL_MAX_LINES) break;
4452
+ }
4453
+ if (current && lines.length < LABEL_MAX_LINES) lines.push(current);
4454
+ if (lines.length === LABEL_MAX_LINES) {
4455
+ const consumed = lines.join(" ").replace(/…$/, "").length;
4456
+ if (consumed < label.replace(/\s+/g, " ").trim().length) {
4457
+ const last = lines[LABEL_MAX_LINES - 1];
4458
+ lines[LABEL_MAX_LINES - 1] = last.endsWith("\u2026") ? last : `${last.slice(0, Math.max(1, max - 1))}\u2026`;
4459
+ }
4460
+ }
4461
+ return lines;
4462
+ }
4463
+ var drawableEdge = (edge, ids) => ids.has(edge.source) && ids.has(edge.target) && edge.source !== edge.target;
4464
+ function classifyLayeredEdges(nodes, edges, rootId = nodes[0]?.id) {
4465
+ const ids = new Set(nodes.map((node) => node.id));
4466
+ const root = rootId !== void 0 && ids.has(rootId) ? rootId : nodes[0]?.id;
4467
+ const outgoing = /* @__PURE__ */ new Map();
4468
+ for (const edge of edges) {
4469
+ if (!drawableEdge(edge, ids)) continue;
4470
+ const list = outgoing.get(edge.source);
4471
+ if (list) list.push(edge.target);
4472
+ else outgoing.set(edge.source, [edge.target]);
4473
+ }
4474
+ const bfs = /* @__PURE__ */ new Map();
4475
+ if (root !== void 0) {
4476
+ bfs.set(root, 0);
4477
+ const queue = [root];
4478
+ for (let head = 0; head < queue.length; head += 1) {
4479
+ const current = queue[head];
4480
+ for (const next of outgoing.get(current) ?? []) {
4481
+ if (!bfs.has(next)) {
4482
+ bfs.set(next, bfs.get(current) + 1);
4483
+ queue.push(next);
4484
+ }
4485
+ }
4486
+ }
4487
+ }
4488
+ const depthById = /* @__PURE__ */ new Map();
4489
+ let deepest = 0;
4490
+ for (const node of nodes) {
4491
+ const supplied = node.depth !== void 0 && Number.isFinite(node.depth) ? Math.max(0, Math.floor(node.depth)) : void 0;
4492
+ const depth = supplied ?? bfs.get(node.id);
4493
+ if (depth === void 0) continue;
4494
+ depthById.set(node.id, depth);
4495
+ deepest = Math.max(deepest, depth);
4496
+ }
4497
+ for (const node of nodes) if (!depthById.has(node.id)) depthById.set(node.id, deepest + 1);
4498
+ const forwardOut = /* @__PURE__ */ new Map();
4499
+ const kindById = /* @__PURE__ */ new Map();
4500
+ const backEdges = [];
4501
+ for (const edge of edges) {
4502
+ if (!drawableEdge(edge, ids)) continue;
4503
+ const from = depthById.get(edge.source);
4504
+ const to = depthById.get(edge.target);
4505
+ if (to === from + 1) {
4506
+ kindById.set(edge.id, "forward");
4507
+ const list = forwardOut.get(edge.source);
4508
+ if (list) list.push(edge.target);
4509
+ else forwardOut.set(edge.source, [edge.target]);
4510
+ } else if (to < from) {
4511
+ backEdges.push(edge);
4512
+ } else {
4513
+ kindById.set(edge.id, "lateral");
4514
+ }
4515
+ }
4516
+ for (const edge of backEdges) {
4517
+ const limit = depthById.get(edge.source);
4518
+ const seen = /* @__PURE__ */ new Set([edge.target]);
4519
+ const stack = [edge.target];
4520
+ let closes = false;
4521
+ while (stack.length > 0 && !closes) {
4522
+ const current = stack.pop();
4523
+ for (const next of forwardOut.get(current) ?? []) {
4524
+ if (next === edge.source) {
4525
+ closes = true;
4526
+ break;
4527
+ }
4528
+ if (!seen.has(next) && depthById.get(next) < limit) {
4529
+ seen.add(next);
4530
+ stack.push(next);
4531
+ }
4532
+ }
4533
+ }
4534
+ kindById.set(edge.id, closes ? "cycle" : "lateral");
4535
+ }
4536
+ return { depthById, kindById };
4537
+ }
4538
+ function clusterIdFor(parentId, type, edgeType) {
4539
+ return `cluster:${parentId}:${type ?? ""}:${edgeType ?? ""}`;
4540
+ }
4541
+ var mean = (values) => values.reduce((sum, value) => sum + value, 0) / values.length;
4542
+ var round1 = (value) => Math.round(value * 10) / 10;
4543
+ function layoutLayeredGraph(nodes, edges, options = {}) {
4544
+ const { nodeWidth, nodeHeight, columnGap, rowGap } = LAYERED_GEOMETRY[options.density ?? "standard"];
4545
+ const threshold = options.clusterThreshold ?? 6;
4546
+ const expanded = options.expandedClusterIds ?? /* @__PURE__ */ new Set();
4547
+ const rootId = options.rootId !== void 0 && nodes.some((node) => node.id === options.rootId) ? options.rootId : nodes[0]?.id;
4548
+ if (nodes.length === 0) {
4549
+ return {
4550
+ rootId,
4551
+ items: [],
4552
+ edges: [],
4553
+ clusters: [],
4554
+ columns: [],
4555
+ itemOf: {},
4556
+ width: 0,
4557
+ height: 0,
4558
+ nodeWidth,
4559
+ nodeHeight,
4560
+ headerHeight: LAYERED_HEADER
4561
+ };
4562
+ }
4563
+ const { depthById, kindById } = classifyLayeredEdges(nodes, edges, rootId);
4564
+ const drawable = edges.filter((edge) => kindById.has(edge.id));
4565
+ const forwardParents = /* @__PURE__ */ new Map();
4566
+ const forwardChildCount = /* @__PURE__ */ new Map();
4567
+ const inCycle = /* @__PURE__ */ new Set();
4568
+ const nodeDegree = /* @__PURE__ */ new Map();
4569
+ for (const edge of drawable) {
4570
+ nodeDegree.set(edge.source, (nodeDegree.get(edge.source) ?? 0) + 1);
4571
+ nodeDegree.set(edge.target, (nodeDegree.get(edge.target) ?? 0) + 1);
4572
+ if (kindById.get(edge.id) === "forward") {
4573
+ const list = forwardParents.get(edge.target);
4574
+ if (list) list.push(edge);
4575
+ else forwardParents.set(edge.target, [edge]);
4576
+ forwardChildCount.set(edge.source, (forwardChildCount.get(edge.source) ?? 0) + 1);
4577
+ } else {
4578
+ inCycle.add(edge.source);
4579
+ inCycle.add(edge.target);
4580
+ }
4581
+ }
4582
+ const groups = /* @__PURE__ */ new Map();
4583
+ if (threshold > 0) {
4584
+ for (const node of nodes) {
4585
+ if (node.id === rootId || inCycle.has(node.id) || (forwardChildCount.get(node.id) ?? 0) > 0) continue;
4586
+ const parents = forwardParents.get(node.id) ?? [];
4587
+ if (parents.length !== 1) continue;
4588
+ const via = parents[0];
4589
+ const id = clusterIdFor(via.source, node.type, via.type);
4590
+ const group = groups.get(id);
4591
+ if (group) {
4592
+ group.members.push(node);
4593
+ continue;
4594
+ }
4595
+ const created = { id, parentId: via.source, depth: depthById.get(node.id), members: [node] };
4596
+ if (node.type !== void 0) created.type = node.type;
4597
+ if (via.type !== void 0) created.edgeType = via.type;
4598
+ const edgeLabel = via.label ?? via.type;
4599
+ if (edgeLabel !== void 0) created.edgeLabel = edgeLabel;
4600
+ groups.set(id, created);
4601
+ }
4602
+ }
4603
+ const clusterById = /* @__PURE__ */ new Map();
4604
+ const itemOf = {};
4605
+ const expandedGroupOf = /* @__PURE__ */ new Map();
4606
+ for (const group of groups.values()) {
4607
+ if (group.members.length < threshold) continue;
4608
+ if (expanded.has(group.id)) {
4609
+ for (const member of group.members) expandedGroupOf.set(member.id, group);
4610
+ continue;
4611
+ }
4612
+ clusterById.set(group.id, group);
4613
+ for (const member of group.members) itemOf[member.id] = group.id;
4614
+ }
4615
+ for (const node of nodes) if (itemOf[node.id] === void 0) itemOf[node.id] = node.id;
4616
+ const columnsByDepth = /* @__PURE__ */ new Map();
4617
+ const itemById = /* @__PURE__ */ new Map();
4618
+ for (const node of nodes) {
4619
+ const id = itemOf[node.id];
4620
+ if (itemById.has(id)) continue;
4621
+ const cluster = clusterById.get(id);
4622
+ const depth = depthById.get(node.id);
4623
+ const item = {
4624
+ id,
4625
+ kind: cluster ? "cluster" : "node",
4626
+ depth,
4627
+ index: 0,
4628
+ x: 0,
4629
+ y: 0,
4630
+ width: nodeWidth,
4631
+ height: nodeHeight,
4632
+ parents: [],
4633
+ children: [],
4634
+ inCycle: cluster ? false : inCycle.has(node.id),
4635
+ degree: cluster ? cluster.members.length : nodeDegree.get(node.id) ?? 0
4636
+ };
4637
+ if (cluster) item.cluster = cluster;
4638
+ else item.node = node;
4639
+ itemById.set(id, item);
4640
+ const column = columnsByDepth.get(depth);
4641
+ if (column) column.push(item);
4642
+ else columnsByDepth.set(depth, [item]);
4643
+ }
4644
+ for (const edge of drawable) {
4645
+ if (kindById.get(edge.id) !== "forward") continue;
4646
+ const from = itemById.get(itemOf[edge.source]);
4647
+ const to = itemById.get(itemOf[edge.target]);
4648
+ if (!from.children.includes(to.id)) from.children.push(to.id);
4649
+ if (!to.parents.includes(from.id)) to.parents.push(from.id);
4650
+ }
4651
+ const depths = [...columnsByDepth.keys()].sort((a, b) => a - b);
4652
+ const position = /* @__PURE__ */ new Map();
4653
+ const reindex = (column) => {
4654
+ column.forEach((item, index) => {
4655
+ item.index = index;
4656
+ position.set(item.id, index);
4657
+ });
4658
+ };
4659
+ for (const depth of depths) reindex(columnsByDepth.get(depth));
4660
+ const groupOfItem = (item) => item.node ? expandedGroupOf.get(item.node.id) : void 0;
4661
+ const sweep = (depth, neighbours) => {
4662
+ const keyed = columnsByDepth.get(depth).map((item) => {
4663
+ const around = neighbours(item).map((id) => position.get(id)).filter((value) => value !== void 0);
4664
+ return { item, key: around.length > 0 ? mean(around) : item.index, tie: item.index };
4665
+ });
4666
+ keyed.sort((a, b) => a.key - b.key || a.tie - b.tie);
4667
+ const ordered = [];
4668
+ const placed = /* @__PURE__ */ new Set();
4669
+ for (const { item } of keyed) {
4670
+ if (placed.has(item.id)) continue;
4671
+ const group = groupOfItem(item);
4672
+ for (const candidate of group ? keyed.map((entry) => entry.item).filter((other) => groupOfItem(other) === group) : [item]) {
4673
+ if (placed.has(candidate.id)) continue;
4674
+ ordered.push(candidate);
4675
+ placed.add(candidate.id);
4676
+ }
4677
+ }
4678
+ columnsByDepth.set(depth, ordered);
4679
+ reindex(ordered);
4680
+ };
4681
+ const inner = depths.slice(1);
4682
+ for (const depth of inner) sweep(depth, (item) => item.parents);
4683
+ for (const depth of [...inner].reverse()) sweep(depth, (item) => item.children);
4684
+ for (const depth of inner) sweep(depth, (item) => item.parents);
4685
+ const top = LAYERED_PADDING + LAYERED_HEADER;
4686
+ const columns = [];
4687
+ let width = 0;
4688
+ let height = 0;
4689
+ for (const depth of depths) {
4690
+ const column = columnsByDepth.get(depth);
4691
+ const x = LAYERED_PADDING + depth * (nodeWidth + columnGap);
4692
+ let cursor = top;
4693
+ let count = 0;
4694
+ const ledGroups = /* @__PURE__ */ new Set();
4695
+ for (const item of column) {
4696
+ const parentCentres = item.parents.map((id) => itemById.get(id)).filter((parent) => parent.depth < depth).map((parent) => parent.y + parent.height / 2);
4697
+ const group = groupOfItem(item);
4698
+ const leadsGroup = group !== void 0 && !ledGroups.has(group);
4699
+ if (group) ledGroups.add(group);
4700
+ const floor = cursor + (leadsGroup ? GROUP_HEADER : 0);
4701
+ const target = parentCentres.length > 0 ? mean(parentCentres) - item.height / 2 : floor;
4702
+ item.x = x;
4703
+ item.y = round1(Math.max(target, floor));
4704
+ if (leadsGroup) item.expandedGroup = group;
4705
+ cursor = item.y + item.height + rowGap;
4706
+ count += item.cluster ? item.cluster.members.length : 1;
4707
+ width = Math.max(width, x + item.width);
4708
+ height = Math.max(height, item.y + item.height);
4709
+ }
4710
+ columns.push({ depth, x, count });
4711
+ }
4712
+ const byPosition = (a, b) => (position.get(a) ?? 0) - (position.get(b) ?? 0);
4713
+ for (const item of itemById.values()) {
4714
+ item.children.sort(byPosition);
4715
+ item.parents.sort(byPosition);
4716
+ }
4717
+ const routed = /* @__PURE__ */ new Map();
4718
+ for (const edge of drawable) {
4719
+ const kind = kindById.get(edge.id);
4720
+ const from = itemById.get(itemOf[edge.source]);
4721
+ const to = itemById.get(itemOf[edge.target]);
4722
+ const key = from.kind === "cluster" || to.kind === "cluster" ? `${from.id}->${to.id}` : edge.id;
4723
+ const existing = routed.get(key);
4724
+ if (existing) {
4725
+ existing.edgeIds.push(edge.id);
4726
+ continue;
4727
+ }
4728
+ let startX;
4729
+ let startY;
4730
+ let endX;
4731
+ let endY;
4732
+ let path;
4733
+ let labelX;
4734
+ let labelY;
4735
+ let startAngle;
4736
+ let endAngle;
4737
+ if (kind === "forward") {
4738
+ startX = from.x + from.width;
4739
+ startY = from.y + from.height / 2;
4740
+ endX = to.x;
4741
+ endY = to.y + to.height / 2;
4742
+ const bend = Math.max(columnGap / 2, 24);
4743
+ path = `M${round1(startX)} ${round1(startY)} C${round1(startX + bend)} ${round1(startY)} ${round1(endX - bend)} ${round1(endY)} ${round1(endX)} ${round1(endY)}`;
4744
+ labelX = (startX + endX) / 2;
4745
+ labelY = (startY + endY) / 2;
4746
+ startAngle = Math.PI;
4747
+ endAngle = 0;
4748
+ } else if (from.depth === to.depth) {
4749
+ startX = from.x + from.width;
4750
+ startY = from.y + from.height / 2;
4751
+ endX = to.x + to.width;
4752
+ endY = to.y + to.height / 2;
4753
+ const bulge = Math.min(columnGap - 8, 20 + Math.abs(endY - startY) * 0.1);
4754
+ path = `M${round1(startX)} ${round1(startY)} C${round1(startX + bulge)} ${round1(startY)} ${round1(endX + bulge)} ${round1(endY)} ${round1(endX)} ${round1(endY)}`;
4755
+ labelX = startX + bulge * 0.75;
4756
+ labelY = (startY + endY) / 2;
4757
+ startAngle = Math.PI;
4758
+ endAngle = Math.PI;
4759
+ } else {
4760
+ startX = from.x + from.width / 2;
4761
+ startY = from.y + from.height;
4762
+ endX = to.x + to.width / 2;
4763
+ endY = to.y + to.height;
4764
+ const dip = 28 + Math.abs(endX - startX) * 0.12;
4765
+ const low = Math.max(startY, endY) + dip;
4766
+ path = `M${round1(startX)} ${round1(startY)} C${round1(startX)} ${round1(low)} ${round1(endX)} ${round1(low)} ${round1(endX)} ${round1(endY)}`;
4767
+ labelX = (startX + endX) / 2;
4768
+ labelY = low - dip * 0.25;
4769
+ startAngle = -Math.PI / 2;
4770
+ endAngle = -Math.PI / 2;
4771
+ height = Math.max(height, low);
4772
+ }
4773
+ const arrow = edge.arrow ?? "forward";
4774
+ const atStart = arrow === "backward";
4775
+ const entry = {
4776
+ id: key,
4777
+ source: from.id,
4778
+ target: to.id,
4779
+ kind,
4780
+ edgeIds: [edge.id],
4781
+ arrow,
4782
+ emphasis: edge.emphasis === true,
4783
+ path,
4784
+ labelX: round1(labelX),
4785
+ labelY: round1(labelY),
4786
+ arrowX: round1(atStart ? startX : endX),
4787
+ arrowY: round1(atStart ? startY : endY),
4788
+ arrowAngle: atStart ? startAngle : endAngle,
4789
+ labelLines: [],
4790
+ autoLabel: to.kind !== "cluster" && (edge.emphasis === true || kind === "forward" && from.children.length <= AUTO_LABEL_MAX_FANOUT)
4791
+ };
4792
+ if (edge.type !== void 0) entry.type = edge.type;
4793
+ const label = edge.label ?? edge.type;
4794
+ if (label !== void 0) entry.label = label;
4795
+ routed.set(key, entry);
4796
+ }
4797
+ const seenLabels = /* @__PURE__ */ new Set();
4798
+ for (const entry of routed.values()) {
4799
+ if (entry.label === void 0) continue;
4800
+ entry.labelLines = wrapEdgeLabel(entry.label, columnGap - 8);
4801
+ if (!entry.autoLabel || entry.emphasis || entry.kind !== "forward") continue;
4802
+ const key = `${entry.source}|${entry.label}`;
4803
+ if (seenLabels.has(key)) entry.autoLabel = false;
4804
+ else seenLabels.add(key);
4805
+ }
4806
+ return {
4807
+ rootId,
4808
+ items: depths.flatMap((depth) => columnsByDepth.get(depth)),
4809
+ edges: [...routed.values()],
4810
+ clusters: [...clusterById.values()],
4811
+ columns,
4812
+ itemOf,
4813
+ width: round1(width + LAYERED_PADDING),
4814
+ height: round1(height + LAYERED_PADDING + 8),
4815
+ nodeWidth,
4816
+ nodeHeight,
4817
+ headerHeight: LAYERED_HEADER
4818
+ };
4819
+ }
4820
+ function layeredNeighbor(layout, currentId, key) {
4821
+ const root = layout.rootId !== void 0 ? layout.itemOf[layout.rootId] : layout.items[0]?.id;
4822
+ const current = layout.items.find((item) => item.id === currentId);
4823
+ if (!current) return root ?? layout.items[0]?.id;
4824
+ const column = layout.items.filter((item) => item.depth === current.depth);
4825
+ switch (key) {
4826
+ case "ArrowUp":
4827
+ return column[current.index - 1]?.id;
4828
+ case "ArrowDown":
4829
+ return column[current.index + 1]?.id;
4830
+ case "ArrowRight":
4831
+ return current.children[0];
4832
+ case "ArrowLeft":
4833
+ return current.parents[0];
4834
+ case "Home":
4835
+ return root;
4836
+ case "End":
4837
+ return column[column.length - 1]?.id;
4838
+ default:
4839
+ return void 0;
4840
+ }
4841
+ }
4375
4842
 
4376
- // src/components/RelationshipGraph.tsx
4377
- var import_jsx_runtime62 = require("react/jsx-runtime");
4843
+ // src/components/RelationshipGraphLayered.tsx
4844
+ var import_react40 = require("react");
4845
+
4846
+ // src/components/RelationshipGraphList.tsx
4847
+ var import_jsx_runtime63 = require("react/jsx-runtime");
4848
+ function EquivalentRelationshipList({
4849
+ nodes,
4850
+ edges,
4851
+ selectedId,
4852
+ labels,
4853
+ onSelect,
4854
+ onExpandNeighbors,
4855
+ onOpenDetails
4856
+ }) {
4857
+ const labelById = new Map(nodes.map((node) => [node.id, node.label]));
4858
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
4859
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("h3", { children: labels.listHeading }),
4860
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("ul", { children: nodes.map((node) => {
4861
+ const neighbors = relationshipNeighbors(node.id, edges).map((id) => labelById.get(id) ?? id);
4862
+ return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
4863
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
4864
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("strong", { children: node.label }),
4865
+ node.type && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: node.type }),
4866
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
4867
+ ] }),
4868
+ /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
4869
+ onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
4870
+ onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: labels.openDetails })
4871
+ ] })
4872
+ ] }, node.id);
4873
+ }) })
4874
+ ] });
4875
+ }
4876
+
4877
+ // src/components/RelationshipGraphLayered.tsx
4878
+ var import_jsx_runtime64 = require("react/jsx-runtime");
4378
4879
  var EMPTY_IDS = /* @__PURE__ */ new Set();
4379
- var EMPTY_LEGEND = [];
4380
- function RelationshipGraph({
4880
+ var MIN_ZOOM = 0.4;
4881
+ var MAX_ZOOM = 1.5;
4882
+ var READABLE_ZOOM = 0.75;
4883
+ var ZOOM_STEP = 1.2;
4884
+ var PAN_STEP = 64;
4885
+ var FOCUS_MARGIN = 24;
4886
+ var NAV_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"];
4887
+ var clampZoom = (zoom) => Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));
4888
+ function initialView(layout, size) {
4889
+ if (size.width === 0 || size.height === 0 || layout.width === 0) return { x: 0, y: 0, zoom: 1 };
4890
+ const fit = Math.min(size.width / layout.width, size.height / layout.height);
4891
+ if (fit < READABLE_ZOOM) return { x: 0, y: 0, zoom: READABLE_ZOOM };
4892
+ const zoom = Math.min(fit, 1);
4893
+ return { x: (size.width - layout.width * zoom) / 2, y: Math.max(0, (size.height - layout.height * zoom) / 2), zoom };
4894
+ }
4895
+ function fitView(layout, size) {
4896
+ if (size.width === 0 || layout.width === 0) return { x: 0, y: 0, zoom: 1 };
4897
+ const zoom = clampZoom(Math.min(size.width / layout.width, size.height / layout.height, 1));
4898
+ return { x: (size.width - layout.width * zoom) / 2, y: Math.max(0, (size.height - layout.height * zoom) / 2), zoom };
4899
+ }
4900
+ var arrowPoints = "0,0 -8,-4.5 -8,4.5";
4901
+ function LayeredRelationshipGraph({
4381
4902
  nodes,
4382
4903
  edges,
4383
4904
  selectedId,
4384
4905
  onSelect,
4385
4906
  onExpandNeighbors,
4386
4907
  onOpenDetails,
4387
- maxNodes = 40,
4908
+ maxNodes = 400,
4388
4909
  density = "standard",
4389
4910
  highlightedNodeIds = EMPTY_IDS,
4390
4911
  conflictedNodeIds = EMPTY_IDS,
4391
4912
  highlightedEdgeIds = EMPTY_IDS,
4392
4913
  conflictedEdgeIds = EMPTY_IDS,
4393
- legend = EMPTY_LEGEND,
4394
- loading,
4395
- error,
4396
- onRetry,
4397
- className
4914
+ legend = [],
4915
+ className,
4916
+ labels,
4917
+ rootId,
4918
+ renderNode,
4919
+ nodeAriaLabel,
4920
+ renderCluster,
4921
+ clusterThreshold,
4922
+ expandedClusterIds,
4923
+ onToggleCluster,
4924
+ dimmedNodeIds = EMPTY_IDS,
4925
+ edgeLabels = "auto",
4926
+ showList = true,
4927
+ height,
4928
+ focusId,
4929
+ onFocusChange
4398
4930
  }) {
4931
+ const hintId = (0, import_react40.useId)();
4399
4932
  const bounded = (0, import_react40.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
4400
- const positioned = (0, import_react40.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
4401
- const positionedById = (0, import_react40.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
4402
- const [zoom, setZoom] = (0, import_react40.useState)(1);
4403
- const [pan, setPan] = (0, import_react40.useState)({ x: 0, y: 0 });
4404
- const [focusedId, setFocusedId] = (0, import_react40.useState)(selectedId ?? positioned[0]?.id);
4405
- const svgRef = (0, import_react40.useRef)(null);
4933
+ const [localExpanded, setLocalExpanded] = (0, import_react40.useState)(EMPTY_IDS);
4934
+ const expanded = expandedClusterIds ?? localExpanded;
4935
+ const layout = (0, import_react40.useMemo)(
4936
+ () => layoutLayeredGraph(bounded.nodes, bounded.edges, {
4937
+ ...rootId !== void 0 ? { rootId } : {},
4938
+ ...clusterThreshold !== void 0 ? { clusterThreshold } : {},
4939
+ expandedClusterIds: expanded,
4940
+ density
4941
+ }),
4942
+ [bounded, rootId, clusterThreshold, expanded, density]
4943
+ );
4944
+ const itemById = (0, import_react40.useMemo)(() => new Map(layout.items.map((item) => [item.id, item])), [layout]);
4945
+ const viewportRef = (0, import_react40.useRef)(null);
4946
+ const itemRefs = (0, import_react40.useRef)(/* @__PURE__ */ new Map());
4947
+ const [size, setSize] = (0, import_react40.useState)({ width: 0, height: 0 });
4948
+ const [view, setView] = (0, import_react40.useState)({ x: 0, y: 0, zoom: 1 });
4949
+ const [animate, setAnimate] = (0, import_react40.useState)(false);
4950
+ const [localFocus, setLocalFocus] = (0, import_react40.useState)(void 0);
4951
+ const [hoverId, setHoverId] = (0, import_react40.useState)(void 0);
4952
+ const viewRef = (0, import_react40.useRef)(view);
4953
+ viewRef.current = view;
4954
+ const layoutRef = (0, import_react40.useRef)(layout);
4955
+ layoutRef.current = layout;
4956
+ const pendingFocus = (0, import_react40.useRef)(void 0);
4957
+ const initialisedFor = (0, import_react40.useRef)(void 0);
4958
+ const rootItemId = layout.rootId !== void 0 ? layout.itemOf[layout.rootId] : layout.items[0]?.id;
4959
+ const requestedFocus = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : localFocus;
4960
+ const focusedId = requestedFocus !== void 0 && itemById.has(requestedFocus) ? requestedFocus : rootItemId;
4961
+ const selectedItemId = selectedId !== void 0 ? layout.itemOf[selectedId] : void 0;
4962
+ const activeIds = (0, import_react40.useMemo)(
4963
+ () => new Set([hoverId, selectedItemId].filter((id) => id !== void 0)),
4964
+ [hoverId, selectedItemId]
4965
+ );
4966
+ (0, import_react40.useEffect)(() => {
4967
+ const element = viewportRef.current;
4968
+ if (!element) return;
4969
+ const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
4970
+ measure();
4971
+ if (typeof ResizeObserver === "undefined") return;
4972
+ const observer = new ResizeObserver(measure);
4973
+ observer.observe(element);
4974
+ return () => observer.disconnect();
4975
+ }, []);
4976
+ (0, import_react40.useEffect)(() => {
4977
+ if (size.width === 0) return;
4978
+ const key = `${layout.rootId ?? ""}`;
4979
+ if (initialisedFor.current === key) return;
4980
+ initialisedFor.current = key;
4981
+ setView(initialView(layout, size));
4982
+ }, [layout, size]);
4983
+ const moveView = (0, import_react40.useCallback)((next, smooth) => {
4984
+ setAnimate(smooth);
4985
+ setView(next);
4986
+ }, []);
4987
+ const ensureVisible = (0, import_react40.useCallback)((id, smooth) => {
4988
+ const element = viewportRef.current;
4989
+ const item = layoutRef.current.items.find((candidate) => candidate.id === id);
4990
+ if (!element || !item) return;
4991
+ const { x, y, zoom } = viewRef.current;
4992
+ const width = element.clientWidth;
4993
+ const heightPx = element.clientHeight;
4994
+ const left = item.x * zoom + x;
4995
+ const top = item.y * zoom + y;
4996
+ const right = left + item.width * zoom;
4997
+ const bottom = top + item.height * zoom;
4998
+ let nextX = x;
4999
+ let nextY = y;
5000
+ if (left < FOCUS_MARGIN) nextX += FOCUS_MARGIN - left;
5001
+ else if (right > width - FOCUS_MARGIN) nextX -= right - (width - FOCUS_MARGIN);
5002
+ if (top < FOCUS_MARGIN) nextY += FOCUS_MARGIN - top;
5003
+ else if (bottom > heightPx - FOCUS_MARGIN) nextY -= bottom - (heightPx - FOCUS_MARGIN);
5004
+ if (nextX !== x || nextY !== y) moveView({ x: nextX, y: nextY, zoom }, smooth);
5005
+ }, [moveView]);
5006
+ const focusItem = (0, import_react40.useCallback)((id) => {
5007
+ setLocalFocus(id);
5008
+ onFocusChange?.(id);
5009
+ requestAnimationFrame(() => {
5010
+ itemRefs.current.get(id)?.focus({ preventScroll: true });
5011
+ ensureVisible(id, true);
5012
+ });
5013
+ }, [ensureVisible, onFocusChange]);
5014
+ (0, import_react40.useEffect)(() => {
5015
+ const wanted = pendingFocus.current;
5016
+ if (wanted !== void 0 && itemById.has(wanted)) {
5017
+ pendingFocus.current = void 0;
5018
+ focusItem(wanted);
5019
+ }
5020
+ }, [itemById, focusItem]);
5021
+ const controlledTarget = focusId !== void 0 ? layout.itemOf[focusId] ?? focusId : void 0;
5022
+ const controlledPresent = controlledTarget !== void 0 && itemById.has(controlledTarget);
5023
+ const controlledKey = `${controlledTarget ?? ""}|${controlledPresent}`;
5024
+ const lastControlledKey = (0, import_react40.useRef)(controlledKey);
5025
+ (0, import_react40.useEffect)(() => {
5026
+ if (lastControlledKey.current === controlledKey) return;
5027
+ lastControlledKey.current = controlledKey;
5028
+ if (!controlledPresent || controlledTarget === void 0) return;
5029
+ requestAnimationFrame(() => {
5030
+ itemRefs.current.get(controlledTarget)?.focus({ preventScroll: true });
5031
+ ensureVisible(controlledTarget, true);
5032
+ });
5033
+ }, [controlledKey, controlledTarget, controlledPresent, ensureVisible]);
5034
+ (0, import_react40.useEffect)(() => {
5035
+ const element = viewportRef.current;
5036
+ if (!element) return;
5037
+ const onWheel = (event) => {
5038
+ if (!event.ctrlKey && !event.metaKey) return;
5039
+ event.preventDefault();
5040
+ const rect = element.getBoundingClientRect();
5041
+ const px = event.clientX - rect.left;
5042
+ const py = event.clientY - rect.top;
5043
+ const current = viewRef.current;
5044
+ const zoom = clampZoom(current.zoom * Math.exp(-event.deltaY * 2e-3));
5045
+ const ratio = zoom / current.zoom;
5046
+ setAnimate(false);
5047
+ setView({ zoom, x: px - (px - current.x) * ratio, y: py - (py - current.y) * ratio });
5048
+ };
5049
+ element.addEventListener("wheel", onWheel, { passive: false });
5050
+ return () => element.removeEventListener("wheel", onWheel);
5051
+ }, []);
5052
+ const pointers = (0, import_react40.useRef)(/* @__PURE__ */ new Map());
5053
+ const pinchDistance = (0, import_react40.useRef)(void 0);
5054
+ const onPointerDown = (event) => {
5055
+ if (event.target.closest("button")) return;
5056
+ event.currentTarget.setPointerCapture?.(event.pointerId);
5057
+ pointers.current.set(event.pointerId, { x: event.clientX, y: event.clientY });
5058
+ pinchDistance.current = void 0;
5059
+ setAnimate(false);
5060
+ };
5061
+ const onPointerMove = (event) => {
5062
+ const previous = pointers.current.get(event.pointerId);
5063
+ if (!previous) return;
5064
+ const current = { x: event.clientX, y: event.clientY };
5065
+ pointers.current.set(event.pointerId, current);
5066
+ const all = [...pointers.current.values()];
5067
+ if (all.length >= 2) {
5068
+ const [a, b] = all;
5069
+ const distance = Math.hypot(a.x - b.x, a.y - b.y);
5070
+ const rect = event.currentTarget.getBoundingClientRect();
5071
+ const mx = (a.x + b.x) / 2 - rect.left;
5072
+ const my = (a.y + b.y) / 2 - rect.top;
5073
+ if (pinchDistance.current !== void 0 && pinchDistance.current > 0) {
5074
+ const base = viewRef.current;
5075
+ const zoom = clampZoom(base.zoom * (distance / pinchDistance.current));
5076
+ const ratio = zoom / base.zoom;
5077
+ setView({ zoom, x: mx - (mx - base.x) * ratio, y: my - (my - base.y) * ratio });
5078
+ }
5079
+ pinchDistance.current = distance;
5080
+ return;
5081
+ }
5082
+ const dx = current.x - previous.x;
5083
+ const dy = current.y - previous.y;
5084
+ setView((value) => ({ ...value, x: value.x + dx, y: value.y + dy }));
5085
+ };
5086
+ const onPointerEnd = (event) => {
5087
+ pointers.current.delete(event.pointerId);
5088
+ pinchDistance.current = void 0;
5089
+ };
5090
+ const zoomBy = (factor) => {
5091
+ const current = viewRef.current;
5092
+ const zoom = clampZoom(current.zoom * factor);
5093
+ const ratio = zoom / current.zoom;
5094
+ const cx0 = size.width / 2;
5095
+ const cy0 = size.height / 2;
5096
+ moveView({ zoom, x: cx0 - (cx0 - current.x) * ratio, y: cy0 - (cy0 - current.y) * ratio }, true);
5097
+ };
5098
+ const panBy = (dx, dy) => moveView({ ...viewRef.current, x: viewRef.current.x + dx, y: viewRef.current.y + dy }, true);
5099
+ const toggleCluster = (clusterId, focusAfter) => {
5100
+ const isExpanded = expanded.has(clusterId);
5101
+ pendingFocus.current = focusAfter;
5102
+ if (expandedClusterIds === void 0) {
5103
+ setLocalExpanded((previous) => {
5104
+ const next = new Set(previous);
5105
+ if (isExpanded) next.delete(clusterId);
5106
+ else next.add(clusterId);
5107
+ return next;
5108
+ });
5109
+ }
5110
+ onToggleCluster?.(clusterId, !isExpanded);
5111
+ };
5112
+ const activate = (item) => {
5113
+ if (item.cluster) {
5114
+ toggleCluster(item.cluster.id, item.cluster.members[0]?.id ?? item.id);
5115
+ return;
5116
+ }
5117
+ if (item.node) {
5118
+ setLocalFocus(item.id);
5119
+ onFocusChange?.(item.id);
5120
+ onSelect?.(item.node);
5121
+ }
5122
+ };
5123
+ const onItemKeyDown = (event, item) => {
5124
+ if (NAV_KEYS.includes(event.key)) {
5125
+ event.preventDefault();
5126
+ const next = layeredNeighbor(layout, item.id, event.key);
5127
+ if (next !== void 0) focusItem(next);
5128
+ }
5129
+ };
5130
+ const labelFor = (item) => {
5131
+ if (item.cluster) {
5132
+ const cluster = item.cluster;
5133
+ return `${labels.cluster(cluster.members.length, cluster.type, cluster.edgeLabel)}, ${labels.expandCluster}`;
5134
+ }
5135
+ const node = item.node;
5136
+ const conflict = conflictedNodeIds.has(node.id) ? labels.conflict : void 0;
5137
+ if (nodeAriaLabel) return [nodeAriaLabel(node), item.inCycle ? labels.cycle : void 0, conflict].filter(Boolean).join(", ");
5138
+ return [node.label, node.type, node.description, labels.relationships(item.degree), item.inCycle ? labels.cycle : void 0, conflict].filter(Boolean).join(", ");
5139
+ };
5140
+ const showLabel = (edge) => {
5141
+ if (edgeLabels === "never" || edge.label === void 0) return false;
5142
+ if (edgeLabels === "always") return true;
5143
+ return edge.autoLabel || activeIds.has(edge.source) || activeIds.has(edge.target) || focusedId === edge.source || focusedId === edge.target;
5144
+ };
5145
+ const viewportStyle = height !== void 0 ? { "--uix-relationship-graph-height": height } : {};
5146
+ const stageStyle = {
5147
+ width: layout.width,
5148
+ height: layout.height,
5149
+ transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`
5150
+ };
5151
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("section", { className: cx("uix-relationship-graph", "uix-relationship-graph--layered", density === "compact" && "uix-relationship-graph--compact", className), "aria-label": labels.graph, children: [
5152
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uix-relationship-graph__toolbar", role: "group", "aria-label": labels.controls, children: [
5153
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => zoomBy(ZOOM_STEP), disabled: view.zoom >= MAX_ZOOM, children: labels.zoomIn }),
5154
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => zoomBy(1 / ZOOM_STEP), disabled: view.zoom <= MIN_ZOOM, children: labels.zoomOut }),
5155
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => moveView(fitView(layout, size), true), children: labels.fit }),
5156
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => moveView(initialView(layout, size), true), children: labels.reset }),
5157
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => panBy(PAN_STEP, 0), "aria-label": labels.panLeft, children: labels.left }),
5158
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => panBy(0, PAN_STEP), "aria-label": labels.panUp, children: labels.up }),
5159
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => panBy(0, -PAN_STEP), "aria-label": labels.panDown, children: labels.down }),
5160
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", onClick: () => panBy(-PAN_STEP, 0), "aria-label": labels.panRight, children: labels.right }),
5161
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(view.zoom * 100)) })
5162
+ ] }),
5163
+ bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
5164
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("p", { id: hintId, className: "uix-visually-hidden", children: labels.keyboardHint }),
5165
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
5166
+ "div",
5167
+ {
5168
+ ref: viewportRef,
5169
+ className: "uix-relationship-graph__viewport",
5170
+ style: viewportStyle,
5171
+ onPointerDown,
5172
+ onPointerMove,
5173
+ onPointerUp: onPointerEnd,
5174
+ onPointerCancel: onPointerEnd,
5175
+ children: /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
5176
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
5177
+ const active = activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id));
5178
+ const angle = edge.arrowAngle * 180 / Math.PI;
5179
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
5180
+ "g",
5181
+ {
5182
+ className: "uix-relationship-graph__link",
5183
+ "data-kind": edge.kind,
5184
+ "data-active": active || void 0,
5185
+ "data-emphasis": edge.emphasis || void 0,
5186
+ "data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
5187
+ "data-dimmed": dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0,
5188
+ children: [
5189
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("path", { d: edge.path }),
5190
+ edge.arrow !== "none" && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
5191
+ showLabel(edge) && /* @__PURE__ */ (0, import_jsx_runtime64.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_runtime64.jsx)("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
5192
+ ]
5193
+ },
5194
+ edge.id
5195
+ );
5196
+ }) }),
5197
+ layout.columns.map((column) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
5198
+ "div",
5199
+ {
5200
+ className: "uix-relationship-graph__column",
5201
+ "aria-hidden": "true",
5202
+ style: { left: column.x, width: layout.nodeWidth },
5203
+ children: labels.column(column.depth, column.count)
5204
+ },
5205
+ column.depth
5206
+ )),
5207
+ /* @__PURE__ */ (0, import_jsx_runtime64.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) => {
5208
+ const selected = item.id === selectedItemId;
5209
+ const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
5210
+ const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
5211
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
5212
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
5213
+ ] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(import_jsx_runtime64.Fragment, { children: [
5214
+ /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
5215
+ (item.node.type || item.node.description) && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
5216
+ ] });
5217
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)(
5218
+ "button",
5219
+ {
5220
+ ref: (element) => {
5221
+ if (element) itemRefs.current.set(item.id, element);
5222
+ else itemRefs.current.delete(item.id);
5223
+ },
5224
+ type: "button",
5225
+ className: "uix-relationship-graph__item",
5226
+ "data-kind": item.kind,
5227
+ "data-node-id": item.id,
5228
+ "data-selected": selected || void 0,
5229
+ "data-dimmed": dimmed || void 0,
5230
+ "data-highlighted": item.node && highlightedNodeIds.has(item.node.id) || void 0,
5231
+ "data-conflicted": item.node && conflictedNodeIds.has(item.node.id) || void 0,
5232
+ "data-root": item.id === rootItemId || void 0,
5233
+ style: { left: item.x, top: item.y, width: item.width, height: item.height },
5234
+ tabIndex: item.id === focusedId ? 0 : -1,
5235
+ "aria-label": labelFor(item),
5236
+ ...item.cluster ? { "aria-expanded": false } : { "aria-pressed": selected },
5237
+ onClick: () => activate(item),
5238
+ onKeyDown: (event) => onItemKeyDown(event, item),
5239
+ onFocus: () => {
5240
+ if (item.id === focusedId) return;
5241
+ setLocalFocus(item.id);
5242
+ onFocusChange?.(item.id);
5243
+ },
5244
+ onPointerEnter: () => setHoverId(item.id),
5245
+ onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
5246
+ children: [
5247
+ body,
5248
+ item.inCycle && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
5249
+ ]
5250
+ },
5251
+ item.id
5252
+ );
5253
+ }) }),
5254
+ layout.items.filter((item) => item.expandedGroup).map((item) => {
5255
+ const group = item.expandedGroup;
5256
+ return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
5257
+ "button",
5258
+ {
5259
+ type: "button",
5260
+ className: "uix-relationship-graph__collapse",
5261
+ "aria-expanded": "true",
5262
+ style: { left: item.x, top: item.y - 26, width: item.width },
5263
+ onClick: () => toggleCluster(group.id, group.id),
5264
+ children: labels.collapseCluster(group.members.length, group.type)
5265
+ },
5266
+ `collapse:${group.id}`
5267
+ );
5268
+ })
5269
+ ] })
5270
+ }
5271
+ ),
5272
+ legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
5273
+ showList && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
5274
+ EquivalentRelationshipList,
5275
+ {
5276
+ nodes: bounded.nodes,
5277
+ edges: bounded.edges,
5278
+ selectedId,
5279
+ labels,
5280
+ onSelect: (id) => {
5281
+ const node = bounded.nodes.find((candidate) => candidate.id === id);
5282
+ if (node) onSelect?.(node);
5283
+ },
5284
+ onExpandNeighbors,
5285
+ onOpenDetails
5286
+ }
5287
+ )
5288
+ ] });
5289
+ }
5290
+
5291
+ // src/components/RelationshipGraph.tsx
5292
+ var import_jsx_runtime65 = require("react/jsx-runtime");
5293
+ var DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
5294
+ graph: "Relationship graph",
5295
+ controls: "Graph view controls",
5296
+ list: "Accessible relationship list",
5297
+ listHeading: "Relationship list",
5298
+ legend: "Relationship types",
5299
+ panLeft: "Pan left",
5300
+ panRight: "Pan right",
5301
+ panUp: "Pan up",
5302
+ panDown: "Pan down",
5303
+ left: "Left",
5304
+ right: "Right",
5305
+ up: "Up",
5306
+ down: "Down",
5307
+ zoomIn: "Zoom in",
5308
+ zoomOut: "Zoom out",
5309
+ fit: "Fit",
5310
+ reset: "Reset view",
5311
+ zoomLevel: (percent) => `Zoom ${percent}%`,
5312
+ bounded: (shown, omitted) => `Showing ${shown} nodes; ${omitted} outside this bounded neighborhood.`,
5313
+ graphSummary: (nodes, edges) => `Graph with ${nodes} nodes and ${edges} relationships`,
5314
+ relationship: "Relationship",
5315
+ conflict: "conflict",
5316
+ connectedTo: (names) => `Connected to ${names}`,
5317
+ noConnections: "No visible connections",
5318
+ expandNeighbors: "Expand neighbors",
5319
+ openDetails: "Open details",
5320
+ column: (depth, count) => `${depth === 0 ? "Start" : `${depth} ${depth === 1 ? "hop" : "hops"}`} \xB7 ${count}`,
5321
+ cluster: (count, type, edgeLabel) => `${count} \xD7 ${type ?? "items"}${edgeLabel ? ` \xB7 ${edgeLabel}` : ""}`,
5322
+ expandCluster: "Show all",
5323
+ collapseCluster: (count, type) => `Collapse ${count} ${type ?? "items"}`,
5324
+ cycle: "cycle",
5325
+ relationships: (count) => `${count} ${count === 1 ? "relationship" : "relationships"}`,
5326
+ roleDescription: "relationship map",
5327
+ keyboardHint: "Arrow keys move between connected items, Enter selects, Home returns to the start.",
5328
+ loading: "Loading relationships\u2026",
5329
+ retry: "Try again",
5330
+ emptyTitle: "No relationships to display.",
5331
+ emptyHint: "Adjust the neighborhood or filters to include a node."
5332
+ };
5333
+ var EMPTY_IDS2 = /* @__PURE__ */ new Set();
5334
+ var EMPTY_LEGEND = [];
5335
+ var RADIAL_SCALE_X = 6;
5336
+ var RADIAL_SCALE_Y = 4;
5337
+ var RADIAL_NODE_HALF_W = 55;
5338
+ var RADIAL_NODE_HALF_H = 18;
5339
+ var RADIAL_MARGIN = 12;
5340
+ function radialViewBox(nodes) {
5341
+ if (nodes.length === 0) return "0 0 600 400";
5342
+ const xs = nodes.map((node) => node.x * RADIAL_SCALE_X);
5343
+ const ys = nodes.map((node) => node.y * RADIAL_SCALE_Y);
5344
+ const minX = Math.min(...xs) - RADIAL_NODE_HALF_W - RADIAL_MARGIN;
5345
+ const maxX = Math.max(...xs) + RADIAL_NODE_HALF_W + RADIAL_MARGIN;
5346
+ const minY = Math.min(...ys) - RADIAL_NODE_HALF_H - RADIAL_MARGIN;
5347
+ const maxY = Math.max(...ys) + RADIAL_NODE_HALF_H + RADIAL_MARGIN;
5348
+ const round = (value) => Number(value.toFixed(2));
5349
+ const width = Math.max(round(maxX - minX), 600);
5350
+ const height = Math.max(round(maxY - minY), 400);
5351
+ return `${round(minX)} ${round(minY)} ${width} ${height}`;
5352
+ }
5353
+ function RelationshipGraph(props) {
5354
+ const labels = (0, import_react41.useMemo)(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
5355
+ const stateClass = cx("uix-relationship-graph uix-relationship-graph--state", props.className);
5356
+ if (props.loading) return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: stateClass, role: "status", children: labels.loading });
5357
+ if (props.error) {
5358
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: stateClass, role: "alert", children: [
5359
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { children: props.error }),
5360
+ props.onRetry && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
5361
+ ] });
5362
+ }
5363
+ if (props.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: stateClass, children: [
5364
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { children: labels.emptyTitle }),
5365
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { children: labels.emptyHint })
5366
+ ] });
5367
+ if (props.layout === "layered") return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(LayeredRelationshipGraph, { ...props, labels });
5368
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(RadialRelationshipGraph, { ...props, labels });
5369
+ }
5370
+ function RadialRelationshipGraph({
5371
+ nodes,
5372
+ edges,
5373
+ selectedId,
5374
+ onSelect,
5375
+ onExpandNeighbors,
5376
+ onOpenDetails,
5377
+ maxNodes = 40,
5378
+ density = "standard",
5379
+ highlightedNodeIds = EMPTY_IDS2,
5380
+ conflictedNodeIds = EMPTY_IDS2,
5381
+ highlightedEdgeIds = EMPTY_IDS2,
5382
+ conflictedEdgeIds = EMPTY_IDS2,
5383
+ legend = EMPTY_LEGEND,
5384
+ className,
5385
+ labels,
5386
+ showList = true
5387
+ }) {
5388
+ const bounded = (0, import_react41.useMemo)(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
5389
+ const positioned = (0, import_react41.useMemo)(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
5390
+ const positionedById = (0, import_react41.useMemo)(() => new Map(positioned.map((node) => [node.id, node])), [positioned]);
5391
+ const [zoom, setZoom] = (0, import_react41.useState)(1);
5392
+ const [pan, setPan] = (0, import_react41.useState)({ x: 0, y: 0 });
5393
+ const [focusedId, setFocusedId] = (0, import_react41.useState)(selectedId ?? positioned[0]?.id);
5394
+ const svgRef = (0, import_react41.useRef)(null);
4406
5395
  const select = (id) => {
4407
5396
  const node = bounded.nodes.find((item) => item.id === id);
4408
5397
  if (node) onSelect?.(node);
@@ -4425,49 +5414,30 @@ function RelationshipGraph({
4425
5414
  setZoom(1);
4426
5415
  setPan({ x: 0, y: 0 });
4427
5416
  };
4428
- if (loading) return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), role: "status", children: "Loading relationships\u2026" });
4429
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), role: "alert", children: [
4430
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: error }),
4431
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
4432
- ] });
4433
- if (bounded.nodes.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), children: [
4434
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: "No relationships to display." }),
4435
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("p", { children: "Adjust the neighborhood or filters to include a node." })
4436
- ] });
4437
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": "Relationship graph", children: [
4438
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": "Graph view controls", children: [
4439
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": "Pan left", children: "Left" }),
4440
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": "Pan up", children: "Up" }),
4441
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": "Pan down", children: "Down" }),
4442
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": "Pan right", children: "Right" }),
4443
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": "Zoom in", children: "Zoom in" }),
4444
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": "Zoom out", children: "Zoom out" }),
4445
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: reset, children: "Reset view" }),
4446
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { "aria-live": "polite", children: [
4447
- "Zoom ",
4448
- Math.round(zoom * 100),
4449
- "%"
4450
- ] })
5417
+ return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
5418
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
5419
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
5420
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
5421
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
5422
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
5423
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
5424
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
5425
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("button", { type: "button", onClick: reset, children: labels.reset }),
5426
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
4451
5427
  ] }),
4452
- bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("p", { className: "uix-relationship-graph__bounded", role: "status", children: [
4453
- "Showing ",
4454
- bounded.nodes.length,
4455
- " nodes; ",
4456
- bounded.omittedNodeCount,
4457
- " outside this bounded neighborhood."
4458
- ] }),
4459
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("svg", { ref: svgRef, viewBox: "0 0 600 400", role: "group", "aria-label": `Graph with ${bounded.nodes.length} nodes and ${bounded.edges.length} relationships`, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
5428
+ bounded.omittedNodeCount > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
5429
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("svg", { ref: svgRef, viewBox: radialViewBox(positioned), role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
4460
5430
  bounded.edges.map((edge) => {
4461
5431
  const source = positionedById.get(edge.source);
4462
5432
  const target = positionedById.get(edge.target);
4463
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("line", { x1: source.x * 6, y1: source.y * 4, x2: target.x * 6, y2: target.y * 4, className: "uix-relationship-graph__edge", "data-highlighted": highlightedEdgeIds.has(edge.id) || void 0, "data-conflicted": conflictedEdgeIds.has(edge.id) || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("title", { children: edge.label ?? edge.type ?? "Relationship" }) }, edge.id);
5433
+ return /* @__PURE__ */ (0, import_jsx_runtime65.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-highlighted": highlightedEdgeIds.has(edge.id) || void 0, "data-conflicted": conflictedEdgeIds.has(edge.id) || void 0, children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
4464
5434
  }),
4465
- positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
5435
+ positioned.map((node) => /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
4466
5436
  "g",
4467
5437
  {
4468
- transform: `translate(${node.x * 6} ${node.y * 4})`,
5438
+ transform: `translate(${node.x * RADIAL_SCALE_X} ${node.y * RADIAL_SCALE_Y})`,
4469
5439
  role: "button",
4470
- "aria-label": `${node.label}${node.type ? `, ${node.type}` : ""}${conflictedNodeIds.has(node.id) ? ", conflict" : ""}`,
5440
+ "aria-label": `${node.label}${node.type ? `, ${node.type}` : ""}${conflictedNodeIds.has(node.id) ? `, ${labels.conflict}` : ""}`,
4471
5441
  tabIndex: focusedId === node.id ? 0 : -1,
4472
5442
  "data-node-id": node.id,
4473
5443
  className: "uix-relationship-graph__node",
@@ -4478,37 +5448,22 @@ function RelationshipGraph({
4478
5448
  onKeyDown: (event) => onNodeKeyDown(event, node.id),
4479
5449
  onClick: () => select(node.id),
4480
5450
  children: [
4481
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("rect", { x: "-55", y: "-18", width: "110", height: "36", rx: "8" }),
4482
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
5451
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("title", { children: node.label }),
5452
+ /* @__PURE__ */ (0, import_jsx_runtime65.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" }),
5453
+ /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("text", { textAnchor: "middle", dominantBaseline: "middle", children: node.label.length > 16 ? `${node.label.slice(0, 15)}\u2026` : node.label })
4483
5454
  ]
4484
5455
  },
4485
5456
  node.id
4486
5457
  ))
4487
5458
  ] }) }) }),
4488
- legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": "Relationship types", children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("li", { "data-type": item.id, children: item.label }, item.id)) }),
4489
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": "Accessible relationship list", children: [
4490
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("h3", { children: "Relationship list" }),
4491
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("ul", { children: bounded.nodes.map((node) => {
4492
- const neighbors = relationshipNeighbors(node.id, bounded.edges).map((id) => bounded.nodes.find((item) => item.id === id)?.label ?? id);
4493
- return /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("li", { "data-selected": selectedId === node.id || void 0, children: [
4494
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("button", { type: "button", onClick: () => select(node.id), "aria-pressed": selectedId === node.id, children: [
4495
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("strong", { children: node.label }),
4496
- node.type && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: node.type }),
4497
- /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("span", { children: neighbors.length ? `Connected to ${neighbors.join(", ")}` : "No visible connections" })
4498
- ] }),
4499
- /* @__PURE__ */ (0, import_jsx_runtime62.jsxs)("span", { className: "uix-relationship-graph__list-actions", children: [
4500
- onExpandNeighbors && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => onExpandNeighbors(node), children: "Expand neighbors" }),
4501
- onOpenDetails && /* @__PURE__ */ (0, import_jsx_runtime62.jsx)("button", { type: "button", onClick: () => onOpenDetails(node), children: "Open details" })
4502
- ] })
4503
- ] }, node.id);
4504
- }) })
4505
- ] })
5459
+ legend.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("li", { "data-type": item.id, children: item.label }, item.id)) }),
5460
+ showList && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
4506
5461
  ] });
4507
5462
  }
4508
5463
 
4509
5464
  // src/components/MatchReview.tsx
4510
- var import_react41 = require("react");
4511
- var import_jsx_runtime63 = require("react/jsx-runtime");
5465
+ var import_react42 = require("react");
5466
+ var import_jsx_runtime66 = require("react/jsx-runtime");
4512
5467
  var valueText = (value) => value == null ? "\u2014" : typeof value === "string" ? value : JSON.stringify(value);
4513
5468
  function MatchReview({
4514
5469
  incoming,
@@ -4524,11 +5479,11 @@ function MatchReview({
4524
5479
  onRetry,
4525
5480
  className
4526
5481
  }) {
4527
- const [internalSelection, setInternalSelection] = (0, import_react41.useState)(/* @__PURE__ */ new Set());
4528
- const [announcement, setAnnouncement] = (0, import_react41.useState)("");
4529
- const [bulkPending, setBulkPending] = (0, import_react41.useState)(false);
5482
+ const [internalSelection, setInternalSelection] = (0, import_react42.useState)(/* @__PURE__ */ new Set());
5483
+ const [announcement, setAnnouncement] = (0, import_react42.useState)("");
5484
+ const [bulkPending, setBulkPending] = (0, import_react42.useState)(false);
4530
5485
  const selection = selectedIds ?? internalSelection;
4531
- const pending = (0, import_react41.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
5486
+ const pending = (0, import_react42.useMemo)(() => candidates.filter((candidate) => candidate.status !== "resolved"), [candidates]);
4532
5487
  const setSelection = (next) => {
4533
5488
  if (selectedIds === void 0) setInternalSelection(next);
4534
5489
  onSelectionChange?.(next);
@@ -4556,55 +5511,55 @@ function MatchReview({
4556
5511
  setBulkPending(false);
4557
5512
  }
4558
5513
  };
4559
- if (loading) return /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: "Loading match candidates\u2026" });
4560
- if (error) return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
4561
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { children: error }),
4562
- onRetry && /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
5514
+ if (loading) return /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "status", children: "Loading match candidates\u2026" });
5515
+ if (error) return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), role: "alert", children: [
5516
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { children: error }),
5517
+ onRetry && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
4563
5518
  ] });
4564
- if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
4565
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { children: "No candidate matches found." }),
4566
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { children: "Choose another record source or continue without a match." })
5519
+ if (candidates.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: cx("uix-match-review uix-match-review--state", className), children: [
5520
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { children: "No candidate matches found." }),
5521
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { children: "Choose another record source or continue without a match." })
4567
5522
  ] });
4568
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": "Match review", children: [
4569
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uix-match-review__summary", children: [
4570
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { children: [
4571
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("strong", { children: incomingLabel }),
4572
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { children: [
5523
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("section", { className: cx("uix-match-review", className), "aria-label": "Match review", children: [
5524
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "uix-match-review__summary", children: [
5525
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { children: [
5526
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("strong", { children: incomingLabel }),
5527
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
4573
5528
  pending.length,
4574
5529
  " pending of ",
4575
5530
  candidates.length
4576
5531
  ] })
4577
5532
  ] }),
4578
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { children: [
4579
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("b", { children: field.label }),
5533
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "uix-match-review__incoming", children: fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
5534
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("b", { children: field.label }),
4580
5535
  field.render?.(incoming[field.id], incoming) ?? valueText(incoming[field.id])
4581
5536
  ] }, field.id)) })
4582
5537
  ] }),
4583
- onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": "Bulk candidate actions", children: [
4584
- /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("span", { children: [
5538
+ onBulkDecision && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "uix-match-review__bulk", "aria-label": "Bulk candidate actions", children: [
5539
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
4585
5540
  selection.size,
4586
5541
  " selected"
4587
5542
  ] }),
4588
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("accept"), children: bulkPending ? "Applying\u2026" : "Accept selected" }),
4589
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("dismiss"), children: bulkPending ? "Applying\u2026" : "Dismiss selected" })
5543
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("accept"), children: bulkPending ? "Applying\u2026" : "Accept selected" }),
5544
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", disabled: selection.size === 0 || bulkPending, onClick: () => void runBulk("dismiss"), children: bulkPending ? "Applying\u2026" : "Dismiss selected" })
4590
5545
  ] }),
4591
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
4592
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("caption", { className: "uix-visually-hidden", children: "Candidate matches and available decisions" }),
4593
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("tr", { children: [
4594
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "uix-visually-hidden", children: "Select" }) }),
4595
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("th", { scope: "col", children: "Confidence" }),
4596
- fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("th", { scope: "col", children: field.label }, field.id)),
4597
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("th", { scope: "col", children: "Status" }),
4598
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("th", { scope: "col", children: "Actions" })
5546
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "uix-match-review__table-wrap", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("table", { className: "uix-table uix-match-review__table", children: [
5547
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("caption", { className: "uix-visually-hidden", children: "Candidate matches and available decisions" }),
5548
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("tr", { children: [
5549
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("th", { scope: "col", children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "uix-visually-hidden", children: "Select" }) }),
5550
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("th", { scope: "col", children: "Confidence" }),
5551
+ fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("th", { scope: "col", children: field.label }, field.id)),
5552
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("th", { scope: "col", children: "Status" }),
5553
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("th", { scope: "col", children: "Actions" })
4599
5554
  ] }) }),
4600
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("tbody", { children: candidates.map((candidate) => {
5555
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("tbody", { children: candidates.map((candidate) => {
4601
5556
  const resolved = candidate.status === "resolved";
4602
- return /* @__PURE__ */ (0, import_jsx_runtime63.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
4603
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": `Select candidate ${candidate.id}` }) }),
4604
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? "Not scored" : `${Math.round(candidate.confidence * 100)}%` }) }),
4605
- fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
4606
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ?? "Resolved" : "Pending" }) }),
4607
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime63.jsx)(
5557
+ return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("tr", { "data-status": candidate.status ?? "pending", children: [
5558
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("input", { type: "checkbox", checked: selection.has(candidate.id), onChange: () => toggle(candidate.id), "aria-label": `Select candidate ${candidate.id}` }) }),
5559
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "uix-match-review__confidence", children: candidate.confidence == null ? "Not scored" : `${Math.round(candidate.confidence * 100)}%` }) }),
5560
+ fields.map((field) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("td", { children: field.render?.(candidate.record[field.id], candidate.record) ?? valueText(candidate.record[field.id]) }, field.id)),
5561
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(StatusPill, { tone: resolved ? "success" : "warning", children: resolved ? candidate.decision ?? "Resolved" : "Pending" }) }),
5562
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("td", { children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "uix-match-review__actions", children: ["accept", "dismiss", "split", "pick-other"].map((action) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
4608
5563
  "button",
4609
5564
  {
4610
5565
  type: "button",
@@ -4618,12 +5573,12 @@ function MatchReview({
4618
5573
  ] }, candidate.id);
4619
5574
  }) })
4620
5575
  ] }) }),
4621
- /* @__PURE__ */ (0, import_jsx_runtime63.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
5576
+ /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
4622
5577
  ] });
4623
5578
  }
4624
5579
 
4625
5580
  // src/components/MetricInput.tsx
4626
- var import_react42 = require("react");
5581
+ var import_react43 = require("react");
4627
5582
 
4628
5583
  // src/metric-model.ts
4629
5584
  function decimals(value) {
@@ -4648,7 +5603,7 @@ function parseMetricValue(value) {
4648
5603
  }
4649
5604
 
4650
5605
  // src/components/MetricInput.tsx
4651
- var import_jsx_runtime64 = require("react/jsx-runtime");
5606
+ var import_jsx_runtime67 = require("react/jsx-runtime");
4652
5607
  var defaultMetricFormat = (input) => input == null ? "" : String(input);
4653
5608
  function MetricInput({
4654
5609
  value,
@@ -4667,11 +5622,11 @@ function MetricInput({
4667
5622
  className,
4668
5623
  id: providedId
4669
5624
  }) {
4670
- const generatedId = (0, import_react42.useId)();
5625
+ const generatedId = (0, import_react43.useId)();
4671
5626
  const id = providedId ?? generatedId;
4672
5627
  const errorId = `${id}-error`;
4673
- const [text, setText] = (0, import_react42.useState)(() => format(value));
4674
- (0, import_react42.useEffect)(() => setText(format(value)), [value, format]);
5628
+ const [text, setText] = (0, import_react43.useState)(() => format(value));
5629
+ (0, import_react43.useEffect)(() => setText(format(value)), [value, format]);
4675
5630
  const commit = (input) => {
4676
5631
  const parsed = parse(input);
4677
5632
  if (input.trim() === "" || parsed !== null) {
@@ -4697,10 +5652,10 @@ function MetricInput({
4697
5652
  const parsed = parse(event.currentTarget.value);
4698
5653
  setText(parsed === null && event.currentTarget.value.trim() !== "" ? format(value) : format(parsed));
4699
5654
  };
4700
- return /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
4701
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
4702
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("div", { className: "uix-metric-input__control", children: [
4703
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)(
5655
+ return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: cx("uix-metric-input", invalid && "uix-metric-input--invalid", className), children: [
5656
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("label", { className: "uix-field__label", htmlFor: id, children: label }),
5657
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-metric-input__control", children: [
5658
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(
4704
5659
  Input,
4705
5660
  {
4706
5661
  id,
@@ -4719,22 +5674,22 @@ function MetricInput({
4719
5674
  readOnly
4720
5675
  }
4721
5676
  ),
4722
- unit && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
4723
- /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "uix-metric-input__steps", children: [
4724
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
4725
- /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
5677
+ unit && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "uix-metric-input__unit", "aria-hidden": "true", children: unit }),
5678
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("span", { className: "uix-metric-input__steps", children: [
5679
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(1), disabled: disabled || readOnly, "aria-label": `Increase ${label}`, children: "+" }),
5680
+ /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("button", { type: "button", className: "uix-metric-input__step", onClick: () => stepBy(-1), disabled: disabled || readOnly, "aria-label": `Decrease ${label}`, children: "\u2212" })
4726
5681
  ] })
4727
5682
  ] }),
4728
- unit && /* @__PURE__ */ (0, import_jsx_runtime64.jsxs)("span", { className: "uix-visually-hidden", children: [
5683
+ unit && /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("span", { className: "uix-visually-hidden", children: [
4729
5684
  "Unit: ",
4730
5685
  unit
4731
5686
  ] }),
4732
- invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
5687
+ invalid && errorMessage && /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { id: errorId, className: "uix-field__error", children: errorMessage })
4733
5688
  ] });
4734
5689
  }
4735
5690
 
4736
5691
  // src/components/LicensePositionBar.tsx
4737
- var import_jsx_runtime65 = require("react/jsx-runtime");
5692
+ var import_jsx_runtime68 = require("react/jsx-runtime");
4738
5693
  var defaultCapacityFormat = (value) => new Intl.NumberFormat().format(value);
4739
5694
  function LicensePositionBar({
4740
5695
  consumed,
@@ -4755,18 +5710,18 @@ function LicensePositionBar({
4755
5710
  const percent = safeEntitled === 0 ? safeConsumed > 0 ? 100 : 0 : safeConsumed / safeEntitled * 100;
4756
5711
  const format = (value) => `${formatValue(value)}${unit ? ` ${unit}` : ""}`;
4757
5712
  const summary = `${consumedLabel}: ${format(safeConsumed)}. ${entitledLabel}: ${format(safeEntitled)}. ${over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}`}.`;
4758
- return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
4759
- /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "uix-license-position__header", children: [
4760
- /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("span", { className: "uix-license-position__value", children: [
5713
+ return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: cx("uix-license-position", over > 0 && "uix-license-position--over", className), ...props, children: [
5714
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "uix-license-position__header", children: [
5715
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { className: "uix-license-position__value", children: [
4761
5716
  format(safeConsumed),
4762
5717
  " / ",
4763
5718
  format(safeEntitled)
4764
5719
  ] }),
4765
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
5720
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusPill, { tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", children: over > 0 ? `${format(over)} ${overLabel}` : `${format(available)} ${availableLabel}` })
4766
5721
  ] }),
4767
- /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { className: "uix-license-position__track", children: [
4768
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
4769
- over > 0 && /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
5722
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "uix-license-position__track", children: [
5723
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(Meter, { value: Math.min(100, percent), tone: over > 0 ? "danger" : percent >= 80 ? "warning" : "success", "aria-label": summary, "aria-valuetext": summary }),
5724
+ over > 0 && /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(
4770
5725
  "span",
4771
5726
  {
4772
5727
  className: "uix-license-position__overflow",
@@ -4775,12 +5730,12 @@ function LicensePositionBar({
4775
5730
  }
4776
5731
  )
4777
5732
  ] }),
4778
- /* @__PURE__ */ (0, import_jsx_runtime65.jsx)("span", { className: "uix-visually-hidden", children: summary })
5733
+ /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { className: "uix-visually-hidden", children: summary })
4779
5734
  ] });
4780
5735
  }
4781
5736
 
4782
5737
  // src/components/BrandProfiles.tsx
4783
- var import_react44 = require("react");
5738
+ var import_react45 = require("react");
4784
5739
 
4785
5740
  // src/color-model.ts
4786
5741
  var clamp2 = (value, min, max) => Math.min(max, Math.max(min, value));
@@ -4849,8 +5804,8 @@ function meetsContrast(background, foreground, minimum = 4.5) {
4849
5804
  }
4850
5805
 
4851
5806
  // src/components/ColorPicker.tsx
4852
- var import_react43 = require("react");
4853
- var import_jsx_runtime66 = require("react/jsx-runtime");
5807
+ var import_react44 = require("react");
5808
+ var import_jsx_runtime69 = require("react/jsx-runtime");
4854
5809
  var EMPTY_COLORS = [];
4855
5810
  function ColorPicker({
4856
5811
  value,
@@ -4863,17 +5818,17 @@ function ColorPicker({
4863
5818
  disabled,
4864
5819
  className
4865
5820
  }) {
4866
- const id = (0, import_react43.useId)();
4867
- const triggerRef = (0, import_react43.useRef)(null);
4868
- const dialogRef = (0, import_react43.useRef)(null);
4869
- const [open, setOpen] = (0, import_react43.useState)(false);
5821
+ const id = (0, import_react44.useId)();
5822
+ const triggerRef = (0, import_react44.useRef)(null);
5823
+ const dialogRef = (0, import_react44.useRef)(null);
5824
+ const [open, setOpen] = (0, import_react44.useState)(false);
4870
5825
  const normalized = normalizeHex(value) ?? "#000000";
4871
- const [hexText, setHexText] = (0, import_react43.useState)(normalized);
4872
- const hsv = (0, import_react43.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
5826
+ const [hexText, setHexText] = (0, import_react44.useState)(normalized);
5827
+ const hsv = (0, import_react44.useMemo)(() => rgbToHsv(hexToRgb(normalized)), [normalized]);
4873
5828
  const ratio = contrastRatio(normalized, foreground) ?? 0;
4874
5829
  const passes = ratio >= minimumContrast;
4875
- (0, import_react43.useEffect)(() => setHexText(normalized), [normalized]);
4876
- (0, import_react43.useEffect)(() => {
5830
+ (0, import_react44.useEffect)(() => setHexText(normalized), [normalized]);
5831
+ (0, import_react44.useEffect)(() => {
4877
5832
  if (!open) return;
4878
5833
  const dialog = dialogRef.current;
4879
5834
  dialog?.querySelector("input,button")?.focus();
@@ -4916,8 +5871,8 @@ function ColorPicker({
4916
5871
  if (next) onChange(next);
4917
5872
  };
4918
5873
  const sampleStyle = { backgroundColor: normalized };
4919
- return /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: cx("uix-color-picker", className), children: [
4920
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
5874
+ return /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: cx("uix-color-picker", className), children: [
5875
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
4921
5876
  "button",
4922
5877
  {
4923
5878
  ref: triggerRef,
@@ -4929,12 +5884,12 @@ function ColorPicker({
4929
5884
  onClick: () => setOpen((current) => !current),
4930
5885
  disabled,
4931
5886
  children: [
4932
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
4933
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { children: normalized })
5887
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { className: "uix-color-picker__swatch", style: sampleStyle, "aria-hidden": "true" }),
5888
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { children: normalized })
4934
5889
  ]
4935
5890
  }
4936
5891
  ),
4937
- open && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)(
5892
+ open && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)(
4938
5893
  "div",
4939
5894
  {
4940
5895
  ref: dialogRef,
@@ -4945,57 +5900,57 @@ function ColorPicker({
4945
5900
  className: "uix-color-picker__popover",
4946
5901
  onKeyDown: onDialogKeyDown,
4947
5902
  children: [
4948
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("span", { style: { color: foreground }, children: "Aa" }) }),
4949
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("label", { className: "uix-color-picker__range", children: [
5903
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { className: "uix-color-picker__preview", style: sampleStyle, children: /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("span", { style: { color: foreground }, children: "Aa" }) }),
5904
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("label", { className: "uix-color-picker__range", children: [
4950
5905
  "Hue ",
4951
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
5906
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { children: [
4952
5907
  Math.round(hsv.h),
4953
5908
  "\xB0"
4954
5909
  ] }),
4955
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
5910
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("input", { type: "range", min: "0", max: "359", value: Math.round(hsv.h), onChange: (event) => updateHsv({ h: Number(event.currentTarget.value) }) })
4956
5911
  ] }),
4957
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("label", { className: "uix-color-picker__range", children: [
5912
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("label", { className: "uix-color-picker__range", children: [
4958
5913
  "Saturation ",
4959
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
5914
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { children: [
4960
5915
  Math.round(hsv.s * 100),
4961
5916
  "%"
4962
5917
  ] }),
4963
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
5918
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.s * 100), onChange: (event) => updateHsv({ s: Number(event.currentTarget.value) / 100 }) })
4964
5919
  ] }),
4965
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("label", { className: "uix-color-picker__range", children: [
5920
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("label", { className: "uix-color-picker__range", children: [
4966
5921
  "Brightness ",
4967
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { children: [
5922
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { children: [
4968
5923
  Math.round(hsv.v * 100),
4969
5924
  "%"
4970
5925
  ] }),
4971
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
5926
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("input", { type: "range", min: "0", max: "100", value: Math.round(hsv.v * 100), onChange: (event) => updateHsv({ v: Number(event.currentTarget.value) / 100 }) })
4972
5927
  ] }),
4973
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("label", { className: "uix-color-picker__hex", children: [
5928
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("label", { className: "uix-color-picker__hex", children: [
4974
5929
  "Hex",
4975
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
4976
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
5930
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("span", { className: "uix-color-picker__hex-row", children: [
5931
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("input", { className: "uix-input", value: hexText, onChange: (event) => setHexText(event.currentTarget.value), onBlur: commitHex, onKeyDown: (event) => {
4977
5932
  if (event.key === "Enter") commitHex();
4978
5933
  }, "aria-invalid": !normalizeHex(hexText) }),
4979
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: "Set" })
5934
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", onClick: commitHex, disabled: !normalizeHex(hexText), children: "Set" })
4980
5935
  ] })
4981
5936
  ] }),
4982
- (presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("div", { className: "uix-color-picker__palettes", children: [
4983
- presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("fieldset", { children: [
4984
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("legend", { children: "Presets" }),
4985
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": `Use preset ${color}` }, color)) })
5937
+ (presets.length > 0 || recent.length > 0) && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("div", { className: "uix-color-picker__palettes", children: [
5938
+ presets.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("fieldset", { children: [
5939
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("legend", { children: "Presets" }),
5940
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { children: presets.map((color) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": `Use preset ${color}` }, color)) })
4986
5941
  ] }),
4987
- recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("fieldset", { children: [
4988
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("legend", { children: "Recent" }),
4989
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": `Use recent color ${color}` }, color)) })
5942
+ recent.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("fieldset", { children: [
5943
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("legend", { children: "Recent" }),
5944
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("div", { children: recent.map((color) => /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("button", { type: "button", className: "uix-color-picker__preset", style: { backgroundColor: normalizeHex(color) ?? color }, onClick: () => choose(color), "aria-label": `Use recent color ${color}` }, color)) })
4990
5945
  ] })
4991
5946
  ] }),
4992
- /* @__PURE__ */ (0, import_jsx_runtime66.jsxs)("p", { className: cx("uix-color-picker__contrast", passes ? "uix-color-picker__contrast--pass" : "uix-color-picker__contrast--fail"), role: "status", "aria-live": "polite", children: [
5947
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsxs)("p", { className: cx("uix-color-picker__contrast", passes ? "uix-color-picker__contrast--pass" : "uix-color-picker__contrast--fail"), role: "status", "aria-live": "polite", children: [
4993
5948
  "Contrast ",
4994
5949
  ratio.toFixed(2),
4995
5950
  ":1 \u2014 ",
4996
5951
  passes ? `passes WCAG AA (${minimumContrast}:1)` : `does not meet WCAG AA (${minimumContrast}:1)`
4997
5952
  ] }),
4998
- /* @__PURE__ */ (0, import_jsx_runtime66.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: "Done" })
5953
+ /* @__PURE__ */ (0, import_jsx_runtime69.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", onClick: close, children: "Done" })
4999
5954
  ]
5000
5955
  }
5001
5956
  )
@@ -5003,7 +5958,7 @@ function ColorPicker({
5003
5958
  }
5004
5959
 
5005
5960
  // src/components/BrandProfiles.tsx
5006
- var import_jsx_runtime67 = require("react/jsx-runtime");
5961
+ var import_jsx_runtime70 = require("react/jsx-runtime");
5007
5962
  var PROFILE_PROPERTIES = {
5008
5963
  brand: "--uix-brand",
5009
5964
  brandForeground: "--uix-brand-fg",
@@ -5072,7 +6027,7 @@ function BrandProfileEditor({
5072
6027
  colorPresets = EMPTY_COLORS2,
5073
6028
  className
5074
6029
  }) {
5075
- const [announcement, setAnnouncement] = (0, import_react44.useState)("");
6030
+ const [announcement, setAnnouncement] = (0, import_react45.useState)("");
5076
6031
  const update = (patch) => onChange({ ...value, ...patch });
5077
6032
  const apply = () => {
5078
6033
  if (applyTarget !== null) applyBrandProfile(value, applyTarget);
@@ -5089,54 +6044,54 @@ function BrandProfileEditor({
5089
6044
  ...value.typography?.sans ? { "--uix-font-sans": value.typography.sans } : {},
5090
6045
  ...value.typography?.heading ? { "--uix-font-heading": value.typography.heading } : {}
5091
6046
  };
5092
- return /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": "Brand profile editor", children: [
5093
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-brand-profiles__form", children: [
5094
- profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { className: "uix-field__label", children: [
6047
+ return /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("section", { className: cx("uix-brand-profiles", className), "aria-label": "Brand profile editor", children: [
6048
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "uix-brand-profiles__form", children: [
6049
+ profiles.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: "uix-field__label", children: [
5095
6050
  "Profile",
5096
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
6051
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("select", { className: "uix-select", value: value.id, onChange: (event) => {
5097
6052
  const selected = profiles.find((profile) => profile.id === event.currentTarget.value);
5098
6053
  if (selected) onSelectProfile?.(selected);
5099
- }, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
6054
+ }, children: profiles.map((profile) => /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("option", { value: profile.id, children: profile.name }, profile.id)) })
5100
6055
  ] }),
5101
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { className: "uix-field__label", children: [
6056
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: "uix-field__label", children: [
5102
6057
  "Name",
5103
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
6058
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("input", { className: "uix-input", value: value.name, onChange: (event) => update({ name: event.currentTarget.value }) })
5104
6059
  ] }),
5105
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
5106
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { children: [
6060
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "uix-brand-profiles__colors", children: [
6061
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { children: [
5107
6062
  "Brand",
5108
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ColorPicker, { label: "Brand color", value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
6063
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ColorPicker, { label: "Brand color", value: value.brand, foreground: value.brandForeground, presets: colorPresets, onChange: (brand) => update({ brand }) })
5109
6064
  ] }),
5110
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { children: [
6065
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { children: [
5111
6066
  "On brand",
5112
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)(ColorPicker, { label: "Brand foreground color", value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
6067
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ColorPicker, { label: "Brand foreground color", value: value.brandForeground, foreground: value.brand, presets: colorPresets, onChange: (brandForeground) => update({ brandForeground }) })
5113
6068
  ] })
5114
6069
  ] }),
5115
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { className: "uix-field__label", children: [
6070
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: "uix-field__label", children: [
5116
6071
  "Body font",
5117
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
6072
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("input", { className: "uix-input", value: value.typography?.sans ?? "", onChange: (event) => update({ typography: { ...value.typography, sans: event.currentTarget.value || void 0 } }) })
5118
6073
  ] }),
5119
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { className: "uix-field__label", children: [
6074
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: "uix-field__label", children: [
5120
6075
  "Heading font",
5121
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
6076
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("input", { className: "uix-input", value: value.typography?.heading ?? "", onChange: (event) => update({ typography: { ...value.typography, heading: event.currentTarget.value || void 0 } }) })
5122
6077
  ] }),
5123
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
6078
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("label", { className: "uix-file-upload uix-brand-profiles__upload", children: [
5124
6079
  "Logo file",
5125
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
6080
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("input", { type: "file", accept: "image/*", onChange: onFile })
5126
6081
  ] }),
5127
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: "Apply profile" }),
5128
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
6082
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", onClick: apply, children: "Apply profile" }),
6083
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "uix-visually-hidden", "aria-live": "polite", children: announcement })
5129
6084
  ] }),
5130
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": `Live preview of ${value.name}`, children: [
5131
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
5132
- value.logo ? /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: "Logo" }),
5133
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("strong", { children: value.name || "Brand preview" })
6085
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "uix-brand-profiles__preview", style: previewStyle, "aria-label": `Live preview of ${value.name}`, children: [
6086
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "uix-brand-profiles__preview-header", children: [
6087
+ value.logo ? /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("img", { src: value.logo.src, alt: value.logo.alt }) : /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("span", { className: "uix-brand-profiles__logo-placeholder", children: "Logo" }),
6088
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("strong", { children: value.name || "Brand preview" })
5134
6089
  ] }),
5135
- /* @__PURE__ */ (0, import_jsx_runtime67.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
5136
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("h3", { children: "Readable, serializable branding" }),
5137
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("p", { children: "Accent, links, rings, and muted states continue through the existing UIx token chain." }),
5138
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: "Primary action" }),
5139
- /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("a", { href: "#brand-profile-preview", children: "Preview link" })
6090
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsxs)("div", { className: "uix-brand-profiles__preview-body", children: [
6091
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("h3", { children: "Readable, serializable branding" }),
6092
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("p", { children: "Accent, links, rings, and muted states continue through the existing UIx token chain." }),
6093
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary", children: "Primary action" }),
6094
+ /* @__PURE__ */ (0, import_jsx_runtime70.jsx)("a", { href: "#brand-profile-preview", children: "Preview link" })
5140
6095
  ] })
5141
6096
  ] })
5142
6097
  ] });
@@ -5144,7 +6099,7 @@ function BrandProfileEditor({
5144
6099
  var BrandProfiles = BrandProfileEditor;
5145
6100
 
5146
6101
  // src/components/DiffViewer.tsx
5147
- var import_react45 = require("react");
6102
+ var import_react46 = require("react");
5148
6103
 
5149
6104
  // src/diff-model.ts
5150
6105
  function isJsonObject(value) {
@@ -5195,7 +6150,7 @@ function summarizeDiff(entries, resolutions = {}) {
5195
6150
  }
5196
6151
 
5197
6152
  // src/components/DiffViewer.tsx
5198
- var import_jsx_runtime68 = require("react/jsx-runtime");
6153
+ var import_jsx_runtime71 = require("react/jsx-runtime");
5199
6154
  var GROUPS = [
5200
6155
  { kind: "conflicted", label: "Conflicted" },
5201
6156
  { kind: "changed", label: "Changed" },
@@ -5214,65 +6169,65 @@ function DiffViewer({
5214
6169
  labels = DEFAULT_LABELS,
5215
6170
  className
5216
6171
  }) {
5217
- const id = (0, import_react45.useId)();
5218
- const entries = (0, import_react45.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
5219
- const [internalResolutions, setInternalResolutions] = (0, import_react45.useState)({});
6172
+ const id = (0, import_react46.useId)();
6173
+ const entries = (0, import_react46.useMemo)(() => providedEntries ?? buildThreeWayDiff(base, current, incoming), [providedEntries, base, current, incoming]);
6174
+ const [internalResolutions, setInternalResolutions] = (0, import_react46.useState)({});
5220
6175
  const resolutions = controlledResolutions ?? internalResolutions;
5221
6176
  const summary = summarizeDiff(entries, resolutions);
5222
6177
  const resolve2 = (path, resolution) => {
5223
6178
  if (controlledResolutions === void 0) setInternalResolutions((currentState) => ({ ...currentState, [path]: resolution }));
5224
6179
  onResolutionChange?.(path, resolution);
5225
6180
  };
5226
- if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": "Configuration differences", children: [
5227
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("h3", { children: "No differences" }),
5228
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("p", { children: "Base, current, and incoming values are aligned." })
6181
+ if (entries.length === 0) return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("section", { className: cx("uix-diff-viewer uix-diff-viewer--empty", className), "aria-label": "Configuration differences", children: [
6182
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("h3", { children: "No differences" }),
6183
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("p", { children: "Base, current, and incoming values are aligned." })
5229
6184
  ] });
5230
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": "Configuration differences", children: [
5231
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "uix-diff-viewer__summary", "aria-label": "Difference summary", children: [
5232
- GROUPS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { children: [
5233
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("b", { children: summary[group.kind] }),
6185
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("section", { className: cx("uix-diff-viewer", className), "aria-label": "Configuration differences", children: [
6186
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uix-diff-viewer__summary", "aria-label": "Difference summary", children: [
6187
+ GROUPS.map((group) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { children: [
6188
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("b", { children: summary[group.kind] }),
5234
6189
  " ",
5235
6190
  group.label.toLowerCase()
5236
6191
  ] }, group.kind)),
5237
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { children: [
5238
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("b", { children: summary.resolved }),
6192
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { children: [
6193
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("b", { children: summary.resolved }),
5239
6194
  " resolved"
5240
6195
  ] }),
5241
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("span", { children: [
5242
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("b", { children: summary.pending }),
6196
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("span", { children: [
6197
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("b", { children: summary.pending }),
5243
6198
  " pending"
5244
6199
  ] })
5245
6200
  ] }),
5246
6201
  GROUPS.map((group) => {
5247
6202
  const grouped = entries.filter((entry) => entry.kind === group.kind);
5248
6203
  if (!grouped.length) return null;
5249
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${group.kind}`, children: [
5250
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("h3", { id: `${id}-${group.kind}`, children: [
6204
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("section", { className: "uix-diff-viewer__group", "aria-labelledby": `${id}-${group.kind}`, children: [
6205
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("h3", { id: `${id}-${group.kind}`, children: [
5251
6206
  group.label,
5252
6207
  " ",
5253
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("span", { children: grouped.length })
6208
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("span", { children: grouped.length })
5254
6209
  ] }),
5255
6210
  grouped.map((entry) => {
5256
6211
  const resolution = resolutions[entry.path] ?? "pending";
5257
- return /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
5258
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("summary", { children: [
5259
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("code", { children: entry.path }),
5260
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolution })
6212
+ return /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("details", { className: "uix-diff-viewer__entry", "data-kind": entry.kind, open: entry.kind === "conflicted", children: [
6213
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("summary", { children: [
6214
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("code", { children: entry.path }),
6215
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)(StatusPill, { tone: resolution === "pending" ? "warning" : "success", children: resolution })
5261
6216
  ] }),
5262
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { role: "region", "aria-label": `${labels[version] ?? `${version[0].toUpperCase()}${version.slice(1)}`} value for ${entry.path}`, children: [
5263
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("strong", { children: labels[version] ?? `${version[0].toUpperCase()}${version.slice(1)}` }),
5264
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("pre", { children: renderValue(entry[version]) })
6217
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("div", { className: "uix-diff-viewer__versions", children: ["base", "current", "incoming"].map((version) => /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { role: "region", "aria-label": `${labels[version] ?? `${version[0].toUpperCase()}${version.slice(1)}`} value for ${entry.path}`, children: [
6218
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("strong", { children: labels[version] ?? `${version[0].toUpperCase()}${version.slice(1)}` }),
6219
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("pre", { children: renderValue(entry[version]) })
5265
6220
  ] }, version)) }),
5266
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("div", { className: "uix-diff-viewer__actions", "aria-label": `Resolve ${entry.path}`, children: [
5267
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", "aria-pressed": resolution === "accept", onClick: () => resolve2(entry.path, "accept"), children: "Accept incoming" }),
5268
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", "aria-pressed": resolution === "skip", onClick: () => resolve2(entry.path, "skip"), children: "Keep current" }),
5269
- /* @__PURE__ */ (0, import_jsx_runtime68.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", "aria-pressed": resolution === "pending", onClick: () => resolve2(entry.path, "pending"), children: "Mark pending" })
6221
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("div", { className: "uix-diff-viewer__actions", "aria-label": `Resolve ${entry.path}`, children: [
6222
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", className: "uix-btn uix-btn--primary uix-btn--sm", "aria-pressed": resolution === "accept", onClick: () => resolve2(entry.path, "accept"), children: "Accept incoming" }),
6223
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", className: "uix-btn uix-btn--secondary uix-btn--sm", "aria-pressed": resolution === "skip", onClick: () => resolve2(entry.path, "skip"), children: "Keep current" }),
6224
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsx)("button", { type: "button", className: "uix-btn uix-btn--ghost uix-btn--sm", "aria-pressed": resolution === "pending", onClick: () => resolve2(entry.path, "pending"), children: "Mark pending" })
5270
6225
  ] })
5271
6226
  ] }, entry.path);
5272
6227
  })
5273
6228
  ] }, group.kind);
5274
6229
  }),
5275
- /* @__PURE__ */ (0, import_jsx_runtime68.jsxs)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: [
6230
+ /* @__PURE__ */ (0, import_jsx_runtime71.jsxs)("p", { className: "uix-visually-hidden", "aria-live": "polite", children: [
5276
6231
  summary.resolved,
5277
6232
  " of ",
5278
6233
  entries.length,
@@ -5312,6 +6267,8 @@ function DiffViewer({
5312
6267
  ConfirmDialog,
5313
6268
  ContentList,
5314
6269
  ContentListItem,
6270
+ DEFAULT_RELATIONSHIP_GRAPH_LABELS,
6271
+ DEFAULT_SAVE_STATUS_LABELS,
5315
6272
  DateRangePicker,
5316
6273
  DescriptionItem,
5317
6274
  DescriptionList,
@@ -5378,6 +6335,7 @@ function DiffViewer({
5378
6335
  RowAction,
5379
6336
  RowActions,
5380
6337
  RuleBuilder,
6338
+ SaveStatus,
5381
6339
  SavedViewMenu,
5382
6340
  SchedulingCalendar,
5383
6341
  SectionHead,
@@ -5423,6 +6381,8 @@ function DiffViewer({
5423
6381
  buildThreeWayDiff,
5424
6382
  clampMetricValue,
5425
6383
  clampWidth,
6384
+ classifyLayeredEdges,
6385
+ clusterIdFor,
5426
6386
  computePosition,
5427
6387
  contrastRatio,
5428
6388
  cx,
@@ -5437,6 +6397,8 @@ function DiffViewer({
5437
6397
  isDateInRange,
5438
6398
  isDateUnavailable,
5439
6399
  isRuleGroup,
6400
+ layeredNeighbor,
6401
+ layoutLayeredGraph,
5440
6402
  layoutRelationshipGraph,
5441
6403
  mapRuleGroup,
5442
6404
  matchFilter,
@@ -5478,6 +6440,7 @@ function DiffViewer({
5478
6440
  useVirtualRows,
5479
6441
  validateRuleDefinition,
5480
6442
  virtualWindow,
6443
+ wrapEdgeLabel,
5481
6444
  zonedDateKey,
5482
6445
  zonedDateSpan
5483
6446
  });