@tscircuit/schematic-viewer 2.0.81 → 2.0.85
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 +3 -1
- package/dist/index.js +1205 -212
- package/dist/index.js.map +1 -1
- package/package.json +5 -1
package/dist/index.js
CHANGED
|
@@ -430,6 +430,321 @@ function buildNetRegistry(circuitJson) {
|
|
|
430
430
|
return { componentIdToKeys, netLabelIdToKey };
|
|
431
431
|
}
|
|
432
432
|
|
|
433
|
+
// lib/hooks/useSchematicSearch.ts
|
|
434
|
+
import { useCallback as useCallback2, useEffect as useEffect3, useMemo, useRef, useState } from "react";
|
|
435
|
+
import { fromString } from "transformation-matrix";
|
|
436
|
+
|
|
437
|
+
// lib/utils/get-schematic-search-results.ts
|
|
438
|
+
var normalize = (value) => String(value ?? "").toLocaleLowerCase();
|
|
439
|
+
var getTextMatchScore = (text, query) => {
|
|
440
|
+
const normalizedText = normalize(text);
|
|
441
|
+
if (normalizedText === query) return 0;
|
|
442
|
+
if (normalizedText.startsWith(query)) return 1;
|
|
443
|
+
if (normalizedText.includes(query)) return 2;
|
|
444
|
+
return Number.POSITIVE_INFINITY;
|
|
445
|
+
};
|
|
446
|
+
var humanizeComponentType = (ftype) => {
|
|
447
|
+
if (!ftype) return void 0;
|
|
448
|
+
return String(ftype).replace(/^simple_/, "").replaceAll("_", " ").replace(/\b\w/g, (character) => character.toLocaleUpperCase());
|
|
449
|
+
};
|
|
450
|
+
var getComponentDetail = (sourceComponent, schematicComponent, primaryLabel) => {
|
|
451
|
+
const componentType = humanizeComponentType(sourceComponent?.ftype);
|
|
452
|
+
let displayName;
|
|
453
|
+
if (sourceComponent?.display_name !== primaryLabel) {
|
|
454
|
+
displayName = sourceComponent?.display_name;
|
|
455
|
+
}
|
|
456
|
+
let componentValue = sourceComponent?.display_value;
|
|
457
|
+
if (!componentValue && sourceComponent) {
|
|
458
|
+
for (const displayField of [
|
|
459
|
+
"display_resistance",
|
|
460
|
+
"display_capacitance",
|
|
461
|
+
"display_inductance",
|
|
462
|
+
"display_frequency",
|
|
463
|
+
"symbol_display_value"
|
|
464
|
+
]) {
|
|
465
|
+
if (displayField in sourceComponent) {
|
|
466
|
+
const displayedMeasurement = sourceComponent[displayField];
|
|
467
|
+
if (typeof displayedMeasurement === "string") {
|
|
468
|
+
componentValue = displayedMeasurement;
|
|
469
|
+
break;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
componentValue ?? (componentValue = schematicComponent.symbol_display_value);
|
|
475
|
+
if (componentType && componentValue) {
|
|
476
|
+
return `${componentType} \xB7 ${componentValue}`;
|
|
477
|
+
}
|
|
478
|
+
return componentValue ?? displayName ?? sourceComponent?.manufacturer_part_number ?? componentType;
|
|
479
|
+
};
|
|
480
|
+
var isSourceComponent = (element) => element.type === "source_component" && "source_component_id" in element;
|
|
481
|
+
var isSourcePort = (element) => element.type === "source_port";
|
|
482
|
+
var isSourceTrace = (element) => element.type === "source_trace";
|
|
483
|
+
var isSchematicComponent = (element) => element.type === "schematic_component";
|
|
484
|
+
var isSchematicPort = (element) => element.type === "schematic_port";
|
|
485
|
+
var isSchematicNetLabel = (element) => element.type === "schematic_net_label";
|
|
486
|
+
var isSchematicSheet = (element) => element.type === "schematic_sheet";
|
|
487
|
+
var getSchematicSheetName = ({
|
|
488
|
+
schematicSheets,
|
|
489
|
+
schematicSheetId
|
|
490
|
+
}) => {
|
|
491
|
+
if (schematicSheets.length <= 1 || !schematicSheetId) return void 0;
|
|
492
|
+
return schematicSheets.find(
|
|
493
|
+
(sheet) => sheet.schematic_sheet_id === schematicSheetId
|
|
494
|
+
)?.name;
|
|
495
|
+
};
|
|
496
|
+
var getSchematicSearchResults = (circuitJson, query) => {
|
|
497
|
+
const normalizedQuery = normalize(query).trim();
|
|
498
|
+
if (!normalizedQuery) return [];
|
|
499
|
+
const sourceComponents = new Map(
|
|
500
|
+
circuitJson.filter(isSourceComponent).map((element) => [element.source_component_id, element])
|
|
501
|
+
);
|
|
502
|
+
const sourcePorts = new Map(
|
|
503
|
+
circuitJson.filter(isSourcePort).map((element) => [element.source_port_id, element])
|
|
504
|
+
);
|
|
505
|
+
const schematicPorts = circuitJson.filter(isSchematicPort);
|
|
506
|
+
const sourceTraces = circuitJson.filter(isSourceTrace);
|
|
507
|
+
const schematicSheets = circuitJson.filter(isSchematicSheet);
|
|
508
|
+
const results = [];
|
|
509
|
+
const resultScores = /* @__PURE__ */ new Map();
|
|
510
|
+
for (const component of circuitJson.filter(isSchematicComponent)) {
|
|
511
|
+
const sourceComponent = component.source_component_id ? sourceComponents.get(component.source_component_id) : void 0;
|
|
512
|
+
const primaryLabel = sourceComponent?.name ?? sourceComponent?.display_name ?? "Component";
|
|
513
|
+
const componentScore = getTextMatchScore(primaryLabel, normalizedQuery);
|
|
514
|
+
if (Number.isFinite(componentScore)) {
|
|
515
|
+
const result = {
|
|
516
|
+
label: primaryLabel,
|
|
517
|
+
detail: getComponentDetail(sourceComponent, component, primaryLabel),
|
|
518
|
+
kind: "component",
|
|
519
|
+
schematicSheetId: component.schematic_sheet_id,
|
|
520
|
+
schematicSheetName: getSchematicSheetName({
|
|
521
|
+
schematicSheets,
|
|
522
|
+
schematicSheetId: component.schematic_sheet_id
|
|
523
|
+
}),
|
|
524
|
+
target: {
|
|
525
|
+
type: "schematic_component",
|
|
526
|
+
id: component.schematic_component_id
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
results.push(result);
|
|
530
|
+
resultScores.set(result, componentScore);
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
for (const netLabel of circuitJson.filter(isSchematicNetLabel)) {
|
|
534
|
+
if (!normalize(netLabel.text).includes(normalizedQuery)) continue;
|
|
535
|
+
const connectedPortIds = /* @__PURE__ */ new Set();
|
|
536
|
+
for (const trace of sourceTraces.filter(
|
|
537
|
+
(sourceTrace) => sourceTrace.connected_source_net_ids.includes(netLabel.source_net_id)
|
|
538
|
+
)) {
|
|
539
|
+
for (const portId of trace.connected_source_port_ids) {
|
|
540
|
+
connectedPortIds.add(portId);
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
const anchorPosition = netLabel.anchor_position ?? netLabel.center;
|
|
544
|
+
const nearestConnectedPort = schematicPorts.filter(
|
|
545
|
+
(port) => connectedPortIds.has(port.source_port_id) && (!netLabel.schematic_sheet_id || !port.schematic_sheet_id || port.schematic_sheet_id === netLabel.schematic_sheet_id)
|
|
546
|
+
).map((port) => ({
|
|
547
|
+
port,
|
|
548
|
+
distance: Math.hypot(
|
|
549
|
+
port.center.x - anchorPosition.x,
|
|
550
|
+
port.center.y - anchorPosition.y
|
|
551
|
+
)
|
|
552
|
+
})).filter(({ distance }) => distance <= 1).sort((a, b) => a.distance - b.distance)[0]?.port;
|
|
553
|
+
const sourcePort = nearestConnectedPort ? sourcePorts.get(nearestConnectedPort.source_port_id) : void 0;
|
|
554
|
+
const connectedComponent = sourcePort?.source_component_id ? sourceComponents.get(sourcePort.source_component_id) : void 0;
|
|
555
|
+
const connectedPinName = sourcePort?.name ?? (sourcePort?.pin_number !== void 0 ? `pin${sourcePort.pin_number}` : nearestConnectedPort?.display_pin_label);
|
|
556
|
+
const connectionLabel = connectedComponent?.name && connectedPinName ? `Connected to ${connectedComponent.name}.${connectedPinName}` : void 0;
|
|
557
|
+
const result = {
|
|
558
|
+
label: netLabel.text,
|
|
559
|
+
detail: connectionLabel,
|
|
560
|
+
kind: "net",
|
|
561
|
+
schematicSheetId: netLabel.schematic_sheet_id,
|
|
562
|
+
schematicSheetName: getSchematicSheetName({
|
|
563
|
+
schematicSheets,
|
|
564
|
+
schematicSheetId: netLabel.schematic_sheet_id
|
|
565
|
+
}),
|
|
566
|
+
target: {
|
|
567
|
+
type: "schematic_net_label",
|
|
568
|
+
id: netLabel.schematic_net_label_id
|
|
569
|
+
}
|
|
570
|
+
};
|
|
571
|
+
results.push(result);
|
|
572
|
+
resultScores.set(result, getTextMatchScore(netLabel.text, normalizedQuery));
|
|
573
|
+
}
|
|
574
|
+
return results.sort((a, b) => {
|
|
575
|
+
return (resultScores.get(a) ?? Number.POSITIVE_INFINITY) - (resultScores.get(b) ?? Number.POSITIVE_INFINITY) || a.label.localeCompare(b.label);
|
|
576
|
+
});
|
|
577
|
+
};
|
|
578
|
+
|
|
579
|
+
// lib/utils/get-search-result-transform.ts
|
|
580
|
+
var getSearchResultTransform = ({
|
|
581
|
+
containerRect,
|
|
582
|
+
targetRect,
|
|
583
|
+
visibleProjection,
|
|
584
|
+
minimumScale
|
|
585
|
+
}) => {
|
|
586
|
+
const currentScale = visibleProjection.a || 1;
|
|
587
|
+
const targetCenterInContainer = {
|
|
588
|
+
x: targetRect.left + targetRect.width / 2 - containerRect.left,
|
|
589
|
+
y: targetRect.top + targetRect.height / 2 - containerRect.top
|
|
590
|
+
};
|
|
591
|
+
const targetCenterBeforeViewerTransform = {
|
|
592
|
+
x: (targetCenterInContainer.x - visibleProjection.e) / currentScale,
|
|
593
|
+
y: (targetCenterInContainer.y - visibleProjection.f) / currentScale
|
|
594
|
+
};
|
|
595
|
+
const targetScale = Math.max(currentScale, minimumScale);
|
|
596
|
+
return {
|
|
597
|
+
a: targetScale,
|
|
598
|
+
b: 0,
|
|
599
|
+
c: 0,
|
|
600
|
+
d: targetScale,
|
|
601
|
+
e: containerRect.width / 2 - targetCenterBeforeViewerTransform.x * targetScale,
|
|
602
|
+
f: containerRect.height / 2 - targetCenterBeforeViewerTransform.y * targetScale
|
|
603
|
+
};
|
|
604
|
+
};
|
|
605
|
+
|
|
606
|
+
// lib/hooks/useSchematicSearch.ts
|
|
607
|
+
var MIN_SEARCH_RESULT_ZOOM = 1.8;
|
|
608
|
+
var SEARCH_FOCUS_ANIMATION_MS = 350;
|
|
609
|
+
var useSchematicSearch = ({
|
|
610
|
+
circuitJson,
|
|
611
|
+
circuitJsonKey,
|
|
612
|
+
svgDivRef,
|
|
613
|
+
containerRef,
|
|
614
|
+
activeSheetId,
|
|
615
|
+
hasMultipleSheets,
|
|
616
|
+
handleSelectSheet,
|
|
617
|
+
svgString,
|
|
618
|
+
svgToScreenProjection,
|
|
619
|
+
setSvgToScreenProjection,
|
|
620
|
+
setIsInteractionEnabled
|
|
621
|
+
}) => {
|
|
622
|
+
const [searchQuery, setSearchQuery] = useState("");
|
|
623
|
+
const [pendingSearchResult, setPendingSearchResult] = useState(null);
|
|
624
|
+
const searchAnimationTimerRef = useRef(
|
|
625
|
+
null
|
|
626
|
+
);
|
|
627
|
+
const searchResults = useMemo(
|
|
628
|
+
() => getSchematicSearchResults(circuitJson, searchQuery),
|
|
629
|
+
[circuitJson, circuitJsonKey, searchQuery]
|
|
630
|
+
);
|
|
631
|
+
const focusSearchResult = useCallback2(
|
|
632
|
+
(result) => {
|
|
633
|
+
const svgRoot = svgDivRef.current;
|
|
634
|
+
const container = containerRef.current;
|
|
635
|
+
if (!svgRoot || !container) return false;
|
|
636
|
+
let attribute = "data-schematic-net-label-id";
|
|
637
|
+
if (result.target.type === "schematic_component") {
|
|
638
|
+
attribute = "data-schematic-component-id";
|
|
639
|
+
}
|
|
640
|
+
const target = Array.from(
|
|
641
|
+
svgRoot.querySelectorAll(`[${attribute}]`)
|
|
642
|
+
).find((element) => element.getAttribute(attribute) === result.target.id);
|
|
643
|
+
if (!target) return false;
|
|
644
|
+
const targetRect = target.getBoundingClientRect();
|
|
645
|
+
const containerRect = container.getBoundingClientRect();
|
|
646
|
+
if (!targetRect.width && !targetRect.height) return false;
|
|
647
|
+
if (searchAnimationTimerRef.current) {
|
|
648
|
+
clearTimeout(searchAnimationTimerRef.current);
|
|
649
|
+
}
|
|
650
|
+
let visibleProjection = svgToScreenProjection;
|
|
651
|
+
const visibleTransform = getComputedStyle(svgRoot).transform;
|
|
652
|
+
if (visibleTransform && visibleTransform !== "none") {
|
|
653
|
+
try {
|
|
654
|
+
visibleProjection = fromString(visibleTransform);
|
|
655
|
+
svgRoot.style.transition = "none";
|
|
656
|
+
svgRoot.style.transform = visibleTransform;
|
|
657
|
+
void svgRoot.offsetWidth;
|
|
658
|
+
} catch {
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
svgRoot.style.transition = `transform ${SEARCH_FOCUS_ANIMATION_MS}ms ease-in-out`;
|
|
662
|
+
void svgRoot.offsetWidth;
|
|
663
|
+
setSvgToScreenProjection(
|
|
664
|
+
getSearchResultTransform({
|
|
665
|
+
containerRect,
|
|
666
|
+
targetRect,
|
|
667
|
+
visibleProjection,
|
|
668
|
+
minimumScale: MIN_SEARCH_RESULT_ZOOM
|
|
669
|
+
})
|
|
670
|
+
);
|
|
671
|
+
searchAnimationTimerRef.current = setTimeout(() => {
|
|
672
|
+
svgRoot.style.transition = "";
|
|
673
|
+
}, SEARCH_FOCUS_ANIMATION_MS);
|
|
674
|
+
svgRoot.querySelectorAll(".schematic-search-match").forEach(
|
|
675
|
+
(element) => element.classList.remove("schematic-search-match")
|
|
676
|
+
);
|
|
677
|
+
svgRoot.querySelectorAll(`[${attribute}]`).forEach((element) => {
|
|
678
|
+
if (element.getAttribute(attribute) === result.target.id) {
|
|
679
|
+
element.classList.add("schematic-search-match");
|
|
680
|
+
}
|
|
681
|
+
});
|
|
682
|
+
return true;
|
|
683
|
+
},
|
|
684
|
+
[containerRef, setSvgToScreenProjection, svgDivRef, svgToScreenProjection]
|
|
685
|
+
);
|
|
686
|
+
const handleSearchResultSelect = useCallback2(
|
|
687
|
+
(result) => {
|
|
688
|
+
setIsInteractionEnabled(true);
|
|
689
|
+
if (result.schematicSheetId && result.schematicSheetId !== activeSheetId && hasMultipleSheets) {
|
|
690
|
+
handleSelectSheet(result.schematicSheetId);
|
|
691
|
+
setPendingSearchResult(result);
|
|
692
|
+
return;
|
|
693
|
+
}
|
|
694
|
+
focusSearchResult(result);
|
|
695
|
+
},
|
|
696
|
+
[
|
|
697
|
+
activeSheetId,
|
|
698
|
+
focusSearchResult,
|
|
699
|
+
handleSelectSheet,
|
|
700
|
+
hasMultipleSheets,
|
|
701
|
+
setIsInteractionEnabled
|
|
702
|
+
]
|
|
703
|
+
);
|
|
704
|
+
const handleCancelSearch = useCallback2(() => {
|
|
705
|
+
setSearchQuery("");
|
|
706
|
+
setPendingSearchResult(null);
|
|
707
|
+
if (searchAnimationTimerRef.current) {
|
|
708
|
+
clearTimeout(searchAnimationTimerRef.current);
|
|
709
|
+
searchAnimationTimerRef.current = null;
|
|
710
|
+
}
|
|
711
|
+
if (svgDivRef.current) {
|
|
712
|
+
svgDivRef.current.style.transition = "";
|
|
713
|
+
svgDivRef.current.querySelectorAll(".schematic-search-match").forEach(
|
|
714
|
+
(element) => element.classList.remove("schematic-search-match")
|
|
715
|
+
);
|
|
716
|
+
}
|
|
717
|
+
}, [svgDivRef]);
|
|
718
|
+
useEffect3(() => {
|
|
719
|
+
if (!pendingSearchResult || !svgString) return;
|
|
720
|
+
const frame = requestAnimationFrame(() => {
|
|
721
|
+
if (focusSearchResult(pendingSearchResult)) {
|
|
722
|
+
setPendingSearchResult(null);
|
|
723
|
+
}
|
|
724
|
+
});
|
|
725
|
+
return () => cancelAnimationFrame(frame);
|
|
726
|
+
}, [focusSearchResult, pendingSearchResult, svgString]);
|
|
727
|
+
useEffect3(() => {
|
|
728
|
+
if (searchQuery) return;
|
|
729
|
+
svgDivRef.current?.querySelectorAll(".schematic-search-match").forEach((element) => element.classList.remove("schematic-search-match"));
|
|
730
|
+
}, [searchQuery, svgDivRef]);
|
|
731
|
+
useEffect3(
|
|
732
|
+
() => () => {
|
|
733
|
+
if (searchAnimationTimerRef.current) {
|
|
734
|
+
clearTimeout(searchAnimationTimerRef.current);
|
|
735
|
+
}
|
|
736
|
+
},
|
|
737
|
+
[]
|
|
738
|
+
);
|
|
739
|
+
return {
|
|
740
|
+
searchQuery,
|
|
741
|
+
setSearchQuery,
|
|
742
|
+
searchResults,
|
|
743
|
+
handleSearchResultSelect,
|
|
744
|
+
handleCancelSearch
|
|
745
|
+
};
|
|
746
|
+
};
|
|
747
|
+
|
|
433
748
|
// lib/utils/debug.ts
|
|
434
749
|
import Debug from "debug";
|
|
435
750
|
var debug = Debug("schematic-viewer");
|
|
@@ -438,16 +753,16 @@ var enableDebug = () => {
|
|
|
438
753
|
};
|
|
439
754
|
|
|
440
755
|
// lib/components/SchematicViewer.tsx
|
|
441
|
-
import { useCallback as
|
|
756
|
+
import { useCallback as useCallback7, useEffect as useEffect11, useMemo as useMemo6, useRef as useRef8, useState as useState8 } from "react";
|
|
442
757
|
import { toString as transformToString } from "transformation-matrix";
|
|
443
758
|
import { useMouseMatrixTransform } from "use-mouse-matrix-transform";
|
|
444
759
|
|
|
445
760
|
// lib/hooks/use-resize-handling.ts
|
|
446
|
-
import { useEffect as
|
|
761
|
+
import { useEffect as useEffect4, useState as useState2 } from "react";
|
|
447
762
|
var useResizeHandling = (containerRef) => {
|
|
448
|
-
const [containerWidth, setContainerWidth] =
|
|
449
|
-
const [containerHeight, setContainerHeight] =
|
|
450
|
-
|
|
763
|
+
const [containerWidth, setContainerWidth] = useState2(0);
|
|
764
|
+
const [containerHeight, setContainerHeight] = useState2(0);
|
|
765
|
+
useEffect4(() => {
|
|
451
766
|
if (!containerRef.current) return;
|
|
452
767
|
const updateDimensions = () => {
|
|
453
768
|
const rect = containerRef.current?.getBoundingClientRect();
|
|
@@ -467,22 +782,22 @@ var useResizeHandling = (containerRef) => {
|
|
|
467
782
|
};
|
|
468
783
|
|
|
469
784
|
// lib/hooks/useContextMenu.ts
|
|
470
|
-
import { useCallback as
|
|
785
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef2, useState as useState3 } from "react";
|
|
471
786
|
var LONG_PRESS_DURATION_MS = 600;
|
|
472
787
|
var MOVEMENT_THRESHOLD_PX = 10;
|
|
473
788
|
var useContextMenu = ({ containerRef }) => {
|
|
474
|
-
const [menuVisible, setMenuVisible] =
|
|
475
|
-
const [menuPos, setMenuPos] =
|
|
476
|
-
const menuRef =
|
|
477
|
-
const interactionOriginRef =
|
|
478
|
-
const longPressTimeoutRef =
|
|
479
|
-
const ignoreContextMenuUntilRef =
|
|
480
|
-
const clearLongPressTimeout =
|
|
789
|
+
const [menuVisible, setMenuVisible] = useState3(false);
|
|
790
|
+
const [menuPos, setMenuPos] = useState3({ x: 0, y: 0 });
|
|
791
|
+
const menuRef = useRef2(null);
|
|
792
|
+
const interactionOriginRef = useRef2(null);
|
|
793
|
+
const longPressTimeoutRef = useRef2(null);
|
|
794
|
+
const ignoreContextMenuUntilRef = useRef2(0);
|
|
795
|
+
const clearLongPressTimeout = useCallback3(() => {
|
|
481
796
|
if (longPressTimeoutRef.current === null) return;
|
|
482
797
|
window.clearTimeout(longPressTimeoutRef.current);
|
|
483
798
|
longPressTimeoutRef.current = null;
|
|
484
799
|
}, []);
|
|
485
|
-
const handleContextMenu =
|
|
800
|
+
const handleContextMenu = useCallback3((event) => {
|
|
486
801
|
event.preventDefault();
|
|
487
802
|
if (Date.now() < ignoreContextMenuUntilRef.current) return;
|
|
488
803
|
const origin = interactionOriginRef.current;
|
|
@@ -493,7 +808,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
493
808
|
setMenuPos({ x: event.clientX, y: event.clientY });
|
|
494
809
|
setMenuVisible(true);
|
|
495
810
|
}, []);
|
|
496
|
-
const handleTouchStart =
|
|
811
|
+
const handleTouchStart = useCallback3(
|
|
497
812
|
(event) => {
|
|
498
813
|
clearLongPressTimeout();
|
|
499
814
|
if (event.touches.length !== 1) {
|
|
@@ -521,7 +836,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
521
836
|
},
|
|
522
837
|
[clearLongPressTimeout, containerRef]
|
|
523
838
|
);
|
|
524
|
-
const handleTouchMove =
|
|
839
|
+
const handleTouchMove = useCallback3(
|
|
525
840
|
(event) => {
|
|
526
841
|
const origin = interactionOriginRef.current;
|
|
527
842
|
if (!origin || event.touches.length !== 1) return;
|
|
@@ -534,11 +849,11 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
534
849
|
},
|
|
535
850
|
[clearLongPressTimeout]
|
|
536
851
|
);
|
|
537
|
-
const handleTouchEnd =
|
|
852
|
+
const handleTouchEnd = useCallback3(() => {
|
|
538
853
|
clearLongPressTimeout();
|
|
539
854
|
interactionOriginRef.current = null;
|
|
540
855
|
}, [clearLongPressTimeout]);
|
|
541
|
-
const handleClickAway =
|
|
856
|
+
const handleClickAway = useCallback3((event) => {
|
|
542
857
|
const target = event.target;
|
|
543
858
|
if (menuRef.current?.contains(target)) return;
|
|
544
859
|
const isInRadixPortal = target.closest?.(
|
|
@@ -547,7 +862,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
547
862
|
if (isInRadixPortal) return;
|
|
548
863
|
setMenuVisible(false);
|
|
549
864
|
}, []);
|
|
550
|
-
|
|
865
|
+
useEffect5(() => {
|
|
551
866
|
if (!menuVisible) return;
|
|
552
867
|
document.addEventListener("mousedown", handleClickAway);
|
|
553
868
|
document.addEventListener("touchstart", handleClickAway);
|
|
@@ -556,7 +871,7 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
556
871
|
document.removeEventListener("touchstart", handleClickAway);
|
|
557
872
|
};
|
|
558
873
|
}, [handleClickAway, menuVisible]);
|
|
559
|
-
|
|
874
|
+
useEffect5(() => clearLongPressTimeout, [clearLongPressTimeout]);
|
|
560
875
|
return {
|
|
561
876
|
menuVisible,
|
|
562
877
|
menuPos,
|
|
@@ -588,7 +903,8 @@ var hiddenSourceComponentKeys = /* @__PURE__ */ new Set([
|
|
|
588
903
|
"subcircuit_id",
|
|
589
904
|
"display_name",
|
|
590
905
|
"ftype",
|
|
591
|
-
"are_pins_interchangeable"
|
|
906
|
+
"are_pins_interchangeable",
|
|
907
|
+
"supplier_part_numbers"
|
|
592
908
|
]);
|
|
593
909
|
var priorityKeys = [
|
|
594
910
|
"name",
|
|
@@ -601,9 +917,17 @@ var priorityKeys = [
|
|
|
601
917
|
"max_voltage_rating",
|
|
602
918
|
"max_current_rating",
|
|
603
919
|
"power_rating",
|
|
604
|
-
"manufacturer_part_number"
|
|
605
|
-
"supplier_part_numbers"
|
|
920
|
+
"manufacturer_part_number"
|
|
606
921
|
];
|
|
922
|
+
var supplierPartNumberUrls = {
|
|
923
|
+
jlcpcb: (partNumber) => `https://jlcpcb.com/partdetail/${encodeURIComponent(partNumber)}`,
|
|
924
|
+
lcsc: (partNumber) => `https://www.lcsc.com/product-detail/${encodeURIComponent(partNumber)}.html`
|
|
925
|
+
};
|
|
926
|
+
var normalizeLcscPartNumber = (partNumber) => {
|
|
927
|
+
const trimmedPartNumber = partNumber.trim();
|
|
928
|
+
const numericPartNumber = /^c?(\d+)$/i.exec(trimmedPartNumber);
|
|
929
|
+
return numericPartNumber ? `C${numericPartNumber[1]}` : trimmedPartNumber;
|
|
930
|
+
};
|
|
607
931
|
var getKeyPriority = (key) => {
|
|
608
932
|
const priority = priorityKeys.indexOf(key);
|
|
609
933
|
return priority === -1 ? priorityKeys.length : priority;
|
|
@@ -631,6 +955,32 @@ var getSourceComponentInfoEntries = (sourceComponent) => Object.entries(sourceCo
|
|
|
631
955
|
label: key,
|
|
632
956
|
value: formatComponentValue(sourceComponent, key, value)
|
|
633
957
|
}));
|
|
958
|
+
var getSupplierPartNumberEntries = (sourceComponent) => {
|
|
959
|
+
const supplierPartNumbers = sourceComponent.supplier_part_numbers;
|
|
960
|
+
if (!supplierPartNumbers) return [];
|
|
961
|
+
return ["jlcpcb", "lcsc"].flatMap((supplier) => {
|
|
962
|
+
const partNumbers = supplierPartNumbers[supplier];
|
|
963
|
+
if (!Array.isArray(partNumbers)) return [];
|
|
964
|
+
const normalizedPartNumbers = [
|
|
965
|
+
...new Set(
|
|
966
|
+
partNumbers.filter(
|
|
967
|
+
(partNumber) => Boolean(typeof partNumber === "string" && partNumber.trim())
|
|
968
|
+
).map(normalizeLcscPartNumber)
|
|
969
|
+
)
|
|
970
|
+
];
|
|
971
|
+
if (!normalizedPartNumbers.length) return [];
|
|
972
|
+
return [
|
|
973
|
+
{
|
|
974
|
+
key: `supplier_part_numbers.${supplier}`,
|
|
975
|
+
label: supplier,
|
|
976
|
+
links: normalizedPartNumbers.map((partNumber) => ({
|
|
977
|
+
partNumber,
|
|
978
|
+
href: supplierPartNumberUrls[supplier](partNumber)
|
|
979
|
+
}))
|
|
980
|
+
}
|
|
981
|
+
];
|
|
982
|
+
});
|
|
983
|
+
};
|
|
634
984
|
var getSchematicComponentDetails = (circuitJson, schematicComponentId) => {
|
|
635
985
|
const schematicComponent = circuitJson.find(
|
|
636
986
|
(element) => element.type === "schematic_component" && element.schematic_component_id === schematicComponentId
|
|
@@ -707,17 +1057,18 @@ var zIndexMap = {
|
|
|
707
1057
|
clickToInteractOverlay: 100,
|
|
708
1058
|
schematicComponentDetailsTooltip: 105,
|
|
709
1059
|
schematicComponentHoverOutline: 47,
|
|
710
|
-
schematicPortHoverOutline: 48
|
|
1060
|
+
schematicPortHoverOutline: 48,
|
|
1061
|
+
schematicSearch: 101
|
|
711
1062
|
};
|
|
712
1063
|
|
|
713
1064
|
// lib/components/MouseTracker.tsx
|
|
714
1065
|
import {
|
|
715
1066
|
createContext,
|
|
716
|
-
useCallback as
|
|
1067
|
+
useCallback as useCallback4,
|
|
717
1068
|
useContext,
|
|
718
|
-
useEffect as
|
|
719
|
-
useMemo,
|
|
720
|
-
useRef as
|
|
1069
|
+
useEffect as useEffect6,
|
|
1070
|
+
useMemo as useMemo2,
|
|
1071
|
+
useRef as useRef3
|
|
721
1072
|
} from "react";
|
|
722
1073
|
import { Fragment, jsx } from "react/jsx-runtime";
|
|
723
1074
|
var MouseTrackerContext = createContext(null);
|
|
@@ -735,19 +1086,19 @@ var MouseTracker = ({ children }) => {
|
|
|
735
1086
|
return /* @__PURE__ */ jsx(MouseTrackerProvider, { children });
|
|
736
1087
|
};
|
|
737
1088
|
var MouseTrackerProvider = ({ children }) => {
|
|
738
|
-
const storeRef =
|
|
1089
|
+
const storeRef = useRef3({
|
|
739
1090
|
pointer: null,
|
|
740
1091
|
boundingBoxes: /* @__PURE__ */ new Map(),
|
|
741
1092
|
hoveringIds: /* @__PURE__ */ new Set(),
|
|
742
1093
|
subscribers: /* @__PURE__ */ new Set(),
|
|
743
1094
|
mouseDownPosition: null
|
|
744
1095
|
});
|
|
745
|
-
const notifySubscribers =
|
|
1096
|
+
const notifySubscribers = useCallback4(() => {
|
|
746
1097
|
for (const callback of storeRef.current.subscribers) {
|
|
747
1098
|
callback();
|
|
748
1099
|
}
|
|
749
1100
|
}, []);
|
|
750
|
-
const updateHovering =
|
|
1101
|
+
const updateHovering = useCallback4(() => {
|
|
751
1102
|
const pointer = storeRef.current.pointer;
|
|
752
1103
|
const newHovering = /* @__PURE__ */ new Set();
|
|
753
1104
|
if (pointer) {
|
|
@@ -766,14 +1117,14 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
766
1117
|
storeRef.current.hoveringIds = newHovering;
|
|
767
1118
|
notifySubscribers();
|
|
768
1119
|
}, [notifySubscribers]);
|
|
769
|
-
const registerBoundingBox =
|
|
1120
|
+
const registerBoundingBox = useCallback4(
|
|
770
1121
|
(id, registration) => {
|
|
771
1122
|
storeRef.current.boundingBoxes.set(id, registration);
|
|
772
1123
|
updateHovering();
|
|
773
1124
|
},
|
|
774
1125
|
[updateHovering]
|
|
775
1126
|
);
|
|
776
|
-
const updateBoundingBox =
|
|
1127
|
+
const updateBoundingBox = useCallback4(
|
|
777
1128
|
(id, registration) => {
|
|
778
1129
|
const existing = storeRef.current.boundingBoxes.get(id);
|
|
779
1130
|
if (existing && boundsAreEqual(existing.bounds, registration.bounds) && existing.onClick === registration.onClick) {
|
|
@@ -784,7 +1135,7 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
784
1135
|
},
|
|
785
1136
|
[updateHovering]
|
|
786
1137
|
);
|
|
787
|
-
const unregisterBoundingBox =
|
|
1138
|
+
const unregisterBoundingBox = useCallback4(
|
|
788
1139
|
(id) => {
|
|
789
1140
|
const removed = storeRef.current.boundingBoxes.delete(id);
|
|
790
1141
|
if (removed) {
|
|
@@ -793,16 +1144,16 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
793
1144
|
},
|
|
794
1145
|
[updateHovering]
|
|
795
1146
|
);
|
|
796
|
-
const subscribe =
|
|
1147
|
+
const subscribe = useCallback4((listener) => {
|
|
797
1148
|
storeRef.current.subscribers.add(listener);
|
|
798
1149
|
return () => {
|
|
799
1150
|
storeRef.current.subscribers.delete(listener);
|
|
800
1151
|
};
|
|
801
1152
|
}, []);
|
|
802
|
-
const isHovering =
|
|
1153
|
+
const isHovering = useCallback4((id) => {
|
|
803
1154
|
return storeRef.current.hoveringIds.has(id);
|
|
804
1155
|
}, []);
|
|
805
|
-
|
|
1156
|
+
useEffect6(() => {
|
|
806
1157
|
const handlePointerPosition = (event) => {
|
|
807
1158
|
const { clientX, clientY } = event;
|
|
808
1159
|
const pointer = storeRef.current.pointer;
|
|
@@ -870,7 +1221,7 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
870
1221
|
window.removeEventListener("click", handleClick);
|
|
871
1222
|
};
|
|
872
1223
|
}, [updateHovering]);
|
|
873
|
-
const value =
|
|
1224
|
+
const value = useMemo2(
|
|
874
1225
|
() => ({
|
|
875
1226
|
registerBoundingBox,
|
|
876
1227
|
updateBoundingBox,
|
|
@@ -890,7 +1241,7 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
890
1241
|
};
|
|
891
1242
|
|
|
892
1243
|
// lib/components/SchematicComponentDetailsTooltip.tsx
|
|
893
|
-
import { useMemo as
|
|
1244
|
+
import { useMemo as useMemo3 } from "react";
|
|
894
1245
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
895
1246
|
var detailLabelStyle = {
|
|
896
1247
|
color: "#64748b",
|
|
@@ -908,11 +1259,15 @@ var SchematicComponentDetailsTooltip = ({
|
|
|
908
1259
|
width,
|
|
909
1260
|
maxHeight
|
|
910
1261
|
}) => {
|
|
911
|
-
const infoEntries =
|
|
1262
|
+
const infoEntries = useMemo3(
|
|
912
1263
|
() => getSourceComponentInfoEntries(sourceComponent),
|
|
913
1264
|
[sourceComponent]
|
|
914
1265
|
);
|
|
915
|
-
const
|
|
1266
|
+
const supplierPartNumberEntries = useMemo3(
|
|
1267
|
+
() => getSupplierPartNumberEntries(sourceComponent),
|
|
1268
|
+
[sourceComponent]
|
|
1269
|
+
);
|
|
1270
|
+
const footprintPreviewUrl = useMemo3(
|
|
916
1271
|
() => footprintPreviewCircuitJson?.length && footprintPreviewViewBox ? getFootprintPreviewUrl(
|
|
917
1272
|
footprintPreviewCircuitJson,
|
|
918
1273
|
footprintPreviewViewBox
|
|
@@ -980,6 +1335,35 @@ var SchematicComponentDetailsTooltip = ({
|
|
|
980
1335
|
}
|
|
981
1336
|
)
|
|
982
1337
|
] }, entry.key)),
|
|
1338
|
+
supplierPartNumberEntries.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
1339
|
+
/* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: entry.label }),
|
|
1340
|
+
/* @__PURE__ */ jsx2(
|
|
1341
|
+
"dd",
|
|
1342
|
+
{
|
|
1343
|
+
style: {
|
|
1344
|
+
minWidth: 0,
|
|
1345
|
+
margin: 0,
|
|
1346
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
|
|
1347
|
+
fontSize: "12px",
|
|
1348
|
+
lineHeight: 1.45,
|
|
1349
|
+
overflowWrap: "anywhere"
|
|
1350
|
+
},
|
|
1351
|
+
children: entry.links.map((link, index) => /* @__PURE__ */ jsxs("span", { children: [
|
|
1352
|
+
index > 0 && ", ",
|
|
1353
|
+
/* @__PURE__ */ jsx2(
|
|
1354
|
+
"a",
|
|
1355
|
+
{
|
|
1356
|
+
href: link.href,
|
|
1357
|
+
target: "_blank",
|
|
1358
|
+
rel: "noreferrer noopener",
|
|
1359
|
+
style: { color: "#2563eb", textDecoration: "underline" },
|
|
1360
|
+
children: link.partNumber
|
|
1361
|
+
}
|
|
1362
|
+
)
|
|
1363
|
+
] }, link.href))
|
|
1364
|
+
}
|
|
1365
|
+
)
|
|
1366
|
+
] }, entry.key)),
|
|
983
1367
|
footprinterString && /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
984
1368
|
/* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: "footprint" }),
|
|
985
1369
|
/* @__PURE__ */ jsx2(
|
|
@@ -1001,7 +1385,7 @@ var SchematicComponentDetailsTooltip = ({
|
|
|
1001
1385
|
]
|
|
1002
1386
|
}
|
|
1003
1387
|
),
|
|
1004
|
-
|
|
1388
|
+
footprintPreviewUrl && /* @__PURE__ */ jsx2("div", { style: { padding: "0 4px 4px" }, children: /* @__PURE__ */ jsx2(
|
|
1005
1389
|
"div",
|
|
1006
1390
|
{
|
|
1007
1391
|
style: {
|
|
@@ -1015,7 +1399,7 @@ var SchematicComponentDetailsTooltip = ({
|
|
|
1015
1399
|
"img",
|
|
1016
1400
|
{
|
|
1017
1401
|
src: footprintPreviewUrl,
|
|
1018
|
-
alt: `${sourceComponent.name} ${footprinterString} PCB footprint`,
|
|
1402
|
+
alt: `${sourceComponent.name}${footprinterString ? ` ${footprinterString}` : ""} PCB footprint`,
|
|
1019
1403
|
loading: "lazy",
|
|
1020
1404
|
referrerPolicy: "no-referrer",
|
|
1021
1405
|
style: {
|
|
@@ -1034,15 +1418,15 @@ var SchematicComponentDetailsTooltip = ({
|
|
|
1034
1418
|
};
|
|
1035
1419
|
|
|
1036
1420
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
1037
|
-
import { useCallback as
|
|
1421
|
+
import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef5, useState as useState4 } from "react";
|
|
1038
1422
|
|
|
1039
1423
|
// lib/hooks/useMouseEventsOverBoundingBox.ts
|
|
1040
1424
|
import {
|
|
1041
1425
|
useContext as useContext2,
|
|
1042
|
-
useEffect as
|
|
1426
|
+
useEffect as useEffect7,
|
|
1043
1427
|
useId,
|
|
1044
|
-
useMemo as
|
|
1045
|
-
useRef as
|
|
1428
|
+
useMemo as useMemo4,
|
|
1429
|
+
useRef as useRef4,
|
|
1046
1430
|
useSyncExternalStore
|
|
1047
1431
|
} from "react";
|
|
1048
1432
|
var useMouseEventsOverBoundingBox = (options) => {
|
|
@@ -1053,15 +1437,15 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
1053
1437
|
);
|
|
1054
1438
|
}
|
|
1055
1439
|
const id = useId();
|
|
1056
|
-
const latestOptionsRef =
|
|
1440
|
+
const latestOptionsRef = useRef4(options);
|
|
1057
1441
|
latestOptionsRef.current = options;
|
|
1058
|
-
const handleClick =
|
|
1442
|
+
const handleClick = useMemo4(
|
|
1059
1443
|
() => (event) => {
|
|
1060
1444
|
latestOptionsRef.current.onClick?.(event);
|
|
1061
1445
|
},
|
|
1062
1446
|
[]
|
|
1063
1447
|
);
|
|
1064
|
-
|
|
1448
|
+
useEffect7(() => {
|
|
1065
1449
|
context.registerBoundingBox(id, {
|
|
1066
1450
|
bounds: latestOptionsRef.current.bounds,
|
|
1067
1451
|
onClick: latestOptionsRef.current.onClick ? handleClick : void 0
|
|
@@ -1070,7 +1454,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
1070
1454
|
context.unregisterBoundingBox(id);
|
|
1071
1455
|
};
|
|
1072
1456
|
}, [context, handleClick, id]);
|
|
1073
|
-
|
|
1457
|
+
useEffect7(() => {
|
|
1074
1458
|
context.updateBoundingBox(id, {
|
|
1075
1459
|
bounds: latestOptionsRef.current.bounds,
|
|
1076
1460
|
onClick: latestOptionsRef.current.onClick ? handleClick : void 0
|
|
@@ -1109,9 +1493,9 @@ var SchematicComponentMouseTarget = ({
|
|
|
1109
1493
|
showOutline,
|
|
1110
1494
|
circuitJsonKey
|
|
1111
1495
|
}) => {
|
|
1112
|
-
const [measurement, setMeasurement] =
|
|
1113
|
-
const frameRef =
|
|
1114
|
-
const measure =
|
|
1496
|
+
const [measurement, setMeasurement] = useState4(null);
|
|
1497
|
+
const frameRef = useRef5(null);
|
|
1498
|
+
const measure = useCallback5(() => {
|
|
1115
1499
|
frameRef.current = null;
|
|
1116
1500
|
const svgDiv = svgDivRef.current;
|
|
1117
1501
|
const container = containerRef.current;
|
|
@@ -1146,14 +1530,14 @@ var SchematicComponentMouseTarget = ({
|
|
|
1146
1530
|
(prev) => areMeasurementsEqual(prev, nextMeasurement) ? prev : nextMeasurement
|
|
1147
1531
|
);
|
|
1148
1532
|
}, [componentId, containerRef, svgDivRef]);
|
|
1149
|
-
const scheduleMeasure =
|
|
1533
|
+
const scheduleMeasure = useCallback5(() => {
|
|
1150
1534
|
if (frameRef.current !== null) return;
|
|
1151
1535
|
frameRef.current = window.requestAnimationFrame(measure);
|
|
1152
1536
|
}, [measure]);
|
|
1153
|
-
|
|
1537
|
+
useEffect8(() => {
|
|
1154
1538
|
scheduleMeasure();
|
|
1155
1539
|
}, [scheduleMeasure, circuitJsonKey]);
|
|
1156
|
-
|
|
1540
|
+
useEffect8(() => {
|
|
1157
1541
|
scheduleMeasure();
|
|
1158
1542
|
const svgDiv = svgDivRef.current;
|
|
1159
1543
|
const container = containerRef.current;
|
|
@@ -1185,7 +1569,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
1185
1569
|
}
|
|
1186
1570
|
};
|
|
1187
1571
|
}, [scheduleMeasure, svgDivRef, containerRef]);
|
|
1188
|
-
const handleClick =
|
|
1572
|
+
const handleClick = useCallback5(
|
|
1189
1573
|
(event) => {
|
|
1190
1574
|
if (onComponentClick) {
|
|
1191
1575
|
onComponentClick(componentId, event);
|
|
@@ -1198,7 +1582,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
1198
1582
|
bounds,
|
|
1199
1583
|
onClick: onComponentClick ? handleClick : void 0
|
|
1200
1584
|
});
|
|
1201
|
-
|
|
1585
|
+
useEffect8(() => {
|
|
1202
1586
|
if (onHoverChange) {
|
|
1203
1587
|
onHoverChange(componentId, hovering);
|
|
1204
1588
|
}
|
|
@@ -1225,7 +1609,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
1225
1609
|
};
|
|
1226
1610
|
|
|
1227
1611
|
// lib/components/SchematicPortMouseTarget.tsx
|
|
1228
|
-
import { useCallback as
|
|
1612
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useRef as useRef6, useState as useState5 } from "react";
|
|
1229
1613
|
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
1230
1614
|
var areMeasurementsEqual2 = (a, b) => {
|
|
1231
1615
|
if (!a && !b) return true;
|
|
@@ -1242,9 +1626,9 @@ var SchematicPortMouseTarget = ({
|
|
|
1242
1626
|
showOutline,
|
|
1243
1627
|
circuitJsonKey
|
|
1244
1628
|
}) => {
|
|
1245
|
-
const [measurement, setMeasurement] =
|
|
1246
|
-
const frameRef =
|
|
1247
|
-
const measure =
|
|
1629
|
+
const [measurement, setMeasurement] = useState5(null);
|
|
1630
|
+
const frameRef = useRef6(null);
|
|
1631
|
+
const measure = useCallback6(() => {
|
|
1248
1632
|
frameRef.current = null;
|
|
1249
1633
|
const svgDiv = svgDivRef.current;
|
|
1250
1634
|
const container = containerRef.current;
|
|
@@ -1280,14 +1664,14 @@ var SchematicPortMouseTarget = ({
|
|
|
1280
1664
|
(prev) => areMeasurementsEqual2(prev, nextMeasurement) ? prev : nextMeasurement
|
|
1281
1665
|
);
|
|
1282
1666
|
}, [portId, containerRef, svgDivRef]);
|
|
1283
|
-
const scheduleMeasure =
|
|
1667
|
+
const scheduleMeasure = useCallback6(() => {
|
|
1284
1668
|
if (frameRef.current !== null) return;
|
|
1285
1669
|
frameRef.current = window.requestAnimationFrame(measure);
|
|
1286
1670
|
}, [measure]);
|
|
1287
|
-
|
|
1671
|
+
useEffect9(() => {
|
|
1288
1672
|
scheduleMeasure();
|
|
1289
1673
|
}, [scheduleMeasure, circuitJsonKey]);
|
|
1290
|
-
|
|
1674
|
+
useEffect9(() => {
|
|
1291
1675
|
scheduleMeasure();
|
|
1292
1676
|
const svgDiv = svgDivRef.current;
|
|
1293
1677
|
const container = containerRef.current;
|
|
@@ -1319,7 +1703,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1319
1703
|
}
|
|
1320
1704
|
};
|
|
1321
1705
|
}, [scheduleMeasure, svgDivRef, containerRef]);
|
|
1322
|
-
const handleClick =
|
|
1706
|
+
const handleClick = useCallback6(
|
|
1323
1707
|
(event) => {
|
|
1324
1708
|
if (onPortClick) {
|
|
1325
1709
|
onPortClick(portId, event);
|
|
@@ -1332,7 +1716,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1332
1716
|
bounds,
|
|
1333
1717
|
onClick: onPortClick ? handleClick : void 0
|
|
1334
1718
|
});
|
|
1335
|
-
|
|
1719
|
+
useEffect9(() => {
|
|
1336
1720
|
if (onHoverChange) {
|
|
1337
1721
|
onHoverChange(portId, hovering);
|
|
1338
1722
|
}
|
|
@@ -1384,10 +1768,548 @@ var SchematicPortMouseTarget = ({
|
|
|
1384
1768
|
] });
|
|
1385
1769
|
};
|
|
1386
1770
|
|
|
1771
|
+
// lib/components/SchematicSearch.tsx
|
|
1772
|
+
import { useEffect as useEffect10, useRef as useRef7, useState as useState6 } from "react";
|
|
1773
|
+
|
|
1774
|
+
// lib/components/SchematicSearchIcons.tsx
|
|
1775
|
+
import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1776
|
+
var Icon = ({
|
|
1777
|
+
children,
|
|
1778
|
+
size,
|
|
1779
|
+
strokeWidth
|
|
1780
|
+
}) => /* @__PURE__ */ jsx5(
|
|
1781
|
+
"svg",
|
|
1782
|
+
{
|
|
1783
|
+
width: size,
|
|
1784
|
+
height: size,
|
|
1785
|
+
viewBox: "0 0 24 24",
|
|
1786
|
+
fill: "none",
|
|
1787
|
+
stroke: "currentColor",
|
|
1788
|
+
strokeWidth,
|
|
1789
|
+
strokeLinecap: "round",
|
|
1790
|
+
strokeLinejoin: "round",
|
|
1791
|
+
"aria-hidden": "true",
|
|
1792
|
+
children
|
|
1793
|
+
}
|
|
1794
|
+
);
|
|
1795
|
+
var SearchIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
|
|
1796
|
+
/* @__PURE__ */ jsx5("circle", { cx: "11", cy: "11", r: "8" }),
|
|
1797
|
+
/* @__PURE__ */ jsx5("path", { d: "m21 21-4.34-4.34" })
|
|
1798
|
+
] });
|
|
1799
|
+
var CloseIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
|
|
1800
|
+
/* @__PURE__ */ jsx5("path", { d: "M18 6 6 18" }),
|
|
1801
|
+
/* @__PURE__ */ jsx5("path", { d: "m6 6 12 12" })
|
|
1802
|
+
] });
|
|
1803
|
+
var ComponentIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
|
|
1804
|
+
/* @__PURE__ */ jsx5("rect", { x: "4", y: "4", width: "16", height: "16", rx: "2" }),
|
|
1805
|
+
/* @__PURE__ */ jsx5("rect", { x: "8", y: "8", width: "8", height: "8", rx: "1" }),
|
|
1806
|
+
/* @__PURE__ */ jsx5("path", { d: "M7 2v2M12 2v2M17 2v2M7 20v2M12 20v2M17 20v2M2 7h2M2 12h2M2 17h2M20 7h2M20 12h2M20 17h2" })
|
|
1807
|
+
] });
|
|
1808
|
+
var NetIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
|
|
1809
|
+
/* @__PURE__ */ jsx5("path", { d: "M15 6a9 9 0 0 0-9 9V3" }),
|
|
1810
|
+
/* @__PURE__ */ jsx5("circle", { cx: "18", cy: "6", r: "3" }),
|
|
1811
|
+
/* @__PURE__ */ jsx5("circle", { cx: "6", cy: "18", r: "3" })
|
|
1812
|
+
] });
|
|
1813
|
+
var EnterIcon = (props) => /* @__PURE__ */ jsxs3(Icon, { ...props, children: [
|
|
1814
|
+
/* @__PURE__ */ jsx5("path", { d: "M20 4v7a4 4 0 0 1-4 4H4" }),
|
|
1815
|
+
/* @__PURE__ */ jsx5("path", { d: "m9 10-5 5 5 5" })
|
|
1816
|
+
] });
|
|
1817
|
+
|
|
1818
|
+
// lib/components/SchematicSearch.tsx
|
|
1819
|
+
import { Fragment as Fragment3, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1820
|
+
var HighlightedSearchText = ({
|
|
1821
|
+
text,
|
|
1822
|
+
query
|
|
1823
|
+
}) => {
|
|
1824
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
1825
|
+
if (!normalizedQuery) return text;
|
|
1826
|
+
const normalizedText = text.toLocaleLowerCase();
|
|
1827
|
+
const parts = [];
|
|
1828
|
+
let cursor = 0;
|
|
1829
|
+
let matchIndex = normalizedText.indexOf(normalizedQuery);
|
|
1830
|
+
while (matchIndex !== -1) {
|
|
1831
|
+
if (matchIndex > cursor) {
|
|
1832
|
+
parts.push(text.slice(cursor, matchIndex));
|
|
1833
|
+
}
|
|
1834
|
+
parts.push(
|
|
1835
|
+
/* @__PURE__ */ jsx6("strong", { style: { fontWeight: 700 }, children: text.slice(matchIndex, matchIndex + normalizedQuery.length) }, `${matchIndex}-${cursor}`)
|
|
1836
|
+
);
|
|
1837
|
+
cursor = matchIndex + normalizedQuery.length;
|
|
1838
|
+
matchIndex = normalizedText.indexOf(normalizedQuery, cursor);
|
|
1839
|
+
}
|
|
1840
|
+
if (cursor < text.length) parts.push(text.slice(cursor));
|
|
1841
|
+
if (parts.length > 0) return parts;
|
|
1842
|
+
return text;
|
|
1843
|
+
};
|
|
1844
|
+
var getShortcutLabel = () => {
|
|
1845
|
+
if (typeof navigator === "undefined") return "Ctrl F";
|
|
1846
|
+
if (/mac/i.test(navigator.platform)) return "\u2318 F";
|
|
1847
|
+
return "Ctrl F";
|
|
1848
|
+
};
|
|
1849
|
+
var SchematicSearch = ({
|
|
1850
|
+
query,
|
|
1851
|
+
onQueryChange,
|
|
1852
|
+
onCancel,
|
|
1853
|
+
results,
|
|
1854
|
+
onSelect,
|
|
1855
|
+
viewerContainerRef
|
|
1856
|
+
}) => {
|
|
1857
|
+
const [isOpen, setIsOpen] = useState6(false);
|
|
1858
|
+
const [activeResultId, setActiveResultId] = useState6(null);
|
|
1859
|
+
const [hoveredResultId, setHoveredResultId] = useState6(null);
|
|
1860
|
+
const inputRef = useRef7(null);
|
|
1861
|
+
const resultsListRef = useRef7(null);
|
|
1862
|
+
const shortcutLabel = getShortcutLabel();
|
|
1863
|
+
useEffect10(() => {
|
|
1864
|
+
setActiveResultId((currentId) => {
|
|
1865
|
+
if (results.some((result) => result.target.id === currentId)) {
|
|
1866
|
+
return currentId;
|
|
1867
|
+
}
|
|
1868
|
+
return results.find((result) => result.kind === "component")?.target.id ?? results[0]?.target.id ?? null;
|
|
1869
|
+
});
|
|
1870
|
+
}, [results]);
|
|
1871
|
+
useEffect10(() => {
|
|
1872
|
+
if (!activeResultId) return;
|
|
1873
|
+
resultsListRef.current?.querySelector(`[data-search-result-id="${activeResultId}"]`)?.scrollIntoView({ behavior: "smooth", block: "nearest" });
|
|
1874
|
+
}, [activeResultId]);
|
|
1875
|
+
useEffect10(() => {
|
|
1876
|
+
const handleSearchShortcut = (event) => {
|
|
1877
|
+
if (event.key === "Escape" && isOpen) {
|
|
1878
|
+
event.preventDefault();
|
|
1879
|
+
event.stopPropagation();
|
|
1880
|
+
event.stopImmediatePropagation();
|
|
1881
|
+
onCancel();
|
|
1882
|
+
setIsOpen(false);
|
|
1883
|
+
inputRef.current?.blur();
|
|
1884
|
+
return;
|
|
1885
|
+
}
|
|
1886
|
+
if (event.code !== "KeyF" && event.key.toLocaleLowerCase() !== "f") {
|
|
1887
|
+
return;
|
|
1888
|
+
}
|
|
1889
|
+
if (!event.metaKey && !event.ctrlKey) {
|
|
1890
|
+
return;
|
|
1891
|
+
}
|
|
1892
|
+
if (!viewerContainerRef.current?.matches(":hover")) return;
|
|
1893
|
+
event.preventDefault();
|
|
1894
|
+
event.stopPropagation();
|
|
1895
|
+
event.stopImmediatePropagation();
|
|
1896
|
+
setIsOpen(true);
|
|
1897
|
+
requestAnimationFrame(() => {
|
|
1898
|
+
inputRef.current?.focus();
|
|
1899
|
+
inputRef.current?.select();
|
|
1900
|
+
});
|
|
1901
|
+
};
|
|
1902
|
+
const shortcutWindows = [window];
|
|
1903
|
+
try {
|
|
1904
|
+
if (window.parent !== window && window.parent.document) {
|
|
1905
|
+
shortcutWindows.push(window.parent);
|
|
1906
|
+
}
|
|
1907
|
+
} catch {
|
|
1908
|
+
}
|
|
1909
|
+
shortcutWindows.forEach(
|
|
1910
|
+
(targetWindow) => targetWindow.addEventListener("keydown", handleSearchShortcut, {
|
|
1911
|
+
capture: true
|
|
1912
|
+
})
|
|
1913
|
+
);
|
|
1914
|
+
return () => {
|
|
1915
|
+
shortcutWindows.forEach(
|
|
1916
|
+
(targetWindow) => targetWindow.removeEventListener("keydown", handleSearchShortcut, {
|
|
1917
|
+
capture: true
|
|
1918
|
+
})
|
|
1919
|
+
);
|
|
1920
|
+
};
|
|
1921
|
+
}, [isOpen, onCancel, viewerContainerRef]);
|
|
1922
|
+
const cancelSearch = () => {
|
|
1923
|
+
onCancel();
|
|
1924
|
+
setIsOpen(false);
|
|
1925
|
+
inputRef.current?.blur();
|
|
1926
|
+
};
|
|
1927
|
+
const openSearch = (focusInput) => {
|
|
1928
|
+
setIsOpen(true);
|
|
1929
|
+
if (focusInput) {
|
|
1930
|
+
requestAnimationFrame(() => inputRef.current?.focus());
|
|
1931
|
+
}
|
|
1932
|
+
};
|
|
1933
|
+
const componentResults = results.filter(
|
|
1934
|
+
(result) => result.kind === "component"
|
|
1935
|
+
);
|
|
1936
|
+
const netResults = results.filter((result) => result.kind === "net");
|
|
1937
|
+
const orderedResults = [...componentResults, ...netResults];
|
|
1938
|
+
const activeResult = orderedResults.find((result) => result.target.id === activeResultId) ?? orderedResults[0];
|
|
1939
|
+
const resultCountLabel = results.length === 1 ? "1 result" : `${results.length} results`;
|
|
1940
|
+
let searchHeaderBorder = "none";
|
|
1941
|
+
if (query) searchHeaderBorder = "1px solid #e8e8e8";
|
|
1942
|
+
const handleSearchKeyDown = (event) => {
|
|
1943
|
+
if (event.key === "Enter" && event.target instanceof Element && event.target.closest('[aria-label="Clear search"]')) {
|
|
1944
|
+
return;
|
|
1945
|
+
}
|
|
1946
|
+
if (event.key === "Escape") {
|
|
1947
|
+
event.preventDefault();
|
|
1948
|
+
cancelSearch();
|
|
1949
|
+
return;
|
|
1950
|
+
}
|
|
1951
|
+
if (orderedResults.length > 0 && (event.key === "ArrowDown" || event.key === "ArrowUp")) {
|
|
1952
|
+
event.preventDefault();
|
|
1953
|
+
let direction = -1;
|
|
1954
|
+
if (event.key === "ArrowDown") direction = 1;
|
|
1955
|
+
setActiveResultId((currentId) => {
|
|
1956
|
+
const currentIndex = orderedResults.findIndex(
|
|
1957
|
+
(result) => result.target.id === currentId
|
|
1958
|
+
);
|
|
1959
|
+
let startIndex = currentIndex;
|
|
1960
|
+
if (currentIndex === -1) {
|
|
1961
|
+
startIndex = 0;
|
|
1962
|
+
if (direction === 1) startIndex = -1;
|
|
1963
|
+
}
|
|
1964
|
+
const nextIndex = (startIndex + direction + orderedResults.length) % orderedResults.length;
|
|
1965
|
+
return orderedResults[nextIndex]?.target.id ?? null;
|
|
1966
|
+
});
|
|
1967
|
+
return;
|
|
1968
|
+
}
|
|
1969
|
+
if (event.key === "Enter" && activeResult) {
|
|
1970
|
+
event.preventDefault();
|
|
1971
|
+
onSelect(activeResult);
|
|
1972
|
+
}
|
|
1973
|
+
};
|
|
1974
|
+
const renderResultSection = (title, sectionResults) => {
|
|
1975
|
+
if (sectionResults.length === 0) return null;
|
|
1976
|
+
return /* @__PURE__ */ jsxs4("section", { children: [
|
|
1977
|
+
/* @__PURE__ */ jsx6(
|
|
1978
|
+
"div",
|
|
1979
|
+
{
|
|
1980
|
+
style: {
|
|
1981
|
+
padding: "6px 12px 3px",
|
|
1982
|
+
backgroundColor: "#f7f7f8",
|
|
1983
|
+
color: "#777777",
|
|
1984
|
+
fontSize: "11px",
|
|
1985
|
+
fontWeight: 600,
|
|
1986
|
+
letterSpacing: "0.02em",
|
|
1987
|
+
textTransform: "lowercase"
|
|
1988
|
+
},
|
|
1989
|
+
children: title
|
|
1990
|
+
}
|
|
1991
|
+
),
|
|
1992
|
+
sectionResults.map((result) => {
|
|
1993
|
+
const active = result.target.id === activeResult?.target.id;
|
|
1994
|
+
const hovering = result.target.id === hoveredResultId;
|
|
1995
|
+
let resultBackground = "#ffffff";
|
|
1996
|
+
if (hovering || active) resultBackground = "#f1f3f5";
|
|
1997
|
+
let resultIcon = /* @__PURE__ */ jsx6(NetIcon, { size: 15, strokeWidth: 1.8 });
|
|
1998
|
+
if (result.kind === "component") {
|
|
1999
|
+
resultIcon = /* @__PURE__ */ jsx6(ComponentIcon, { size: 15, strokeWidth: 1.8 });
|
|
2000
|
+
}
|
|
2001
|
+
const selectResult = () => {
|
|
2002
|
+
inputRef.current?.blur();
|
|
2003
|
+
setActiveResultId(result.target.id);
|
|
2004
|
+
onSelect(result);
|
|
2005
|
+
};
|
|
2006
|
+
return /* @__PURE__ */ jsxs4(
|
|
2007
|
+
"button",
|
|
2008
|
+
{
|
|
2009
|
+
type: "button",
|
|
2010
|
+
"data-search-result-id": result.target.id,
|
|
2011
|
+
onPointerUp: (event) => {
|
|
2012
|
+
if (event.button === 0) selectResult();
|
|
2013
|
+
},
|
|
2014
|
+
onClick: (event) => {
|
|
2015
|
+
if (event.detail === 0) selectResult();
|
|
2016
|
+
},
|
|
2017
|
+
onMouseEnter: () => setHoveredResultId(result.target.id),
|
|
2018
|
+
onMouseLeave: () => setHoveredResultId(null),
|
|
2019
|
+
style: {
|
|
2020
|
+
width: "100%",
|
|
2021
|
+
display: "flex",
|
|
2022
|
+
alignItems: "center",
|
|
2023
|
+
gap: "9px",
|
|
2024
|
+
padding: "7px 12px",
|
|
2025
|
+
border: "none",
|
|
2026
|
+
background: resultBackground,
|
|
2027
|
+
color: "#222222",
|
|
2028
|
+
cursor: "pointer",
|
|
2029
|
+
textAlign: "left"
|
|
2030
|
+
},
|
|
2031
|
+
children: [
|
|
2032
|
+
/* @__PURE__ */ jsx6(
|
|
2033
|
+
"span",
|
|
2034
|
+
{
|
|
2035
|
+
style: {
|
|
2036
|
+
width: "26px",
|
|
2037
|
+
height: "26px",
|
|
2038
|
+
flexShrink: 0,
|
|
2039
|
+
display: "grid",
|
|
2040
|
+
placeItems: "center",
|
|
2041
|
+
border: "1px solid #e5e5e5",
|
|
2042
|
+
borderRadius: "6px",
|
|
2043
|
+
backgroundColor: "#f7f7f7",
|
|
2044
|
+
color: "#666666"
|
|
2045
|
+
},
|
|
2046
|
+
children: resultIcon
|
|
2047
|
+
}
|
|
2048
|
+
),
|
|
2049
|
+
/* @__PURE__ */ jsxs4("span", { style: { minWidth: 0, flex: 1 }, children: [
|
|
2050
|
+
/* @__PURE__ */ jsx6(
|
|
2051
|
+
"span",
|
|
2052
|
+
{
|
|
2053
|
+
style: {
|
|
2054
|
+
display: "block",
|
|
2055
|
+
overflow: "hidden",
|
|
2056
|
+
fontSize: "13px",
|
|
2057
|
+
fontWeight: 400,
|
|
2058
|
+
lineHeight: 1.25,
|
|
2059
|
+
textOverflow: "ellipsis",
|
|
2060
|
+
whiteSpace: "nowrap"
|
|
2061
|
+
},
|
|
2062
|
+
children: /* @__PURE__ */ jsx6(HighlightedSearchText, { text: result.label, query })
|
|
2063
|
+
}
|
|
2064
|
+
),
|
|
2065
|
+
result.detail && /* @__PURE__ */ jsx6(
|
|
2066
|
+
"span",
|
|
2067
|
+
{
|
|
2068
|
+
style: {
|
|
2069
|
+
display: "block",
|
|
2070
|
+
overflow: "hidden",
|
|
2071
|
+
marginTop: "2px",
|
|
2072
|
+
color: "#777777",
|
|
2073
|
+
fontSize: "11px",
|
|
2074
|
+
lineHeight: 1.2,
|
|
2075
|
+
textOverflow: "ellipsis",
|
|
2076
|
+
whiteSpace: "nowrap"
|
|
2077
|
+
},
|
|
2078
|
+
children: result.detail
|
|
2079
|
+
}
|
|
2080
|
+
),
|
|
2081
|
+
result.schematicSheetName && /* @__PURE__ */ jsxs4(
|
|
2082
|
+
"span",
|
|
2083
|
+
{
|
|
2084
|
+
style: {
|
|
2085
|
+
display: "block",
|
|
2086
|
+
overflow: "hidden",
|
|
2087
|
+
marginTop: "2px",
|
|
2088
|
+
color: "#777777",
|
|
2089
|
+
fontSize: "11px",
|
|
2090
|
+
lineHeight: 1.2,
|
|
2091
|
+
textOverflow: "ellipsis",
|
|
2092
|
+
whiteSpace: "nowrap"
|
|
2093
|
+
},
|
|
2094
|
+
children: [
|
|
2095
|
+
"Sheet: ",
|
|
2096
|
+
result.schematicSheetName
|
|
2097
|
+
]
|
|
2098
|
+
}
|
|
2099
|
+
)
|
|
2100
|
+
] }),
|
|
2101
|
+
active && /* @__PURE__ */ jsx6(
|
|
2102
|
+
"span",
|
|
2103
|
+
{
|
|
2104
|
+
title: "Press Enter to open",
|
|
2105
|
+
style: {
|
|
2106
|
+
flexShrink: 0,
|
|
2107
|
+
color: "#666666",
|
|
2108
|
+
fontSize: "17px",
|
|
2109
|
+
lineHeight: 1
|
|
2110
|
+
},
|
|
2111
|
+
children: /* @__PURE__ */ jsx6(EnterIcon, { size: 14, strokeWidth: 1.8 })
|
|
2112
|
+
}
|
|
2113
|
+
)
|
|
2114
|
+
]
|
|
2115
|
+
},
|
|
2116
|
+
result.target.id
|
|
2117
|
+
);
|
|
2118
|
+
})
|
|
2119
|
+
] });
|
|
2120
|
+
};
|
|
2121
|
+
return /* @__PURE__ */ jsx6(
|
|
2122
|
+
"div",
|
|
2123
|
+
{
|
|
2124
|
+
"data-schematic-search": true,
|
|
2125
|
+
onPointerDown: (event) => event.stopPropagation(),
|
|
2126
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
2127
|
+
onTouchStart: (event) => event.stopPropagation(),
|
|
2128
|
+
onTouchEnd: (event) => event.stopPropagation(),
|
|
2129
|
+
style: {
|
|
2130
|
+
position: "relative",
|
|
2131
|
+
zIndex: zIndexMap.schematicSearch,
|
|
2132
|
+
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif'
|
|
2133
|
+
},
|
|
2134
|
+
children: !isOpen ? /* @__PURE__ */ jsx6(
|
|
2135
|
+
"button",
|
|
2136
|
+
{
|
|
2137
|
+
type: "button",
|
|
2138
|
+
title: "Search schematic",
|
|
2139
|
+
"aria-label": "Search schematic",
|
|
2140
|
+
onPointerDown: (event) => {
|
|
2141
|
+
event.stopPropagation();
|
|
2142
|
+
if (event.pointerType !== "mouse") openSearch(false);
|
|
2143
|
+
},
|
|
2144
|
+
onPointerUp: (event) => {
|
|
2145
|
+
if (event.pointerType === "mouse" && event.button === 0) {
|
|
2146
|
+
openSearch(true);
|
|
2147
|
+
}
|
|
2148
|
+
},
|
|
2149
|
+
onClick: (event) => {
|
|
2150
|
+
if (event.detail === 0) openSearch(true);
|
|
2151
|
+
},
|
|
2152
|
+
style: {
|
|
2153
|
+
width: "32px",
|
|
2154
|
+
height: "32px",
|
|
2155
|
+
display: "grid",
|
|
2156
|
+
placeItems: "center",
|
|
2157
|
+
padding: 0,
|
|
2158
|
+
border: "none",
|
|
2159
|
+
borderRadius: "4px",
|
|
2160
|
+
backgroundColor: "#ffffff",
|
|
2161
|
+
color: "#000000",
|
|
2162
|
+
cursor: "pointer",
|
|
2163
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
|
|
2164
|
+
},
|
|
2165
|
+
children: /* @__PURE__ */ jsx6(SearchIcon, { size: 16, strokeWidth: 2 })
|
|
2166
|
+
}
|
|
2167
|
+
) : /* @__PURE__ */ jsxs4(
|
|
2168
|
+
"div",
|
|
2169
|
+
{
|
|
2170
|
+
onKeyDown: handleSearchKeyDown,
|
|
2171
|
+
style: {
|
|
2172
|
+
width: "min(280px, calc(100vw - 32px))",
|
|
2173
|
+
overflow: "hidden",
|
|
2174
|
+
border: "none",
|
|
2175
|
+
borderRadius: "4px",
|
|
2176
|
+
backgroundColor: "#ffffff",
|
|
2177
|
+
boxShadow: "0 2px 4px rgba(0,0,0,0.1)"
|
|
2178
|
+
},
|
|
2179
|
+
children: [
|
|
2180
|
+
/* @__PURE__ */ jsxs4(
|
|
2181
|
+
"div",
|
|
2182
|
+
{
|
|
2183
|
+
style: {
|
|
2184
|
+
display: "flex",
|
|
2185
|
+
alignItems: "center",
|
|
2186
|
+
gap: "8px",
|
|
2187
|
+
height: "32px",
|
|
2188
|
+
boxSizing: "border-box",
|
|
2189
|
+
padding: "0 12px",
|
|
2190
|
+
borderBottom: searchHeaderBorder
|
|
2191
|
+
},
|
|
2192
|
+
children: [
|
|
2193
|
+
/* @__PURE__ */ jsx6(SearchIcon, { size: 15, strokeWidth: 2 }),
|
|
2194
|
+
/* @__PURE__ */ jsx6(
|
|
2195
|
+
"input",
|
|
2196
|
+
{
|
|
2197
|
+
ref: inputRef,
|
|
2198
|
+
value: query,
|
|
2199
|
+
"aria-label": "Search components and nets",
|
|
2200
|
+
placeholder: "Search...",
|
|
2201
|
+
onPointerUp: (event) => event.currentTarget.focus(),
|
|
2202
|
+
onChange: (event) => onQueryChange(event.target.value),
|
|
2203
|
+
style: {
|
|
2204
|
+
minWidth: 0,
|
|
2205
|
+
flex: 1,
|
|
2206
|
+
border: "none",
|
|
2207
|
+
outline: "none",
|
|
2208
|
+
fontSize: "13px",
|
|
2209
|
+
color: "#222222",
|
|
2210
|
+
background: "transparent"
|
|
2211
|
+
}
|
|
2212
|
+
}
|
|
2213
|
+
),
|
|
2214
|
+
query && results.length > 0 ? /* @__PURE__ */ jsx6(
|
|
2215
|
+
"span",
|
|
2216
|
+
{
|
|
2217
|
+
style: {
|
|
2218
|
+
flexShrink: 0,
|
|
2219
|
+
color: "#888888",
|
|
2220
|
+
fontSize: "12px",
|
|
2221
|
+
whiteSpace: "nowrap"
|
|
2222
|
+
},
|
|
2223
|
+
children: resultCountLabel
|
|
2224
|
+
}
|
|
2225
|
+
) : /* @__PURE__ */ jsx6(
|
|
2226
|
+
"kbd",
|
|
2227
|
+
{
|
|
2228
|
+
style: {
|
|
2229
|
+
flexShrink: 0,
|
|
2230
|
+
padding: "2px 5px",
|
|
2231
|
+
border: "1px solid #dddddd",
|
|
2232
|
+
borderRadius: "4px",
|
|
2233
|
+
backgroundColor: "#f7f7f7",
|
|
2234
|
+
color: "#777777",
|
|
2235
|
+
fontFamily: "inherit",
|
|
2236
|
+
fontSize: "10px",
|
|
2237
|
+
lineHeight: 1.2
|
|
2238
|
+
},
|
|
2239
|
+
children: shortcutLabel
|
|
2240
|
+
}
|
|
2241
|
+
),
|
|
2242
|
+
isOpen && /* @__PURE__ */ jsx6(
|
|
2243
|
+
"button",
|
|
2244
|
+
{
|
|
2245
|
+
type: "button",
|
|
2246
|
+
"aria-label": "Clear search",
|
|
2247
|
+
onPointerUp: (event) => {
|
|
2248
|
+
if (event.button === 0) cancelSearch();
|
|
2249
|
+
},
|
|
2250
|
+
onClick: (event) => {
|
|
2251
|
+
if (event.detail === 0) cancelSearch();
|
|
2252
|
+
},
|
|
2253
|
+
style: {
|
|
2254
|
+
border: "none",
|
|
2255
|
+
background: "transparent",
|
|
2256
|
+
color: "#777777",
|
|
2257
|
+
cursor: "pointer",
|
|
2258
|
+
width: "20px",
|
|
2259
|
+
height: "20px",
|
|
2260
|
+
display: "grid",
|
|
2261
|
+
placeItems: "center",
|
|
2262
|
+
padding: 0,
|
|
2263
|
+
lineHeight: 1
|
|
2264
|
+
},
|
|
2265
|
+
children: /* @__PURE__ */ jsx6(CloseIcon, { size: 16, strokeWidth: 2 })
|
|
2266
|
+
}
|
|
2267
|
+
)
|
|
2268
|
+
]
|
|
2269
|
+
}
|
|
2270
|
+
),
|
|
2271
|
+
query && /* @__PURE__ */ jsx6(
|
|
2272
|
+
"div",
|
|
2273
|
+
{
|
|
2274
|
+
ref: resultsListRef,
|
|
2275
|
+
style: {
|
|
2276
|
+
maxHeight: "240px",
|
|
2277
|
+
overflowX: "hidden",
|
|
2278
|
+
overflowY: "auto",
|
|
2279
|
+
overscrollBehavior: "contain",
|
|
2280
|
+
scrollBehavior: "smooth",
|
|
2281
|
+
touchAction: "pan-y",
|
|
2282
|
+
WebkitOverflowScrolling: "touch"
|
|
2283
|
+
},
|
|
2284
|
+
onWheel: (event) => event.stopPropagation(),
|
|
2285
|
+
onTouchMove: (event) => event.stopPropagation(),
|
|
2286
|
+
children: results.length === 0 ? /* @__PURE__ */ jsx6(
|
|
2287
|
+
"div",
|
|
2288
|
+
{
|
|
2289
|
+
style: {
|
|
2290
|
+
padding: "12px",
|
|
2291
|
+
color: "#777777",
|
|
2292
|
+
fontSize: "13px"
|
|
2293
|
+
},
|
|
2294
|
+
children: "No matching components or nets"
|
|
2295
|
+
}
|
|
2296
|
+
) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
2297
|
+
renderResultSection("components", componentResults),
|
|
2298
|
+
renderResultSection("nets", netResults)
|
|
2299
|
+
] })
|
|
2300
|
+
}
|
|
2301
|
+
)
|
|
2302
|
+
]
|
|
2303
|
+
}
|
|
2304
|
+
)
|
|
2305
|
+
}
|
|
2306
|
+
);
|
|
2307
|
+
};
|
|
2308
|
+
|
|
1387
2309
|
// lib/components/SchematicSheetSelector.tsx
|
|
1388
|
-
import { useState as
|
|
2310
|
+
import { useState as useState7 } from "react";
|
|
1389
2311
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
1390
|
-
import { Fragment as
|
|
2312
|
+
import { Fragment as Fragment4, jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1391
2313
|
var FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1392
2314
|
var contentStyles = {
|
|
1393
2315
|
backgroundColor: "#ffffff",
|
|
@@ -1437,7 +2359,7 @@ var MENU_CSS = `
|
|
|
1437
2359
|
.sv-sheet-chevron { transition: transform 0.2s ease; }
|
|
1438
2360
|
[data-state="open"] > .sv-sheet-chevron { transform: rotate(180deg); }
|
|
1439
2361
|
`;
|
|
1440
|
-
var CheckIcon = () => /* @__PURE__ */
|
|
2362
|
+
var CheckIcon = () => /* @__PURE__ */ jsx7(
|
|
1441
2363
|
"svg",
|
|
1442
2364
|
{
|
|
1443
2365
|
width: "14",
|
|
@@ -1449,10 +2371,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx5(
|
|
|
1449
2371
|
strokeLinecap: "round",
|
|
1450
2372
|
strokeLinejoin: "round",
|
|
1451
2373
|
"aria-hidden": "true",
|
|
1452
|
-
children: /* @__PURE__ */
|
|
2374
|
+
children: /* @__PURE__ */ jsx7("path", { d: "M20 6 9 17l-5-5" })
|
|
1453
2375
|
}
|
|
1454
2376
|
);
|
|
1455
|
-
var ChevronDownIcon = ({ className }) => /* @__PURE__ */
|
|
2377
|
+
var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx7(
|
|
1456
2378
|
"svg",
|
|
1457
2379
|
{
|
|
1458
2380
|
className,
|
|
@@ -1466,7 +2388,7 @@ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx5(
|
|
|
1466
2388
|
strokeLinejoin: "round",
|
|
1467
2389
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
1468
2390
|
"aria-hidden": "true",
|
|
1469
|
-
children: /* @__PURE__ */
|
|
2391
|
+
children: /* @__PURE__ */ jsx7("path", { d: "m6 9 6 6 6-6" })
|
|
1470
2392
|
}
|
|
1471
2393
|
);
|
|
1472
2394
|
var SchematicSheetSelector = ({
|
|
@@ -1474,25 +2396,22 @@ var SchematicSheetSelector = ({
|
|
|
1474
2396
|
selectedSheetId,
|
|
1475
2397
|
onSelectSheet
|
|
1476
2398
|
}) => {
|
|
1477
|
-
const [open, setOpen] =
|
|
2399
|
+
const [open, setOpen] = useState7(false);
|
|
1478
2400
|
if (sheets.length <= 1) return null;
|
|
1479
2401
|
const selectedSheet = sheets.find(
|
|
1480
2402
|
(s) => s.schematic_sheet_id === selectedSheetId
|
|
1481
2403
|
);
|
|
1482
2404
|
const selectedLabel = selectedSheet?.name ?? "Select sheet";
|
|
1483
|
-
return /* @__PURE__ */
|
|
1484
|
-
/* @__PURE__ */
|
|
1485
|
-
/* @__PURE__ */
|
|
1486
|
-
/* @__PURE__ */
|
|
2405
|
+
return /* @__PURE__ */ jsxs5(Fragment4, { children: [
|
|
2406
|
+
/* @__PURE__ */ jsx7("style", { children: MENU_CSS }),
|
|
2407
|
+
/* @__PURE__ */ jsxs5(DropdownMenu.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
2408
|
+
/* @__PURE__ */ jsx7(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
|
|
1487
2409
|
"button",
|
|
1488
2410
|
{
|
|
1489
2411
|
type: "button",
|
|
1490
2412
|
title: selectedLabel,
|
|
1491
2413
|
onPointerDown: (e) => e.stopPropagation(),
|
|
1492
2414
|
style: {
|
|
1493
|
-
position: "absolute",
|
|
1494
|
-
top: "16px",
|
|
1495
|
-
left: "16px",
|
|
1496
2415
|
display: "flex",
|
|
1497
2416
|
alignItems: "center",
|
|
1498
2417
|
gap: "6px",
|
|
@@ -1506,17 +2425,16 @@ var SchematicSheetSelector = ({
|
|
|
1506
2425
|
cursor: "pointer",
|
|
1507
2426
|
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
|
1508
2427
|
fontSize: "13px",
|
|
1509
|
-
fontFamily: FONT_FAMILY
|
|
1510
|
-
zIndex: zIndexMap.viewMenuIcon
|
|
2428
|
+
fontFamily: FONT_FAMILY
|
|
1511
2429
|
},
|
|
1512
2430
|
children: [
|
|
1513
|
-
/* @__PURE__ */
|
|
1514
|
-
/* @__PURE__ */
|
|
1515
|
-
/* @__PURE__ */
|
|
2431
|
+
/* @__PURE__ */ jsx7("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
|
|
2432
|
+
/* @__PURE__ */ jsx7("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
|
|
2433
|
+
/* @__PURE__ */ jsx7(ChevronDownIcon, { className: "sv-sheet-chevron" })
|
|
1516
2434
|
]
|
|
1517
2435
|
}
|
|
1518
2436
|
) }),
|
|
1519
|
-
/* @__PURE__ */
|
|
2437
|
+
/* @__PURE__ */ jsx7(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx7(
|
|
1520
2438
|
DropdownMenu.Content,
|
|
1521
2439
|
{
|
|
1522
2440
|
style: contentStyles,
|
|
@@ -1526,7 +2444,7 @@ var SchematicSheetSelector = ({
|
|
|
1526
2444
|
collisionPadding: 10,
|
|
1527
2445
|
children: sheets.map((sheet) => {
|
|
1528
2446
|
const selected = sheet.schematic_sheet_id === selectedSheetId;
|
|
1529
|
-
return /* @__PURE__ */
|
|
2447
|
+
return /* @__PURE__ */ jsxs5(
|
|
1530
2448
|
DropdownMenu.Item,
|
|
1531
2449
|
{
|
|
1532
2450
|
className: "sv-sheet-item",
|
|
@@ -1538,8 +2456,8 @@ var SchematicSheetSelector = ({
|
|
|
1538
2456
|
setOpen(false);
|
|
1539
2457
|
},
|
|
1540
2458
|
children: [
|
|
1541
|
-
/* @__PURE__ */
|
|
1542
|
-
/* @__PURE__ */
|
|
2459
|
+
/* @__PURE__ */ jsx7("span", { style: iconSlotStyles, children: selected && /* @__PURE__ */ jsx7(CheckIcon, {}) }),
|
|
2460
|
+
/* @__PURE__ */ jsx7("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
|
|
1543
2461
|
]
|
|
1544
2462
|
},
|
|
1545
2463
|
sheet.schematic_sheet_id
|
|
@@ -1554,12 +2472,16 @@ var SchematicSheetSelector = ({
|
|
|
1554
2472
|
// lib/components/ViewMenu.tsx
|
|
1555
2473
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
1556
2474
|
import { su as su3 } from "@tscircuit/soup-util";
|
|
1557
|
-
import { useMemo as
|
|
2475
|
+
import { useMemo as useMemo5 } from "react";
|
|
1558
2476
|
|
|
1559
2477
|
// package.json
|
|
1560
2478
|
var package_default = {
|
|
1561
2479
|
name: "@tscircuit/schematic-viewer",
|
|
1562
|
-
version: "2.0.
|
|
2480
|
+
version: "2.0.81",
|
|
2481
|
+
repository: {
|
|
2482
|
+
type: "git",
|
|
2483
|
+
url: "https://github.com/tscircuit/schematic-viewer"
|
|
2484
|
+
},
|
|
1563
2485
|
main: "dist/index.js",
|
|
1564
2486
|
type: "module",
|
|
1565
2487
|
scripts: {
|
|
@@ -1609,7 +2531,7 @@ var package_default = {
|
|
|
1609
2531
|
};
|
|
1610
2532
|
|
|
1611
2533
|
// lib/components/ViewMenu.tsx
|
|
1612
|
-
import { jsx as
|
|
2534
|
+
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1613
2535
|
var FONT_FAMILY2 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1614
2536
|
var contentStyles2 = {
|
|
1615
2537
|
backgroundColor: "#262626",
|
|
@@ -1658,7 +2580,7 @@ var HIGHLIGHT_CSS = `
|
|
|
1658
2580
|
.sv-vm-item:hover:not([data-disabled]) { background-color: #404040; }
|
|
1659
2581
|
.sv-vm-item[data-disabled] { opacity: 0.45; cursor: not-allowed; }
|
|
1660
2582
|
`;
|
|
1661
|
-
var CheckIcon2 = () => /* @__PURE__ */
|
|
2583
|
+
var CheckIcon2 = () => /* @__PURE__ */ jsx8(
|
|
1662
2584
|
"svg",
|
|
1663
2585
|
{
|
|
1664
2586
|
width: "14",
|
|
@@ -1670,7 +2592,7 @@ var CheckIcon2 = () => /* @__PURE__ */ jsx6(
|
|
|
1670
2592
|
strokeLinecap: "round",
|
|
1671
2593
|
strokeLinejoin: "round",
|
|
1672
2594
|
"aria-hidden": "true",
|
|
1673
|
-
children: /* @__PURE__ */
|
|
2595
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
|
|
1674
2596
|
}
|
|
1675
2597
|
);
|
|
1676
2598
|
var ViewMenu = ({
|
|
@@ -1686,7 +2608,7 @@ var ViewMenu = ({
|
|
|
1686
2608
|
showPorts,
|
|
1687
2609
|
onTogglePorts
|
|
1688
2610
|
}) => {
|
|
1689
|
-
const hasGroups =
|
|
2611
|
+
const hasGroups = useMemo5(() => {
|
|
1690
2612
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1691
2613
|
try {
|
|
1692
2614
|
const sourceGroups = su3(circuitJson).source_group?.list() || [];
|
|
@@ -1710,7 +2632,7 @@ var ViewMenu = ({
|
|
|
1710
2632
|
return false;
|
|
1711
2633
|
}
|
|
1712
2634
|
}, [circuitJsonKey]);
|
|
1713
|
-
const hasPorts =
|
|
2635
|
+
const hasPorts = useMemo5(() => {
|
|
1714
2636
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1715
2637
|
try {
|
|
1716
2638
|
return (su3(circuitJson).schematic_port?.list() || []).length > 0;
|
|
@@ -1719,7 +2641,7 @@ var ViewMenu = ({
|
|
|
1719
2641
|
return false;
|
|
1720
2642
|
}
|
|
1721
2643
|
}, [circuitJsonKey]);
|
|
1722
|
-
return /* @__PURE__ */
|
|
2644
|
+
return /* @__PURE__ */ jsx8(
|
|
1723
2645
|
"div",
|
|
1724
2646
|
{
|
|
1725
2647
|
ref: menuRef,
|
|
@@ -1730,9 +2652,9 @@ var ViewMenu = ({
|
|
|
1730
2652
|
width: 0,
|
|
1731
2653
|
height: 0
|
|
1732
2654
|
},
|
|
1733
|
-
children: /* @__PURE__ */
|
|
1734
|
-
/* @__PURE__ */
|
|
1735
|
-
/* @__PURE__ */
|
|
2655
|
+
children: /* @__PURE__ */ jsxs6(DropdownMenu2.Root, { open: true, onOpenChange, modal: false, children: [
|
|
2656
|
+
/* @__PURE__ */ jsx8(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx8("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
|
|
2657
|
+
/* @__PURE__ */ jsx8(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs6(
|
|
1736
2658
|
DropdownMenu2.Content,
|
|
1737
2659
|
{
|
|
1738
2660
|
style: contentStyles2,
|
|
@@ -1741,8 +2663,8 @@ var ViewMenu = ({
|
|
|
1741
2663
|
collisionPadding: 10,
|
|
1742
2664
|
avoidCollisions: true,
|
|
1743
2665
|
children: [
|
|
1744
|
-
/* @__PURE__ */
|
|
1745
|
-
/* @__PURE__ */
|
|
2666
|
+
/* @__PURE__ */ jsx8("style", { children: HIGHLIGHT_CSS }),
|
|
2667
|
+
/* @__PURE__ */ jsxs6(
|
|
1746
2668
|
DropdownMenu2.Item,
|
|
1747
2669
|
{
|
|
1748
2670
|
className: "sv-vm-item",
|
|
@@ -1755,12 +2677,12 @@ var ViewMenu = ({
|
|
|
1755
2677
|
if (hasPorts) onTogglePorts(!showPorts);
|
|
1756
2678
|
},
|
|
1757
2679
|
children: [
|
|
1758
|
-
/* @__PURE__ */
|
|
1759
|
-
/* @__PURE__ */
|
|
2680
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showPorts && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
|
|
2681
|
+
/* @__PURE__ */ jsx8("span", { children: "Show Schematic Ports" })
|
|
1760
2682
|
]
|
|
1761
2683
|
}
|
|
1762
2684
|
),
|
|
1763
|
-
/* @__PURE__ */
|
|
2685
|
+
/* @__PURE__ */ jsxs6(
|
|
1764
2686
|
DropdownMenu2.Item,
|
|
1765
2687
|
{
|
|
1766
2688
|
className: "sv-vm-item",
|
|
@@ -1773,12 +2695,12 @@ var ViewMenu = ({
|
|
|
1773
2695
|
if (hasGroups) onToggleGroups(!showGroups);
|
|
1774
2696
|
},
|
|
1775
2697
|
children: [
|
|
1776
|
-
/* @__PURE__ */
|
|
1777
|
-
/* @__PURE__ */
|
|
2698
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showGroups && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
|
|
2699
|
+
/* @__PURE__ */ jsx8("span", { children: "View Schematic Groups" })
|
|
1778
2700
|
]
|
|
1779
2701
|
}
|
|
1780
2702
|
),
|
|
1781
|
-
/* @__PURE__ */
|
|
2703
|
+
/* @__PURE__ */ jsxs6(
|
|
1782
2704
|
DropdownMenu2.Item,
|
|
1783
2705
|
{
|
|
1784
2706
|
className: "sv-vm-item",
|
|
@@ -1789,13 +2711,13 @@ var ViewMenu = ({
|
|
|
1789
2711
|
onToggleGrid(!showGrid);
|
|
1790
2712
|
},
|
|
1791
2713
|
children: [
|
|
1792
|
-
/* @__PURE__ */
|
|
1793
|
-
/* @__PURE__ */
|
|
2714
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: showGrid && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
|
|
2715
|
+
/* @__PURE__ */ jsx8("span", { children: "Show Grid" })
|
|
1794
2716
|
]
|
|
1795
2717
|
}
|
|
1796
2718
|
),
|
|
1797
|
-
/* @__PURE__ */
|
|
1798
|
-
/* @__PURE__ */
|
|
2719
|
+
/* @__PURE__ */ jsx8(DropdownMenu2.Separator, { style: separatorStyles }),
|
|
2720
|
+
/* @__PURE__ */ jsxs6(
|
|
1799
2721
|
"div",
|
|
1800
2722
|
{
|
|
1801
2723
|
style: {
|
|
@@ -1821,7 +2743,7 @@ var ViewMenu = ({
|
|
|
1821
2743
|
};
|
|
1822
2744
|
|
|
1823
2745
|
// lib/components/SchematicViewer.tsx
|
|
1824
|
-
import { jsx as
|
|
2746
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1825
2747
|
var SchematicViewer = ({
|
|
1826
2748
|
circuitJson,
|
|
1827
2749
|
containerStyle,
|
|
@@ -1835,6 +2757,7 @@ var SchematicViewer = ({
|
|
|
1835
2757
|
showSchematicPorts,
|
|
1836
2758
|
onSchematicPortClicked,
|
|
1837
2759
|
onSchematicSheetChange,
|
|
2760
|
+
searchEnabled = true,
|
|
1838
2761
|
css,
|
|
1839
2762
|
className
|
|
1840
2763
|
}) => {
|
|
@@ -1844,11 +2767,11 @@ var SchematicViewer = ({
|
|
|
1844
2767
|
const getCircuitHash = (circuitJson2) => {
|
|
1845
2768
|
return `${circuitJson2?.length || 0}_${circuitJson2?.editCount || 0}`;
|
|
1846
2769
|
};
|
|
1847
|
-
const circuitJsonKey =
|
|
2770
|
+
const circuitJsonKey = useMemo6(
|
|
1848
2771
|
() => getCircuitHash(circuitJson),
|
|
1849
2772
|
[circuitJson]
|
|
1850
2773
|
);
|
|
1851
|
-
const schematicSheets =
|
|
2774
|
+
const schematicSheets = useMemo6(() => {
|
|
1852
2775
|
try {
|
|
1853
2776
|
return circuitJson.filter((elm) => elm?.type === "schematic_sheet").slice().sort((a, b) => (a.sheet_index ?? 0) - (b.sheet_index ?? 0));
|
|
1854
2777
|
} catch (err) {
|
|
@@ -1858,7 +2781,7 @@ var SchematicViewer = ({
|
|
|
1858
2781
|
}, [circuitJsonKey]);
|
|
1859
2782
|
const hasMultipleSheets = schematicSheets.length > 1;
|
|
1860
2783
|
const defaultSheetId = schematicSheets[0]?.schematic_sheet_id;
|
|
1861
|
-
const [selectedSheetId, setSelectedSheetId] =
|
|
2784
|
+
const [selectedSheetId, setSelectedSheetId] = useState8(
|
|
1862
2785
|
() => {
|
|
1863
2786
|
const stored = getStoredString(STORAGE_KEYS.SELECTED_SCHEMATIC_SHEET);
|
|
1864
2787
|
if (stored && schematicSheets.some((s) => s.schematic_sheet_id === stored)) {
|
|
@@ -1867,14 +2790,14 @@ var SchematicViewer = ({
|
|
|
1867
2790
|
return defaultSheetId;
|
|
1868
2791
|
}
|
|
1869
2792
|
);
|
|
1870
|
-
|
|
2793
|
+
useEffect11(() => {
|
|
1871
2794
|
const stillExists = selectedSheetId !== void 0 && schematicSheets.some((s) => s.schematic_sheet_id === selectedSheetId);
|
|
1872
2795
|
if (!stillExists) {
|
|
1873
2796
|
setSelectedSheetId(defaultSheetId);
|
|
1874
2797
|
}
|
|
1875
2798
|
}, [circuitJsonKey]);
|
|
1876
2799
|
const activeSheetId = hasMultipleSheets ? selectedSheetId ?? defaultSheetId : void 0;
|
|
1877
|
-
const handleSelectSheet =
|
|
2800
|
+
const handleSelectSheet = useCallback7(
|
|
1878
2801
|
(sheetId) => {
|
|
1879
2802
|
setSelectedSheetId(sheetId);
|
|
1880
2803
|
setStoredString(STORAGE_KEYS.SELECTED_SCHEMATIC_SHEET, sheetId);
|
|
@@ -1882,27 +2805,27 @@ var SchematicViewer = ({
|
|
|
1882
2805
|
},
|
|
1883
2806
|
[onSchematicSheetChange]
|
|
1884
2807
|
);
|
|
1885
|
-
const [showGridInternal, setShowGridInternal] =
|
|
2808
|
+
const [showGridInternal, setShowGridInternal] = useState8(false);
|
|
1886
2809
|
const showGrid = debugGrid || showGridInternal;
|
|
1887
|
-
const [isInteractionEnabled, setIsInteractionEnabled] =
|
|
2810
|
+
const [isInteractionEnabled, setIsInteractionEnabled] = useState8(
|
|
1888
2811
|
!clickToInteractEnabled
|
|
1889
2812
|
);
|
|
1890
|
-
const [showSchematicGroups, setShowSchematicGroups] =
|
|
2813
|
+
const [showSchematicGroups, setShowSchematicGroups] = useState8(() => {
|
|
1891
2814
|
if (disableGroups) return false;
|
|
1892
2815
|
return getStoredBoolean(STORAGE_KEYS.IS_SHOWING_SCHEMATIC_GROUPS, false);
|
|
1893
2816
|
});
|
|
1894
|
-
const [showSchematicPortsInternal, setShowSchematicPortsInternal] =
|
|
2817
|
+
const [showSchematicPortsInternal, setShowSchematicPortsInternal] = useState8(
|
|
1895
2818
|
() => showSchematicPorts ?? getStoredBoolean(STORAGE_KEYS.IS_SHOWING_SCHEMATIC_PORTS, false)
|
|
1896
2819
|
);
|
|
1897
|
-
|
|
2820
|
+
useEffect11(() => {
|
|
1898
2821
|
if (showSchematicPorts !== void 0) {
|
|
1899
2822
|
setShowSchematicPortsInternal(showSchematicPorts);
|
|
1900
2823
|
}
|
|
1901
2824
|
}, [showSchematicPorts]);
|
|
1902
|
-
const [isHoveringClickableComponent, setIsHoveringClickableComponent] =
|
|
1903
|
-
const hoveringComponentsRef =
|
|
1904
|
-
const [selectedSchematicComponent, setSelectedSchematicComponent] =
|
|
1905
|
-
const handleComponentHoverChange =
|
|
2825
|
+
const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState8(false);
|
|
2826
|
+
const hoveringComponentsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2827
|
+
const [selectedSchematicComponent, setSelectedSchematicComponent] = useState8(null);
|
|
2828
|
+
const handleComponentHoverChange = useCallback7(
|
|
1906
2829
|
(componentId, isHovering) => {
|
|
1907
2830
|
if (isHovering) {
|
|
1908
2831
|
hoveringComponentsRef.current.add(componentId);
|
|
@@ -1913,9 +2836,9 @@ var SchematicViewer = ({
|
|
|
1913
2836
|
},
|
|
1914
2837
|
[]
|
|
1915
2838
|
);
|
|
1916
|
-
const [isHoveringClickablePort, setIsHoveringClickablePort] =
|
|
1917
|
-
const hoveringPortsRef =
|
|
1918
|
-
const handlePortHoverChange =
|
|
2839
|
+
const [isHoveringClickablePort, setIsHoveringClickablePort] = useState8(false);
|
|
2840
|
+
const hoveringPortsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2841
|
+
const handlePortHoverChange = useCallback7(
|
|
1919
2842
|
(portId, isHovering) => {
|
|
1920
2843
|
if (isHovering) {
|
|
1921
2844
|
hoveringPortsRef.current.add(portId);
|
|
@@ -1926,10 +2849,10 @@ var SchematicViewer = ({
|
|
|
1926
2849
|
},
|
|
1927
2850
|
[]
|
|
1928
2851
|
);
|
|
1929
|
-
const svgDivRef =
|
|
1930
|
-
const touchStartRef =
|
|
1931
|
-
const zoomScaleRef =
|
|
1932
|
-
const schematicComponentIds =
|
|
2852
|
+
const svgDivRef = useRef8(null);
|
|
2853
|
+
const touchStartRef = useRef8(null);
|
|
2854
|
+
const zoomScaleRef = useRef8({ x: 1, y: 1 });
|
|
2855
|
+
const schematicComponentIds = useMemo6(() => {
|
|
1933
2856
|
try {
|
|
1934
2857
|
const components = su4(circuitJson).schematic_component?.list() ?? [];
|
|
1935
2858
|
return components.filter(
|
|
@@ -1940,7 +2863,7 @@ var SchematicViewer = ({
|
|
|
1940
2863
|
return [];
|
|
1941
2864
|
}
|
|
1942
2865
|
}, [circuitJsonKey, circuitJson, activeSheetId]);
|
|
1943
|
-
const schematicPortsInfo =
|
|
2866
|
+
const schematicPortsInfo = useMemo6(() => {
|
|
1944
2867
|
if (!showSchematicPortsInternal) return [];
|
|
1945
2868
|
try {
|
|
1946
2869
|
const ports = (su4(circuitJson).schematic_port?.list() ?? []).filter(
|
|
@@ -1980,14 +2903,21 @@ var SchematicViewer = ({
|
|
|
1980
2903
|
}
|
|
1981
2904
|
touchStartRef.current = null;
|
|
1982
2905
|
};
|
|
1983
|
-
const shouldPanSchematic =
|
|
2906
|
+
const shouldPanSchematic = useCallback7(
|
|
1984
2907
|
(event) => {
|
|
2908
|
+
if (event.target instanceof Element && event.target.closest("[data-schematic-search]")) {
|
|
2909
|
+
return false;
|
|
2910
|
+
}
|
|
1985
2911
|
if (event.type !== "mousedown" || !("button" in event)) return true;
|
|
1986
2912
|
return event.button !== 2 && !(event.button === 0 && event.ctrlKey);
|
|
1987
2913
|
},
|
|
1988
2914
|
[]
|
|
1989
2915
|
);
|
|
1990
|
-
const {
|
|
2916
|
+
const {
|
|
2917
|
+
ref: containerRef,
|
|
2918
|
+
transform: svgToScreenProjection,
|
|
2919
|
+
setTransform: setSvgToScreenProjection
|
|
2920
|
+
} = useMouseMatrixTransform({
|
|
1991
2921
|
onSetTransform(transform) {
|
|
1992
2922
|
const zoomChanged = transform.a !== zoomScaleRef.current.x || transform.d !== zoomScaleRef.current.y;
|
|
1993
2923
|
zoomScaleRef.current = { x: transform.a, y: transform.d };
|
|
@@ -2009,14 +2939,14 @@ var SchematicViewer = ({
|
|
|
2009
2939
|
contextMenuEventHandlers
|
|
2010
2940
|
} = useContextMenu({ containerRef });
|
|
2011
2941
|
const { containerWidth, containerHeight } = useResizeHandling(containerRef);
|
|
2012
|
-
const selectedComponentDetails =
|
|
2942
|
+
const selectedComponentDetails = useMemo6(
|
|
2013
2943
|
() => selectedSchematicComponent ? getSchematicComponentDetails(
|
|
2014
2944
|
circuitJson,
|
|
2015
2945
|
selectedSchematicComponent.schematicComponentId
|
|
2016
2946
|
) : null,
|
|
2017
2947
|
[circuitJsonKey, circuitJson, selectedSchematicComponent]
|
|
2018
2948
|
);
|
|
2019
|
-
const componentTooltipLayout =
|
|
2949
|
+
const componentTooltipLayout = useMemo6(() => {
|
|
2020
2950
|
if (!selectedSchematicComponent || !containerWidth || !containerHeight) {
|
|
2021
2951
|
return null;
|
|
2022
2952
|
}
|
|
@@ -2037,7 +2967,7 @@ var SchematicViewer = ({
|
|
|
2037
2967
|
);
|
|
2038
2968
|
return { left, top, width, maxHeight };
|
|
2039
2969
|
}, [selectedSchematicComponent, containerWidth, containerHeight]);
|
|
2040
|
-
const handleSchematicComponentClick =
|
|
2970
|
+
const handleSchematicComponentClick = useCallback7(
|
|
2041
2971
|
(schematicComponentId, event) => {
|
|
2042
2972
|
if (event.target instanceof Element && event.target.closest("[data-schematic-component-details-tooltip]")) {
|
|
2043
2973
|
return;
|
|
@@ -2056,10 +2986,10 @@ var SchematicViewer = ({
|
|
|
2056
2986
|
},
|
|
2057
2987
|
[containerRef, onSchematicComponentClicked]
|
|
2058
2988
|
);
|
|
2059
|
-
|
|
2989
|
+
useEffect11(() => {
|
|
2060
2990
|
setSelectedSchematicComponent(null);
|
|
2061
2991
|
}, [circuitJsonKey, activeSheetId]);
|
|
2062
|
-
|
|
2992
|
+
useEffect11(() => {
|
|
2063
2993
|
if (!selectedSchematicComponent) return;
|
|
2064
2994
|
const handleKeyDown = (event) => {
|
|
2065
2995
|
if (event.key === "Escape") {
|
|
@@ -2079,7 +3009,7 @@ var SchematicViewer = ({
|
|
|
2079
3009
|
document.removeEventListener("mousedown", handleDocumentMouseDown);
|
|
2080
3010
|
};
|
|
2081
3011
|
}, [selectedSchematicComponent]);
|
|
2082
|
-
const svgString =
|
|
3012
|
+
const svgString = useMemo6(() => {
|
|
2083
3013
|
if (!containerWidth || !containerHeight) return "";
|
|
2084
3014
|
return convertCircuitJsonToSchematicSvg(circuitJson, {
|
|
2085
3015
|
width: containerWidth,
|
|
@@ -2102,12 +3032,31 @@ var SchematicViewer = ({
|
|
|
2102
3032
|
showSchematicPortsInternal,
|
|
2103
3033
|
activeSheetId
|
|
2104
3034
|
]);
|
|
2105
|
-
const containerBackgroundColor =
|
|
3035
|
+
const containerBackgroundColor = useMemo6(() => {
|
|
2106
3036
|
const match = svgString.match(
|
|
2107
3037
|
/<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
|
|
2108
3038
|
);
|
|
2109
3039
|
return match?.[1] ?? "transparent";
|
|
2110
3040
|
}, [svgString]);
|
|
3041
|
+
const {
|
|
3042
|
+
searchQuery,
|
|
3043
|
+
setSearchQuery,
|
|
3044
|
+
searchResults,
|
|
3045
|
+
handleSearchResultSelect,
|
|
3046
|
+
handleCancelSearch
|
|
3047
|
+
} = useSchematicSearch({
|
|
3048
|
+
circuitJson,
|
|
3049
|
+
circuitJsonKey,
|
|
3050
|
+
svgDivRef,
|
|
3051
|
+
containerRef,
|
|
3052
|
+
activeSheetId,
|
|
3053
|
+
hasMultipleSheets,
|
|
3054
|
+
handleSelectSheet,
|
|
3055
|
+
svgString,
|
|
3056
|
+
svgToScreenProjection,
|
|
3057
|
+
setSvgToScreenProjection,
|
|
3058
|
+
setIsInteractionEnabled
|
|
3059
|
+
});
|
|
2111
3060
|
useSchematicGroupsOverlay({
|
|
2112
3061
|
svgDivRef,
|
|
2113
3062
|
circuitJson,
|
|
@@ -2120,8 +3069,8 @@ var SchematicViewer = ({
|
|
|
2120
3069
|
circuitJsonKey: `${circuitJsonKey}_${activeSheetId ?? ""}`,
|
|
2121
3070
|
enabled: netHoverHighlightEnabled
|
|
2122
3071
|
});
|
|
2123
|
-
const svgDiv =
|
|
2124
|
-
() => /* @__PURE__ */
|
|
3072
|
+
const svgDiv = useMemo6(
|
|
3073
|
+
() => /* @__PURE__ */ jsx9(
|
|
2125
3074
|
"div",
|
|
2126
3075
|
{
|
|
2127
3076
|
ref: svgDivRef,
|
|
@@ -2135,12 +3084,28 @@ var SchematicViewer = ({
|
|
|
2135
3084
|
),
|
|
2136
3085
|
[svgString, isInteractionEnabled, clickToInteractEnabled]
|
|
2137
3086
|
);
|
|
2138
|
-
return /* @__PURE__ */
|
|
2139
|
-
netHoverHighlightEnabled && /* @__PURE__ */
|
|
3087
|
+
return /* @__PURE__ */ jsxs7(MouseTracker, { children: [
|
|
3088
|
+
netHoverHighlightEnabled && /* @__PURE__ */ jsx9("style", { children: `.sch-net-faded { opacity: 0.35; }
|
|
2140
3089
|
svg :is(g.trace, g.trace-overlays, g[data-schematic-component-id], [data-schematic-net-label-id]) { transition: opacity 0.12s ease-in-out; }` }),
|
|
2141
|
-
/* @__PURE__ */
|
|
2142
|
-
|
|
2143
|
-
|
|
3090
|
+
searchEnabled && /* @__PURE__ */ jsx9("style", { children: `.schematic-search-match text,
|
|
3091
|
+
text.schematic-search-match {
|
|
3092
|
+
fill: #ff00d4 !important;
|
|
3093
|
+
}
|
|
3094
|
+
.schematic-search-match [stroke]:not(text):not([stroke="none"]),
|
|
3095
|
+
[stroke]:not(text):not([stroke="none"]).schematic-search-match {
|
|
3096
|
+
stroke: #ff00d4 !important;
|
|
3097
|
+
}
|
|
3098
|
+
.schematic-viewer-toolbar {
|
|
3099
|
+
flex-direction: row;
|
|
3100
|
+
}
|
|
3101
|
+
@media (max-width: 640px) {
|
|
3102
|
+
.schematic-viewer-toolbar {
|
|
3103
|
+
flex-direction: column;
|
|
3104
|
+
}
|
|
3105
|
+
}` }),
|
|
3106
|
+
/* @__PURE__ */ jsx9("style", { children: ".schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }" }),
|
|
3107
|
+
onSchematicPortClicked && /* @__PURE__ */ jsx9("style", { children: "[data-schematic-port-id]:hover { cursor: pointer !important; }" }),
|
|
3108
|
+
/* @__PURE__ */ jsxs7(
|
|
2144
3109
|
"div",
|
|
2145
3110
|
{
|
|
2146
3111
|
ref: containerRef,
|
|
@@ -2175,7 +3140,7 @@ var SchematicViewer = ({
|
|
|
2175
3140
|
},
|
|
2176
3141
|
onTouchCancel: contextMenuEventHandlers.onTouchCancel,
|
|
2177
3142
|
children: [
|
|
2178
|
-
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */
|
|
3143
|
+
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx9(
|
|
2179
3144
|
"div",
|
|
2180
3145
|
{
|
|
2181
3146
|
onClick: (e) => {
|
|
@@ -2194,7 +3159,7 @@ var SchematicViewer = ({
|
|
|
2194
3159
|
pointerEvents: "all",
|
|
2195
3160
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
2196
3161
|
},
|
|
2197
|
-
children: /* @__PURE__ */
|
|
3162
|
+
children: /* @__PURE__ */ jsx9(
|
|
2198
3163
|
"div",
|
|
2199
3164
|
{
|
|
2200
3165
|
style: {
|
|
@@ -2211,7 +3176,7 @@ var SchematicViewer = ({
|
|
|
2211
3176
|
)
|
|
2212
3177
|
}
|
|
2213
3178
|
),
|
|
2214
|
-
menuVisible && /* @__PURE__ */
|
|
3179
|
+
menuVisible && /* @__PURE__ */ jsx9(
|
|
2215
3180
|
ViewMenu,
|
|
2216
3181
|
{
|
|
2217
3182
|
circuitJson,
|
|
@@ -2238,15 +3203,43 @@ var SchematicViewer = ({
|
|
|
2238
3203
|
onToggleGrid: setShowGridInternal
|
|
2239
3204
|
}
|
|
2240
3205
|
),
|
|
2241
|
-
/* @__PURE__ */
|
|
2242
|
-
|
|
3206
|
+
/* @__PURE__ */ jsxs7(
|
|
3207
|
+
"div",
|
|
2243
3208
|
{
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
3209
|
+
className: "schematic-viewer-toolbar",
|
|
3210
|
+
style: {
|
|
3211
|
+
position: "absolute",
|
|
3212
|
+
top: "16px",
|
|
3213
|
+
left: "16px",
|
|
3214
|
+
display: "flex",
|
|
3215
|
+
alignItems: "flex-start",
|
|
3216
|
+
gap: "8px",
|
|
3217
|
+
zIndex: zIndexMap.schematicSearch
|
|
3218
|
+
},
|
|
3219
|
+
children: [
|
|
3220
|
+
/* @__PURE__ */ jsx9(
|
|
3221
|
+
SchematicSheetSelector,
|
|
3222
|
+
{
|
|
3223
|
+
sheets: schematicSheets,
|
|
3224
|
+
selectedSheetId: activeSheetId,
|
|
3225
|
+
onSelectSheet: handleSelectSheet
|
|
3226
|
+
}
|
|
3227
|
+
),
|
|
3228
|
+
searchEnabled && /* @__PURE__ */ jsx9(
|
|
3229
|
+
SchematicSearch,
|
|
3230
|
+
{
|
|
3231
|
+
query: searchQuery,
|
|
3232
|
+
onQueryChange: setSearchQuery,
|
|
3233
|
+
onCancel: handleCancelSearch,
|
|
3234
|
+
results: searchResults,
|
|
3235
|
+
onSelect: handleSearchResultSelect,
|
|
3236
|
+
viewerContainerRef: containerRef
|
|
3237
|
+
}
|
|
3238
|
+
)
|
|
3239
|
+
]
|
|
2247
3240
|
}
|
|
2248
3241
|
),
|
|
2249
|
-
schematicComponentIds.map((componentId) => /* @__PURE__ */
|
|
3242
|
+
schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx9(
|
|
2250
3243
|
SchematicComponentMouseTarget,
|
|
2251
3244
|
{
|
|
2252
3245
|
componentId,
|
|
@@ -2260,7 +3253,7 @@ var SchematicViewer = ({
|
|
|
2260
3253
|
componentId
|
|
2261
3254
|
)),
|
|
2262
3255
|
svgDiv,
|
|
2263
|
-
selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */
|
|
3256
|
+
selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */ jsx9(
|
|
2264
3257
|
SchematicComponentDetailsTooltip,
|
|
2265
3258
|
{
|
|
2266
3259
|
sourceComponent: selectedComponentDetails.sourceComponent,
|
|
@@ -2270,7 +3263,7 @@ var SchematicViewer = ({
|
|
|
2270
3263
|
...componentTooltipLayout
|
|
2271
3264
|
}
|
|
2272
3265
|
),
|
|
2273
|
-
showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */
|
|
3266
|
+
showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx9(
|
|
2274
3267
|
SchematicPortMouseTarget,
|
|
2275
3268
|
{
|
|
2276
3269
|
portId,
|
|
@@ -2300,7 +3293,7 @@ import {
|
|
|
2300
3293
|
convertCircuitJsonToSchematicSimulationSvg,
|
|
2301
3294
|
convertCircuitJsonToSimulationGraphSvg
|
|
2302
3295
|
} from "circuit-to-svg";
|
|
2303
|
-
import { useEffect as
|
|
3296
|
+
import { useEffect as useEffect12, useMemo as useMemo7, useRef as useRef9, useState as useState10 } from "react";
|
|
2304
3297
|
import { toString as transformToString2 } from "transformation-matrix";
|
|
2305
3298
|
import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
|
|
2306
3299
|
|
|
@@ -2318,8 +3311,8 @@ var getAnalogSimulationBackgroundColor = (simulationSvg, colorOverrides) => getR
|
|
|
2318
3311
|
|
|
2319
3312
|
// lib/components/AnalogSimulationSelector.tsx
|
|
2320
3313
|
import * as DropdownMenu3 from "@radix-ui/react-dropdown-menu";
|
|
2321
|
-
import { useState as
|
|
2322
|
-
import { Fragment as
|
|
3314
|
+
import { useState as useState9 } from "react";
|
|
3315
|
+
import { Fragment as Fragment5, jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2323
3316
|
var FONT_FAMILY3 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2324
3317
|
var contentStyles3 = {
|
|
2325
3318
|
backgroundColor: "#ffffff",
|
|
@@ -2369,7 +3362,7 @@ var MENU_CSS2 = `
|
|
|
2369
3362
|
.sv-simulation-chevron { transition: transform 0.2s ease; }
|
|
2370
3363
|
[data-state="open"] > .sv-simulation-chevron { transform: rotate(180deg); }
|
|
2371
3364
|
`;
|
|
2372
|
-
var CheckIcon3 = () => /* @__PURE__ */
|
|
3365
|
+
var CheckIcon3 = () => /* @__PURE__ */ jsx10(
|
|
2373
3366
|
"svg",
|
|
2374
3367
|
{
|
|
2375
3368
|
width: "14",
|
|
@@ -2381,10 +3374,10 @@ var CheckIcon3 = () => /* @__PURE__ */ jsx8(
|
|
|
2381
3374
|
strokeLinecap: "round",
|
|
2382
3375
|
strokeLinejoin: "round",
|
|
2383
3376
|
"aria-hidden": "true",
|
|
2384
|
-
children: /* @__PURE__ */
|
|
3377
|
+
children: /* @__PURE__ */ jsx10("path", { d: "M20 6 9 17l-5-5" })
|
|
2385
3378
|
}
|
|
2386
3379
|
);
|
|
2387
|
-
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */
|
|
3380
|
+
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx10(
|
|
2388
3381
|
"svg",
|
|
2389
3382
|
{
|
|
2390
3383
|
className,
|
|
@@ -2398,7 +3391,7 @@ var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx8(
|
|
|
2398
3391
|
strokeLinejoin: "round",
|
|
2399
3392
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
2400
3393
|
"aria-hidden": "true",
|
|
2401
|
-
children: /* @__PURE__ */
|
|
3394
|
+
children: /* @__PURE__ */ jsx10("path", { d: "m6 9 6 6 6-6" })
|
|
2402
3395
|
}
|
|
2403
3396
|
);
|
|
2404
3397
|
var getSimulationLabels = (simulations) => {
|
|
@@ -2417,17 +3410,17 @@ var AnalogSimulationSelector = ({
|
|
|
2417
3410
|
selectedSimulationExperimentId,
|
|
2418
3411
|
onSelectSimulation
|
|
2419
3412
|
}) => {
|
|
2420
|
-
const [open, setOpen] =
|
|
3413
|
+
const [open, setOpen] = useState9(false);
|
|
2421
3414
|
if (simulations.length <= 1) return null;
|
|
2422
3415
|
const simulationLabels = getSimulationLabels(simulations);
|
|
2423
3416
|
const selectedSimulation = simulationLabels.find(
|
|
2424
3417
|
({ simulation }) => simulation.simulation_experiment_id === selectedSimulationExperimentId
|
|
2425
3418
|
);
|
|
2426
3419
|
const selectedLabel = selectedSimulation?.label ?? "Select simulation";
|
|
2427
|
-
return /* @__PURE__ */
|
|
2428
|
-
/* @__PURE__ */
|
|
2429
|
-
/* @__PURE__ */
|
|
2430
|
-
/* @__PURE__ */
|
|
3420
|
+
return /* @__PURE__ */ jsxs8(Fragment5, { children: [
|
|
3421
|
+
/* @__PURE__ */ jsx10("style", { children: MENU_CSS2 }),
|
|
3422
|
+
/* @__PURE__ */ jsxs8(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
3423
|
+
/* @__PURE__ */ jsx10(DropdownMenu3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs8(
|
|
2431
3424
|
"button",
|
|
2432
3425
|
{
|
|
2433
3426
|
type: "button",
|
|
@@ -2454,13 +3447,13 @@ var AnalogSimulationSelector = ({
|
|
|
2454
3447
|
zIndex: zIndexMap.viewMenuIcon
|
|
2455
3448
|
},
|
|
2456
3449
|
children: [
|
|
2457
|
-
/* @__PURE__ */
|
|
2458
|
-
/* @__PURE__ */
|
|
2459
|
-
/* @__PURE__ */
|
|
3450
|
+
/* @__PURE__ */ jsx10("span", { style: { color: "#888888", flexShrink: 0 }, children: "Simulation:" }),
|
|
3451
|
+
/* @__PURE__ */ jsx10("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: selectedLabel }),
|
|
3452
|
+
/* @__PURE__ */ jsx10(ChevronDownIcon2, { className: "sv-simulation-chevron" })
|
|
2460
3453
|
]
|
|
2461
3454
|
}
|
|
2462
3455
|
) }),
|
|
2463
|
-
/* @__PURE__ */
|
|
3456
|
+
/* @__PURE__ */ jsx10(DropdownMenu3.Portal, { children: /* @__PURE__ */ jsx10(
|
|
2464
3457
|
DropdownMenu3.Content,
|
|
2465
3458
|
{
|
|
2466
3459
|
style: contentStyles3,
|
|
@@ -2470,7 +3463,7 @@ var AnalogSimulationSelector = ({
|
|
|
2470
3463
|
collisionPadding: 10,
|
|
2471
3464
|
children: simulationLabels.map(({ simulation, label }) => {
|
|
2472
3465
|
const selected = simulation.simulation_experiment_id === selectedSimulationExperimentId;
|
|
2473
|
-
return /* @__PURE__ */
|
|
3466
|
+
return /* @__PURE__ */ jsxs8(
|
|
2474
3467
|
DropdownMenu3.Item,
|
|
2475
3468
|
{
|
|
2476
3469
|
className: "sv-simulation-item",
|
|
@@ -2482,8 +3475,8 @@ var AnalogSimulationSelector = ({
|
|
|
2482
3475
|
setOpen(false);
|
|
2483
3476
|
},
|
|
2484
3477
|
children: [
|
|
2485
|
-
/* @__PURE__ */
|
|
2486
|
-
/* @__PURE__ */
|
|
3478
|
+
/* @__PURE__ */ jsx10("span", { style: iconSlotStyles3, children: selected && /* @__PURE__ */ jsx10(CheckIcon3, {}) }),
|
|
3479
|
+
/* @__PURE__ */ jsx10("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: label })
|
|
2487
3480
|
]
|
|
2488
3481
|
},
|
|
2489
3482
|
simulation.simulation_experiment_id
|
|
@@ -2496,7 +3489,7 @@ var AnalogSimulationSelector = ({
|
|
|
2496
3489
|
};
|
|
2497
3490
|
|
|
2498
3491
|
// lib/components/AnalogSimulationViewer.tsx
|
|
2499
|
-
import { jsx as
|
|
3492
|
+
import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2500
3493
|
var DEFAULT_RENDER_WIDTH = 1200;
|
|
2501
3494
|
var DEFAULT_COMBINED_RENDER_ASPECT_RATIO = 1;
|
|
2502
3495
|
var DEFAULT_GRAPH_ONLY_RENDER_ASPECT_RATIO = 2;
|
|
@@ -2511,16 +3504,16 @@ var AnalogSimulationViewer = ({
|
|
|
2511
3504
|
onSimulationChange,
|
|
2512
3505
|
acSweepView = "magnitude"
|
|
2513
3506
|
}) => {
|
|
2514
|
-
const [circuitJson, setCircuitJson] =
|
|
2515
|
-
const [isLoading, setIsLoading] =
|
|
2516
|
-
const [error, setError] =
|
|
2517
|
-
const [svgObjectUrl, setSvgObjectUrl] =
|
|
2518
|
-
const containerRef =
|
|
2519
|
-
const imgRef =
|
|
3507
|
+
const [circuitJson, setCircuitJson] = useState10(null);
|
|
3508
|
+
const [isLoading, setIsLoading] = useState10(true);
|
|
3509
|
+
const [error, setError] = useState10(null);
|
|
3510
|
+
const [svgObjectUrl, setSvgObjectUrl] = useState10(null);
|
|
3511
|
+
const containerRef = useRef9(null);
|
|
3512
|
+
const imgRef = useRef9(null);
|
|
2520
3513
|
const { containerWidth } = useResizeHandling(
|
|
2521
3514
|
containerRef
|
|
2522
3515
|
);
|
|
2523
|
-
const [isDragging, setIsDragging] =
|
|
3516
|
+
const [isDragging, setIsDragging] = useState10(false);
|
|
2524
3517
|
const {
|
|
2525
3518
|
ref: transformRef,
|
|
2526
3519
|
cancelDrag: _cancelDrag,
|
|
@@ -2536,23 +3529,23 @@ var AnalogSimulationViewer = ({
|
|
|
2536
3529
|
const renderAspectRatio = width && height ? width / height : defaultRenderAspectRatio;
|
|
2537
3530
|
const effectiveWidth = width || (height ? height * renderAspectRatio : containerWidth) || DEFAULT_RENDER_WIDTH;
|
|
2538
3531
|
const effectiveHeight = height || effectiveWidth / renderAspectRatio;
|
|
2539
|
-
|
|
3532
|
+
useEffect12(() => {
|
|
2540
3533
|
setIsLoading(true);
|
|
2541
3534
|
setError(null);
|
|
2542
3535
|
setCircuitJson(inputCircuitJson);
|
|
2543
3536
|
setIsLoading(false);
|
|
2544
3537
|
}, [inputCircuitJson]);
|
|
2545
|
-
const simulationExperiments =
|
|
3538
|
+
const simulationExperiments = useMemo7(() => {
|
|
2546
3539
|
if (!circuitJson) return [];
|
|
2547
3540
|
return circuitJson.filter(
|
|
2548
3541
|
(element) => element.type === "simulation_experiment"
|
|
2549
3542
|
);
|
|
2550
3543
|
}, [circuitJson]);
|
|
2551
|
-
const [selectedSimulationExperimentId, setSelectedSimulationExperimentId] =
|
|
3544
|
+
const [selectedSimulationExperimentId, setSelectedSimulationExperimentId] = useState10(null);
|
|
2552
3545
|
const simulationExperimentId = (selectedSimulationExperimentId && simulationExperiments.some(
|
|
2553
3546
|
(simulation) => simulation.simulation_experiment_id === selectedSimulationExperimentId
|
|
2554
3547
|
) ? selectedSimulationExperimentId : simulationExperiments[0]?.simulation_experiment_id) ?? null;
|
|
2555
|
-
|
|
3548
|
+
useEffect12(() => {
|
|
2556
3549
|
if (simulationExperimentId !== selectedSimulationExperimentId) {
|
|
2557
3550
|
setSelectedSimulationExperimentId(simulationExperimentId);
|
|
2558
3551
|
}
|
|
@@ -2561,7 +3554,7 @@ var AnalogSimulationViewer = ({
|
|
|
2561
3554
|
setSelectedSimulationExperimentId(nextSimulationExperimentId);
|
|
2562
3555
|
onSimulationChange?.(nextSimulationExperimentId);
|
|
2563
3556
|
};
|
|
2564
|
-
const simulationSvg =
|
|
3557
|
+
const simulationSvg = useMemo7(() => {
|
|
2565
3558
|
if (!circuitJson || !effectiveWidth || !effectiveHeight || !simulationExperimentId)
|
|
2566
3559
|
return "";
|
|
2567
3560
|
try {
|
|
@@ -2589,7 +3582,7 @@ var AnalogSimulationViewer = ({
|
|
|
2589
3582
|
simulationExperimentId,
|
|
2590
3583
|
acSweepView
|
|
2591
3584
|
]);
|
|
2592
|
-
|
|
3585
|
+
useEffect12(() => {
|
|
2593
3586
|
if (!simulationSvg) {
|
|
2594
3587
|
setSvgObjectUrl(null);
|
|
2595
3588
|
return;
|
|
@@ -2606,7 +3599,7 @@ var AnalogSimulationViewer = ({
|
|
|
2606
3599
|
setSvgObjectUrl(null);
|
|
2607
3600
|
}
|
|
2608
3601
|
}, [simulationSvg]);
|
|
2609
|
-
const containerBackgroundColor =
|
|
3602
|
+
const containerBackgroundColor = useMemo7(() => {
|
|
2610
3603
|
return getAnalogSimulationBackgroundColor(simulationSvg, colorOverrides);
|
|
2611
3604
|
}, [simulationSvg, colorOverrides]);
|
|
2612
3605
|
const handleMouseDown = (_e) => {
|
|
@@ -2615,7 +3608,7 @@ var AnalogSimulationViewer = ({
|
|
|
2615
3608
|
const handleTouchStart = (_e) => {
|
|
2616
3609
|
setIsDragging(true);
|
|
2617
3610
|
};
|
|
2618
|
-
|
|
3611
|
+
useEffect12(() => {
|
|
2619
3612
|
const handleMouseUp = () => {
|
|
2620
3613
|
setIsDragging(false);
|
|
2621
3614
|
};
|
|
@@ -2630,7 +3623,7 @@ var AnalogSimulationViewer = ({
|
|
|
2630
3623
|
};
|
|
2631
3624
|
}, []);
|
|
2632
3625
|
if (isLoading) {
|
|
2633
|
-
return /* @__PURE__ */
|
|
3626
|
+
return /* @__PURE__ */ jsx11(
|
|
2634
3627
|
"div",
|
|
2635
3628
|
{
|
|
2636
3629
|
style: {
|
|
@@ -2650,7 +3643,7 @@ var AnalogSimulationViewer = ({
|
|
|
2650
3643
|
);
|
|
2651
3644
|
}
|
|
2652
3645
|
if (error) {
|
|
2653
|
-
return /* @__PURE__ */
|
|
3646
|
+
return /* @__PURE__ */ jsx11(
|
|
2654
3647
|
"div",
|
|
2655
3648
|
{
|
|
2656
3649
|
style: {
|
|
@@ -2665,15 +3658,15 @@ var AnalogSimulationViewer = ({
|
|
|
2665
3658
|
...containerStyle
|
|
2666
3659
|
},
|
|
2667
3660
|
className,
|
|
2668
|
-
children: /* @__PURE__ */
|
|
2669
|
-
/* @__PURE__ */
|
|
2670
|
-
/* @__PURE__ */
|
|
3661
|
+
children: /* @__PURE__ */ jsxs9("div", { style: { textAlign: "center", padding: "20px" }, children: [
|
|
3662
|
+
/* @__PURE__ */ jsx11("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
|
|
3663
|
+
/* @__PURE__ */ jsx11("div", { style: { fontSize: "14px" }, children: error })
|
|
2671
3664
|
] })
|
|
2672
3665
|
}
|
|
2673
3666
|
);
|
|
2674
3667
|
}
|
|
2675
3668
|
if (!simulationSvg) {
|
|
2676
|
-
return /* @__PURE__ */
|
|
3669
|
+
return /* @__PURE__ */ jsxs9(
|
|
2677
3670
|
"div",
|
|
2678
3671
|
{
|
|
2679
3672
|
style: {
|
|
@@ -2689,11 +3682,11 @@ var AnalogSimulationViewer = ({
|
|
|
2689
3682
|
},
|
|
2690
3683
|
className,
|
|
2691
3684
|
children: [
|
|
2692
|
-
/* @__PURE__ */
|
|
2693
|
-
/* @__PURE__ */
|
|
3685
|
+
/* @__PURE__ */ jsx11("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
|
|
3686
|
+
/* @__PURE__ */ jsxs9("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
|
|
2694
3687
|
"Use",
|
|
2695
3688
|
" ",
|
|
2696
|
-
/* @__PURE__ */
|
|
3689
|
+
/* @__PURE__ */ jsx11(
|
|
2697
3690
|
"code",
|
|
2698
3691
|
{
|
|
2699
3692
|
style: {
|
|
@@ -2713,7 +3706,7 @@ var AnalogSimulationViewer = ({
|
|
|
2713
3706
|
}
|
|
2714
3707
|
);
|
|
2715
3708
|
}
|
|
2716
|
-
return /* @__PURE__ */
|
|
3709
|
+
return /* @__PURE__ */ jsxs9(
|
|
2717
3710
|
"div",
|
|
2718
3711
|
{
|
|
2719
3712
|
ref: (node) => {
|
|
@@ -2732,7 +3725,7 @@ var AnalogSimulationViewer = ({
|
|
|
2732
3725
|
onMouseDown: handleMouseDown,
|
|
2733
3726
|
onTouchStart: handleTouchStart,
|
|
2734
3727
|
children: [
|
|
2735
|
-
/* @__PURE__ */
|
|
3728
|
+
/* @__PURE__ */ jsx11(
|
|
2736
3729
|
AnalogSimulationSelector,
|
|
2737
3730
|
{
|
|
2738
3731
|
simulations: simulationExperiments,
|
|
@@ -2740,7 +3733,7 @@ var AnalogSimulationViewer = ({
|
|
|
2740
3733
|
onSelectSimulation: handleSelectSimulation
|
|
2741
3734
|
}
|
|
2742
3735
|
),
|
|
2743
|
-
svgObjectUrl ? /* @__PURE__ */
|
|
3736
|
+
svgObjectUrl ? /* @__PURE__ */ jsx11(
|
|
2744
3737
|
"img",
|
|
2745
3738
|
{
|
|
2746
3739
|
ref: imgRef,
|
|
@@ -2754,7 +3747,7 @@ var AnalogSimulationViewer = ({
|
|
|
2754
3747
|
objectFit: "contain"
|
|
2755
3748
|
}
|
|
2756
3749
|
}
|
|
2757
|
-
) : /* @__PURE__ */
|
|
3750
|
+
) : /* @__PURE__ */ jsx11(
|
|
2758
3751
|
"div",
|
|
2759
3752
|
{
|
|
2760
3753
|
style: {
|