@tensor_1/react 2.47.0 → 2.49.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 (204) hide show
  1. package/README.md +540 -2
  2. package/dist/{SchedulingCalendar-B6TakO2h.d.ts → SchedulingCalendar-WWyFL3Eo.d.ts} +51 -2
  3. package/dist/announce.d.ts +10 -0
  4. package/dist/announce.js +30 -0
  5. package/dist/chart-analytic.cjs +33 -25
  6. package/dist/chart-preset.cjs +23 -15
  7. package/dist/chart.cjs +23 -15
  8. package/dist/combobox-model.d.ts +10 -1
  9. package/dist/combobox-model.js +15 -0
  10. package/dist/command-palette-model.d.ts +44 -0
  11. package/dist/command-palette-model.js +36 -0
  12. package/dist/components/AccountMenu.d.ts +44 -0
  13. package/dist/components/AccountMenu.js +43 -0
  14. package/dist/components/AppShell.d.ts +45 -2
  15. package/dist/components/AppShell.js +116 -5
  16. package/dist/components/AuditLog.d.ts +128 -0
  17. package/dist/components/AuditLog.js +196 -0
  18. package/dist/components/BrandProfiles.js +4 -3
  19. package/dist/components/Breadcrumbs.d.ts +9 -2
  20. package/dist/components/Breadcrumbs.js +3 -2
  21. package/dist/components/Button.d.ts +12 -5
  22. package/dist/components/Button.js +7 -3
  23. package/dist/components/Card.d.ts +18 -1
  24. package/dist/components/Card.js +5 -1
  25. package/dist/components/ChangeHighlight.d.ts +30 -0
  26. package/dist/components/ChangeHighlight.js +21 -0
  27. package/dist/components/ChartCore.js +2 -1
  28. package/dist/components/Checkbox.d.ts +27 -1
  29. package/dist/components/Checkbox.js +31 -2
  30. package/dist/components/Chip.d.ts +7 -3
  31. package/dist/components/Chip.js +2 -2
  32. package/dist/components/CodeDisplay.d.ts +65 -0
  33. package/dist/components/CodeDisplay.js +124 -0
  34. package/dist/components/Combobox.d.ts +27 -6
  35. package/dist/components/Combobox.js +195 -58
  36. package/dist/components/CommandPalette.d.ts +36 -1
  37. package/dist/components/CommandPalette.js +254 -2
  38. package/dist/components/ContactCard.d.ts +66 -0
  39. package/dist/components/ContactCard.js +74 -0
  40. package/dist/components/Count.d.ts +24 -0
  41. package/dist/components/Count.js +32 -0
  42. package/dist/components/DashboardCanvas.js +14 -0
  43. package/dist/components/DataWorkspace.d.ts +167 -0
  44. package/dist/components/DataWorkspace.js +380 -0
  45. package/dist/components/DateFieldParts.d.ts +2 -1
  46. package/dist/components/DateFieldParts.js +7 -0
  47. package/dist/components/DatePicker.d.ts +9 -2
  48. package/dist/components/DatePicker.js +67 -28
  49. package/dist/components/DateRangePicker.d.ts +12 -2
  50. package/dist/components/DateRangePicker.js +13 -12
  51. package/dist/components/DetailPage.d.ts +7 -1
  52. package/dist/components/DetailPage.js +2 -1
  53. package/dist/components/Dialogs.d.ts +71 -10
  54. package/dist/components/Dialogs.js +130 -30
  55. package/dist/components/DiffViewer.d.ts +23 -3
  56. package/dist/components/DiffViewer.js +26 -12
  57. package/dist/components/DiscardPrompt.js +16 -0
  58. package/dist/components/DisplayPreferences.d.ts +83 -0
  59. package/dist/components/DisplayPreferences.js +185 -0
  60. package/dist/components/EditorialHome.d.ts +23 -3
  61. package/dist/components/EditorialHome.js +16 -11
  62. package/dist/components/EntityPicker.d.ts +20 -3
  63. package/dist/components/EntityPicker.js +32 -13
  64. package/dist/components/FilterEditor.d.ts +18 -4
  65. package/dist/components/FilterEditor.js +141 -19
  66. package/dist/components/FocusOnMount.d.ts +282 -0
  67. package/dist/components/FocusOnMount.js +12 -0
  68. package/dist/components/InfoTip.js +11 -12
  69. package/dist/components/InlineEdit.d.ts +87 -20
  70. package/dist/components/InlineEdit.js +197 -54
  71. package/dist/components/Input.d.ts +12 -2
  72. package/dist/components/Input.js +5 -3
  73. package/dist/components/Kanban.d.ts +14 -3
  74. package/dist/components/Kanban.js +9 -4
  75. package/dist/components/Kbd.d.ts +6 -1
  76. package/dist/components/Kbd.js +6 -6
  77. package/dist/components/Lightbox.d.ts +41 -5
  78. package/dist/components/Lightbox.js +95 -9
  79. package/dist/components/MatchReview.d.ts +40 -1
  80. package/dist/components/MatchReview.js +130 -4
  81. package/dist/components/MetricInput.js +3 -2
  82. package/dist/components/Modal.d.ts +2 -1
  83. package/dist/components/Modal.js +13 -4
  84. package/dist/components/MotionList.d.ts +303 -0
  85. package/dist/components/MotionList.js +175 -0
  86. package/dist/components/NavFavourites.d.ts +5 -0
  87. package/dist/components/NavFavourites.js +7 -7
  88. package/dist/components/OtpInput.d.ts +33 -0
  89. package/dist/components/OtpInput.js +123 -0
  90. package/dist/components/PageHeader.d.ts +7 -1
  91. package/dist/components/PageHeader.js +2 -2
  92. package/dist/components/Pagination.js +6 -5
  93. package/dist/components/PasswordInput.d.ts +34 -0
  94. package/dist/components/PasswordInput.js +101 -0
  95. package/dist/components/Peek.js +3 -3
  96. package/dist/components/Popover.js +11 -0
  97. package/dist/components/PrintLayout.d.ts +63 -0
  98. package/dist/components/PrintLayout.js +114 -0
  99. package/dist/components/QrCode.d.ts +47 -0
  100. package/dist/components/QrCode.js +55 -0
  101. package/dist/components/QrScanner.d.ts +95 -0
  102. package/dist/components/QrScanner.js +266 -0
  103. package/dist/components/RelationshipGraph.d.ts +32 -1
  104. package/dist/components/RelationshipGraph.js +22 -6
  105. package/dist/components/RelationshipGraphLayered.d.ts +1 -1
  106. package/dist/components/RelationshipGraphLayered.js +268 -118
  107. package/dist/components/RelationshipGraphList.js +33 -6
  108. package/dist/components/RuleBuilder.js +39 -7
  109. package/dist/components/SchedulingAgenda.d.ts +3 -1
  110. package/dist/components/SchedulingCalendar.d.ts +3 -1
  111. package/dist/components/SchedulingCalendar.js +43 -4
  112. package/dist/components/SchedulingResourceDay.d.ts +57 -0
  113. package/dist/components/SchedulingResourceDay.js +287 -0
  114. package/dist/components/SchedulingTimeGrid.d.ts +3 -1
  115. package/dist/components/SchedulingTimeline.d.ts +3 -1
  116. package/dist/components/SearchSuggest.d.ts +23 -3
  117. package/dist/components/SearchSuggest.js +56 -18
  118. package/dist/components/Segmented.d.ts +39 -4
  119. package/dist/components/Segmented.js +39 -5
  120. package/dist/components/Select.d.ts +3 -2
  121. package/dist/components/Select.js +7 -1
  122. package/dist/components/ShortcutHint.d.ts +11 -10
  123. package/dist/components/ShortcutHint.js +44 -38
  124. package/dist/components/Sidebar.d.ts +36 -4
  125. package/dist/components/Sidebar.js +37 -12
  126. package/dist/components/SortableList.d.ts +45 -0
  127. package/dist/components/SortableList.js +147 -0
  128. package/dist/components/Stat.d.ts +28 -3
  129. package/dist/components/Stat.js +13 -3
  130. package/dist/components/States.d.ts +33 -1
  131. package/dist/components/States.js +43 -1
  132. package/dist/components/StatusPill.d.ts +14 -3
  133. package/dist/components/StatusPill.js +11 -3
  134. package/dist/components/Steps.js +2 -1
  135. package/dist/components/Table.d.ts +9 -2
  136. package/dist/components/Table.js +4 -2
  137. package/dist/components/TableControls.js +18 -58
  138. package/dist/components/TableOverflowProbe.d.ts +12 -0
  139. package/dist/components/TableOverflowProbe.js +27 -0
  140. package/dist/components/Tabs.d.ts +2 -1
  141. package/dist/components/Tabs.js +10 -2
  142. package/dist/components/TagInput.d.ts +67 -0
  143. package/dist/components/TagInput.js +342 -0
  144. package/dist/components/Textarea.d.ts +5 -0
  145. package/dist/components/Textarea.js +2 -2
  146. package/dist/components/TimePicker.d.ts +80 -0
  147. package/dist/components/TimePicker.js +347 -0
  148. package/dist/components/Toast.d.ts +1 -1
  149. package/dist/components/Toast.js +109 -4
  150. package/dist/components/Tooltip.d.ts +8 -4
  151. package/dist/components/Tooltip.js +86 -28
  152. package/dist/components/Tree.d.ts +8 -0
  153. package/dist/components/Tree.js +11 -5
  154. package/dist/display-preferences-model.d.ts +53 -0
  155. package/dist/display-preferences-model.js +64 -0
  156. package/dist/emoji.cjs +143 -49
  157. package/dist/filter-model.d.ts +59 -3
  158. package/dist/filter-model.js +67 -2
  159. package/dist/hooks/useAnchoredPosition.js +14 -2
  160. package/dist/hooks/useChangeHighlight.d.ts +33 -0
  161. package/dist/hooks/useChangeHighlight.js +44 -0
  162. package/dist/hooks/useDeferredReorder.d.ts +32 -0
  163. package/dist/hooks/useDeferredReorder.js +47 -0
  164. package/dist/hooks/useDialog.d.ts +5 -0
  165. package/dist/hooks/useDialog.js +17 -3
  166. package/dist/hooks/useKeyboardGrab.d.ts +58 -0
  167. package/dist/hooks/useKeyboardGrab.js +118 -0
  168. package/dist/hooks/useOptimisticValue.d.ts +51 -0
  169. package/dist/hooks/useOptimisticValue.js +61 -0
  170. package/dist/hooks/useReducedMotion.d.ts +4 -1
  171. package/dist/hooks/useReducedMotion.js +7 -1
  172. package/dist/hooks/useResolvedFilterLabels.d.ts +15 -0
  173. package/dist/hooks/useResolvedFilterLabels.js +34 -0
  174. package/dist/hooks/useSlidingIndicator.d.ts +18 -0
  175. package/dist/hooks/useSlidingIndicator.js +80 -0
  176. package/dist/hooks/useVirtualRows.d.ts +21 -2
  177. package/dist/hooks/useVirtualRows.js +30 -3
  178. package/dist/icons/Icon.d.ts +1 -1
  179. package/dist/index.cjs +19687 -13423
  180. package/dist/index.d.cts +3419 -651
  181. package/dist/index.d.ts +48 -18
  182. package/dist/index.js +153 -9
  183. package/dist/labels-context.d.ts +93 -3
  184. package/dist/motion.d.ts +11 -0
  185. package/dist/motion.js +35 -0
  186. package/dist/overlay-stack.d.ts +6 -0
  187. package/dist/overlay-stack.js +13 -0
  188. package/dist/qr-model.d.ts +65 -0
  189. package/dist/qr-model.js +323 -0
  190. package/dist/relationship-graph-model.d.ts +92 -3
  191. package/dist/relationship-graph-model.js +134 -15
  192. package/dist/reorder.d.ts +30 -0
  193. package/dist/reorder.js +74 -0
  194. package/dist/rich-text.cjs +46 -4
  195. package/dist/scheduling-resource-model.d.ts +76 -0
  196. package/dist/scheduling-resource-model.js +74 -0
  197. package/dist/search-suggest-model.js +3 -1
  198. package/dist/shell-context.d.ts +11 -0
  199. package/dist/shell-context.js +7 -0
  200. package/dist/time-field-model.d.ts +46 -0
  201. package/dist/time-field-model.js +152 -0
  202. package/dist/toast-store.d.ts +22 -3
  203. package/dist/toast-store.js +26 -9
  204. package/package.json +2 -1
@@ -1,22 +1,30 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react";
4
- import { boundRelationshipGraph, layeredNeighbor, layoutLayeredGraph } from "../relationship-graph-model.js";
3
+ import { useCallback, useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from "react";
4
+ import { boundRelationshipGraph, edgeLabelSize, layeredNeighbor, layoutLayeredGraph, separateEdgeLabels } from "../relationship-graph-model.js";
5
5
  import { cx } from "../cx.js";
6
6
  import { Maximize2Icon, Minimize2Icon, MinusIcon, PlusIcon, RotateCcwIcon, ScanIcon } from "../icons/components.js";
7
7
  import { useKbdPlatform } from "./Kbd.js";
8
+ import { prefersReducedMotion } from "../hooks/useReducedMotion.js";
8
9
  import { EquivalentRelationshipList } from "./RelationshipGraphList.js";
9
10
  import { Tooltip } from "./Tooltip.js";
10
11
  const EMPTY_IDS = /* @__PURE__ */ new Set();
12
+ const useIsomorphicLayoutEffect = typeof document !== "undefined" ? useLayoutEffect : useEffect;
11
13
  const MIN_ZOOM = 0.4;
12
14
  const MAX_ZOOM = 1.5;
13
15
  const READABLE_ZOOM = 0.75;
14
16
  const ZOOM_STEP = 1.2;
15
17
  const PAN_STEP = 64;
16
18
  const FOCUS_MARGIN = 24;
19
+ const DESCRIBED_RELATIONS = 5;
17
20
  const HINT_MS = 1600;
21
+ const LABEL_FONT_PX = 12.5;
22
+ const MIN_LABEL_PX = 11;
23
+ const LABEL_CHIP_PAD_X = 6;
24
+ const LABEL_CHIP_PAD_Y = 2;
18
25
  const NAV_KEYS = ["ArrowUp", "ArrowDown", "ArrowLeft", "ArrowRight", "Home", "End"];
19
26
  const clampZoom = (zoom) => Math.min(MAX_ZOOM, Math.max(MIN_ZOOM, zoom));
27
+ const footerGutter = (viewport, footer) => footer && footer.parentElement === viewport ? Math.min(footer.offsetHeight, viewport.clientHeight) : 0;
20
28
  function initialView(layout, size) {
21
29
  if (size.width === 0 || size.height === 0 || layout.width === 0) return { x: 0, y: 0, zoom: 1 };
22
30
  const fit = Math.min(size.width / layout.width, size.height / layout.height);
@@ -60,9 +68,12 @@ function LayeredRelationshipGraph({
60
68
  focusId,
61
69
  onFocusChange,
62
70
  controls = "full",
63
- initialView: initialViewMode = "readable"
71
+ initialView: initialViewMode = "readable",
72
+ revealId,
73
+ markRoot
64
74
  }) {
65
75
  const hintId = useId();
76
+ const describeId = useId();
66
77
  const viewportHintId = useId();
67
78
  const compact = controls === "compact";
68
79
  const bounded = useMemo(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
@@ -85,11 +96,14 @@ function LayeredRelationshipGraph({
85
96
  const viewportRef = useRef(null);
86
97
  const itemRefs = useRef(/* @__PURE__ */ new Map());
87
98
  const fullscreenButtonRef = useRef(null);
99
+ const footerRef = useRef(null);
100
+ const edgesRef = useRef(null);
88
101
  const [size, setSize] = useState({ width: 0, height: 0 });
89
102
  const [view, setView] = useState({ x: 0, y: 0, zoom: 1 });
90
103
  const [animate, setAnimate] = useState(false);
91
104
  const [localFocus, setLocalFocus] = useState(void 0);
92
105
  const [hoverId, setHoverId] = useState(void 0);
106
+ const [focusWithinId, setFocusWithinId] = useState(void 0);
93
107
  const [fullscreen, setFullscreen] = useState(false);
94
108
  const [wheelHint, setWheelHint] = useState(false);
95
109
  const viewRef = useRef(view);
@@ -116,13 +130,14 @@ function LayeredRelationshipGraph({
116
130
  useEffect(() => {
117
131
  const element = viewportRef.current;
118
132
  if (!element) return;
119
- const measure = () => setSize({ width: element.clientWidth, height: element.clientHeight });
133
+ const measure = () => setSize({ width: element.clientWidth, height: Math.max(0, element.clientHeight - footerGutter(element, footerRef.current)) });
120
134
  measure();
121
135
  if (typeof ResizeObserver === "undefined") return;
122
136
  const observer = new ResizeObserver(measure);
123
137
  observer.observe(element);
138
+ if (footerRef.current) observer.observe(footerRef.current);
124
139
  return () => observer.disconnect();
125
- }, []);
140
+ }, [compact]);
126
141
  useEffect(() => {
127
142
  if (size.width === 0) return;
128
143
  const key = `${layout.rootId ?? ""}`;
@@ -147,7 +162,7 @@ function LayeredRelationshipGraph({
147
162
  }, [fullscreen]);
148
163
  useEffect(() => () => clearTimeout(hintTimer.current), []);
149
164
  const moveView = useCallback((next, smooth) => {
150
- setAnimate(smooth);
165
+ setAnimate(smooth && !prefersReducedMotion());
151
166
  setView(next);
152
167
  }, []);
153
168
  const ensureVisible = useCallback((id, smooth) => {
@@ -165,8 +180,10 @@ function LayeredRelationshipGraph({
165
180
  let nextY = y;
166
181
  if (left < FOCUS_MARGIN) nextX += FOCUS_MARGIN - left;
167
182
  else if (right > width - FOCUS_MARGIN) nextX -= right - (width - FOCUS_MARGIN);
183
+ const footer = footerRef.current;
184
+ const bottomMargin = footer ? Math.max(FOCUS_MARGIN, heightPx - footer.offsetTop + 8) : FOCUS_MARGIN;
168
185
  if (top < FOCUS_MARGIN) nextY += FOCUS_MARGIN - top;
169
- else if (bottom > heightPx - FOCUS_MARGIN) nextY -= bottom - (heightPx - FOCUS_MARGIN);
186
+ else if (bottom > heightPx - bottomMargin) nextY -= bottom - (heightPx - bottomMargin);
170
187
  if (nextX !== x || nextY !== y) moveView({ x: nextX, y: nextY, zoom }, smooth);
171
188
  }, [moveView]);
172
189
  const focusItem = useCallback((id) => {
@@ -197,6 +214,18 @@ function LayeredRelationshipGraph({
197
214
  ensureVisible(controlledTarget, true);
198
215
  });
199
216
  }, [controlledKey, controlledTarget, controlledPresent, ensureVisible]);
217
+ const revealTarget = revealId !== void 0 ? layout.itemOf[revealId] ?? revealId : void 0;
218
+ const revealReady = revealTarget !== void 0 && itemById.has(revealTarget) && size.width > 0;
219
+ const revealedKey = useRef(void 0);
220
+ useEffect(() => {
221
+ if (!revealReady || revealTarget === void 0 || initialisedFor.current === void 0) return;
222
+ if (revealedKey.current === revealTarget) return;
223
+ revealedKey.current = revealTarget;
224
+ requestAnimationFrame(() => ensureVisible(revealTarget, true));
225
+ }, [revealReady, revealTarget, ensureVisible]);
226
+ useEffect(() => {
227
+ if (revealId === void 0) revealedKey.current = void 0;
228
+ }, [revealId]);
200
229
  useEffect(() => {
201
230
  const element = viewportRef.current;
202
231
  if (!element) return;
@@ -331,18 +360,240 @@ function LayeredRelationshipGraph({
331
360
  if (nodeAriaLabel) return [nodeAriaLabel(node), item.inCycle ? labels.cycle : void 0, conflict].filter(Boolean).join(", ");
332
361
  return [node.label, node.type, node.description, labels.relationships(item.degree), item.inCycle ? labels.cycle : void 0, conflict].filter(Boolean).join(", ");
333
362
  };
363
+ const nodeLabelById = useMemo(() => new Map(bounded.nodes.map((node) => [node.id, node.label])), [bounded.nodes]);
364
+ const relationsOf = useMemo(() => {
365
+ const map = /* @__PURE__ */ new Map();
366
+ const add = (id, text) => {
367
+ const list = map.get(id);
368
+ if (list) list.push(text);
369
+ else map.set(id, [text]);
370
+ };
371
+ for (const edge of bounded.edges) {
372
+ if (!nodeLabelById.has(edge.source) || !nodeLabelById.has(edge.target) || edge.source === edge.target) continue;
373
+ const relation = edge.label ?? edge.type ?? labels.relationship;
374
+ const note = edge.description ? ` (${edge.description})` : "";
375
+ add(edge.source, `${labels.relationTo(relation, nodeLabelById.get(edge.target))}${note}`);
376
+ add(edge.target, `${labels.relationFrom(relation, nodeLabelById.get(edge.source))}${note}`);
377
+ }
378
+ const described = /* @__PURE__ */ new Map();
379
+ for (const [id, list] of map) {
380
+ const hidden = list.length - DESCRIBED_RELATIONS;
381
+ described.set(id, hidden > 0 ? `${list.slice(0, DESCRIBED_RELATIONS).join("; ")}; ${labels.moreRelations(hidden, showList)}` : list.join("; "));
382
+ }
383
+ return described;
384
+ }, [bounded.edges, nodeLabelById, labels, showList]);
385
+ const showRoot = markRoot ?? rootId !== void 0;
334
386
  const showLabel = (edge) => {
335
387
  if (edgeLabels === "never" || edge.label === void 0) return false;
336
388
  if (edgeLabels === "always") return true;
337
- return edge.autoLabel || activeIds.has(edge.source) || activeIds.has(edge.target) || focusedId === edge.source || focusedId === edge.target;
389
+ if (edge.columnLabel) return false;
390
+ return edge.autoLabel || activeIds.has(edge.source) || activeIds.has(edge.target) || focusWithinId === edge.source || focusWithinId === edge.target;
338
391
  };
339
392
  const viewportStyle = height !== void 0 ? { "--uix-relationship-graph-height": height } : {};
393
+ const zoomStep = Math.min(1, Math.max(0.05, Math.floor(view.zoom * 20) / 20));
340
394
  const stageStyle = {
341
395
  width: layout.width,
342
396
  height: layout.height,
343
397
  transform: `translate(${view.x}px, ${view.y}px) scale(${view.zoom})`
344
398
  };
345
399
  const zoomPercent = Math.round(view.zoom * 100);
400
+ const labelPlacement = useMemo(() => {
401
+ const shown = layout.edges.filter(showLabel);
402
+ const count = /* @__PURE__ */ new Map();
403
+ for (const edge of shown) count.set(edge.label ?? "", (count.get(edge.label ?? "") ?? 0) + 1);
404
+ const scales = /* @__PURE__ */ new Map();
405
+ const boxes = [];
406
+ for (const edge of shown) {
407
+ const lines = edge.kind === "cycle" ? [...edge.labelLines, labels.cycle] : edge.labelLines;
408
+ const size2 = edgeLabelSize(lines);
409
+ const scale = Math.max(1, Math.min(1 / zoomStep, edge.labelRoom / size2.width));
410
+ if (edgeLabels !== "always" && LABEL_FONT_PX * scale * zoomStep < MIN_LABEL_PX - 0.01) continue;
411
+ scales.set(edge.id, scale);
412
+ const priority = (activeIds.has(edge.source) || activeIds.has(edge.target) ? 4 : 0) + (edge.tone || edge.emphasis ? 2 : 0) + (count.get(edge.label ?? "") === 1 ? 1 : 0);
413
+ boxes.push({ id: edge.id, x: edge.labelX, y: edge.labelY, width: size2.width * scale, height: size2.height * scale, priority });
414
+ }
415
+ const placed = separateEdgeLabels(boxes, { maxShift: 48 / zoomStep, obstacles: layout.items });
416
+ return new Map([...placed].map(([id, place]) => [id, { ...place, scale: scales.get(id) ?? 1 }]));
417
+ }, [layout, edgeLabels, activeIds, focusWithinId, labels, zoomStep]);
418
+ const live = useRef({ activate, onItemKeyDown, onFocusChange, toggleCluster, onSelect });
419
+ live.current = { activate, onItemKeyDown, onFocusChange, toggleCluster, onSelect };
420
+ const edgeLayer = useMemo(() => {
421
+ const ordered = layout.edges.map((edge) => ({ edge, active: activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id)) })).sort((a, b) => Number(a.active) - Number(b.active));
422
+ const dimmed = (edge) => dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0;
423
+ return /* @__PURE__ */ jsxs("svg", { ref: edgesRef, className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: [
424
+ ordered.map(({ edge, active }) => {
425
+ const angle = edge.arrowAngle * 180 / Math.PI;
426
+ return /* @__PURE__ */ jsxs(
427
+ "g",
428
+ {
429
+ className: "uix-relationship-graph__link",
430
+ "data-edge": edge.id,
431
+ "data-kind": edge.kind,
432
+ "data-bus": edge.bus || void 0,
433
+ "data-active": active || void 0,
434
+ "data-emphasis": edge.emphasis || void 0,
435
+ "data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
436
+ "data-dimmed": dimmed(edge),
437
+ "data-variant": edge.variant === "dashed" ? "dashed" : void 0,
438
+ "data-tone": edge.tone,
439
+ children: [
440
+ /* @__PURE__ */ jsx("path", { d: edge.path }),
441
+ edge.arrow !== "none" && /* @__PURE__ */ jsx("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` })
442
+ ]
443
+ },
444
+ edge.id
445
+ );
446
+ }),
447
+ /* @__PURE__ */ jsx("g", { className: "uix-relationship-graph__edge-labels", children: ordered.map(({ edge, active }) => {
448
+ const placed = labelPlacement.get(edge.id);
449
+ if (!placed || placed.hidden) return null;
450
+ const lines = edge.kind === "cycle" ? [...edge.labelLines, labels.cycle] : edge.labelLines;
451
+ const chip = edgeLabelSize(lines);
452
+ return /* @__PURE__ */ jsxs(
453
+ "g",
454
+ {
455
+ className: "uix-relationship-graph__edge-label",
456
+ "data-edge": edge.id,
457
+ "data-active": active || void 0,
458
+ "data-dimmed": dimmed(edge),
459
+ "data-tone": edge.tone,
460
+ "data-moved": placed.y !== edge.labelY || void 0,
461
+ style: placed.scale !== 1 ? { "--uix-graph-label-scale": placed.scale } : void 0,
462
+ children: [
463
+ /* @__PURE__ */ jsx("rect", { x: placed.x - chip.width / 2, y: placed.y - chip.height / 2, width: chip.width, height: chip.height, rx: 4 }),
464
+ /* @__PURE__ */ jsx("text", { x: placed.x, y: placed.y, textAnchor: "middle", dominantBaseline: "central", children: lines.map((line, index) => /* @__PURE__ */ jsx("tspan", { x: placed.x, dy: index === 0 ? `${-(lines.length - 1) * 0.6}em` : "1.2em", children: line }, index)) })
465
+ ]
466
+ },
467
+ edge.id
468
+ );
469
+ }) })
470
+ ] });
471
+ }, [layout, activeIds, highlightedEdgeIds, conflictedEdgeIds, dimmedNodeIds, labelPlacement, labels]);
472
+ useIsomorphicLayoutEffect(() => {
473
+ const svg = edgesRef.current;
474
+ if (!svg) return;
475
+ for (const group of Array.from(svg.querySelectorAll(".uix-relationship-graph__edge-label"))) {
476
+ const text = group.querySelector("text");
477
+ const rect = group.querySelector("rect");
478
+ if (!text || !rect || typeof text.getBBox !== "function") continue;
479
+ let box;
480
+ try {
481
+ box = text.getBBox();
482
+ } catch {
483
+ continue;
484
+ }
485
+ if (box.width === 0) continue;
486
+ rect.setAttribute("x", String(box.x - LABEL_CHIP_PAD_X));
487
+ rect.setAttribute("y", String(box.y - LABEL_CHIP_PAD_Y));
488
+ rect.setAttribute("width", String(box.width + 2 * LABEL_CHIP_PAD_X));
489
+ rect.setAttribute("height", String(box.height + 2 * LABEL_CHIP_PAD_Y));
490
+ }
491
+ }, [edgeLayer]);
492
+ const itemLayer = useMemo(() => /* @__PURE__ */ jsxs(Fragment, { children: [
493
+ layout.columns.map((column) => /* @__PURE__ */ jsxs(
494
+ "div",
495
+ {
496
+ className: "uix-relationship-graph__column",
497
+ "aria-hidden": "true",
498
+ style: { left: column.x, width: layout.nodeWidth + 64 },
499
+ children: [
500
+ labels.column(column.depth, column.count),
501
+ column.edgeLabel !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
502
+ " \xB7 ",
503
+ column.edgeLabel
504
+ ] })
505
+ ]
506
+ },
507
+ column.depth
508
+ )),
509
+ /* @__PURE__ */ 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, itemIndex) => {
510
+ const selected = item.id === selectedItemId;
511
+ const relations = item.node ? relationsOf.get(item.node.id) : void 0;
512
+ const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
513
+ const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
514
+ /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
515
+ /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
516
+ ] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
517
+ /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
518
+ (item.node.type || item.node.description) && /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
519
+ ] });
520
+ return /* @__PURE__ */ jsxs(
521
+ "button",
522
+ {
523
+ ref: (element) => {
524
+ if (element) itemRefs.current.set(item.id, element);
525
+ else itemRefs.current.delete(item.id);
526
+ },
527
+ type: "button",
528
+ className: "uix-relationship-graph__item",
529
+ "data-kind": item.kind,
530
+ "data-node-id": item.id,
531
+ "data-selected": selected || void 0,
532
+ "data-dimmed": dimmed || void 0,
533
+ "data-highlighted": item.node && highlightedNodeIds.has(item.node.id) || void 0,
534
+ "data-conflicted": item.node && conflictedNodeIds.has(item.node.id) || void 0,
535
+ "data-root": showRoot && item.id === rootItemId || void 0,
536
+ "data-tone": item.node?.tone,
537
+ "data-flag": item.inCycle || void 0,
538
+ style: { left: item.x, top: item.y, width: item.width, height: item.height },
539
+ tabIndex: item.id === focusedId ? 0 : -1,
540
+ "aria-label": labelFor(item),
541
+ "aria-describedby": relations ? `${describeId}-${itemIndex}` : void 0,
542
+ ...item.cluster ? { "aria-expanded": false } : { "aria-pressed": selected },
543
+ onClick: () => live.current.activate(item),
544
+ onKeyDown: (event) => live.current.onItemKeyDown(event, item),
545
+ onFocus: () => {
546
+ setFocusWithinId(item.id);
547
+ if (item.id === focusedId) return;
548
+ setLocalFocus(item.id);
549
+ live.current.onFocusChange?.(item.id);
550
+ },
551
+ onBlur: () => setFocusWithinId((current) => current === item.id ? void 0 : current),
552
+ onPointerEnter: () => setHoverId(item.id),
553
+ onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
554
+ children: [
555
+ body,
556
+ item.inCycle && /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
557
+ ]
558
+ },
559
+ item.id
560
+ );
561
+ }) }),
562
+ /* @__PURE__ */ jsx("div", { hidden: true, children: layout.items.map((item, itemIndex) => {
563
+ const relations = item.node ? relationsOf.get(item.node.id) : void 0;
564
+ return relations ? /* @__PURE__ */ jsx("span", { id: `${describeId}-${itemIndex}`, children: relations }, item.id) : null;
565
+ }) }),
566
+ layout.items.filter((item) => item.expandedGroup).map((item) => {
567
+ const group = item.expandedGroup;
568
+ return /* @__PURE__ */ jsx(
569
+ "button",
570
+ {
571
+ type: "button",
572
+ className: "uix-relationship-graph__collapse",
573
+ "aria-expanded": "true",
574
+ style: { left: item.x, top: item.y - 26, width: item.width },
575
+ onClick: () => live.current.toggleCluster(group.id, group.id),
576
+ children: labels.collapseCluster(group.members.length, group.type)
577
+ },
578
+ `collapse:${group.id}`
579
+ );
580
+ })
581
+ ] }), [layout, labels, selectedItemId, focusedId, relationsOf, dimmedNodeIds, highlightedNodeIds, conflictedNodeIds, showRoot, rootItemId, describeId, hintId, bounded, renderNode, renderCluster, nodeAriaLabel]);
582
+ const listLayer = useMemo(() => showList && /* @__PURE__ */ jsx(
583
+ EquivalentRelationshipList,
584
+ {
585
+ nodes: bounded.nodes,
586
+ edges: bounded.edges,
587
+ selectedId,
588
+ labels,
589
+ onSelect: (id) => {
590
+ const node = bounded.nodes.find((candidate) => candidate.id === id);
591
+ if (node) live.current.onSelect?.(node);
592
+ },
593
+ onExpandNeighbors,
594
+ onOpenDetails
595
+ }
596
+ ), [showList, bounded, selectedId, labels, onExpandNeighbors, onOpenDetails]);
346
597
  const control = (label, icon, onClick, { disabled = false, keys, ref } = {}) => /* @__PURE__ */ jsx(Tooltip, { label, placement: "top", ...keys ? { shortcut: keys } : {}, children: /* @__PURE__ */ jsx("button", { ref, type: "button", className: "uix-relationship-graph__control", "aria-label": label, onClick, disabled, children: icon }) });
347
598
  return /* @__PURE__ */ jsxs(
348
599
  "section",
@@ -381,6 +632,7 @@ function LayeredRelationshipGraph({
381
632
  onPointerMove,
382
633
  onPointerUp: onPointerEnd,
383
634
  onPointerCancel: onPointerEnd,
635
+ onDragStart: (event) => event.preventDefault(),
384
636
  ...compact ? {
385
637
  tabIndex: 0,
386
638
  role: "group",
@@ -390,103 +642,12 @@ function LayeredRelationshipGraph({
390
642
  } : {},
391
643
  children: [
392
644
  /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__stage", style: stageStyle, "data-animate": animate || void 0, onTransitionEnd: () => setAnimate(false), children: [
393
- /* @__PURE__ */ jsx("svg", { className: "uix-relationship-graph__edges", width: layout.width, height: layout.height, "aria-hidden": "true", focusable: "false", children: layout.edges.map((edge) => {
394
- const active = activeIds.has(edge.source) || activeIds.has(edge.target) || edge.edgeIds.some((id) => highlightedEdgeIds.has(id));
395
- const angle = edge.arrowAngle * 180 / Math.PI;
396
- return /* @__PURE__ */ jsxs(
397
- "g",
398
- {
399
- className: "uix-relationship-graph__link",
400
- "data-kind": edge.kind,
401
- "data-active": active || void 0,
402
- "data-emphasis": edge.emphasis || void 0,
403
- "data-conflicted": edge.edgeIds.some((id) => conflictedEdgeIds.has(id)) || void 0,
404
- "data-dimmed": dimmedNodeIds.has(edge.source) && dimmedNodeIds.has(edge.target) || void 0,
405
- children: [
406
- /* @__PURE__ */ jsx("path", { d: edge.path }),
407
- edge.arrow !== "none" && /* @__PURE__ */ jsx("polygon", { points: arrowPoints, transform: `translate(${edge.arrowX} ${edge.arrowY}) rotate(${angle})` }),
408
- showLabel(edge) && /* @__PURE__ */ 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__ */ jsx("tspan", { x: edge.labelX, dy: index === 0 ? `${-(lines.length - 1) * 0.55}em` : "1.1em", children: line }, index)) })
409
- ]
410
- },
411
- edge.id
412
- );
413
- }) }),
414
- layout.columns.map((column) => /* @__PURE__ */ jsx(
415
- "div",
416
- {
417
- className: "uix-relationship-graph__column",
418
- "aria-hidden": "true",
419
- style: { left: column.x, width: layout.nodeWidth },
420
- children: labels.column(column.depth, column.count)
421
- },
422
- column.depth
423
- )),
424
- /* @__PURE__ */ 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) => {
425
- const selected = item.id === selectedItemId;
426
- const dimmed = item.node ? dimmedNodeIds.has(item.node.id) : item.cluster.members.every((member) => dimmedNodeIds.has(member.id));
427
- const body = item.cluster ? renderCluster?.(item.cluster) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
428
- /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-label", children: labels.cluster(item.cluster.members.length, item.cluster.type, item.cluster.edgeLabel) }),
429
- /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-meta", children: labels.expandCluster })
430
- ] }) : renderNode?.(item.node, { selected, dimmed }) ?? /* @__PURE__ */ jsxs(Fragment, { children: [
431
- /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-label", children: item.node.label }),
432
- (item.node.type || item.node.description) && /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-meta", children: [item.node.type, item.node.description].filter(Boolean).join(" \xB7 ") })
433
- ] });
434
- return /* @__PURE__ */ jsxs(
435
- "button",
436
- {
437
- ref: (element) => {
438
- if (element) itemRefs.current.set(item.id, element);
439
- else itemRefs.current.delete(item.id);
440
- },
441
- type: "button",
442
- className: "uix-relationship-graph__item",
443
- "data-kind": item.kind,
444
- "data-node-id": item.id,
445
- "data-selected": selected || void 0,
446
- "data-dimmed": dimmed || void 0,
447
- "data-highlighted": item.node && highlightedNodeIds.has(item.node.id) || void 0,
448
- "data-conflicted": item.node && conflictedNodeIds.has(item.node.id) || void 0,
449
- "data-root": item.id === rootItemId || void 0,
450
- style: { left: item.x, top: item.y, width: item.width, height: item.height },
451
- tabIndex: item.id === focusedId ? 0 : -1,
452
- "aria-label": labelFor(item),
453
- ...item.cluster ? { "aria-expanded": false } : { "aria-pressed": selected },
454
- onClick: () => activate(item),
455
- onKeyDown: (event) => onItemKeyDown(event, item),
456
- onFocus: () => {
457
- if (item.id === focusedId) return;
458
- setLocalFocus(item.id);
459
- onFocusChange?.(item.id);
460
- },
461
- onPointerEnter: () => setHoverId(item.id),
462
- onPointerLeave: () => setHoverId((current) => current === item.id ? void 0 : current),
463
- children: [
464
- body,
465
- item.inCycle && /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__item-flag", "aria-hidden": "true", children: labels.cycle })
466
- ]
467
- },
468
- item.id
469
- );
470
- }) }),
471
- layout.items.filter((item) => item.expandedGroup).map((item) => {
472
- const group = item.expandedGroup;
473
- return /* @__PURE__ */ jsx(
474
- "button",
475
- {
476
- type: "button",
477
- className: "uix-relationship-graph__collapse",
478
- "aria-expanded": "true",
479
- style: { left: item.x, top: item.y - 26, width: item.width },
480
- onClick: () => toggleCluster(group.id, group.id),
481
- children: labels.collapseCluster(group.members.length, group.type)
482
- },
483
- `collapse:${group.id}`
484
- );
485
- })
645
+ edgeLayer,
646
+ itemLayer
486
647
  ] }),
487
648
  compact && /* @__PURE__ */ jsxs(Fragment, { children: [
488
649
  wheelHint && /* @__PURE__ */ jsx("p", { className: "uix-relationship-graph__toast", role: "status", children: labels.navigationHint(modifier) }),
489
- /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__footer", children: [
650
+ /* @__PURE__ */ jsxs("div", { ref: footerRef, className: "uix-relationship-graph__footer", children: [
490
651
  /* @__PURE__ */ jsx("p", { className: "uix-relationship-graph__hint", "aria-hidden": "true", children: labels.navigationHint(modifier) }),
491
652
  /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__controls", role: "group", "aria-label": labels.controls, children: [
492
653
  /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__zoom-level", "aria-live": "polite", children: labels.zoomLevel(zoomPercent) }),
@@ -508,22 +669,11 @@ function LayeredRelationshipGraph({
508
669
  ]
509
670
  }
510
671
  ),
511
- legend.length > 0 && /* @__PURE__ */ jsx("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ jsx("li", { "data-type": entry.id, children: entry.label }, entry.id)) }),
512
- showList && /* @__PURE__ */ jsx(
513
- EquivalentRelationshipList,
514
- {
515
- nodes: bounded.nodes,
516
- edges: bounded.edges,
517
- selectedId,
518
- labels,
519
- onSelect: (id) => {
520
- const node = bounded.nodes.find((candidate) => candidate.id === id);
521
- if (node) onSelect?.(node);
522
- },
523
- onExpandNeighbors,
524
- onOpenDetails
525
- }
526
- )
672
+ legend.length > 0 && /* @__PURE__ */ jsx("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((entry) => /* @__PURE__ */ jsxs("li", { "data-type": entry.id, "data-tone": entry.tone, "data-shape": entry.shape, "data-variant": entry.variant, children: [
673
+ /* @__PURE__ */ jsx("span", { className: "uix-relationship-graph__legend-mark", "aria-hidden": "true" }),
674
+ entry.label
675
+ ] }, entry.id)) }),
676
+ listLayer
527
677
  ]
528
678
  }
529
679
  );
@@ -1,5 +1,7 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { useId, useState } from "react";
2
3
  import { relationshipNeighbors } from "../relationship-graph-model.js";
4
+ const LISTED_NEIGHBOURS = 8;
3
5
  function EquivalentRelationshipList({
4
6
  nodes,
5
7
  edges,
@@ -9,16 +11,41 @@ function EquivalentRelationshipList({
9
11
  onExpandNeighbors,
10
12
  onOpenDetails
11
13
  }) {
14
+ const id = useId();
15
+ const [open, setOpen] = useState(() => /* @__PURE__ */ new Set());
12
16
  const labelById = new Map(nodes.map((node) => [node.id, node.label]));
13
17
  return /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": labels.list, children: [
14
18
  /* @__PURE__ */ jsx("h3", { children: labels.listHeading }),
15
- /* @__PURE__ */ jsx("ul", { children: nodes.map((node) => {
16
- const neighbors = relationshipNeighbors(node.id, edges).map((id) => labelById.get(id) ?? id);
19
+ /* @__PURE__ */ jsx("ul", { children: nodes.map((node, index) => {
20
+ const neighbors = relationshipNeighbors(node.id, edges).map((neighbor) => labelById.get(neighbor) ?? neighbor);
21
+ const all = open.has(node.id);
22
+ const shown = all ? neighbors : neighbors.slice(0, LISTED_NEIGHBOURS);
23
+ const headingId = `${id}-${index}`;
17
24
  return /* @__PURE__ */ jsxs("li", { "data-selected": selectedId === node.id || void 0, children: [
18
- /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
19
- /* @__PURE__ */ jsx("strong", { children: node.label }),
20
- node.type && /* @__PURE__ */ jsx("span", { children: node.type }),
21
- /* @__PURE__ */ jsx("span", { children: neighbors.length ? labels.connectedTo(neighbors.join(", ")) : labels.noConnections })
25
+ /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__list-main", children: [
26
+ /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => onSelect(node.id), "aria-pressed": selectedId === node.id, children: [
27
+ /* @__PURE__ */ jsx("strong", { children: node.label }),
28
+ node.type && /* @__PURE__ */ jsx("span", { children: node.type })
29
+ ] }),
30
+ neighbors.length === 0 ? /* @__PURE__ */ jsx("p", { className: "uix-relationship-graph__list-none", children: labels.noConnections }) : /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__list-relations", children: [
31
+ /* @__PURE__ */ jsx("span", { id: headingId, children: labels.connectedHeading }),
32
+ /* @__PURE__ */ jsx("ul", { "aria-labelledby": headingId, children: shown.map((name, at) => /* @__PURE__ */ jsx("li", { children: name }, at)) }),
33
+ neighbors.length > LISTED_NEIGHBOURS && /* @__PURE__ */ jsx(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ className: "uix-btn uix-btn--link uix-relationship-graph__list-more",
38
+ "aria-expanded": all,
39
+ onClick: () => setOpen((previous) => {
40
+ const next = new Set(previous);
41
+ if (all) next.delete(node.id);
42
+ else next.add(node.id);
43
+ return next;
44
+ }),
45
+ children: all ? labels.showFewerRelations : labels.showAllRelations(neighbors.length)
46
+ }
47
+ )
48
+ ] })
22
49
  ] }),
23
50
  /* @__PURE__ */ jsxs("span", { className: "uix-relationship-graph__list-actions", children: [
24
51
  onExpandNeighbors && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onExpandNeighbors(node), children: labels.expandNeighbors }),
@@ -13,6 +13,7 @@ import {
13
13
  } from "../rule-builder-model.js";
14
14
  import { fillLabel } from "../fill-label.js";
15
15
  import { useUixLabels } from "../labels-context.js";
16
+ import { Select } from "./Select.js";
16
17
  const DEFAULT_RULE_BUILDER_LABELS = {
17
18
  region: "Rule builder",
18
19
  summary: "Rule summary",
@@ -94,10 +95,16 @@ function RuleGroupEditor({ group, depth, root, fields, operators, maxDepth, disa
94
95
  combinator === "or" ? labels.any : labels.all
95
96
  ] }) : /* @__PURE__ */ jsxs("label", { children: [
96
97
  labels.match,
97
- /* @__PURE__ */ jsxs("select", { className: "uix-select uix-select--sm", value: group.combinator, disabled, onChange: (event) => updateNode(group.id, (node) => ({ ...node, combinator: event.currentTarget.value })), children: [
98
- /* @__PURE__ */ jsx("option", { value: "and", children: labels.all }),
99
- /* @__PURE__ */ jsx("option", { value: "or", children: labels.any })
100
- ] })
98
+ /* @__PURE__ */ jsx(
99
+ Select,
100
+ {
101
+ size: "sm",
102
+ value: group.combinator,
103
+ disabled,
104
+ options: [{ value: "and", label: labels.all }, { value: "or", label: labels.any }],
105
+ onValueChange: (next) => updateNode(group.id, (node) => ({ ...node, combinator: next }))
106
+ }
107
+ )
101
108
  ] }))
102
109
  ] }),
103
110
  /* @__PURE__ */ jsx("div", { className: "uix-rule-builder__rows", children: group.conditions.map((node, index) => isRuleGroup(node) ? /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__nested", children: [
@@ -134,11 +141,27 @@ function ConditionRow({ labels, condition, fields, operators, disabled, onChange
134
141
  return /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__condition", children: [
135
142
  /* @__PURE__ */ jsxs("label", { children: [
136
143
  /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: labels.field }),
137
- /* @__PURE__ */ jsx("select", { className: "uix-select", value: condition.field, onChange: (event) => setField(event.currentTarget.value), disabled, children: fields.map((item) => /* @__PURE__ */ jsx("option", { value: item.id, children: item.label }, item.id)) })
144
+ /* @__PURE__ */ jsx(
145
+ Select,
146
+ {
147
+ value: condition.field,
148
+ disabled,
149
+ options: fields.map((item) => ({ value: item.id, label: item.label })),
150
+ onValueChange: (next) => setField(next)
151
+ }
152
+ )
138
153
  ] }),
139
154
  /* @__PURE__ */ jsxs("label", { children: [
140
155
  /* @__PURE__ */ jsx("span", { className: "uix-visually-hidden", children: labels.operator }),
141
- /* @__PURE__ */ jsx("select", { className: "uix-select", value: condition.operator, onChange: (event) => onChange({ ...condition, operator: event.currentTarget.value }), disabled, children: availableOperators.map((item) => /* @__PURE__ */ jsx("option", { value: item.id, children: item.label }, item.id)) })
156
+ /* @__PURE__ */ jsx(
157
+ Select,
158
+ {
159
+ value: condition.operator,
160
+ disabled,
161
+ options: availableOperators.map((item) => ({ value: item.id, label: item.label })),
162
+ onValueChange: (next) => onChange({ ...condition, operator: next })
163
+ }
164
+ )
142
165
  ] }),
143
166
  operator?.requiresValue !== false && /* @__PURE__ */ jsx("div", { className: "uix-rule-builder__value", children: field?.renderValueEditor?.({ condition, onChange: (value) => onChange({ ...condition, value }), disabled }) ?? /* @__PURE__ */ 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": fillLabel(labels.valueFor, { field: field?.label ?? labels.itemCondition }) }) }),
144
167
  controls
@@ -243,7 +266,16 @@ function RuleBuilder({
243
266
  value.then.map((action, index) => {
244
267
  const definition = actions.find((item) => item.id === action.type);
245
268
  return /* @__PURE__ */ jsxs("div", { className: "uix-rule-builder__action", children: [
246
- /* @__PURE__ */ jsx("select", { className: "uix-select", value: action.type, disabled, onChange: (event) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: event.currentTarget.value } : item)), "aria-label": labels.actionType, children: actions.map((item) => /* @__PURE__ */ jsx("option", { value: item.id, children: item.label }, item.id)) }),
269
+ /* @__PURE__ */ jsx(
270
+ Select,
271
+ {
272
+ value: action.type,
273
+ disabled,
274
+ "aria-label": labels.actionType,
275
+ options: actions.map((item) => ({ value: item.id, label: item.label })),
276
+ onValueChange: (next) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, type: next } : item))
277
+ }
278
+ ),
247
279
  definition?.renderParameters?.(action, (parameters) => updateActions(value.then.map((item) => item.id === action.id ? { ...item, parameters } : item)), disabled),
248
280
  !disabled && /* @__PURE__ */ jsx(
249
281
  RowControls,
@@ -1,8 +1,10 @@
1
1
  import * as react from 'react';
2
2
  import { ReactNode } from 'react';
3
- import { S as SchedulingAgendaGroup, e as SchedulingCalendarLabels, i as SchedulingDatePart, d as SchedulingCalendarEntry, l as SchedulingMarker, f as SchedulingCalendarOverlay } from '../SchedulingCalendar-B6TakO2h.js';
3
+ import { S as SchedulingAgendaGroup, e as SchedulingCalendarLabels, i as SchedulingDatePart, d as SchedulingCalendarEntry, l as SchedulingMarker, f as SchedulingCalendarOverlay } from '../SchedulingCalendar-WWyFL3Eo.js';
4
4
  import '../calendar-model.js';
5
5
  import '../scheduling-calendar-model.js';
6
+ import './SchedulingResourceDay.js';
7
+ import '../scheduling-resource-model.js';
6
8
 
7
9
  /** The height of one row of the virtualised agenda, in px. The stylesheet uses the same number. */
8
10
  declare const AGENDA_VIRTUAL_ROW = 44;