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