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