@tscircuit/schematic-viewer 2.0.54 → 2.0.55

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.54",
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,20 @@ 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 [showGrid, setShowGrid] = useState7(debugGrid);
2427
+ const [isInteractionEnabled, setIsInteractionEnabled] = useState7(
2265
2428
  !clickToInteractEnabled
2266
2429
  );
2267
- const [showViewMenu, setShowViewMenu] = useState6(false);
2268
- const [showSchematicGroups, setShowSchematicGroups] = useState6(() => {
2430
+ const [showViewMenu, setShowViewMenu] = useState7(false);
2431
+ const [showSchematicGroups, setShowSchematicGroups] = useState7(() => {
2269
2432
  if (disableGroups) return false;
2270
2433
  return getStoredBoolean("schematic_viewer_show_groups", false);
2271
2434
  });
2272
- const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState6(false);
2273
- const hoveringComponentsRef = useRef7(/* @__PURE__ */ new Set());
2274
- const handleComponentHoverChange = useCallback5(
2435
+ const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState7(false);
2436
+ const hoveringComponentsRef = useRef8(/* @__PURE__ */ new Set());
2437
+ const handleComponentHoverChange = useCallback6(
2275
2438
  (componentId, isHovering) => {
2276
2439
  if (isHovering) {
2277
2440
  hoveringComponentsRef.current.add(componentId);
@@ -2282,8 +2445,21 @@ var SchematicViewer = ({
2282
2445
  },
2283
2446
  []
2284
2447
  );
2285
- const svgDivRef = useRef7(null);
2286
- const touchStartRef = useRef7(null);
2448
+ const [isHoveringClickablePort, setIsHoveringClickablePort] = useState7(false);
2449
+ const hoveringPortsRef = useRef8(/* @__PURE__ */ new Set());
2450
+ const handlePortHoverChange = useCallback6(
2451
+ (portId, isHovering) => {
2452
+ if (isHovering) {
2453
+ hoveringPortsRef.current.add(portId);
2454
+ } else {
2455
+ hoveringPortsRef.current.delete(portId);
2456
+ }
2457
+ setIsHoveringClickablePort(hoveringPortsRef.current.size > 0);
2458
+ },
2459
+ []
2460
+ );
2461
+ const svgDivRef = useRef8(null);
2462
+ const touchStartRef = useRef8(null);
2287
2463
  const schematicComponentIds = useMemo5(() => {
2288
2464
  try {
2289
2465
  return su6(circuitJson).schematic_component?.list()?.map((component) => component.schematic_component_id) ?? [];
@@ -2292,6 +2468,25 @@ var SchematicViewer = ({
2292
2468
  return [];
2293
2469
  }
2294
2470
  }, [circuitJsonKey, circuitJson]);
2471
+ const schematicPortsInfo = useMemo5(() => {
2472
+ if (!showSchematicPorts) return [];
2473
+ try {
2474
+ const ports = su6(circuitJson).schematic_port?.list() ?? [];
2475
+ return ports.map((port) => {
2476
+ const sourcePort = su6(circuitJson).source_port.get(port.source_port_id);
2477
+ const sourceComponent = sourcePort?.source_component_id ? su6(circuitJson).source_component.get(sourcePort.source_component_id) : null;
2478
+ const componentName = sourceComponent?.name ?? "?";
2479
+ const pinLabel = port.display_pin_label ?? sourcePort?.pin_number ?? sourcePort?.name ?? "?";
2480
+ return {
2481
+ portId: port.source_port_id,
2482
+ label: `${componentName}.${pinLabel}`
2483
+ };
2484
+ });
2485
+ } catch (err) {
2486
+ console.error("Failed to derive schematic port info", err);
2487
+ return [];
2488
+ }
2489
+ }, [circuitJsonKey, circuitJson, showSchematicPorts]);
2295
2490
  const handleTouchStart = (e) => {
2296
2491
  const touch = e.touches[0];
2297
2492
  touchStartRef.current = {
@@ -2311,9 +2506,9 @@ var SchematicViewer = ({
2311
2506
  }
2312
2507
  touchStartRef.current = null;
2313
2508
  };
2314
- const [internalEditEvents, setInternalEditEvents] = useState6([]);
2315
- const circuitJsonRef = useRef7(circuitJson);
2316
- useEffect11(() => {
2509
+ const [internalEditEvents, setInternalEditEvents] = useState7([]);
2510
+ const circuitJsonRef = useRef8(circuitJson);
2511
+ useEffect12(() => {
2317
2512
  const circuitHash = getCircuitHash(circuitJson);
2318
2513
  const circuitHashRef = getCircuitHash(circuitJsonRef.current);
2319
2514
  if (circuitHash !== circuitHashRef) {
@@ -2407,12 +2602,12 @@ var SchematicViewer = ({
2407
2602
  circuitJsonKey,
2408
2603
  showGroups: showSchematicGroups && !disableGroups
2409
2604
  });
2410
- const handleComponentTouchStartRef = useRef7(handleComponentTouchStart);
2411
- useEffect11(() => {
2605
+ const handleComponentTouchStartRef = useRef8(handleComponentTouchStart);
2606
+ useEffect12(() => {
2412
2607
  handleComponentTouchStartRef.current = handleComponentTouchStart;
2413
2608
  }, [handleComponentTouchStart]);
2414
2609
  const svgDiv = useMemo5(
2415
- () => /* @__PURE__ */ jsx11(
2610
+ () => /* @__PURE__ */ jsx12(
2416
2611
  "div",
2417
2612
  {
2418
2613
  ref: svgDivRef,
@@ -2437,9 +2632,10 @@ var SchematicViewer = ({
2437
2632
  showSpiceOverlay
2438
2633
  ]
2439
2634
  );
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(
2635
+ return /* @__PURE__ */ jsxs7(MouseTracker, { children: [
2636
+ onSchematicComponentClicked && /* @__PURE__ */ jsx12("style", { children: `.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }` }),
2637
+ onSchematicPortClicked && /* @__PURE__ */ jsx12("style", { children: `[data-schematic-port-id]:hover { cursor: pointer !important; }` }),
2638
+ /* @__PURE__ */ jsxs7(
2443
2639
  "div",
2444
2640
  {
2445
2641
  ref: containerRef,
@@ -2447,7 +2643,7 @@ var SchematicViewer = ({
2447
2643
  position: "relative",
2448
2644
  backgroundColor: containerBackgroundColor,
2449
2645
  overflow: "hidden",
2450
- cursor: showSpiceOverlay ? "auto" : isDragging ? "grabbing" : clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent && onSchematicComponentClicked ? "pointer" : "grab",
2646
+ cursor: showSpiceOverlay ? "auto" : isDragging ? "grabbing" : clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent && onSchematicComponentClicked ? "pointer" : isHoveringClickablePort && onSchematicPortClicked ? "pointer" : "grab",
2451
2647
  minHeight: "300px",
2452
2648
  ...containerStyle
2453
2649
  },
@@ -2480,7 +2676,7 @@ var SchematicViewer = ({
2480
2676
  handleTouchEnd(e);
2481
2677
  },
2482
2678
  children: [
2483
- !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx11(
2679
+ !isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx12(
2484
2680
  "div",
2485
2681
  {
2486
2682
  onClick: (e) => {
@@ -2499,7 +2695,7 @@ var SchematicViewer = ({
2499
2695
  pointerEvents: "all",
2500
2696
  touchAction: "pan-x pan-y pinch-zoom"
2501
2697
  },
2502
- children: /* @__PURE__ */ jsx11(
2698
+ children: /* @__PURE__ */ jsx12(
2503
2699
  "div",
2504
2700
  {
2505
2701
  style: {
@@ -2516,28 +2712,28 @@ var SchematicViewer = ({
2516
2712
  )
2517
2713
  }
2518
2714
  ),
2519
- /* @__PURE__ */ jsx11(
2715
+ /* @__PURE__ */ jsx12(
2520
2716
  ViewMenuIcon,
2521
2717
  {
2522
2718
  active: showViewMenu,
2523
2719
  onClick: () => setShowViewMenu(!showViewMenu)
2524
2720
  }
2525
2721
  ),
2526
- editingEnabled && /* @__PURE__ */ jsx11(
2722
+ editingEnabled && /* @__PURE__ */ jsx12(
2527
2723
  EditIcon,
2528
2724
  {
2529
2725
  active: editModeEnabled,
2530
2726
  onClick: () => setEditModeEnabled(!editModeEnabled)
2531
2727
  }
2532
2728
  ),
2533
- editingEnabled && editModeEnabled && /* @__PURE__ */ jsx11(
2729
+ editingEnabled && editModeEnabled && /* @__PURE__ */ jsx12(
2534
2730
  GridIcon,
2535
2731
  {
2536
2732
  active: snapToGrid,
2537
2733
  onClick: () => setSnapToGrid(!snapToGrid)
2538
2734
  }
2539
2735
  ),
2540
- /* @__PURE__ */ jsx11(
2736
+ /* @__PURE__ */ jsx12(
2541
2737
  ViewMenu,
2542
2738
  {
2543
2739
  circuitJson,
@@ -2555,8 +2751,8 @@ var SchematicViewer = ({
2555
2751
  onToggleGrid: setShowGrid
2556
2752
  }
2557
2753
  ),
2558
- spiceSimulationEnabled && /* @__PURE__ */ jsx11(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
2559
- showSpiceOverlay && /* @__PURE__ */ jsx11(
2754
+ spiceSimulationEnabled && /* @__PURE__ */ jsx12(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
2755
+ showSpiceOverlay && /* @__PURE__ */ jsx12(
2560
2756
  SpiceSimulationOverlay,
2561
2757
  {
2562
2758
  spiceString,
@@ -2573,7 +2769,7 @@ var SchematicViewer = ({
2573
2769
  hasRun: hasSpiceSimRun
2574
2770
  }
2575
2771
  ),
2576
- onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx11(
2772
+ onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx12(
2577
2773
  SchematicComponentMouseTarget,
2578
2774
  {
2579
2775
  componentId,
@@ -2591,7 +2787,26 @@ var SchematicViewer = ({
2591
2787
  },
2592
2788
  componentId
2593
2789
  )),
2594
- svgDiv
2790
+ svgDiv,
2791
+ showSchematicPorts && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx12(
2792
+ SchematicPortMouseTarget,
2793
+ {
2794
+ portId,
2795
+ portLabel: label,
2796
+ svgDivRef,
2797
+ containerRef,
2798
+ showOutline: true,
2799
+ circuitJsonKey,
2800
+ onHoverChange: handlePortHoverChange,
2801
+ onPortClick: onSchematicPortClicked ? (id, event) => {
2802
+ onSchematicPortClicked?.({
2803
+ schematicPortId: id,
2804
+ event
2805
+ });
2806
+ } : void 0
2807
+ },
2808
+ portId
2809
+ ))
2595
2810
  ]
2596
2811
  }
2597
2812
  )
@@ -2602,10 +2817,10 @@ var SchematicViewer = ({
2602
2817
  import {
2603
2818
  convertCircuitJsonToSchematicSimulationSvg
2604
2819
  } from "circuit-to-svg";
2605
- import { useEffect as useEffect12, useState as useState7, useMemo as useMemo6, useRef as useRef8 } from "react";
2820
+ import { useEffect as useEffect13, useState as useState8, useMemo as useMemo6, useRef as useRef9 } from "react";
2606
2821
  import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
2607
2822
  import { toString as transformToString2 } from "transformation-matrix";
2608
- import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
2823
+ import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2609
2824
  var AnalogSimulationViewer = ({
2610
2825
  circuitJson: inputCircuitJson,
2611
2826
  containerStyle,
@@ -2614,16 +2829,16 @@ var AnalogSimulationViewer = ({
2614
2829
  height,
2615
2830
  className
2616
2831
  }) => {
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);
2832
+ const [circuitJson, setCircuitJson] = useState8(null);
2833
+ const [isLoading, setIsLoading] = useState8(true);
2834
+ const [error, setError] = useState8(null);
2835
+ const [svgObjectUrl, setSvgObjectUrl] = useState8(null);
2836
+ const containerRef = useRef9(null);
2837
+ const imgRef = useRef9(null);
2623
2838
  const { containerWidth, containerHeight } = useResizeHandling(
2624
2839
  containerRef
2625
2840
  );
2626
- const [isDragging, setIsDragging] = useState7(false);
2841
+ const [isDragging, setIsDragging] = useState8(false);
2627
2842
  const {
2628
2843
  ref: transformRef,
2629
2844
  cancelDrag: _cancelDrag,
@@ -2637,7 +2852,7 @@ var AnalogSimulationViewer = ({
2637
2852
  });
2638
2853
  const effectiveWidth = width || containerWidth || 1e3;
2639
2854
  const effectiveHeight = height || containerHeight || 600;
2640
- useEffect12(() => {
2855
+ useEffect13(() => {
2641
2856
  setIsLoading(true);
2642
2857
  setError(null);
2643
2858
  setCircuitJson(inputCircuitJson);
@@ -2678,7 +2893,7 @@ var AnalogSimulationViewer = ({
2678
2893
  simulationExperimentId,
2679
2894
  simulationGraphIds
2680
2895
  ]);
2681
- useEffect12(() => {
2896
+ useEffect13(() => {
2682
2897
  if (!simulationSvg) {
2683
2898
  setSvgObjectUrl(null);
2684
2899
  return;
@@ -2708,7 +2923,7 @@ var AnalogSimulationViewer = ({
2708
2923
  const handleTouchStart = (_e) => {
2709
2924
  setIsDragging(true);
2710
2925
  };
2711
- useEffect12(() => {
2926
+ useEffect13(() => {
2712
2927
  const handleMouseUp = () => {
2713
2928
  setIsDragging(false);
2714
2929
  };
@@ -2723,7 +2938,7 @@ var AnalogSimulationViewer = ({
2723
2938
  };
2724
2939
  }, []);
2725
2940
  if (isLoading) {
2726
- return /* @__PURE__ */ jsx12(
2941
+ return /* @__PURE__ */ jsx13(
2727
2942
  "div",
2728
2943
  {
2729
2944
  style: {
@@ -2743,7 +2958,7 @@ var AnalogSimulationViewer = ({
2743
2958
  );
2744
2959
  }
2745
2960
  if (error) {
2746
- return /* @__PURE__ */ jsx12(
2961
+ return /* @__PURE__ */ jsx13(
2747
2962
  "div",
2748
2963
  {
2749
2964
  style: {
@@ -2758,15 +2973,15 @@ var AnalogSimulationViewer = ({
2758
2973
  ...containerStyle
2759
2974
  },
2760
2975
  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 })
2976
+ children: /* @__PURE__ */ jsxs8("div", { style: { textAlign: "center", padding: "20px" }, children: [
2977
+ /* @__PURE__ */ jsx13("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
2978
+ /* @__PURE__ */ jsx13("div", { style: { fontSize: "14px" }, children: error })
2764
2979
  ] })
2765
2980
  }
2766
2981
  );
2767
2982
  }
2768
2983
  if (!simulationSvg) {
2769
- return /* @__PURE__ */ jsxs7(
2984
+ return /* @__PURE__ */ jsxs8(
2770
2985
  "div",
2771
2986
  {
2772
2987
  style: {
@@ -2782,11 +2997,11 @@ var AnalogSimulationViewer = ({
2782
2997
  },
2783
2998
  className,
2784
2999
  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: [
3000
+ /* @__PURE__ */ jsx13("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
3001
+ /* @__PURE__ */ jsxs8("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
2787
3002
  "Use",
2788
3003
  " ",
2789
- /* @__PURE__ */ jsx12(
3004
+ /* @__PURE__ */ jsx13(
2790
3005
  "code",
2791
3006
  {
2792
3007
  style: {
@@ -2806,7 +3021,7 @@ var AnalogSimulationViewer = ({
2806
3021
  }
2807
3022
  );
2808
3023
  }
2809
- return /* @__PURE__ */ jsx12(
3024
+ return /* @__PURE__ */ jsx13(
2810
3025
  "div",
2811
3026
  {
2812
3027
  ref: (node) => {
@@ -2824,7 +3039,7 @@ var AnalogSimulationViewer = ({
2824
3039
  className,
2825
3040
  onMouseDown: handleMouseDown,
2826
3041
  onTouchStart: handleTouchStart,
2827
- children: svgObjectUrl ? /* @__PURE__ */ jsx12(
3042
+ children: svgObjectUrl ? /* @__PURE__ */ jsx13(
2828
3043
  "img",
2829
3044
  {
2830
3045
  ref: imgRef,
@@ -2838,7 +3053,7 @@ var AnalogSimulationViewer = ({
2838
3053
  objectFit: "contain"
2839
3054
  }
2840
3055
  }
2841
- ) : /* @__PURE__ */ jsx12(
3056
+ ) : /* @__PURE__ */ jsx13(
2842
3057
  "div",
2843
3058
  {
2844
3059
  style: {