@tscircuit/schematic-viewer 2.0.68 → 2.0.69

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/dist/index.d.ts CHANGED
@@ -17,6 +17,8 @@ interface Props$1 {
17
17
  colorOverrides?: ColorOverrides;
18
18
  spiceSimulationEnabled?: boolean;
19
19
  disableGroups?: boolean;
20
+ /** Fade unrelated nets/chips when hovering a wire or net label. Default true. */
21
+ netHoverHighlightEnabled?: boolean;
20
22
  css?: string;
21
23
  className?: string;
22
24
  onSchematicComponentClicked?: (options: {
@@ -31,7 +33,7 @@ interface Props$1 {
31
33
  /** Called when the active schematic sheet changes (multi-sheet circuits). */
32
34
  onSchematicSheetChange?: (schematicSheetId: string) => void;
33
35
  }
34
- declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, disableGroups, onSchematicComponentClicked, showSchematicPorts, onSchematicPortClicked, onSchematicSheetChange, css, className, }: Props$1) => react.JSX.Element;
36
+ declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, disableGroups, netHoverHighlightEnabled, onSchematicComponentClicked, showSchematicPorts, onSchematicPortClicked, onSchematicSheetChange, css, className, }: Props$1) => react.JSX.Element;
35
37
 
36
38
  interface BoundingBoxBounds {
37
39
  minX: number;
package/dist/index.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  convertCircuitJsonToSchematicSvg
4
4
  } from "circuit-to-svg";
5
- import { su as su6 } from "@tscircuit/soup-util";
5
+ import { su as su7 } from "@tscircuit/soup-util";
6
6
 
7
7
  // lib/hooks/useChangeSchematicComponentLocationsInSvg.ts
8
8
  import "@tscircuit/soup-util";
@@ -461,6 +461,125 @@ function calculateGroupBounds(components, svg) {
461
461
  return bounds;
462
462
  }
463
463
 
464
+ // lib/hooks/useSchematicNetHover.ts
465
+ import { su as su4 } from "@tscircuit/soup-util";
466
+ import { useEffect as useEffect4 } from "react";
467
+ var FADED_CLASS = "sch-net-faded";
468
+ var TRACE_SELECTOR = "g.trace[data-subcircuit-connectivity-map-key], g.trace-overlays[data-subcircuit-connectivity-map-key]";
469
+ var NET_LABEL_SELECTOR = "[data-schematic-net-label-id]";
470
+ var useSchematicNetHover = ({
471
+ svgDivRef,
472
+ circuitJson,
473
+ circuitJsonKey,
474
+ enabled
475
+ }) => {
476
+ useEffect4(() => {
477
+ const svgDiv = svgDivRef.current;
478
+ if (!enabled || !svgDiv) return;
479
+ const { componentIdToKeys, netLabelIdToKey } = buildNetRegistry(circuitJson);
480
+ let netElements = [];
481
+ const triggerNetKeys = /* @__PURE__ */ new Map();
482
+ let hoveredNetKey = null;
483
+ const collectNetElements = () => {
484
+ for (const { el } of netElements) el.classList.remove(FADED_CLASS);
485
+ netElements = [];
486
+ triggerNetKeys.clear();
487
+ hoveredNetKey = null;
488
+ const svg = svgDiv.querySelector("svg");
489
+ if (!svg) return;
490
+ for (const el of Array.from(svg.querySelectorAll(TRACE_SELECTOR))) {
491
+ const key = el.getAttribute("data-subcircuit-connectivity-map-key");
492
+ const keys = /* @__PURE__ */ new Set();
493
+ if (key) {
494
+ keys.add(key);
495
+ triggerNetKeys.set(el, key);
496
+ }
497
+ netElements.push({ el, keys });
498
+ }
499
+ for (const el of Array.from(
500
+ svg.querySelectorAll("g[data-schematic-component-id]")
501
+ )) {
502
+ const id = el.getAttribute("data-schematic-component-id");
503
+ netElements.push({ el, keys: componentIdToKeys.get(id) ?? /* @__PURE__ */ new Set() });
504
+ }
505
+ for (const el of Array.from(svg.querySelectorAll(NET_LABEL_SELECTOR))) {
506
+ const key = netLabelIdToKey.get(
507
+ el.getAttribute("data-schematic-net-label-id")
508
+ );
509
+ const keys = /* @__PURE__ */ new Set();
510
+ if (key) {
511
+ keys.add(key);
512
+ triggerNetKeys.set(el, key);
513
+ }
514
+ netElements.push({ el, keys });
515
+ }
516
+ };
517
+ const highlightNet = (key) => {
518
+ if (key === hoveredNetKey) return;
519
+ hoveredNetKey = key;
520
+ for (const { el, keys } of netElements) {
521
+ el.classList.toggle(FADED_CLASS, key !== null && !keys.has(key));
522
+ }
523
+ };
524
+ const handleMouseOver = (e) => {
525
+ const target = e.target;
526
+ if (!(target instanceof Element)) {
527
+ highlightNet(null);
528
+ return;
529
+ }
530
+ const trigger = target.closest(`${TRACE_SELECTOR}, ${NET_LABEL_SELECTOR}`);
531
+ if (!trigger) {
532
+ highlightNet(null);
533
+ return;
534
+ }
535
+ highlightNet(triggerNetKeys.get(trigger) ?? null);
536
+ };
537
+ const handleMouseLeave = () => highlightNet(null);
538
+ collectNetElements();
539
+ svgDiv.addEventListener("mouseover", handleMouseOver);
540
+ svgDiv.addEventListener("mouseleave", handleMouseLeave);
541
+ const observer = new MutationObserver(collectNetElements);
542
+ observer.observe(svgDiv, { childList: true });
543
+ return () => {
544
+ observer.disconnect();
545
+ svgDiv.removeEventListener("mouseover", handleMouseOver);
546
+ svgDiv.removeEventListener("mouseleave", handleMouseLeave);
547
+ for (const { el } of netElements) el.classList.remove(FADED_CLASS);
548
+ };
549
+ }, [svgDivRef, circuitJsonKey, enabled]);
550
+ };
551
+ function buildNetRegistry(circuitJson) {
552
+ const cju = su4(circuitJson);
553
+ const srcCompToSchComp = /* @__PURE__ */ new Map();
554
+ for (const c of cju.schematic_component.list()) {
555
+ if (c.source_component_id) {
556
+ srcCompToSchComp.set(c.source_component_id, c.schematic_component_id);
557
+ }
558
+ }
559
+ const componentIdToKeys = /* @__PURE__ */ new Map();
560
+ for (const sourceTrace of cju.source_trace.list()) {
561
+ const key = sourceTrace.subcircuit_connectivity_map_key;
562
+ if (!key) continue;
563
+ for (const portId of sourceTrace.connected_source_port_ids ?? []) {
564
+ const schCompId = srcCompToSchComp.get(
565
+ cju.source_port.get(portId)?.source_component_id ?? ""
566
+ );
567
+ if (!schCompId) continue;
568
+ if (!componentIdToKeys.has(schCompId)) {
569
+ componentIdToKeys.set(schCompId, /* @__PURE__ */ new Set());
570
+ }
571
+ componentIdToKeys.get(schCompId).add(key);
572
+ }
573
+ }
574
+ const netLabelIdToKey = /* @__PURE__ */ new Map();
575
+ for (const label of cju.schematic_net_label.list()) {
576
+ if (!label.source_net_id) continue;
577
+ const key = cju.source_net.get(label.source_net_id)?.subcircuit_connectivity_map_key ?? label.source_net_id;
578
+ netLabelIdToKey.set(label.schematic_net_label_id, key);
579
+ }
580
+ return { componentIdToKeys, netLabelIdToKey };
581
+ }
582
+
464
583
  // lib/utils/debug.ts
465
584
  import Debug from "debug";
466
585
  var debug = Debug("schematic-viewer");
@@ -470,7 +589,7 @@ var enableDebug = () => {
470
589
  var debug_default = debug;
471
590
 
472
591
  // lib/components/SchematicViewer.tsx
473
- import { useCallback as useCallback6, useEffect as useEffect12, useMemo as useMemo5, useRef as useRef8, useState as useState8 } from "react";
592
+ import { useCallback as useCallback6, useEffect as useEffect13, useMemo as useMemo5, useRef as useRef8, useState as useState8 } from "react";
474
593
  import {
475
594
  fromString,
476
595
  identity,
@@ -479,11 +598,11 @@ import {
479
598
  import { useMouseMatrixTransform } from "use-mouse-matrix-transform";
480
599
 
481
600
  // lib/hooks/use-resize-handling.ts
482
- import { useEffect as useEffect4, useState } from "react";
601
+ import { useEffect as useEffect5, useState } from "react";
483
602
  var useResizeHandling = (containerRef) => {
484
603
  const [containerWidth, setContainerWidth] = useState(0);
485
604
  const [containerHeight, setContainerHeight] = useState(0);
486
- useEffect4(() => {
605
+ useEffect5(() => {
487
606
  if (!containerRef.current) return;
488
607
  const updateDimensions = () => {
489
608
  const rect = containerRef.current?.getBoundingClientRect();
@@ -503,8 +622,8 @@ var useResizeHandling = (containerRef) => {
503
622
  };
504
623
 
505
624
  // lib/hooks/useComponentDragging.ts
506
- import { su as su4 } from "@tscircuit/soup-util";
507
- import { useCallback, useEffect as useEffect5, useRef as useRef3, useState as useState2 } from "react";
625
+ import { su as su5 } from "@tscircuit/soup-util";
626
+ import { useCallback, useEffect as useEffect6, useRef as useRef3, useState as useState2 } from "react";
508
627
  import { compose as compose2 } from "transformation-matrix";
509
628
  var debug2 = debug_default.extend("useComponentDragging");
510
629
  var useComponentDragging = ({
@@ -527,7 +646,7 @@ var useComponentDragging = ({
527
646
  const componentPositionsRef = useRef3(
528
647
  /* @__PURE__ */ new Map()
529
648
  );
530
- useEffect5(() => {
649
+ useEffect6(() => {
531
650
  editEvents.forEach((event) => {
532
651
  if ("edit_event_type" in event && event.edit_event_type === "edit_schematic_component_location" && !event.in_progress) {
533
652
  componentPositionsRef.current.set(event.schematic_component_id, {
@@ -548,7 +667,7 @@ var useComponentDragging = ({
548
667
  );
549
668
  if (!schematic_component_id) return false;
550
669
  if (cancelDrag) cancelDrag();
551
- const schematic_component = su4(circuitJson).schematic_component.get(
670
+ const schematic_component = su5(circuitJson).schematic_component.get(
552
671
  schematic_component_id
553
672
  );
554
673
  if (!schematic_component) return false;
@@ -664,7 +783,7 @@ var useComponentDragging = ({
664
783
  }, [onEditEvent]);
665
784
  const handleMouseUp = useCallback(() => endDrag(), [endDrag]);
666
785
  const handleTouchEnd = useCallback(() => endDrag(), [endDrag]);
667
- useEffect5(() => {
786
+ useEffect6(() => {
668
787
  window.addEventListener("mousemove", handleMouseMove);
669
788
  window.addEventListener("mouseup", handleMouseUp);
670
789
  window.addEventListener("touchmove", handleTouchMove, { passive: false });
@@ -796,13 +915,13 @@ var GridIcon = ({
796
915
 
797
916
  // lib/components/ViewMenu.tsx
798
917
  import { useMemo } from "react";
799
- import { su as su5 } from "@tscircuit/soup-util";
918
+ import { su as su6 } from "@tscircuit/soup-util";
800
919
  import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
801
920
 
802
921
  // package.json
803
922
  var package_default = {
804
923
  name: "@tscircuit/schematic-viewer",
805
- version: "2.0.67",
924
+ version: "2.0.68",
806
925
  main: "dist/index.js",
807
926
  type: "module",
808
927
  scripts: {
@@ -832,7 +951,7 @@ var package_default = {
832
951
  "react-dom": "^19.1.0",
833
952
  "react-reconciler": "^0.31.0",
834
953
  semver: "^7.7.2",
835
- tscircuit: "^0.0.1972",
954
+ tscircuit: "^0.0.2012",
836
955
  tsup: "^8.3.5",
837
956
  vite: "^6.0.3"
838
957
  },
@@ -976,13 +1095,13 @@ var ViewMenu = ({
976
1095
  const hasGroups = useMemo(() => {
977
1096
  if (!circuitJson || circuitJson.length === 0) return false;
978
1097
  try {
979
- const sourceGroups = su5(circuitJson).source_group?.list() || [];
1098
+ const sourceGroups = su6(circuitJson).source_group?.list() || [];
980
1099
  if (sourceGroups.length > 0) return true;
981
- const schematicComponents = su5(circuitJson).schematic_component?.list() || [];
1100
+ const schematicComponents = su6(circuitJson).schematic_component?.list() || [];
982
1101
  if (schematicComponents.length > 1) {
983
1102
  const componentTypes = /* @__PURE__ */ new Set();
984
1103
  for (const comp of schematicComponents) {
985
- const sourceComp = su5(circuitJson).source_component.get(
1104
+ const sourceComp = su6(circuitJson).source_component.get(
986
1105
  comp.source_component_id
987
1106
  );
988
1107
  if (sourceComp?.ftype) {
@@ -1312,7 +1431,7 @@ var SpicePlot = ({
1312
1431
  };
1313
1432
 
1314
1433
  // lib/components/SpiceSimulationOverlay.tsx
1315
- import { useEffect as useEffect6, useState as useState3 } from "react";
1434
+ import { useEffect as useEffect7, useState as useState3 } from "react";
1316
1435
  import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
1317
1436
  var SpiceSimulationOverlay = ({
1318
1437
  spiceString,
@@ -1331,7 +1450,7 @@ var SpiceSimulationOverlay = ({
1331
1450
  const [durationDraft, setDurationDraft] = useState3(
1332
1451
  String(simOptions.duration)
1333
1452
  );
1334
- useEffect6(() => {
1453
+ useEffect7(() => {
1335
1454
  setStartTimeDraft(String(simOptions.startTime));
1336
1455
  setDurationDraft(String(simOptions.duration));
1337
1456
  }, [simOptions.startTime, simOptions.duration]);
@@ -1578,7 +1697,7 @@ var SpiceSimulationOverlay = ({
1578
1697
  };
1579
1698
 
1580
1699
  // lib/hooks/useSpiceSimulation.ts
1581
- import { useState as useState4, useEffect as useEffect7 } from "react";
1700
+ import { useState as useState4, useEffect as useEffect8 } from "react";
1582
1701
 
1583
1702
  // lib/workers/spice-simulation.worker.blob.js
1584
1703
  var b64 = "dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=";
@@ -1633,7 +1752,7 @@ var useSpiceSimulation = (spiceString) => {
1633
1752
  const [nodes, setNodes] = useState4([]);
1634
1753
  const [isLoading, setIsLoading] = useState4(true);
1635
1754
  const [error, setError] = useState4(null);
1636
- useEffect7(() => {
1755
+ useEffect8(() => {
1637
1756
  if (!spiceString) {
1638
1757
  setIsLoading(false);
1639
1758
  setPlotData([]);
@@ -1812,7 +1931,7 @@ import {
1812
1931
  createContext,
1813
1932
  useCallback as useCallback3,
1814
1933
  useContext,
1815
- useEffect as useEffect8,
1934
+ useEffect as useEffect9,
1816
1935
  useMemo as useMemo3,
1817
1936
  useRef as useRef4
1818
1937
  } from "react";
@@ -1896,7 +2015,7 @@ var MouseTracker = ({ children }) => {
1896
2015
  const isHovering = useCallback3((id) => {
1897
2016
  return storeRef.current.hoveringIds.has(id);
1898
2017
  }, []);
1899
- useEffect8(() => {
2018
+ useEffect9(() => {
1900
2019
  const handlePointerPosition = (event) => {
1901
2020
  const { clientX, clientY } = event;
1902
2021
  const pointer = storeRef.current.pointer;
@@ -1984,12 +2103,12 @@ var MouseTracker = ({ children }) => {
1984
2103
  };
1985
2104
 
1986
2105
  // lib/components/SchematicComponentMouseTarget.tsx
1987
- import { useCallback as useCallback4, useEffect as useEffect10, useRef as useRef6, useState as useState5 } from "react";
2106
+ import { useCallback as useCallback4, useEffect as useEffect11, useRef as useRef6, useState as useState5 } from "react";
1988
2107
 
1989
2108
  // lib/hooks/useMouseEventsOverBoundingBox.ts
1990
2109
  import {
1991
2110
  useContext as useContext2,
1992
- useEffect as useEffect9,
2111
+ useEffect as useEffect10,
1993
2112
  useId,
1994
2113
  useMemo as useMemo4,
1995
2114
  useRef as useRef5,
@@ -2011,7 +2130,7 @@ var useMouseEventsOverBoundingBox = (options) => {
2011
2130
  },
2012
2131
  []
2013
2132
  );
2014
- useEffect9(() => {
2133
+ useEffect10(() => {
2015
2134
  context.registerBoundingBox(id, {
2016
2135
  bounds: latestOptionsRef.current.bounds,
2017
2136
  onClick: latestOptionsRef.current.onClick ? handleClick : void 0
@@ -2020,7 +2139,7 @@ var useMouseEventsOverBoundingBox = (options) => {
2020
2139
  context.unregisterBoundingBox(id);
2021
2140
  };
2022
2141
  }, [context, handleClick, id]);
2023
- useEffect9(() => {
2142
+ useEffect10(() => {
2024
2143
  context.updateBoundingBox(id, {
2025
2144
  bounds: latestOptionsRef.current.bounds,
2026
2145
  onClick: latestOptionsRef.current.onClick ? handleClick : void 0
@@ -2100,10 +2219,10 @@ var SchematicComponentMouseTarget = ({
2100
2219
  if (frameRef.current !== null) return;
2101
2220
  frameRef.current = window.requestAnimationFrame(measure);
2102
2221
  }, [measure]);
2103
- useEffect10(() => {
2222
+ useEffect11(() => {
2104
2223
  scheduleMeasure();
2105
2224
  }, [scheduleMeasure, circuitJsonKey]);
2106
- useEffect10(() => {
2225
+ useEffect11(() => {
2107
2226
  scheduleMeasure();
2108
2227
  const svgDiv = svgDivRef.current;
2109
2228
  const container = containerRef.current;
@@ -2148,7 +2267,7 @@ var SchematicComponentMouseTarget = ({
2148
2267
  bounds,
2149
2268
  onClick: onComponentClick ? handleClick : void 0
2150
2269
  });
2151
- useEffect10(() => {
2270
+ useEffect11(() => {
2152
2271
  if (onHoverChange) {
2153
2272
  onHoverChange(componentId, hovering);
2154
2273
  }
@@ -2175,7 +2294,7 @@ var SchematicComponentMouseTarget = ({
2175
2294
  };
2176
2295
 
2177
2296
  // lib/components/SchematicPortMouseTarget.tsx
2178
- import { useCallback as useCallback5, useEffect as useEffect11, useRef as useRef7, useState as useState6 } from "react";
2297
+ import { useCallback as useCallback5, useEffect as useEffect12, useRef as useRef7, useState as useState6 } from "react";
2179
2298
  import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
2180
2299
  var areMeasurementsEqual2 = (a, b) => {
2181
2300
  if (!a && !b) return true;
@@ -2234,10 +2353,10 @@ var SchematicPortMouseTarget = ({
2234
2353
  if (frameRef.current !== null) return;
2235
2354
  frameRef.current = window.requestAnimationFrame(measure);
2236
2355
  }, [measure]);
2237
- useEffect11(() => {
2356
+ useEffect12(() => {
2238
2357
  scheduleMeasure();
2239
2358
  }, [scheduleMeasure, circuitJsonKey]);
2240
- useEffect11(() => {
2359
+ useEffect12(() => {
2241
2360
  scheduleMeasure();
2242
2361
  const svgDiv = svgDivRef.current;
2243
2362
  const container = containerRef.current;
@@ -2282,7 +2401,7 @@ var SchematicPortMouseTarget = ({
2282
2401
  bounds,
2283
2402
  onClick: onPortClick ? handleClick : void 0
2284
2403
  });
2285
- useEffect11(() => {
2404
+ useEffect12(() => {
2286
2405
  if (onHoverChange) {
2287
2406
  onHoverChange(portId, hovering);
2288
2407
  }
@@ -2516,6 +2635,7 @@ var SchematicViewer = ({
2516
2635
  colorOverrides,
2517
2636
  spiceSimulationEnabled = false,
2518
2637
  disableGroups = false,
2638
+ netHoverHighlightEnabled = true,
2519
2639
  onSchematicComponentClicked,
2520
2640
  showSchematicPorts = false,
2521
2641
  onSchematicPortClicked,
@@ -2561,7 +2681,7 @@ var SchematicViewer = ({
2561
2681
  return defaultSheetId;
2562
2682
  }
2563
2683
  );
2564
- useEffect12(() => {
2684
+ useEffect13(() => {
2565
2685
  const stillExists = selectedSheetId !== void 0 && schematicSheets.some((s) => s.schematic_sheet_id === selectedSheetId);
2566
2686
  if (!stillExists) {
2567
2687
  setSelectedSheetId(defaultSheetId);
@@ -2591,7 +2711,7 @@ var SchematicViewer = ({
2591
2711
  spiceSimOptions.duration
2592
2712
  ]);
2593
2713
  const [hasSpiceSimRun, setHasSpiceSimRun] = useState8(false);
2594
- useEffect12(() => {
2714
+ useEffect13(() => {
2595
2715
  setHasSpiceSimRun(false);
2596
2716
  }, [circuitJsonKey]);
2597
2717
  const {
@@ -2642,7 +2762,7 @@ var SchematicViewer = ({
2642
2762
  const touchStartRef = useRef8(null);
2643
2763
  const schematicComponentIds = useMemo5(() => {
2644
2764
  try {
2645
- const components = su6(circuitJson).schematic_component?.list() ?? [];
2765
+ const components = su7(circuitJson).schematic_component?.list() ?? [];
2646
2766
  return components.filter(
2647
2767
  (component) => !activeSheetId || component.schematic_sheet_id === activeSheetId
2648
2768
  ).map((component) => component.schematic_component_id);
@@ -2654,12 +2774,12 @@ var SchematicViewer = ({
2654
2774
  const schematicPortsInfo = useMemo5(() => {
2655
2775
  if (!showSchematicPorts) return [];
2656
2776
  try {
2657
- const ports = (su6(circuitJson).schematic_port?.list() ?? []).filter(
2777
+ const ports = (su7(circuitJson).schematic_port?.list() ?? []).filter(
2658
2778
  (port) => !activeSheetId || port.schematic_sheet_id === activeSheetId
2659
2779
  );
2660
2780
  return ports.map((port) => {
2661
- const sourcePort = su6(circuitJson).source_port.get(port.source_port_id);
2662
- const sourceComponent = sourcePort?.source_component_id ? su6(circuitJson).source_component.get(sourcePort.source_component_id) : null;
2781
+ const sourcePort = su7(circuitJson).source_port.get(port.source_port_id);
2782
+ const sourceComponent = sourcePort?.source_component_id ? su7(circuitJson).source_component.get(sourcePort.source_component_id) : null;
2663
2783
  const componentName = sourceComponent?.name ?? "?";
2664
2784
  const pinLabel = port.display_pin_label ?? sourcePort?.pin_number ?? sourcePort?.name ?? "?";
2665
2785
  return {
@@ -2693,7 +2813,7 @@ var SchematicViewer = ({
2693
2813
  };
2694
2814
  const [internalEditEvents, setInternalEditEvents] = useState8([]);
2695
2815
  const circuitJsonRef = useRef8(circuitJson);
2696
- useEffect12(() => {
2816
+ useEffect13(() => {
2697
2817
  const circuitHash = getCircuitHash(circuitJson);
2698
2818
  const circuitHashRef = getCircuitHash(circuitJsonRef.current);
2699
2819
  if (circuitHash !== circuitHashRef) {
@@ -2798,8 +2918,14 @@ var SchematicViewer = ({
2798
2918
  circuitJsonKey: `${circuitJsonKey}_${activeSheetId ?? ""}`,
2799
2919
  showGroups: showSchematicGroups && !disableGroups
2800
2920
  });
2921
+ useSchematicNetHover({
2922
+ svgDivRef,
2923
+ circuitJson,
2924
+ circuitJsonKey: `${circuitJsonKey}_${activeSheetId ?? ""}`,
2925
+ enabled: netHoverHighlightEnabled
2926
+ });
2801
2927
  const handleComponentTouchStartRef = useRef8(handleComponentTouchStart);
2802
- useEffect12(() => {
2928
+ useEffect13(() => {
2803
2929
  handleComponentTouchStartRef.current = handleComponentTouchStart;
2804
2930
  }, [handleComponentTouchStart]);
2805
2931
  const svgDiv = useMemo5(
@@ -2829,6 +2955,8 @@ var SchematicViewer = ({
2829
2955
  ]
2830
2956
  );
2831
2957
  return /* @__PURE__ */ jsxs8(MouseTracker, { children: [
2958
+ netHoverHighlightEnabled && /* @__PURE__ */ jsx13("style", { children: `.sch-net-faded { opacity: 0.35; }
2959
+ svg :is(g.trace, g.trace-overlays, g[data-schematic-component-id], [data-schematic-net-label-id]) { transition: opacity 0.12s ease-in-out; }` }),
2832
2960
  onSchematicComponentClicked && /* @__PURE__ */ jsx13("style", { children: `.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }` }),
2833
2961
  onSchematicPortClicked && /* @__PURE__ */ jsx13("style", { children: `[data-schematic-port-id]:hover { cursor: pointer !important; }` }),
2834
2962
  /* @__PURE__ */ jsxs8(
@@ -3014,7 +3142,7 @@ var SchematicViewer = ({
3014
3142
  import {
3015
3143
  convertCircuitJsonToSchematicSimulationSvg
3016
3144
  } from "circuit-to-svg";
3017
- import { useEffect as useEffect13, useState as useState9, useMemo as useMemo6, useRef as useRef9 } from "react";
3145
+ import { useEffect as useEffect14, useState as useState9, useMemo as useMemo6, useRef as useRef9 } from "react";
3018
3146
  import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
3019
3147
  import { toString as transformToString2 } from "transformation-matrix";
3020
3148
  import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
@@ -3052,7 +3180,7 @@ var AnalogSimulationViewer = ({
3052
3180
  const renderAspectRatio = width && height ? width / height : DEFAULT_RENDER_ASPECT_RATIO;
3053
3181
  const effectiveWidth = width || (height ? height * renderAspectRatio : containerWidth) || DEFAULT_RENDER_WIDTH;
3054
3182
  const effectiveHeight = height || effectiveWidth / renderAspectRatio;
3055
- useEffect13(() => {
3183
+ useEffect14(() => {
3056
3184
  setIsLoading(true);
3057
3185
  setError(null);
3058
3186
  setCircuitJson(inputCircuitJson);
@@ -3099,7 +3227,7 @@ var AnalogSimulationViewer = ({
3099
3227
  simulationCurrentGraphIds,
3100
3228
  simulationVoltageGraphIds
3101
3229
  ]);
3102
- useEffect13(() => {
3230
+ useEffect14(() => {
3103
3231
  if (!simulationSvg) {
3104
3232
  setSvgObjectUrl(null);
3105
3233
  return;
@@ -3129,7 +3257,7 @@ var AnalogSimulationViewer = ({
3129
3257
  const handleTouchStart = (_e) => {
3130
3258
  setIsDragging(true);
3131
3259
  };
3132
- useEffect13(() => {
3260
+ useEffect14(() => {
3133
3261
  const handleMouseUp = () => {
3134
3262
  setIsDragging(false);
3135
3263
  };