@tscircuit/schematic-viewer 2.0.54 → 2.0.56

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/CLAUDE.md ADDED
@@ -0,0 +1 @@
1
+ - Use `bun`/`bunx` instead of `npm`/`npx`
package/bun.lockb CHANGED
Binary file
package/dist/index.d.ts CHANGED
@@ -21,8 +21,13 @@ interface Props$1 {
21
21
  schematicComponentId: string;
22
22
  event: MouseEvent;
23
23
  }) => void;
24
+ showSchematicPorts?: boolean;
25
+ onSchematicPortClicked?: (options: {
26
+ schematicPortId: string;
27
+ event: MouseEvent;
28
+ }) => void;
24
29
  }
25
- declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, disableGroups, onSchematicComponentClicked, }: Props$1) => react_jsx_runtime.JSX.Element;
30
+ declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, disableGroups, onSchematicComponentClicked, showSchematicPorts, onSchematicPortClicked, }: Props$1) => react_jsx_runtime.JSX.Element;
26
31
 
27
32
  interface BoundingBoxBounds {
28
33
  minX: number;
package/dist/index.js CHANGED
@@ -470,7 +470,7 @@ var enableDebug = () => {
470
470
  var debug_default = debug;
471
471
 
472
472
  // lib/components/SchematicViewer.tsx
473
- import { useCallback as useCallback5, useEffect as useEffect11, useMemo as useMemo5, useRef as useRef7, useState as useState6 } from "react";
473
+ import { useCallback as useCallback6, useEffect as useEffect12, useMemo as useMemo5, useRef as useRef8, useState as useState7 } from "react";
474
474
  import {
475
475
  fromString,
476
476
  identity,
@@ -693,7 +693,8 @@ var zIndexMap = {
693
693
  viewMenu: 55,
694
694
  viewMenuBackdrop: 54,
695
695
  clickToInteractOverlay: 100,
696
- schematicComponentHoverOutline: 47
696
+ schematicComponentHoverOutline: 47,
697
+ schematicPortHoverOutline: 48
697
698
  };
698
699
 
699
700
  // lib/components/EditIcon.tsx
@@ -851,7 +852,7 @@ import { su as su5 } from "@tscircuit/soup-util";
851
852
  // package.json
852
853
  var package_default = {
853
854
  name: "@tscircuit/schematic-viewer",
854
- version: "2.0.53",
855
+ version: "2.0.55",
855
856
  main: "dist/index.js",
856
857
  type: "module",
857
858
  scripts: {
@@ -2198,8 +2199,168 @@ var SchematicComponentMouseTarget = ({
2198
2199
  );
2199
2200
  };
2200
2201
 
2202
+ // lib/components/SchematicPortMouseTarget.tsx
2203
+ import { useCallback as useCallback5, useEffect as useEffect11, useRef as useRef7, useState as useState6 } from "react";
2204
+ import { Fragment as Fragment3, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2205
+ var areMeasurementsEqual2 = (a, b) => {
2206
+ if (!a && !b) return true;
2207
+ if (!a || !b) return false;
2208
+ return Math.abs(a.bounds.minX - b.bounds.minX) < 0.5 && Math.abs(a.bounds.maxX - b.bounds.maxX) < 0.5 && Math.abs(a.bounds.minY - b.bounds.minY) < 0.5 && Math.abs(a.bounds.maxY - b.bounds.maxY) < 0.5 && Math.abs(a.rect.left - b.rect.left) < 0.5 && Math.abs(a.rect.top - b.rect.top) < 0.5 && Math.abs(a.rect.width - b.rect.width) < 0.5 && Math.abs(a.rect.height - b.rect.height) < 0.5;
2209
+ };
2210
+ var SchematicPortMouseTarget = ({
2211
+ portId,
2212
+ portLabel,
2213
+ svgDivRef,
2214
+ containerRef,
2215
+ onPortClick,
2216
+ onHoverChange,
2217
+ showOutline,
2218
+ circuitJsonKey
2219
+ }) => {
2220
+ const [measurement, setMeasurement] = useState6(null);
2221
+ const frameRef = useRef7(null);
2222
+ const measure = useCallback5(() => {
2223
+ frameRef.current = null;
2224
+ const svgDiv = svgDivRef.current;
2225
+ const container = containerRef.current;
2226
+ if (!svgDiv || !container) {
2227
+ setMeasurement((prev) => prev ? null : prev);
2228
+ return;
2229
+ }
2230
+ const element = svgDiv.querySelector(
2231
+ `[data-schematic-port-id="${portId}"]`
2232
+ );
2233
+ if (!element) {
2234
+ setMeasurement((prev) => prev ? null : prev);
2235
+ return;
2236
+ }
2237
+ const elementRect = element.getBoundingClientRect();
2238
+ const containerRect = container.getBoundingClientRect();
2239
+ const padding = 4;
2240
+ const nextMeasurement = {
2241
+ bounds: {
2242
+ minX: elementRect.left - padding,
2243
+ maxX: elementRect.right + padding,
2244
+ minY: elementRect.top - padding,
2245
+ maxY: elementRect.bottom + padding
2246
+ },
2247
+ rect: {
2248
+ left: elementRect.left - containerRect.left - padding,
2249
+ top: elementRect.top - containerRect.top - padding,
2250
+ width: elementRect.width + padding * 2,
2251
+ height: elementRect.height + padding * 2
2252
+ }
2253
+ };
2254
+ setMeasurement(
2255
+ (prev) => areMeasurementsEqual2(prev, nextMeasurement) ? prev : nextMeasurement
2256
+ );
2257
+ }, [portId, containerRef, svgDivRef]);
2258
+ const scheduleMeasure = useCallback5(() => {
2259
+ if (frameRef.current !== null) return;
2260
+ frameRef.current = window.requestAnimationFrame(measure);
2261
+ }, [measure]);
2262
+ useEffect11(() => {
2263
+ scheduleMeasure();
2264
+ }, [scheduleMeasure, circuitJsonKey]);
2265
+ useEffect11(() => {
2266
+ scheduleMeasure();
2267
+ const svgDiv = svgDivRef.current;
2268
+ const container = containerRef.current;
2269
+ if (!svgDiv || !container) return;
2270
+ const resizeObserver = typeof ResizeObserver !== "undefined" ? new ResizeObserver(() => {
2271
+ scheduleMeasure();
2272
+ }) : null;
2273
+ resizeObserver?.observe(container);
2274
+ resizeObserver?.observe(svgDiv);
2275
+ const mutationObserver = typeof MutationObserver !== "undefined" ? new MutationObserver(() => {
2276
+ scheduleMeasure();
2277
+ }) : null;
2278
+ mutationObserver?.observe(svgDiv, {
2279
+ attributes: true,
2280
+ attributeFilter: ["style", "transform"],
2281
+ subtree: true,
2282
+ childList: true
2283
+ });
2284
+ window.addEventListener("scroll", scheduleMeasure, true);
2285
+ window.addEventListener("resize", scheduleMeasure);
2286
+ return () => {
2287
+ resizeObserver?.disconnect();
2288
+ mutationObserver?.disconnect();
2289
+ window.removeEventListener("scroll", scheduleMeasure, true);
2290
+ window.removeEventListener("resize", scheduleMeasure);
2291
+ if (frameRef.current !== null) {
2292
+ cancelAnimationFrame(frameRef.current);
2293
+ frameRef.current = null;
2294
+ }
2295
+ };
2296
+ }, [scheduleMeasure, svgDivRef, containerRef]);
2297
+ const handleClick = useCallback5(
2298
+ (event) => {
2299
+ if (onPortClick) {
2300
+ onPortClick(portId, event);
2301
+ }
2302
+ },
2303
+ [portId, onPortClick]
2304
+ );
2305
+ const bounds = measurement?.bounds ?? null;
2306
+ const { hovering } = useMouseEventsOverBoundingBox({
2307
+ bounds,
2308
+ onClick: onPortClick ? handleClick : void 0
2309
+ });
2310
+ useEffect11(() => {
2311
+ if (onHoverChange) {
2312
+ onHoverChange(portId, hovering);
2313
+ }
2314
+ }, [hovering, portId, onHoverChange]);
2315
+ if (!measurement || !showOutline) {
2316
+ return null;
2317
+ }
2318
+ const rect = measurement.rect;
2319
+ return /* @__PURE__ */ jsxs6(Fragment3, { children: [
2320
+ /* @__PURE__ */ jsx11(
2321
+ "div",
2322
+ {
2323
+ style: {
2324
+ position: "absolute",
2325
+ left: rect.left,
2326
+ top: rect.top,
2327
+ width: rect.width,
2328
+ height: rect.height,
2329
+ border: hovering ? "1.5px solid rgba(255, 153, 51, 0.9)" : "1.5px solid rgba(255, 153, 51, 0.3)",
2330
+ backgroundColor: hovering ? "rgba(255, 153, 51, 0.15)" : "rgba(255, 153, 51, 0.05)",
2331
+ borderRadius: "50%",
2332
+ pointerEvents: "none",
2333
+ zIndex: zIndexMap.schematicPortHoverOutline,
2334
+ transition: "border-color 0.15s, background-color 0.15s"
2335
+ }
2336
+ }
2337
+ ),
2338
+ hovering && portLabel && /* @__PURE__ */ jsx11(
2339
+ "div",
2340
+ {
2341
+ style: {
2342
+ position: "absolute",
2343
+ left: rect.left + rect.width / 2,
2344
+ top: rect.top - 24,
2345
+ transform: "translateX(-50%)",
2346
+ backgroundColor: "rgba(0, 0, 0, 0.85)",
2347
+ color: "white",
2348
+ padding: "4px 8px",
2349
+ borderRadius: "4px",
2350
+ fontSize: "12px",
2351
+ fontFamily: "monospace",
2352
+ whiteSpace: "nowrap",
2353
+ pointerEvents: "none",
2354
+ zIndex: zIndexMap.schematicPortHoverOutline + 1
2355
+ },
2356
+ children: portLabel
2357
+ }
2358
+ )
2359
+ ] });
2360
+ };
2361
+
2201
2362
  // lib/components/SchematicViewer.tsx
2202
- import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2363
+ import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2203
2364
  var SchematicViewer = ({
2204
2365
  circuitJson,
2205
2366
  containerStyle,
@@ -2213,13 +2374,15 @@ var SchematicViewer = ({
2213
2374
  colorOverrides,
2214
2375
  spiceSimulationEnabled = false,
2215
2376
  disableGroups = false,
2216
- onSchematicComponentClicked
2377
+ onSchematicComponentClicked,
2378
+ showSchematicPorts = false,
2379
+ onSchematicPortClicked
2217
2380
  }) => {
2218
2381
  if (debug3) {
2219
2382
  enableDebug();
2220
2383
  }
2221
- const [showSpiceOverlay, setShowSpiceOverlay] = useState6(false);
2222
- const [spiceSimOptions, setSpiceSimOptions] = useState6({
2384
+ const [showSpiceOverlay, setShowSpiceOverlay] = useState7(false);
2385
+ const [spiceSimOptions, setSpiceSimOptions] = useState7({
2223
2386
  showVoltage: true,
2224
2387
  showCurrent: false,
2225
2388
  startTime: 0,
@@ -2248,8 +2411,8 @@ var SchematicViewer = ({
2248
2411
  spiceSimOptions.startTime,
2249
2412
  spiceSimOptions.duration
2250
2413
  ]);
2251
- const [hasSpiceSimRun, setHasSpiceSimRun] = useState6(false);
2252
- useEffect11(() => {
2414
+ const [hasSpiceSimRun, setHasSpiceSimRun] = useState7(false);
2415
+ useEffect12(() => {
2253
2416
  setHasSpiceSimRun(false);
2254
2417
  }, [circuitJsonKey]);
2255
2418
  const {
@@ -2258,20 +2421,21 @@ var SchematicViewer = ({
2258
2421
  isLoading: isSpiceSimLoading,
2259
2422
  error: spiceSimError
2260
2423
  } = useSpiceSimulation(hasSpiceSimRun ? spiceString : null);
2261
- const [editModeEnabled, setEditModeEnabled] = useState6(defaultEditMode);
2262
- const [snapToGrid, setSnapToGrid] = useState6(true);
2263
- const [showGrid, setShowGrid] = useState6(debugGrid);
2264
- const [isInteractionEnabled, setIsInteractionEnabled] = useState6(
2424
+ const [editModeEnabled, setEditModeEnabled] = useState7(defaultEditMode);
2425
+ const [snapToGrid, setSnapToGrid] = useState7(true);
2426
+ const [showGridInternal, setShowGridInternal] = useState7(false);
2427
+ const showGrid = debugGrid || showGridInternal;
2428
+ const [isInteractionEnabled, setIsInteractionEnabled] = useState7(
2265
2429
  !clickToInteractEnabled
2266
2430
  );
2267
- const [showViewMenu, setShowViewMenu] = useState6(false);
2268
- const [showSchematicGroups, setShowSchematicGroups] = useState6(() => {
2431
+ const [showViewMenu, setShowViewMenu] = useState7(false);
2432
+ const [showSchematicGroups, setShowSchematicGroups] = useState7(() => {
2269
2433
  if (disableGroups) return false;
2270
2434
  return getStoredBoolean("schematic_viewer_show_groups", false);
2271
2435
  });
2272
- const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState6(false);
2273
- const hoveringComponentsRef = useRef7(/* @__PURE__ */ new Set());
2274
- const handleComponentHoverChange = useCallback5(
2436
+ const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState7(false);
2437
+ const hoveringComponentsRef = useRef8(/* @__PURE__ */ new Set());
2438
+ const handleComponentHoverChange = useCallback6(
2275
2439
  (componentId, isHovering) => {
2276
2440
  if (isHovering) {
2277
2441
  hoveringComponentsRef.current.add(componentId);
@@ -2282,8 +2446,21 @@ var SchematicViewer = ({
2282
2446
  },
2283
2447
  []
2284
2448
  );
2285
- const svgDivRef = useRef7(null);
2286
- const touchStartRef = useRef7(null);
2449
+ const [isHoveringClickablePort, setIsHoveringClickablePort] = useState7(false);
2450
+ const hoveringPortsRef = useRef8(/* @__PURE__ */ new Set());
2451
+ const handlePortHoverChange = useCallback6(
2452
+ (portId, isHovering) => {
2453
+ if (isHovering) {
2454
+ hoveringPortsRef.current.add(portId);
2455
+ } else {
2456
+ hoveringPortsRef.current.delete(portId);
2457
+ }
2458
+ setIsHoveringClickablePort(hoveringPortsRef.current.size > 0);
2459
+ },
2460
+ []
2461
+ );
2462
+ const svgDivRef = useRef8(null);
2463
+ const touchStartRef = useRef8(null);
2287
2464
  const schematicComponentIds = useMemo5(() => {
2288
2465
  try {
2289
2466
  return su6(circuitJson).schematic_component?.list()?.map((component) => component.schematic_component_id) ?? [];
@@ -2292,6 +2469,25 @@ var SchematicViewer = ({
2292
2469
  return [];
2293
2470
  }
2294
2471
  }, [circuitJsonKey, circuitJson]);
2472
+ const schematicPortsInfo = useMemo5(() => {
2473
+ if (!showSchematicPorts) return [];
2474
+ try {
2475
+ const ports = su6(circuitJson).schematic_port?.list() ?? [];
2476
+ return ports.map((port) => {
2477
+ const sourcePort = su6(circuitJson).source_port.get(port.source_port_id);
2478
+ const sourceComponent = sourcePort?.source_component_id ? su6(circuitJson).source_component.get(sourcePort.source_component_id) : null;
2479
+ const componentName = sourceComponent?.name ?? "?";
2480
+ const pinLabel = port.display_pin_label ?? sourcePort?.pin_number ?? sourcePort?.name ?? "?";
2481
+ return {
2482
+ portId: port.source_port_id,
2483
+ label: `${componentName}.${pinLabel}`
2484
+ };
2485
+ });
2486
+ } catch (err) {
2487
+ console.error("Failed to derive schematic port info", err);
2488
+ return [];
2489
+ }
2490
+ }, [circuitJsonKey, circuitJson, showSchematicPorts]);
2295
2491
  const handleTouchStart = (e) => {
2296
2492
  const touch = e.touches[0];
2297
2493
  touchStartRef.current = {
@@ -2311,9 +2507,9 @@ var SchematicViewer = ({
2311
2507
  }
2312
2508
  touchStartRef.current = null;
2313
2509
  };
2314
- const [internalEditEvents, setInternalEditEvents] = useState6([]);
2315
- const circuitJsonRef = useRef7(circuitJson);
2316
- useEffect11(() => {
2510
+ const [internalEditEvents, setInternalEditEvents] = useState7([]);
2511
+ const circuitJsonRef = useRef8(circuitJson);
2512
+ useEffect12(() => {
2317
2513
  const circuitHash = getCircuitHash(circuitJson);
2318
2514
  const circuitHashRef = getCircuitHash(circuitJsonRef.current);
2319
2515
  if (circuitHash !== circuitHashRef) {
@@ -2407,12 +2603,12 @@ var SchematicViewer = ({
2407
2603
  circuitJsonKey,
2408
2604
  showGroups: showSchematicGroups && !disableGroups
2409
2605
  });
2410
- const handleComponentTouchStartRef = useRef7(handleComponentTouchStart);
2411
- useEffect11(() => {
2606
+ const handleComponentTouchStartRef = useRef8(handleComponentTouchStart);
2607
+ useEffect12(() => {
2412
2608
  handleComponentTouchStartRef.current = handleComponentTouchStart;
2413
2609
  }, [handleComponentTouchStart]);
2414
2610
  const svgDiv = useMemo5(
2415
- () => /* @__PURE__ */ jsx11(
2611
+ () => /* @__PURE__ */ jsx12(
2416
2612
  "div",
2417
2613
  {
2418
2614
  ref: svgDivRef,
@@ -2437,9 +2633,10 @@ var SchematicViewer = ({
2437
2633
  showSpiceOverlay
2438
2634
  ]
2439
2635
  );
2440
- return /* @__PURE__ */ jsxs6(MouseTracker, { children: [
2441
- onSchematicComponentClicked && /* @__PURE__ */ jsx11("style", { children: `.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }` }),
2442
- /* @__PURE__ */ jsxs6(
2636
+ return /* @__PURE__ */ jsxs7(MouseTracker, { children: [
2637
+ onSchematicComponentClicked && /* @__PURE__ */ jsx12("style", { children: `.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }` }),
2638
+ onSchematicPortClicked && /* @__PURE__ */ jsx12("style", { children: `[data-schematic-port-id]:hover { cursor: pointer !important; }` }),
2639
+ /* @__PURE__ */ jsxs7(
2443
2640
  "div",
2444
2641
  {
2445
2642
  ref: containerRef,
@@ -2447,7 +2644,7 @@ var SchematicViewer = ({
2447
2644
  position: "relative",
2448
2645
  backgroundColor: containerBackgroundColor,
2449
2646
  overflow: "hidden",
2450
- cursor: showSpiceOverlay ? "auto" : isDragging ? "grabbing" : clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent && onSchematicComponentClicked ? "pointer" : "grab",
2647
+ cursor: showSpiceOverlay ? "auto" : isDragging ? "grabbing" : clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent && onSchematicComponentClicked ? "pointer" : isHoveringClickablePort && onSchematicPortClicked ? "pointer" : "grab",
2451
2648
  minHeight: "300px",
2452
2649
  ...containerStyle
2453
2650
  },
@@ -2480,7 +2677,7 @@ var SchematicViewer = ({
2480
2677
  handleTouchEnd(e);
2481
2678
  },
2482
2679
  children: [
2483
- !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx11(
2680
+ !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx12(
2484
2681
  "div",
2485
2682
  {
2486
2683
  onClick: (e) => {
@@ -2499,7 +2696,7 @@ var SchematicViewer = ({
2499
2696
  pointerEvents: "all",
2500
2697
  touchAction: "pan-x pan-y pinch-zoom"
2501
2698
  },
2502
- children: /* @__PURE__ */ jsx11(
2699
+ children: /* @__PURE__ */ jsx12(
2503
2700
  "div",
2504
2701
  {
2505
2702
  style: {
@@ -2516,28 +2713,28 @@ var SchematicViewer = ({
2516
2713
  )
2517
2714
  }
2518
2715
  ),
2519
- /* @__PURE__ */ jsx11(
2716
+ /* @__PURE__ */ jsx12(
2520
2717
  ViewMenuIcon,
2521
2718
  {
2522
2719
  active: showViewMenu,
2523
2720
  onClick: () => setShowViewMenu(!showViewMenu)
2524
2721
  }
2525
2722
  ),
2526
- editingEnabled && /* @__PURE__ */ jsx11(
2723
+ editingEnabled && /* @__PURE__ */ jsx12(
2527
2724
  EditIcon,
2528
2725
  {
2529
2726
  active: editModeEnabled,
2530
2727
  onClick: () => setEditModeEnabled(!editModeEnabled)
2531
2728
  }
2532
2729
  ),
2533
- editingEnabled && editModeEnabled && /* @__PURE__ */ jsx11(
2730
+ editingEnabled && editModeEnabled && /* @__PURE__ */ jsx12(
2534
2731
  GridIcon,
2535
2732
  {
2536
2733
  active: snapToGrid,
2537
2734
  onClick: () => setSnapToGrid(!snapToGrid)
2538
2735
  }
2539
2736
  ),
2540
- /* @__PURE__ */ jsx11(
2737
+ /* @__PURE__ */ jsx12(
2541
2738
  ViewMenu,
2542
2739
  {
2543
2740
  circuitJson,
@@ -2552,11 +2749,11 @@ var SchematicViewer = ({
2552
2749
  }
2553
2750
  },
2554
2751
  showGrid,
2555
- onToggleGrid: setShowGrid
2752
+ onToggleGrid: setShowGridInternal
2556
2753
  }
2557
2754
  ),
2558
- spiceSimulationEnabled && /* @__PURE__ */ jsx11(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
2559
- showSpiceOverlay && /* @__PURE__ */ jsx11(
2755
+ spiceSimulationEnabled && /* @__PURE__ */ jsx12(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
2756
+ showSpiceOverlay && /* @__PURE__ */ jsx12(
2560
2757
  SpiceSimulationOverlay,
2561
2758
  {
2562
2759
  spiceString,
@@ -2573,7 +2770,7 @@ var SchematicViewer = ({
2573
2770
  hasRun: hasSpiceSimRun
2574
2771
  }
2575
2772
  ),
2576
- onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx11(
2773
+ onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx12(
2577
2774
  SchematicComponentMouseTarget,
2578
2775
  {
2579
2776
  componentId,
@@ -2591,7 +2788,26 @@ var SchematicViewer = ({
2591
2788
  },
2592
2789
  componentId
2593
2790
  )),
2594
- svgDiv
2791
+ svgDiv,
2792
+ showSchematicPorts && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx12(
2793
+ SchematicPortMouseTarget,
2794
+ {
2795
+ portId,
2796
+ portLabel: label,
2797
+ svgDivRef,
2798
+ containerRef,
2799
+ showOutline: true,
2800
+ circuitJsonKey,
2801
+ onHoverChange: handlePortHoverChange,
2802
+ onPortClick: onSchematicPortClicked ? (id, event) => {
2803
+ onSchematicPortClicked?.({
2804
+ schematicPortId: id,
2805
+ event
2806
+ });
2807
+ } : void 0
2808
+ },
2809
+ portId
2810
+ ))
2595
2811
  ]
2596
2812
  }
2597
2813
  )
@@ -2602,10 +2818,10 @@ var SchematicViewer = ({
2602
2818
  import {
2603
2819
  convertCircuitJsonToSchematicSimulationSvg
2604
2820
  } from "circuit-to-svg";
2605
- import { useEffect as useEffect12, useState as useState7, useMemo as useMemo6, useRef as useRef8 } from "react";
2821
+ import { useEffect as useEffect13, useState as useState8, useMemo as useMemo6, useRef as useRef9 } from "react";
2606
2822
  import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
2607
2823
  import { toString as transformToString2 } from "transformation-matrix";
2608
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2824
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2609
2825
  var AnalogSimulationViewer = ({
2610
2826
  circuitJson: inputCircuitJson,
2611
2827
  containerStyle,
@@ -2614,16 +2830,16 @@ var AnalogSimulationViewer = ({
2614
2830
  height,
2615
2831
  className
2616
2832
  }) => {
2617
- const [circuitJson, setCircuitJson] = useState7(null);
2618
- const [isLoading, setIsLoading] = useState7(true);
2619
- const [error, setError] = useState7(null);
2620
- const [svgObjectUrl, setSvgObjectUrl] = useState7(null);
2621
- const containerRef = useRef8(null);
2622
- const imgRef = useRef8(null);
2833
+ const [circuitJson, setCircuitJson] = useState8(null);
2834
+ const [isLoading, setIsLoading] = useState8(true);
2835
+ const [error, setError] = useState8(null);
2836
+ const [svgObjectUrl, setSvgObjectUrl] = useState8(null);
2837
+ const containerRef = useRef9(null);
2838
+ const imgRef = useRef9(null);
2623
2839
  const { containerWidth, containerHeight } = useResizeHandling(
2624
2840
  containerRef
2625
2841
  );
2626
- const [isDragging, setIsDragging] = useState7(false);
2842
+ const [isDragging, setIsDragging] = useState8(false);
2627
2843
  const {
2628
2844
  ref: transformRef,
2629
2845
  cancelDrag: _cancelDrag,
@@ -2637,7 +2853,7 @@ var AnalogSimulationViewer = ({
2637
2853
  });
2638
2854
  const effectiveWidth = width || containerWidth || 1e3;
2639
2855
  const effectiveHeight = height || containerHeight || 600;
2640
- useEffect12(() => {
2856
+ useEffect13(() => {
2641
2857
  setIsLoading(true);
2642
2858
  setError(null);
2643
2859
  setCircuitJson(inputCircuitJson);
@@ -2678,7 +2894,7 @@ var AnalogSimulationViewer = ({
2678
2894
  simulationExperimentId,
2679
2895
  simulationGraphIds
2680
2896
  ]);
2681
- useEffect12(() => {
2897
+ useEffect13(() => {
2682
2898
  if (!simulationSvg) {
2683
2899
  setSvgObjectUrl(null);
2684
2900
  return;
@@ -2708,7 +2924,7 @@ var AnalogSimulationViewer = ({
2708
2924
  const handleTouchStart = (_e) => {
2709
2925
  setIsDragging(true);
2710
2926
  };
2711
- useEffect12(() => {
2927
+ useEffect13(() => {
2712
2928
  const handleMouseUp = () => {
2713
2929
  setIsDragging(false);
2714
2930
  };
@@ -2723,7 +2939,7 @@ var AnalogSimulationViewer = ({
2723
2939
  };
2724
2940
  }, []);
2725
2941
  if (isLoading) {
2726
- return /* @__PURE__ */ jsx12(
2942
+ return /* @__PURE__ */ jsx13(
2727
2943
  "div",
2728
2944
  {
2729
2945
  style: {
@@ -2743,7 +2959,7 @@ var AnalogSimulationViewer = ({
2743
2959
  );
2744
2960
  }
2745
2961
  if (error) {
2746
- return /* @__PURE__ */ jsx12(
2962
+ return /* @__PURE__ */ jsx13(
2747
2963
  "div",
2748
2964
  {
2749
2965
  style: {
@@ -2758,15 +2974,15 @@ var AnalogSimulationViewer = ({
2758
2974
  ...containerStyle
2759
2975
  },
2760
2976
  className,
2761
- children: /* @__PURE__ */ jsxs7("div", { style: { textAlign: "center", padding: "20px" }, children: [
2762
- /* @__PURE__ */ jsx12("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
2763
- /* @__PURE__ */ jsx12("div", { style: { fontSize: "14px" }, children: error })
2977
+ children: /* @__PURE__ */ jsxs8("div", { style: { textAlign: "center", padding: "20px" }, children: [
2978
+ /* @__PURE__ */ jsx13("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
2979
+ /* @__PURE__ */ jsx13("div", { style: { fontSize: "14px" }, children: error })
2764
2980
  ] })
2765
2981
  }
2766
2982
  );
2767
2983
  }
2768
2984
  if (!simulationSvg) {
2769
- return /* @__PURE__ */ jsxs7(
2985
+ return /* @__PURE__ */ jsxs8(
2770
2986
  "div",
2771
2987
  {
2772
2988
  style: {
@@ -2782,11 +2998,11 @@ var AnalogSimulationViewer = ({
2782
2998
  },
2783
2999
  className,
2784
3000
  children: [
2785
- /* @__PURE__ */ jsx12("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
2786
- /* @__PURE__ */ jsxs7("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
3001
+ /* @__PURE__ */ jsx13("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
3002
+ /* @__PURE__ */ jsxs8("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
2787
3003
  "Use",
2788
3004
  " ",
2789
- /* @__PURE__ */ jsx12(
3005
+ /* @__PURE__ */ jsx13(
2790
3006
  "code",
2791
3007
  {
2792
3008
  style: {
@@ -2806,7 +3022,7 @@ var AnalogSimulationViewer = ({
2806
3022
  }
2807
3023
  );
2808
3024
  }
2809
- return /* @__PURE__ */ jsx12(
3025
+ return /* @__PURE__ */ jsx13(
2810
3026
  "div",
2811
3027
  {
2812
3028
  ref: (node) => {
@@ -2824,7 +3040,7 @@ var AnalogSimulationViewer = ({
2824
3040
  className,
2825
3041
  onMouseDown: handleMouseDown,
2826
3042
  onTouchStart: handleTouchStart,
2827
- children: svgObjectUrl ? /* @__PURE__ */ jsx12(
3043
+ children: svgObjectUrl ? /* @__PURE__ */ jsx13(
2828
3044
  "img",
2829
3045
  {
2830
3046
  ref: imgRef,
@@ -2838,7 +3054,7 @@ var AnalogSimulationViewer = ({
2838
3054
  objectFit: "contain"
2839
3055
  }
2840
3056
  }
2841
- ) : /* @__PURE__ */ jsx12(
3057
+ ) : /* @__PURE__ */ jsx13(
2842
3058
  "div",
2843
3059
  {
2844
3060
  style: {