@mp70/react-networks 0.1.0-alpha → 0.1.4-alpha

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # @react-networks/network-diagrams
1
+ # @mp70/react-networks
2
2
 
3
- [![npm version](https://badge.fury.io/js/%40react-networks%2Fnetwork-diagrams.svg)](https://badge.fury.io/js/%40react-networks%2Fnetwork-diagrams)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
3
+ [![npm version](https://badge.fury.io/js/%40mp70%2Freact-networks.svg)](https://badge.fury.io/js/%40mp70%2Freact-networks)
4
+ [![License: AGPL v3](https://img.shields.io/badge/License-AGPLv3-blue.svg)](https://www.gnu.org/licenses/agpl-3.0)
5
5
  [![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)
6
6
 
7
7
  A production-ready React library for creating interactive network diagrams with support for rack management, fiber networks, and power distribution. Built on React Flow with TypeScript support.
@@ -14,7 +14,7 @@ A production-ready React library for creating interactive network diagrams with
14
14
  - **⚡ Power Distribution**: Vertical PDU support with power connections
15
15
  - **👁️ View Switching**: Front/rear view switching for devices and racks
16
16
  - **📐 Rack Alignment**: Align rack bottoms to the same horizontal plane
17
- - **🔗 NetBox Integration**: Built-in support for NetBox data import/export
17
+ - **🔗 Inventory Integration**: Built-in helpers to import/export generic inventory/CMDB data
18
18
  - **🎨 Customizable**: Extensive styling and theming options
19
19
  - **📱 Responsive**: Works on desktop and mobile devices
20
20
  - **🔧 TypeScript**: Full TypeScript support with comprehensive type definitions
@@ -24,19 +24,19 @@ A production-ready React library for creating interactive network diagrams with
24
24
  ### Installation
25
25
 
26
26
  ```bash
27
- npm install @react-networks/network-diagrams react react-dom reactflow
27
+ npm install @mp70/react-networks react react-dom reactflow
28
28
  # or
29
- yarn add @react-networks/network-diagrams react react-dom reactflow
29
+ yarn add @mp70/react-networks react react-dom reactflow
30
30
  # or
31
- pnpm add @react-networks/network-diagrams react react-dom reactflow
31
+ pnpm add @mp70/react-networks react react-dom reactflow
32
32
  ```
33
33
 
34
34
  ### Basic Usage
35
35
 
36
36
  ```tsx
37
37
  import React from 'react';
38
- import { NetworkDiagram, NetworkNode, NetworkEdge } from '@react-networks/network-diagrams';
39
- import '@react-networks/network-diagrams/index.css';
38
+ import { NetworkDiagram, NetworkNode, NetworkEdge } from '@mp70/react-networks';
39
+ import '@mp70/react-networks/index.css';
40
40
 
41
41
  const nodes: NetworkNode[] = [
42
42
  {
@@ -144,7 +144,7 @@ type NetworkEdgeType = 'fiber' | 'ethernet' | 'power';
144
144
  ### Rack Configuration
145
145
 
146
146
  ```tsx
147
- import { RackConfig, buildNodesFromRackConfig, Width } from '@react-networks/network-diagrams';
147
+ import { RackConfig, buildNodesFromRackConfig, Width } from '@mp70/react-networks';
148
148
 
149
149
  const rackSchema: RackConfig[] = [
150
150
  {
@@ -190,24 +190,24 @@ const rackSchema: RackConfig[] = [
190
190
  const nodes = buildNodesFromRackConfig(rackSchema);
191
191
  ```
192
192
 
193
- ### NetBox Integration
193
+ ### Inventory Integration
194
194
 
195
195
  ```tsx
196
- import { netboxToNetworkDiagram } from '@react-networks/network-diagrams';
196
+ import { inventoryToNetworkDiagram } from '@mp70/react-networks';
197
197
 
198
- const netboxData = {
199
- racks: [...], // NetBox rack data
200
- devices: [...], // NetBox device data
201
- cables: [...] // NetBox cable data
198
+ const inventoryData = {
199
+ racks: [...],
200
+ devices: [...],
201
+ cables: [...]
202
202
  };
203
203
 
204
- const { nodes, edges } = netboxToNetworkDiagram(netboxData);
204
+ const { nodes, edges } = inventoryToNetworkDiagram(inventoryData);
205
205
  ```
206
206
 
207
207
  ### Custom Styling
208
208
 
209
209
  ```tsx
210
- import '@react-networks/network-diagrams/index.css';
210
+ import '@mp70/react-networks/index.css';
211
211
 
212
212
  // Override CSS variables
213
213
  .network-diagram {
@@ -312,7 +312,7 @@ We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) f
312
312
 
313
313
  ## 📄 License
314
314
 
315
- MIT License - see [LICENSE](LICENSE) for details.
315
+ Dual-licensed under AGPL-3.0 or Commercial. See [LICENSE](LICENSE) for details.
316
316
 
317
317
  ## 🆘 Support
318
318
 
@@ -324,7 +324,7 @@ MIT License - see [LICENSE](LICENSE) for details.
324
324
  ## 🙏 Acknowledgments
325
325
 
326
326
  - [React Flow](https://reactflow.dev) for the excellent diagram foundation
327
- - [NetBox](https://netbox.dev) for network infrastructure management inspiration
327
+ - Network inventory/CMDB projects for inspiration
328
328
  - The open source community for feedback and contributions
329
329
 
330
330
  ---
package/dist/index.css CHANGED
@@ -20,4 +20,109 @@
20
20
  z-index: 500 !important;
21
21
  }
22
22
 
23
+ /* React Flow theming */
24
+ .react-flow-dark {
25
+ --react-flow-background: #1a1a1a;
26
+ --react-flow-text: #ffffff;
27
+ --react-flow-border: #404040;
28
+ --react-flow-controls-bg: #2d2d2d;
29
+ --react-flow-controls-border: #404040;
30
+ --react-flow-minimap-bg: #2d2d2d;
31
+ --react-flow-minimap-border: #404040;
32
+ }
33
+
34
+ .react-flow-light {
35
+ --react-flow-background: #ffffff;
36
+ --react-flow-text: #1a1a1a;
37
+ --react-flow-border: #e9ecef;
38
+ --react-flow-controls-bg: #f8f9fa;
39
+ --react-flow-controls-border: #e9ecef;
40
+ --react-flow-minimap-bg: #f8f9fa;
41
+ --react-flow-minimap-border: #e9ecef;
42
+ }
43
+
44
+ /* Apply ReactFlow theming */
45
+ .react-flow-dark .react-flow__background {
46
+ background-color: var(--react-flow-background);
47
+ }
48
+
49
+ .react-flow-light .react-flow__background {
50
+ background-color: var(--react-flow-background);
51
+ }
52
+
53
+ .react-flow-dark .react-flow__controls {
54
+ background-color: var(--react-flow-controls-bg);
55
+ border-color: var(--react-flow-controls-border);
56
+ }
57
+
58
+ .react-flow-light .react-flow__controls {
59
+ background-color: var(--react-flow-controls-bg);
60
+ border-color: var(--react-flow-controls-border);
61
+ }
62
+
63
+ .react-flow-dark .react-flow__minimap {
64
+ background-color: var(--react-flow-minimap-bg);
65
+ border-color: var(--react-flow-minimap-border);
66
+ }
67
+
68
+ .react-flow-light .react-flow__minimap {
69
+ background-color: var(--react-flow-minimap-bg);
70
+ border-color: var(--react-flow-minimap-border);
71
+ }
72
+
73
+ .react-flow-dark .react-flow__controls-button {
74
+ background-color: var(--react-flow-controls-bg);
75
+ color: var(--react-flow-text);
76
+ border-color: var(--react-flow-controls-border);
77
+ }
78
+
79
+ .react-flow-light .react-flow__controls-button {
80
+ background-color: var(--react-flow-controls-bg);
81
+ color: var(--react-flow-text);
82
+ border-color: var(--react-flow-controls-border);
83
+ }
84
+
85
+ .react-flow-dark .react-flow__controls-button:hover {
86
+ background-color: #4b5563;
87
+ }
88
+
89
+ .react-flow-light .react-flow__controls-button:hover {
90
+ background-color: #e9ecef;
91
+ }
92
+
93
+ /* React Networks Attribution */
94
+ .react-networks-attribution {
95
+ padding: 0;
96
+ margin: 0;
97
+ z-index: 1000;
98
+ }
99
+
100
+ .react-networks-attribution-link {
101
+ font-size: 7px;
102
+ color: #9ca3af;
103
+ text-decoration: none;
104
+ font-family: Inter, system-ui, -apple-system, sans-serif;
105
+ transition: color 0.2s ease;
106
+ padding: 1px 4px;
107
+ border-radius: 2px;
108
+ display: inline-block;
109
+ background: rgba(0, 0, 0, 0.3);
110
+ backdrop-filter: blur(4px);
111
+ }
112
+
113
+ .react-networks-attribution-link:hover {
114
+ color: #e5e7eb;
115
+ background: rgba(0, 0, 0, 0.4);
116
+ }
117
+
118
+ /* Light mode attribution */
119
+ .react-flow-light .react-networks-attribution-link {
120
+ color: #6b7280;
121
+ background: rgba(255, 255, 255, 0.6);
122
+ }
123
+
124
+ .react-flow-light .react-networks-attribution-link:hover {
125
+ color: #1a1a1a;
126
+ background: rgba(255, 255, 255, 0.8);
127
+ }
23
128
 
package/dist/index.d.mts CHANGED
@@ -1,150 +1,5 @@
1
1
  import React$1 from 'react';
2
- import { NodeProps, EdgeProps } from 'reactflow';
3
-
4
- interface NetBoxDevice {
5
- id: number;
6
- name: string;
7
- device_type: {
8
- id: number;
9
- model: string;
10
- manufacturer: {
11
- name: string;
12
- };
13
- };
14
- device_role: {
15
- name: string;
16
- color: string;
17
- };
18
- site: {
19
- name: string;
20
- };
21
- rack: {
22
- id: number;
23
- name: string;
24
- } | null;
25
- position: number | null;
26
- face: 'front' | 'rear' | null;
27
- status: {
28
- label: string;
29
- value: string;
30
- color: string;
31
- };
32
- primary_ip4?: {
33
- address: string;
34
- };
35
- primary_ip6?: {
36
- address: string;
37
- };
38
- interfaces: NetBoxInterface[];
39
- }
40
- interface NetBoxInterface {
41
- id: number;
42
- name: string;
43
- type: {
44
- label: string;
45
- value: string;
46
- };
47
- enabled: boolean;
48
- mac_address: string | null;
49
- mtu: number | null;
50
- connected_endpoint_type: string | null;
51
- connected_endpoint: {
52
- device: {
53
- name: string;
54
- };
55
- name: string;
56
- } | null;
57
- cable: {
58
- id: number;
59
- label: string;
60
- type: string;
61
- color: string;
62
- } | null;
63
- }
64
- interface NetBoxRack {
65
- id: number;
66
- name: string;
67
- site: {
68
- name: string;
69
- };
70
- group: {
71
- name: string;
72
- } | null;
73
- tenant: {
74
- name: string;
75
- } | null;
76
- role: {
77
- name: string;
78
- color: string;
79
- } | null;
80
- status: {
81
- label: string;
82
- value: string;
83
- color: string;
84
- };
85
- facility_id: string | null;
86
- serial: string | null;
87
- asset_tag: string | null;
88
- type: {
89
- label: string;
90
- value: string;
91
- };
92
- width: {
93
- label: string;
94
- value: number;
95
- };
96
- u_height: number;
97
- desc_units: boolean;
98
- outer_width: number | null;
99
- outer_depth: number | null;
100
- weight: number | null;
101
- max_weight: number | null;
102
- weight_unit: string;
103
- mounting_depth: number | null;
104
- devices: NetBoxDevice[];
105
- }
106
- interface NetBoxCable {
107
- id: number;
108
- label: string;
109
- type: {
110
- label: string;
111
- value: string;
112
- };
113
- status: {
114
- label: string;
115
- value: string;
116
- color: string;
117
- };
118
- color: string;
119
- length: number | null;
120
- length_unit: string;
121
- termination_a_type: string;
122
- termination_a: {
123
- device: {
124
- name: string;
125
- };
126
- name: string;
127
- };
128
- termination_b_type: string;
129
- termination_b: {
130
- device: {
131
- name: string;
132
- };
133
- name: string;
134
- };
135
- }
136
- interface NetBoxConnection {
137
- id: string;
138
- source: {
139
- device: string;
140
- interface: string;
141
- };
142
- target: {
143
- device: string;
144
- interface: string;
145
- };
146
- cable: NetBoxCable;
147
- }
2
+ import { NodeProps, EdgeProps, Edge, Connection } from 'reactflow';
148
3
 
149
4
  /**
150
5
  * Rack device width configuration
@@ -200,6 +55,11 @@ type DeviceView = 'front' | 'rear';
200
55
  * @public
201
56
  */
202
57
  type PowerSide = 'left' | 'right';
58
+ /**
59
+ * U numbering direction for racks
60
+ * @public
61
+ */
62
+ type UNumberingDirection = 'bottom-up' | 'top-down';
203
63
  /**
204
64
  * Network node data structure
205
65
  * @public
@@ -254,6 +114,10 @@ interface NetworkNode {
254
114
  heightCm?: number;
255
115
  /** Number of AC power ports */
256
116
  powerPorts?: number;
117
+ /** U numbering direction for rack nodes */
118
+ uNumberingDirection?: UNumberingDirection;
119
+ /** Custom header text for rack nodes */
120
+ customHeaderText?: string;
257
121
  /** Additional custom properties */
258
122
  [key: string]: any;
259
123
  };
@@ -315,6 +179,10 @@ interface RackConfig {
315
179
  };
316
180
  /** Rack height in U units */
317
181
  units: number;
182
+ /** U numbering direction (default: 'bottom-up') */
183
+ uNumberingDirection?: UNumberingDirection;
184
+ /** Custom header text for rack */
185
+ customHeaderText?: string;
318
186
  /** Devices mounted in the rack */
319
187
  devices: RackDevice[];
320
188
  }
@@ -374,7 +242,6 @@ interface FiberCable {
374
242
  to: string;
375
243
  };
376
244
  }
377
-
378
245
  /**
379
246
  * Network diagram component props
380
247
  * @public
@@ -396,8 +263,8 @@ interface NetworkDiagramProps {
396
263
  store?: any;
397
264
  /** Enable debug mode */
398
265
  debug?: boolean;
399
- /** Callback when a node is clicked */
400
- onNodeClick?: (node: NetworkNode) => void;
266
+ /** Callback when a node is clicked or selection changes (null when deselected) */
267
+ onNodeClick?: (node: NetworkNode | null) => void;
401
268
  /** Callback when an edge is clicked */
402
269
  onEdgeClick?: (edge: NetworkEdge) => void;
403
270
  /** Callback when device view changes */
@@ -410,23 +277,26 @@ interface NetworkDiagramProps {
410
277
  style?: React.CSSProperties;
411
278
  /** If true, vertically align rack bottoms to the same baseline */
412
279
  alignRacksToBottom?: boolean;
413
- }
414
- /**
415
- * NetBox integration props
416
- * @public
417
- */
418
- interface NetBoxNetworkDiagramProps extends NetworkDiagramProps {
419
- /** NetBox data for integration */
420
- netboxData?: {
421
- /** NetBox racks */
422
- racks: NetBoxRack[];
423
- /** NetBox devices */
424
- devices: NetBoxDevice[];
425
- /** NetBox cables */
426
- cables: NetBoxCable[];
427
- };
428
- /** Callback when NetBox data is updated */
429
- onNetBoxUpdate?: (data: any) => void;
280
+ /** Color mode for the diagram */
281
+ colorMode?: 'light' | 'dark' | 'system';
282
+ /** Callback when React Flow instance is initialized */
283
+ onInit?: (instance: any) => void;
284
+ /** Callback to get React Flow methods for save/restore */
285
+ onFlowMethods?: (methods: {
286
+ toObject: () => any;
287
+ setViewport: (viewport: any) => void;
288
+ setNodes: (nodes: any[]) => void;
289
+ setEdges: (edges: any[]) => void;
290
+ toImage: (options?: any) => Promise<string>;
291
+ }) => void;
292
+ /** Show download button */
293
+ showDownloadButton?: boolean;
294
+ /** Download button position */
295
+ downloadButtonPosition?: 'top-right' | 'top-left' | 'bottom-right' | 'bottom-left';
296
+ /** Custom download button text */
297
+ downloadButtonText?: string;
298
+ /** Download button styling options */
299
+ downloadButtonStyle?: React.CSSProperties;
430
300
  }
431
301
 
432
302
  declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
@@ -434,6 +304,7 @@ declare const NetworkDiagram: React$1.FC<NetworkDiagramProps>;
434
304
  interface RackNodeProps extends NodeProps<NetworkNode['data']> {
435
305
  onViewChange?: (nodeId: string, view: 'front' | 'rear') => void;
436
306
  onRackFaceChange?: (rackId: string, face: 'front' | 'rear') => void;
307
+ isDragOver?: boolean;
437
308
  }
438
309
  declare const RackNode: React$1.FC<RackNodeProps>;
439
310
 
@@ -447,35 +318,111 @@ declare const DeviceNode: React$1.FC<NodeProps<NetworkNode['data']>>;
447
318
 
448
319
  declare const VerticalPDU: React$1.FC<NodeProps<NetworkNode['data']>>;
449
320
 
321
+ interface InventoryRackDTO {
322
+ id: string | number;
323
+ name: string;
324
+ status?: {
325
+ value?: string;
326
+ } | string;
327
+ u_height?: number;
328
+ units?: number;
329
+ facility_id?: string | number;
330
+ serial?: string;
331
+ asset_tag?: string;
332
+ site?: {
333
+ name?: string;
334
+ } | string;
335
+ role?: {
336
+ name?: string;
337
+ } | string;
338
+ tenant?: {
339
+ name?: string;
340
+ } | string;
341
+ }
342
+ interface InventoryDeviceDTO {
343
+ id: string | number;
344
+ name: string;
345
+ status?: {
346
+ value?: string;
347
+ } | string;
348
+ device_type?: {
349
+ u_height?: number;
350
+ model?: string;
351
+ manufacturer?: {
352
+ name?: string;
353
+ };
354
+ };
355
+ model?: string;
356
+ manufacturer?: string;
357
+ device_role?: {
358
+ name?: string;
359
+ } | string;
360
+ u_height?: number;
361
+ position?: number;
362
+ face?: 'front' | 'rear';
363
+ rack?: {
364
+ id?: string | number;
365
+ name?: string;
366
+ } | string | number;
367
+ primary_ip4?: {
368
+ address?: string;
369
+ } | string;
370
+ primary_ip6?: {
371
+ address?: string;
372
+ } | string;
373
+ site?: {
374
+ name?: string;
375
+ } | string;
376
+ }
377
+ interface InventoryCableDTO {
378
+ id: string | number;
379
+ type?: {
380
+ label?: string;
381
+ };
382
+ bandwidth?: string;
383
+ length?: number;
384
+ color?: string;
385
+ status?: {
386
+ value?: string;
387
+ } | string;
388
+ termination_a?: {
389
+ device?: {
390
+ id?: string | number;
391
+ } | string | number;
392
+ name?: string;
393
+ } | string;
394
+ termination_b?: {
395
+ device?: {
396
+ id?: string | number;
397
+ } | string | number;
398
+ name?: string;
399
+ } | string;
400
+ }
450
401
  /**
451
- * Convert NetBox rack data to NetworkNode
402
+ * Convert inventory rack data to NetworkNode
452
403
  */
453
- declare const netboxRackToNetworkNode: (rack: NetBoxRack) => NetworkNode;
404
+ declare const inventoryRackToNetworkNode: (rack: InventoryRackDTO) => NetworkNode;
454
405
  /**
455
- * Convert NetBox device data to NetworkNode
406
+ * Convert inventory device data to NetworkNode
456
407
  */
457
- declare const netboxDeviceToNetworkNode: (device: NetBoxDevice) => NetworkNode;
408
+ declare const inventoryDeviceToNetworkNode: (device: InventoryDeviceDTO) => NetworkNode;
458
409
  /**
459
- * Convert NetBox cable data to NetworkEdge
410
+ * Convert inventory cable data to NetworkEdge
460
411
  */
461
- declare const netboxCableToNetworkEdge: (cable: NetBoxCable) => NetworkEdge;
412
+ declare const inventoryCableToNetworkEdge: (cable: InventoryCableDTO) => NetworkEdge;
462
413
  /**
463
- * Convert NetBox data to network diagram format
414
+ * Convert inventory data to network diagram format
464
415
  */
465
- declare const netboxToNetworkDiagram: (data: {
466
- racks: NetBoxRack[];
467
- devices: NetBoxDevice[];
468
- cables: NetBoxCable[];
416
+ declare const inventoryToNetworkDiagram: (data: {
417
+ racks: InventoryRackDTO[];
418
+ devices: InventoryDeviceDTO[];
419
+ cables: InventoryCableDTO[];
469
420
  }) => {
470
421
  nodes: NetworkNode[];
471
422
  edges: NetworkEdge[];
472
423
  };
473
424
  /**
474
- * Calculate U position for devices in a rack
475
- */
476
- declare const calculateUPositions: (devices: NetBoxDevice[], rackHeight: number) => Map<number, number>;
477
- /**
478
- * Generate layout positions for nodes
425
+ * Generate simple layout positions for nodes array
479
426
  */
480
427
  declare const generateLayout: (nodes: NetworkNode[]) => NetworkNode[];
481
428
 
@@ -501,7 +448,7 @@ declare const findNextAvailableUPosition: (rack: NetworkNode, device: NetworkNod
501
448
  /**
502
449
  * Calculate device position based on U position within a rack
503
450
  */
504
- declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number) => {
451
+ declare const calculateDevicePositionFromU: (rack: NetworkNode, uPosition: number, deviceHeight?: number) => {
505
452
  x: number;
506
453
  y: number;
507
454
  };
@@ -557,7 +504,7 @@ interface DevicePlacementValidation {
557
504
  /**
558
505
  * Validate device placements within a rack schema
559
506
  */
560
- declare function validateRackDevicePlacements(rack: RackConfig, options?: RackSchemaOptions): DevicePlacementValidation;
507
+ declare function validateRackDevicePlacements(rack: RackConfig, _options?: RackSchemaOptions): DevicePlacementValidation;
561
508
  /**
562
509
  * Build NetworkNode array from RackConfig array with comprehensive validation
563
510
  */
@@ -622,6 +569,74 @@ declare function getPDUPortType(portIndex: number): string;
622
569
  */
623
570
  declare function getDeviceConnectorType(deviceName: string): string;
624
571
 
572
+ /**
573
+ * Get the color code for a device status
574
+ * @param status - The device status
575
+ * @returns Hex color code for the status
576
+ * @public
577
+ */
578
+ declare function getStatusColor(status: DeviceStatus | string): string;
579
+
580
+ /**
581
+ * Calculate the bounding box of a rack node
582
+ * @param rack - The rack node
583
+ * @returns Object with left, right, top, and bottom coordinates
584
+ * @public
585
+ */
586
+ declare function getRackBounds(rack: NetworkNode): {
587
+ left: number;
588
+ right: number;
589
+ top: number;
590
+ bottom: number;
591
+ };
592
+ /**
593
+ * Check if a point is inside a rack's bounds
594
+ * @param point - The point coordinates { x, y }
595
+ * @param rack - The rack node
596
+ * @returns True if the point is inside the rack
597
+ * @public
598
+ */
599
+ declare function isPointInRack(point: {
600
+ x: number;
601
+ y: number;
602
+ }, rack: NetworkNode): boolean;
603
+ /**
604
+ * Find the nearest rack to a point from a list of racks
605
+ * Only considers racks that contain the point
606
+ * @param point - The point coordinates { x, y }
607
+ * @param racks - Array of rack nodes
608
+ * @returns The nearest rack node, or null if no rack contains the point
609
+ * @public
610
+ */
611
+ declare function findNearestRack(point: {
612
+ x: number;
613
+ y: number;
614
+ }, racks: NetworkNode[]): NetworkNode | null;
615
+
616
+ /**
617
+ * Options for replacing an edge in the edges array
618
+ */
619
+ interface ReplaceEdgeOptions {
620
+ /** Existing edges array */
621
+ edges: Edge[];
622
+ /** Connection parameters for the new edge */
623
+ connection: Connection;
624
+ /** Type of edge to create */
625
+ edgeType: 'power' | 'fiber';
626
+ /** Function to calculate zIndex for the edge */
627
+ selectEdgeZIndex: (edge: NetworkEdge) => number;
628
+ /** Whether to find edge by source or target */
629
+ findBy: 'source' | 'target';
630
+ }
631
+ /**
632
+ * Replace an existing edge with a new connection
633
+ * This is used for PDU and switch connections that allow replacing existing edges
634
+ * @param options - Options for edge replacement
635
+ * @returns New edges array with the edge replaced, or null if no existing edge found
636
+ * @public
637
+ */
638
+ declare function replaceEdge(options: ReplaceEdgeOptions): Edge[] | null;
639
+
625
640
  interface NetworkDiagramState {
626
641
  nodes: NetworkNode[];
627
642
  edges: NetworkEdge[];
@@ -646,6 +661,8 @@ interface NetworkDiagramStore {
646
661
  subscribe: (listener: (state: NetworkDiagramState) => void) => () => void;
647
662
  selectEdgeZIndex: (edge: NetworkEdge) => number;
648
663
  validateConnection: (params: ValidateConnectionParams) => ValidationResult;
664
+ selectNodeById: (id: string) => NetworkNode | undefined;
665
+ selectConnectedEdges: (nodeId: string) => NetworkEdge[];
649
666
  }
650
667
  declare function createNetworkDiagramStore(initial?: Partial<NetworkDiagramState>, options?: NetworkDiagramOptions): NetworkDiagramStore;
651
668
 
@@ -653,4 +670,4 @@ declare function useNetworkDiagram(store: NetworkDiagramStore): NetworkDiagramSt
653
670
  declare function useNodes(store: NetworkDiagramStore): NetworkNode[];
654
671
  declare function useEdges(store: NetworkDiagramStore): NetworkEdge[];
655
672
 
656
- export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, type NetBoxCable, type NetBoxConnection, type NetBoxDevice, type NetBoxInterface, type NetBoxNetworkDiagramProps, type NetBoxRack, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, calculateUPositions, createNetworkDiagramStore, createRackConfigFromNodes, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, isHighPowerConnector, isUPositionAvailable, netboxCableToNetworkEdge, netboxDeviceToNetworkNode, netboxRackToNetworkNode, netboxToNetworkDiagram, removeDeviceFromRack, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };
673
+ export { DeviceNode, DevicePlacementError, type DevicePlacementValidation, type FiberCable, FiberEdge, FiberNode, NetworkDiagram, type NetworkDiagramProps, type NetworkEdge, type NetworkNode, POWER_CONNECTORS, type Port, type PortBlock, PowerEdge, type RackConfig, type RackDevice, RackNode, type RackSchemaOptions, type ReplaceEdgeOptions, VerticalPDU, Width, addDeviceToRack, buildNodesFromRackConfig, calculateDevicePositionFromU, createNetworkDiagramStore, createRackConfigFromNodes, findNearestRack, findNextAvailableUPosition, generateLayout, getConnectorConfig, getDeviceConnectorType, getPDUPortType, getPowerPortStyle, getRackBounds, getStatusColor, inventoryCableToNetworkEdge, inventoryDeviceToNetworkNode, inventoryRackToNetworkNode, inventoryToNetworkDiagram, isHighPowerConnector, isPointInRack, isUPositionAvailable, removeDeviceFromRack, replaceEdge, snapToUPosition, updateDeviceUPosition$1 as updateDeviceUPosition, updateDeviceUPosition as updateDeviceUPositionInSchema, useEdges as useDiagramEdges, useNodes as useDiagramNodes, useNetworkDiagram, validateAndSnapDevice, validateRackDevicePlacements };