@tensor_1/react 2.16.0 → 2.18.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 (75) hide show
  1. package/README.md +29 -0
  2. package/dist/chart-preset.cjs +15 -3
  3. package/dist/chart.cjs +15 -3
  4. package/dist/components/Alert.js +15 -7
  5. package/dist/components/AppShell.d.ts +3 -1
  6. package/dist/components/AppShell.js +3 -1
  7. package/dist/components/Avatar.js +2 -1
  8. package/dist/components/Button.js +32 -16
  9. package/dist/components/Card.d.ts +3 -1
  10. package/dist/components/Card.js +2 -2
  11. package/dist/components/ChartCore.js +15 -3
  12. package/dist/components/CommandPalette.d.ts +4 -2
  13. package/dist/components/CommandPalette.js +66 -13
  14. package/dist/components/Comments.d.ts +5 -1
  15. package/dist/components/Comments.js +1 -1
  16. package/dist/components/Composer.d.ts +8 -1
  17. package/dist/components/Composer.js +7 -2
  18. package/dist/components/DetailLayout.js +1 -1
  19. package/dist/components/Drawer.d.ts +3 -4
  20. package/dist/components/Drawer.js +6 -4
  21. package/dist/components/Field.js +6 -3
  22. package/dist/components/Inbox.d.ts +13 -3
  23. package/dist/components/Inbox.js +62 -3
  24. package/dist/components/Input.d.ts +13 -2
  25. package/dist/components/Input.js +20 -5
  26. package/dist/components/Kanban.d.ts +15 -3
  27. package/dist/components/Kanban.js +42 -10
  28. package/dist/components/Meter.d.ts +3 -1
  29. package/dist/components/Meter.js +9 -1
  30. package/dist/components/Modal.d.ts +4 -5
  31. package/dist/components/Modal.js +4 -4
  32. package/dist/components/NavFavourites.js +11 -0
  33. package/dist/components/PageHeader.d.ts +3 -1
  34. package/dist/components/PageHeader.js +2 -2
  35. package/dist/components/Peek.d.ts +3 -4
  36. package/dist/components/Peek.js +9 -6
  37. package/dist/components/Progress.d.ts +3 -1
  38. package/dist/components/Progress.js +5 -3
  39. package/dist/components/Radio.d.ts +3 -1
  40. package/dist/components/Radio.js +6 -2
  41. package/dist/components/RelationshipGraph.d.ts +81 -3
  42. package/dist/components/RelationshipGraph.js +81 -57
  43. package/dist/components/RelationshipGraphLayered.d.ts +8 -0
  44. package/dist/components/RelationshipGraphLayered.js +420 -0
  45. package/dist/components/RelationshipGraphList.d.ts +16 -0
  46. package/dist/components/RelationshipGraphList.js +33 -0
  47. package/dist/components/Spinner.d.ts +3 -1
  48. package/dist/components/Spinner.js +3 -3
  49. package/dist/components/Stat.js +5 -1
  50. package/dist/components/States.d.ts +1 -0
  51. package/dist/components/States.js +7 -1
  52. package/dist/components/Table.d.ts +8 -1
  53. package/dist/components/Table.js +10 -6
  54. package/dist/components/Tabs.d.ts +13 -1
  55. package/dist/components/Tabs.js +79 -4
  56. package/dist/components/Timeline.d.ts +3 -3
  57. package/dist/components/Timeline.js +3 -3
  58. package/dist/components/Toast.js +42 -5
  59. package/dist/components/Tooltip.d.ts +3 -1
  60. package/dist/components/Tooltip.js +44 -5
  61. package/dist/components/Tree.d.ts +2 -0
  62. package/dist/components/Tree.js +26 -4
  63. package/dist/hooks/useDialog.d.ts +1 -1
  64. package/dist/hooks/useDialog.js +17 -2
  65. package/dist/hooks/useTable.d.ts +5 -0
  66. package/dist/hooks/useTable.js +20 -1
  67. package/dist/index.cjs +1791 -446
  68. package/dist/index.d.cts +311 -36
  69. package/dist/index.d.ts +4 -4
  70. package/dist/index.js +10 -3
  71. package/dist/relationship-graph-model.d.ts +112 -1
  72. package/dist/relationship-graph-model.js +420 -1
  73. package/dist/tree-model.d.ts +4 -0
  74. package/dist/tree-model.js +8 -0
  75. package/package.json +1 -1
@@ -1,10 +1,54 @@
1
1
  import * as react from 'react';
2
- import { RelationshipGraphNode, RelationshipGraphEdge } from '../relationship-graph-model.js';
2
+ import { ReactNode } from 'react';
3
+ import { RelationshipGraphNode, RelationshipGraphEdge, RelationshipGraphCluster } from '../relationship-graph-model.js';
3
4
 
4
5
  interface RelationshipGraphLegendItem {
5
6
  id: string;
6
7
  label: string;
7
8
  }
9
+ /** Every visible or announced string. Pass translations; English defaults fill the gaps. */
10
+ interface RelationshipGraphLabels {
11
+ graph: string;
12
+ controls: string;
13
+ list: string;
14
+ listHeading: string;
15
+ legend: string;
16
+ panLeft: string;
17
+ panRight: string;
18
+ panUp: string;
19
+ panDown: string;
20
+ left: string;
21
+ right: string;
22
+ up: string;
23
+ down: string;
24
+ zoomIn: string;
25
+ zoomOut: string;
26
+ fit: string;
27
+ reset: string;
28
+ zoomLevel: (percent: number) => string;
29
+ bounded: (shown: number, omitted: number) => string;
30
+ graphSummary: (nodes: number, edges: number) => string;
31
+ relationship: string;
32
+ conflict: string;
33
+ connectedTo: (names: string) => string;
34
+ noConnections: string;
35
+ expandNeighbors: string;
36
+ openDetails: string;
37
+ /** Layered column header, e.g. "2 hops · 14". */
38
+ column: (depth: number, count: number) => string;
39
+ cluster: (count: number, type: string | undefined, edgeLabel: string | undefined) => string;
40
+ expandCluster: string;
41
+ collapseCluster: (count: number, type: string | undefined) => string;
42
+ cycle: string;
43
+ relationships: (count: number) => string;
44
+ roleDescription: string;
45
+ keyboardHint: string;
46
+ loading: string;
47
+ retry: string;
48
+ emptyTitle: string;
49
+ emptyHint: string;
50
+ }
51
+ declare const DEFAULT_RELATIONSHIP_GRAPH_LABELS: RelationshipGraphLabels;
8
52
  interface RelationshipGraphProps {
9
53
  nodes: RelationshipGraphNode[];
10
54
  edges: RelationshipGraphEdge[];
@@ -12,6 +56,7 @@ interface RelationshipGraphProps {
12
56
  onSelect?: (node: RelationshipGraphNode) => void;
13
57
  onExpandNeighbors?: (node: RelationshipGraphNode) => void;
14
58
  onOpenDetails?: (node: RelationshipGraphNode) => void;
59
+ /** Node budget. Default 40 (radial) or 400 (layered). */
15
60
  maxNodes?: number;
16
61
  density?: 'compact' | 'standard';
17
62
  highlightedNodeIds?: ReadonlySet<string>;
@@ -23,8 +68,41 @@ interface RelationshipGraphProps {
23
68
  error?: string;
24
69
  onRetry?: () => void;
25
70
  className?: string;
71
+ /** `radial` (default) rings around the selection; `layered` reads left to right by distance from `rootId`. */
72
+ layout?: 'radial' | 'layered';
73
+ /** Layered: the column-0 node (default: the first node). */
74
+ rootId?: string;
75
+ labels?: Partial<RelationshipGraphLabels>;
76
+ /** Layered: node body. Whatever it shows must also be in `nodeAriaLabel`. */
77
+ renderNode?: (node: RelationshipGraphNode, state: {
78
+ selected: boolean;
79
+ dimmed: boolean;
80
+ }) => ReactNode;
81
+ /** Layered: full accessible name for a node. */
82
+ nodeAriaLabel?: (node: RelationshipGraphNode) => string;
83
+ /** Layered: cluster body. Whatever it shows must also be in the cluster's accessible name. */
84
+ renderCluster?: (cluster: RelationshipGraphCluster) => ReactNode;
85
+ /** Layered: minimum leaf-sibling group that collapses into a cluster. Default 6; 0 disables. */
86
+ clusterThreshold?: number;
87
+ /** Layered: controlled set of expanded cluster ids. */
88
+ expandedClusterIds?: ReadonlySet<string>;
89
+ onToggleCluster?: (clusterId: string, expanded: boolean) => void;
90
+ /** Layered: nodes drawn muted (state must also be stated in text by the consumer). */
91
+ dimmedNodeIds?: ReadonlySet<string>;
92
+ /** Layered: when edge labels show. `auto` = emphasised edges, small fan-outs, and edges of the active node. */
93
+ edgeLabels?: 'auto' | 'always' | 'never';
94
+ /** Render the built-in equivalent list. Set false ONLY when an equivalent list is rendered in the same region. */
95
+ showList?: boolean;
96
+ /** Layered: CSS length for the viewport height. */
97
+ height?: string;
98
+ /** Layered: controlled roving focus. */
99
+ focusId?: string;
100
+ onFocusChange?: (id: string) => void;
26
101
  }
27
102
  /** Bounded, deterministic SVG relationship view with an equivalent accessible list. */
28
- declare function RelationshipGraph({ nodes, edges, selectedId, onSelect, onExpandNeighbors, onOpenDetails, maxNodes, density, highlightedNodeIds, conflictedNodeIds, highlightedEdgeIds, conflictedEdgeIds, legend, loading, error, onRetry, className, }: RelationshipGraphProps): react.JSX.Element;
103
+ declare function RelationshipGraph(props: RelationshipGraphProps): react.JSX.Element;
104
+ type ResolvedRelationshipGraphProps = Omit<RelationshipGraphProps, 'labels'> & {
105
+ labels: RelationshipGraphLabels;
106
+ };
29
107
 
30
- export { RelationshipGraph, type RelationshipGraphLegendItem, type RelationshipGraphProps };
108
+ export { DEFAULT_RELATIONSHIP_GRAPH_LABELS, RelationshipGraph, type RelationshipGraphLabels, type RelationshipGraphLegendItem, type RelationshipGraphProps, type ResolvedRelationshipGraphProps };
@@ -1,11 +1,70 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useMemo, useRef, useState } from "react";
4
- import { boundRelationshipGraph, layoutRelationshipGraph, relationshipNeighbors, traverseRelationshipNode } from "../relationship-graph-model.js";
4
+ import { boundRelationshipGraph, layoutRelationshipGraph, traverseRelationshipNode } from "../relationship-graph-model.js";
5
5
  import { cx } from "../cx.js";
6
+ import { LayeredRelationshipGraph } from "./RelationshipGraphLayered.js";
7
+ import { EquivalentRelationshipList } from "./RelationshipGraphList.js";
8
+ const DEFAULT_RELATIONSHIP_GRAPH_LABELS = {
9
+ graph: "Relationship graph",
10
+ controls: "Graph view controls",
11
+ list: "Accessible relationship list",
12
+ listHeading: "Relationship list",
13
+ legend: "Relationship types",
14
+ panLeft: "Pan left",
15
+ panRight: "Pan right",
16
+ panUp: "Pan up",
17
+ panDown: "Pan down",
18
+ left: "Left",
19
+ right: "Right",
20
+ up: "Up",
21
+ down: "Down",
22
+ zoomIn: "Zoom in",
23
+ zoomOut: "Zoom out",
24
+ fit: "Fit",
25
+ reset: "Reset view",
26
+ zoomLevel: (percent) => `Zoom ${percent}%`,
27
+ bounded: (shown, omitted) => `Showing ${shown} nodes; ${omitted} outside this bounded neighborhood.`,
28
+ graphSummary: (nodes, edges) => `Graph with ${nodes} nodes and ${edges} relationships`,
29
+ relationship: "Relationship",
30
+ conflict: "conflict",
31
+ connectedTo: (names) => `Connected to ${names}`,
32
+ noConnections: "No visible connections",
33
+ expandNeighbors: "Expand neighbors",
34
+ openDetails: "Open details",
35
+ column: (depth, count) => `${depth === 0 ? "Start" : `${depth} ${depth === 1 ? "hop" : "hops"}`} \xB7 ${count}`,
36
+ cluster: (count, type, edgeLabel) => `${count} \xD7 ${type ?? "items"}${edgeLabel ? ` \xB7 ${edgeLabel}` : ""}`,
37
+ expandCluster: "Show all",
38
+ collapseCluster: (count, type) => `Collapse ${count} ${type ?? "items"}`,
39
+ cycle: "cycle",
40
+ relationships: (count) => `${count} ${count === 1 ? "relationship" : "relationships"}`,
41
+ roleDescription: "relationship map",
42
+ keyboardHint: "Arrow keys move between connected items, Enter selects, Home returns to the start.",
43
+ loading: "Loading relationships\u2026",
44
+ retry: "Try again",
45
+ emptyTitle: "No relationships to display.",
46
+ emptyHint: "Adjust the neighborhood or filters to include a node."
47
+ };
6
48
  const EMPTY_IDS = /* @__PURE__ */ new Set();
7
49
  const EMPTY_LEGEND = [];
8
- function RelationshipGraph({
50
+ function RelationshipGraph(props) {
51
+ const labels = useMemo(() => ({ ...DEFAULT_RELATIONSHIP_GRAPH_LABELS, ...props.labels }), [props.labels]);
52
+ const stateClass = cx("uix-relationship-graph uix-relationship-graph--state", props.className);
53
+ if (props.loading) return /* @__PURE__ */ jsx("div", { className: stateClass, role: "status", children: labels.loading });
54
+ if (props.error) {
55
+ return /* @__PURE__ */ jsxs("div", { className: stateClass, role: "alert", children: [
56
+ /* @__PURE__ */ jsx("p", { children: props.error }),
57
+ props.onRetry && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: props.onRetry, children: labels.retry })
58
+ ] });
59
+ }
60
+ if (props.nodes.length === 0) return /* @__PURE__ */ jsxs("div", { className: stateClass, children: [
61
+ /* @__PURE__ */ jsx("p", { children: labels.emptyTitle }),
62
+ /* @__PURE__ */ jsx("p", { children: labels.emptyHint })
63
+ ] });
64
+ if (props.layout === "layered") return /* @__PURE__ */ jsx(LayeredRelationshipGraph, { ...props, labels });
65
+ return /* @__PURE__ */ jsx(RadialRelationshipGraph, { ...props, labels });
66
+ }
67
+ function RadialRelationshipGraph({
9
68
  nodes,
10
69
  edges,
11
70
  selectedId,
@@ -19,10 +78,9 @@ function RelationshipGraph({
19
78
  highlightedEdgeIds = EMPTY_IDS,
20
79
  conflictedEdgeIds = EMPTY_IDS,
21
80
  legend = EMPTY_LEGEND,
22
- loading,
23
- error,
24
- onRetry,
25
- className
81
+ className,
82
+ labels,
83
+ showList = true
26
84
  }) {
27
85
  const bounded = useMemo(() => boundRelationshipGraph(nodes, edges, maxNodes), [nodes, edges, maxNodes]);
28
86
  const positioned = useMemo(() => layoutRelationshipGraph(bounded.nodes, bounded.edges, selectedId), [bounded, selectedId]);
@@ -53,49 +111,30 @@ function RelationshipGraph({
53
111
  setZoom(1);
54
112
  setPan({ x: 0, y: 0 });
55
113
  };
56
- if (loading) return /* @__PURE__ */ jsx("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), role: "status", children: "Loading relationships\u2026" });
57
- if (error) return /* @__PURE__ */ jsxs("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), role: "alert", children: [
58
- /* @__PURE__ */ jsx("p", { children: error }),
59
- onRetry && /* @__PURE__ */ jsx("button", { type: "button", className: "uix-btn uix-btn--secondary", onClick: onRetry, children: "Try again" })
60
- ] });
61
- if (bounded.nodes.length === 0) return /* @__PURE__ */ jsxs("div", { className: cx("uix-relationship-graph uix-relationship-graph--state", className), children: [
62
- /* @__PURE__ */ jsx("p", { children: "No relationships to display." }),
63
- /* @__PURE__ */ jsx("p", { children: "Adjust the neighborhood or filters to include a node." })
64
- ] });
65
- return /* @__PURE__ */ jsxs("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": "Relationship graph", children: [
66
- /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__toolbar", "aria-label": "Graph view controls", children: [
67
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": "Pan left", children: "Left" }),
68
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": "Pan up", children: "Up" }),
69
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": "Pan down", children: "Down" }),
70
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": "Pan right", children: "Right" }),
71
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": "Zoom in", children: "Zoom in" }),
72
- /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": "Zoom out", children: "Zoom out" }),
73
- /* @__PURE__ */ jsx("button", { type: "button", onClick: reset, children: "Reset view" }),
74
- /* @__PURE__ */ jsxs("span", { "aria-live": "polite", children: [
75
- "Zoom ",
76
- Math.round(zoom * 100),
77
- "%"
78
- ] })
79
- ] }),
80
- bounded.omittedNodeCount > 0 && /* @__PURE__ */ jsxs("p", { className: "uix-relationship-graph__bounded", role: "status", children: [
81
- "Showing ",
82
- bounded.nodes.length,
83
- " nodes; ",
84
- bounded.omittedNodeCount,
85
- " outside this bounded neighborhood."
114
+ return /* @__PURE__ */ jsxs("section", { className: cx("uix-relationship-graph", `uix-relationship-graph--${density}`, className), "aria-label": labels.graph, children: [
115
+ /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__toolbar", "aria-label": labels.controls, children: [
116
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x - 24 })), "aria-label": labels.panLeft, children: labels.left }),
117
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y - 24 })), "aria-label": labels.panUp, children: labels.up }),
118
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, y: value.y + 24 })), "aria-label": labels.panDown, children: labels.down }),
119
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setPan((value) => ({ ...value, x: value.x + 24 })), "aria-label": labels.panRight, children: labels.right }),
120
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setZoom((value) => Math.min(2, Number((value + 0.2).toFixed(1)))), "aria-label": labels.zoomIn, children: labels.zoomIn }),
121
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => setZoom((value) => Math.max(0.5, Number((value - 0.2).toFixed(1)))), "aria-label": labels.zoomOut, children: labels.zoomOut }),
122
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: reset, children: labels.reset }),
123
+ /* @__PURE__ */ jsx("span", { "aria-live": "polite", children: labels.zoomLevel(Math.round(zoom * 100)) })
86
124
  ] }),
87
- /* @__PURE__ */ jsx("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ 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__ */ jsxs("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
125
+ bounded.omittedNodeCount > 0 && /* @__PURE__ */ jsx("p", { className: "uix-relationship-graph__bounded", role: "status", children: labels.bounded(bounded.nodes.length, bounded.omittedNodeCount) }),
126
+ /* @__PURE__ */ jsx("div", { className: "uix-relationship-graph__visual", children: /* @__PURE__ */ jsx("svg", { ref: svgRef, viewBox: "0 0 600 400", role: "group", "aria-label": labels.graphSummary(bounded.nodes.length, bounded.edges.length), children: /* @__PURE__ */ jsxs("g", { transform: `translate(${pan.x} ${pan.y}) scale(${zoom})`, children: [
88
127
  bounded.edges.map((edge) => {
89
128
  const source = positionedById.get(edge.source);
90
129
  const target = positionedById.get(edge.target);
91
- return /* @__PURE__ */ 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__ */ jsx("title", { children: edge.label ?? edge.type ?? "Relationship" }) }, edge.id);
130
+ return /* @__PURE__ */ 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__ */ jsx("title", { children: edge.label ?? edge.type ?? labels.relationship }) }, edge.id);
92
131
  }),
93
132
  positioned.map((node) => /* @__PURE__ */ jsxs(
94
133
  "g",
95
134
  {
96
135
  transform: `translate(${node.x * 6} ${node.y * 4})`,
97
136
  role: "button",
98
- "aria-label": `${node.label}${node.type ? `, ${node.type}` : ""}${conflictedNodeIds.has(node.id) ? ", conflict" : ""}`,
137
+ "aria-label": `${node.label}${node.type ? `, ${node.type}` : ""}${conflictedNodeIds.has(node.id) ? `, ${labels.conflict}` : ""}`,
99
138
  tabIndex: focusedId === node.id ? 0 : -1,
100
139
  "data-node-id": node.id,
101
140
  className: "uix-relationship-graph__node",
@@ -113,26 +152,11 @@ function RelationshipGraph({
113
152
  node.id
114
153
  ))
115
154
  ] }) }) }),
116
- legend.length > 0 && /* @__PURE__ */ jsx("ul", { className: "uix-relationship-graph__legend", "aria-label": "Relationship types", children: legend.map((item) => /* @__PURE__ */ jsx("li", { "data-type": item.id, children: item.label }, item.id)) }),
117
- /* @__PURE__ */ jsxs("div", { className: "uix-relationship-graph__list", role: "region", "aria-label": "Accessible relationship list", children: [
118
- /* @__PURE__ */ jsx("h3", { children: "Relationship list" }),
119
- /* @__PURE__ */ jsx("ul", { children: bounded.nodes.map((node) => {
120
- const neighbors = relationshipNeighbors(node.id, bounded.edges).map((id) => bounded.nodes.find((item) => item.id === id)?.label ?? id);
121
- return /* @__PURE__ */ jsxs("li", { "data-selected": selectedId === node.id || void 0, children: [
122
- /* @__PURE__ */ jsxs("button", { type: "button", onClick: () => select(node.id), "aria-pressed": selectedId === node.id, children: [
123
- /* @__PURE__ */ jsx("strong", { children: node.label }),
124
- node.type && /* @__PURE__ */ jsx("span", { children: node.type }),
125
- /* @__PURE__ */ jsx("span", { children: neighbors.length ? `Connected to ${neighbors.join(", ")}` : "No visible connections" })
126
- ] }),
127
- /* @__PURE__ */ jsxs("span", { className: "uix-relationship-graph__list-actions", children: [
128
- onExpandNeighbors && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onExpandNeighbors(node), children: "Expand neighbors" }),
129
- onOpenDetails && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onOpenDetails(node), children: "Open details" })
130
- ] })
131
- ] }, node.id);
132
- }) })
133
- ] })
155
+ legend.length > 0 && /* @__PURE__ */ jsx("ul", { className: "uix-relationship-graph__legend", "aria-label": labels.legend, children: legend.map((item) => /* @__PURE__ */ jsx("li", { "data-type": item.id, children: item.label }, item.id)) }),
156
+ showList && /* @__PURE__ */ jsx(EquivalentRelationshipList, { nodes: bounded.nodes, edges: bounded.edges, selectedId, labels, onSelect: select, onExpandNeighbors, onOpenDetails })
134
157
  ] });
135
158
  }
136
159
  export {
160
+ DEFAULT_RELATIONSHIP_GRAPH_LABELS,
137
161
  RelationshipGraph
138
162
  };
@@ -0,0 +1,8 @@
1
+ import * as react from 'react';
2
+ import { ResolvedRelationshipGraphProps } from './RelationshipGraph.js';
3
+ import '../relationship-graph-model.js';
4
+
5
+ /** `RelationshipGraph layout="layered"` (ADR-0003). Internal — reached through RelationshipGraph. */
6
+ declare function LayeredRelationshipGraph({ nodes, edges, selectedId, onSelect, onExpandNeighbors, onOpenDetails, maxNodes, density, highlightedNodeIds, conflictedNodeIds, highlightedEdgeIds, conflictedEdgeIds, legend, className, labels, rootId, renderNode, nodeAriaLabel, renderCluster, clusterThreshold, expandedClusterIds, onToggleCluster, dimmedNodeIds, edgeLabels, showList, height, focusId, onFocusChange, }: ResolvedRelationshipGraphProps): react.JSX.Element;
7
+
8
+ export { LayeredRelationshipGraph };