Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions lib/components/SchematicViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
} from "circuit-to-svg"
import { su } from "@tscircuit/soup-util"
import { useChangeSchematicComponentLocationsInSvg } from "lib/hooks/useChangeSchematicComponentLocationsInSvg"
import { useHighlightConnectedSchematicTraces } from "lib/hooks/useHighlightConnectedSchematicTraces"
import { useChangeSchematicTracesForMovedComponents } from "lib/hooks/useChangeSchematicTracesForMovedComponents"
import { useSchematicGroupsOverlay } from "lib/hooks/useSchematicGroupsOverlay"
import { enableDebug } from "lib/utils/debug"
Expand Down Expand Up @@ -351,6 +352,13 @@ export const SchematicViewer = ({
editEvents: editEventsWithUnappliedEditEvents,
})

useHighlightConnectedSchematicTraces({
svgDivRef,
circuitJson,
circuitJsonKey,
svgString,
})

// Add group overlays when enabled
useSchematicGroupsOverlay({
svgDivRef,
Expand Down
85 changes: 85 additions & 0 deletions lib/hooks/useHighlightConnectedSchematicTraces.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { useEffect } from "react"
import { su } from "@tscircuit/soup-util"
import type { CircuitJson } from "circuit-json"

interface UseHighlightConnectedSchematicTracesOptions {
svgDivRef: React.RefObject<HTMLDivElement | null>
circuitJson: CircuitJson
circuitJsonKey: string
svgString: string
}

export const useHighlightConnectedSchematicTraces = ({
svgDivRef,
circuitJson,
circuitJsonKey,
svgString,
}: UseHighlightConnectedSchematicTracesOptions) => {
useEffect(() => {
const svgDiv = svgDivRef.current
const svg = svgDiv?.querySelector("svg")
if (!svg) return

const schematicTraces = su(circuitJson).schematic_trace?.list() ?? []
const netKeyToTraceIds = new Map<string, Set<string>>()

for (const trace of schematicTraces) {
const traceId = trace.schematic_trace_id
const netKey = (trace as any).subcircuit_connectivity_map_key
if (!traceId || !netKey) continue

if (!netKeyToTraceIds.has(netKey)) {
netKeyToTraceIds.set(netKey, new Set())
}
netKeyToTraceIds.get(netKey)?.add(traceId)
}

if (netKeyToTraceIds.size === 0) return

const appliedClasses: Array<{
traceGroup: SVGGElement
className: string
}> = []
const cssRules: string[] = []

Array.from(netKeyToTraceIds.entries()).forEach(([, traceIds], netIndex) => {
const className = `schematic-trace-net-${netIndex}`

for (const traceId of traceIds) {
const traceGroups = svg.querySelectorAll<SVGGElement>(
`[data-schematic-trace-id="${traceId}"]`,
)
for (const traceGroup of Array.from(traceGroups)) {
traceGroup.classList.add(className)
appliedClasses.push({ traceGroup, className })
}
}

cssRules.push(`
.${className}:hover,
svg:has(.${className}:hover) .${className} {
filter: invert(1);
}

.${className}:hover .trace-crossing-outline,
svg:has(.${className}:hover) .${className} .trace-crossing-outline {
opacity: 0;
}
`)
})

const style = document.createElementNS(
"http://www.w3.org/2000/svg",
"style",
)
style.textContent = cssRules.join("\n")
svg.prepend(style)

return () => {
for (const { traceGroup, className } of appliedClasses) {
traceGroup.classList.remove(className)
}
style.remove()
}
}, [svgDivRef, circuitJson, circuitJsonKey, svgString])
}
Loading