@tscircuit/schematic-viewer 2.0.79 → 2.0.81
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.js +463 -110
- package/dist/index.js.map +1 -1
- package/package.json +3 -1
package/dist/index.js
CHANGED
|
@@ -438,7 +438,7 @@ var enableDebug = () => {
|
|
|
438
438
|
};
|
|
439
439
|
|
|
440
440
|
// lib/components/SchematicViewer.tsx
|
|
441
|
-
import { useCallback as useCallback6, useEffect as useEffect9, useMemo as
|
|
441
|
+
import { useCallback as useCallback6, useEffect as useEffect9, useMemo as useMemo5, useRef as useRef6, useState as useState6 } from "react";
|
|
442
442
|
import { toString as transformToString } from "transformation-matrix";
|
|
443
443
|
import { useMouseMatrixTransform } from "use-mouse-matrix-transform";
|
|
444
444
|
|
|
@@ -575,12 +575,137 @@ var useContextMenu = ({ containerRef }) => {
|
|
|
575
575
|
};
|
|
576
576
|
};
|
|
577
577
|
|
|
578
|
+
// lib/utils/component-details.ts
|
|
579
|
+
import {
|
|
580
|
+
getPcbElementBounds,
|
|
581
|
+
getPcbElementsWithinBounds
|
|
582
|
+
} from "@tscircuit/circuit-json-util";
|
|
583
|
+
import { gzipSync, strToU8 } from "fflate";
|
|
584
|
+
var hiddenSourceComponentKeys = /* @__PURE__ */ new Set([
|
|
585
|
+
"type",
|
|
586
|
+
"source_component_id",
|
|
587
|
+
"source_group_id",
|
|
588
|
+
"subcircuit_id",
|
|
589
|
+
"display_name",
|
|
590
|
+
"ftype",
|
|
591
|
+
"are_pins_interchangeable"
|
|
592
|
+
]);
|
|
593
|
+
var priorityKeys = [
|
|
594
|
+
"name",
|
|
595
|
+
"resistance",
|
|
596
|
+
"capacitance",
|
|
597
|
+
"inductance",
|
|
598
|
+
"frequency",
|
|
599
|
+
"voltage",
|
|
600
|
+
"current",
|
|
601
|
+
"max_voltage_rating",
|
|
602
|
+
"max_current_rating",
|
|
603
|
+
"power_rating",
|
|
604
|
+
"manufacturer_part_number",
|
|
605
|
+
"supplier_part_numbers"
|
|
606
|
+
];
|
|
607
|
+
var getKeyPriority = (key) => {
|
|
608
|
+
const priority = priorityKeys.indexOf(key);
|
|
609
|
+
return priority === -1 ? priorityKeys.length : priority;
|
|
610
|
+
};
|
|
611
|
+
var formatComponentValue = (sourceComponent, key, value) => {
|
|
612
|
+
if (key === "name") return String(value);
|
|
613
|
+
const displayValue = sourceComponent[`display_${key}`];
|
|
614
|
+
if (typeof displayValue === "string" && displayValue.trim()) {
|
|
615
|
+
const propValue = key === "resistance" ? displayValue.replace(/Ω$/, "") : displayValue;
|
|
616
|
+
return JSON.stringify(propValue);
|
|
617
|
+
}
|
|
618
|
+
return JSON.stringify(value) ?? String(value);
|
|
619
|
+
};
|
|
620
|
+
var getSourceComponentInfoEntries = (sourceComponent) => Object.entries(sourceComponent).filter(([key, value]) => {
|
|
621
|
+
if (hiddenSourceComponentKeys.has(key)) return false;
|
|
622
|
+
if (key.startsWith("display_") && key.slice("display_".length) in sourceComponent) {
|
|
623
|
+
return false;
|
|
624
|
+
}
|
|
625
|
+
return value !== void 0 && value !== null && value !== "";
|
|
626
|
+
}).sort(([keyA], [keyB]) => {
|
|
627
|
+
const priorityDifference = getKeyPriority(keyA) - getKeyPriority(keyB);
|
|
628
|
+
return priorityDifference || keyA.localeCompare(keyB);
|
|
629
|
+
}).map(([key, value]) => ({
|
|
630
|
+
key,
|
|
631
|
+
label: key,
|
|
632
|
+
value: formatComponentValue(sourceComponent, key, value)
|
|
633
|
+
}));
|
|
634
|
+
var getSchematicComponentDetails = (circuitJson, schematicComponentId) => {
|
|
635
|
+
const schematicComponent = circuitJson.find(
|
|
636
|
+
(element) => element.type === "schematic_component" && element.schematic_component_id === schematicComponentId
|
|
637
|
+
);
|
|
638
|
+
if (!schematicComponent) return null;
|
|
639
|
+
const sourceComponent = circuitJson.find(
|
|
640
|
+
(element) => element.type === "source_component" && element.source_component_id === schematicComponent.source_component_id
|
|
641
|
+
);
|
|
642
|
+
if (!sourceComponent) return null;
|
|
643
|
+
const pcbComponent = circuitJson.find(
|
|
644
|
+
(element) => element.type === "pcb_component" && element.source_component_id === sourceComponent.source_component_id
|
|
645
|
+
);
|
|
646
|
+
const cadComponent = circuitJson.find(
|
|
647
|
+
(element) => element.type === "cad_component" && element.source_component_id === sourceComponent.source_component_id && (!pcbComponent || element.pcb_component_id === pcbComponent.pcb_component_id)
|
|
648
|
+
);
|
|
649
|
+
const footprinterString = pcbComponent?.footprinter_string ?? cadComponent?.footprinter_string;
|
|
650
|
+
const footprintPreview = pcbComponent ? getPcbComponentPreview(circuitJson, pcbComponent.pcb_component_id) : null;
|
|
651
|
+
return {
|
|
652
|
+
schematicComponent,
|
|
653
|
+
sourceComponent,
|
|
654
|
+
pcbComponent,
|
|
655
|
+
footprinterString,
|
|
656
|
+
footprintPreviewCircuitJson: footprintPreview?.circuitJson,
|
|
657
|
+
footprintPreviewViewBox: footprintPreview?.viewBox
|
|
658
|
+
};
|
|
659
|
+
};
|
|
660
|
+
var PCB_PREVIEW_PADDING_MM = 2;
|
|
661
|
+
var getPcbComponentPreview = (circuitJson, pcbComponentId) => {
|
|
662
|
+
const pcbComponent = circuitJson.find(
|
|
663
|
+
(element) => element.type === "pcb_component" && element.pcb_component_id === pcbComponentId
|
|
664
|
+
);
|
|
665
|
+
if (!pcbComponent) return null;
|
|
666
|
+
const componentBounds = getPcbElementBounds(pcbComponent);
|
|
667
|
+
if (!componentBounds) return null;
|
|
668
|
+
const viewBox = {
|
|
669
|
+
minX: componentBounds.minX - PCB_PREVIEW_PADDING_MM,
|
|
670
|
+
minY: componentBounds.minY - PCB_PREVIEW_PADDING_MM,
|
|
671
|
+
maxX: componentBounds.maxX + PCB_PREVIEW_PADDING_MM,
|
|
672
|
+
maxY: componentBounds.maxY + PCB_PREVIEW_PADDING_MM
|
|
673
|
+
};
|
|
674
|
+
return {
|
|
675
|
+
circuitJson: getPcbElementsWithinBounds(circuitJson, viewBox),
|
|
676
|
+
viewBox
|
|
677
|
+
};
|
|
678
|
+
};
|
|
679
|
+
var bytesToBase64 = (bytes) => {
|
|
680
|
+
let binary = "";
|
|
681
|
+
const chunkSize = 8192;
|
|
682
|
+
for (let index = 0; index < bytes.length; index += chunkSize) {
|
|
683
|
+
binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
|
|
684
|
+
}
|
|
685
|
+
return btoa(binary);
|
|
686
|
+
};
|
|
687
|
+
var getFootprintPreviewUrl = (footprintPreviewCircuitJson, viewBox) => {
|
|
688
|
+
const encodedCircuitJson = bytesToBase64(
|
|
689
|
+
gzipSync(strToU8(JSON.stringify(footprintPreviewCircuitJson)))
|
|
690
|
+
);
|
|
691
|
+
const url = new URL("https://svg.tscircuit.com/");
|
|
692
|
+
url.searchParams.set("svg_type", "pcb");
|
|
693
|
+
url.searchParams.set("circuit_json", encodedCircuitJson);
|
|
694
|
+
url.searchParams.set(
|
|
695
|
+
"viewbox",
|
|
696
|
+
[viewBox.minX, viewBox.minY, viewBox.maxX, viewBox.maxY].join(",")
|
|
697
|
+
);
|
|
698
|
+
url.searchParams.set("background_color", "#f8fafc");
|
|
699
|
+
return url.toString();
|
|
700
|
+
};
|
|
701
|
+
|
|
578
702
|
// lib/utils/z-index-map.ts
|
|
579
703
|
var zIndexMap = {
|
|
580
704
|
contextMenu: 110,
|
|
581
705
|
viewMenu: 55,
|
|
582
706
|
viewMenuIcon: 48,
|
|
583
707
|
clickToInteractOverlay: 100,
|
|
708
|
+
schematicComponentDetailsTooltip: 105,
|
|
584
709
|
schematicComponentHoverOutline: 47,
|
|
585
710
|
schematicPortHoverOutline: 48
|
|
586
711
|
};
|
|
@@ -764,6 +889,150 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
764
889
|
return /* @__PURE__ */ jsx(MouseTrackerContext.Provider, { value, children });
|
|
765
890
|
};
|
|
766
891
|
|
|
892
|
+
// lib/components/SchematicComponentDetailsTooltip.tsx
|
|
893
|
+
import { useMemo as useMemo2 } from "react";
|
|
894
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
895
|
+
var detailLabelStyle = {
|
|
896
|
+
color: "#64748b",
|
|
897
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
|
|
898
|
+
fontSize: "12px",
|
|
899
|
+
lineHeight: 1.45
|
|
900
|
+
};
|
|
901
|
+
var SchematicComponentDetailsTooltip = ({
|
|
902
|
+
sourceComponent,
|
|
903
|
+
footprinterString,
|
|
904
|
+
footprintPreviewCircuitJson,
|
|
905
|
+
footprintPreviewViewBox,
|
|
906
|
+
left,
|
|
907
|
+
top,
|
|
908
|
+
width,
|
|
909
|
+
maxHeight
|
|
910
|
+
}) => {
|
|
911
|
+
const infoEntries = useMemo2(
|
|
912
|
+
() => getSourceComponentInfoEntries(sourceComponent),
|
|
913
|
+
[sourceComponent]
|
|
914
|
+
);
|
|
915
|
+
const footprintPreviewUrl = useMemo2(
|
|
916
|
+
() => footprintPreviewCircuitJson?.length && footprintPreviewViewBox ? getFootprintPreviewUrl(
|
|
917
|
+
footprintPreviewCircuitJson,
|
|
918
|
+
footprintPreviewViewBox
|
|
919
|
+
) : void 0,
|
|
920
|
+
[footprintPreviewCircuitJson, footprintPreviewViewBox]
|
|
921
|
+
);
|
|
922
|
+
return /* @__PURE__ */ jsxs(
|
|
923
|
+
"dialog",
|
|
924
|
+
{
|
|
925
|
+
open: true,
|
|
926
|
+
"aria-label": `${sourceComponent.name} component details`,
|
|
927
|
+
"data-schematic-component-details-tooltip": true,
|
|
928
|
+
style: {
|
|
929
|
+
position: "absolute",
|
|
930
|
+
left,
|
|
931
|
+
right: "auto",
|
|
932
|
+
top,
|
|
933
|
+
bottom: "auto",
|
|
934
|
+
width,
|
|
935
|
+
maxHeight,
|
|
936
|
+
margin: 0,
|
|
937
|
+
padding: 0,
|
|
938
|
+
overflowY: "auto",
|
|
939
|
+
boxSizing: "border-box",
|
|
940
|
+
border: "1px solid #cbd5e1",
|
|
941
|
+
borderRadius: "4px",
|
|
942
|
+
backgroundColor: "rgba(255, 255, 255, 0.98)",
|
|
943
|
+
boxShadow: "0 20px 25px -5px rgba(15, 23, 42, 0.18), 0 8px 10px -6px rgba(15, 23, 42, 0.12)",
|
|
944
|
+
color: "#0f172a",
|
|
945
|
+
fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
946
|
+
pointerEvents: "auto",
|
|
947
|
+
userSelect: "text",
|
|
948
|
+
WebkitUserSelect: "text",
|
|
949
|
+
zIndex: zIndexMap.schematicComponentDetailsTooltip
|
|
950
|
+
},
|
|
951
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
952
|
+
onClick: (event) => event.stopPropagation(),
|
|
953
|
+
children: [
|
|
954
|
+
/* @__PURE__ */ jsxs(
|
|
955
|
+
"dl",
|
|
956
|
+
{
|
|
957
|
+
style: {
|
|
958
|
+
display: "grid",
|
|
959
|
+
gridTemplateColumns: "minmax(110px, 0.8fr) minmax(0, 1.2fr)",
|
|
960
|
+
gap: "6px 12px",
|
|
961
|
+
margin: 0,
|
|
962
|
+
padding: "8px"
|
|
963
|
+
},
|
|
964
|
+
children: [
|
|
965
|
+
infoEntries.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
966
|
+
/* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: entry.label }),
|
|
967
|
+
/* @__PURE__ */ jsx2(
|
|
968
|
+
"dd",
|
|
969
|
+
{
|
|
970
|
+
style: {
|
|
971
|
+
minWidth: 0,
|
|
972
|
+
margin: 0,
|
|
973
|
+
color: "#1e293b",
|
|
974
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
|
|
975
|
+
fontSize: "12px",
|
|
976
|
+
lineHeight: 1.45,
|
|
977
|
+
overflowWrap: "anywhere"
|
|
978
|
+
},
|
|
979
|
+
children: entry.value
|
|
980
|
+
}
|
|
981
|
+
)
|
|
982
|
+
] }, entry.key)),
|
|
983
|
+
footprinterString && /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
984
|
+
/* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: "footprint" }),
|
|
985
|
+
/* @__PURE__ */ jsx2(
|
|
986
|
+
"dd",
|
|
987
|
+
{
|
|
988
|
+
style: {
|
|
989
|
+
minWidth: 0,
|
|
990
|
+
margin: 0,
|
|
991
|
+
color: "#1e293b",
|
|
992
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
|
|
993
|
+
fontSize: "12px",
|
|
994
|
+
lineHeight: 1.45,
|
|
995
|
+
overflowWrap: "anywhere"
|
|
996
|
+
},
|
|
997
|
+
children: JSON.stringify(footprinterString)
|
|
998
|
+
}
|
|
999
|
+
)
|
|
1000
|
+
] })
|
|
1001
|
+
]
|
|
1002
|
+
}
|
|
1003
|
+
),
|
|
1004
|
+
footprinterString && footprintPreviewUrl && /* @__PURE__ */ jsx2("div", { style: { padding: "0 4px 4px" }, children: /* @__PURE__ */ jsx2(
|
|
1005
|
+
"div",
|
|
1006
|
+
{
|
|
1007
|
+
style: {
|
|
1008
|
+
height: "210px",
|
|
1009
|
+
overflow: "hidden",
|
|
1010
|
+
border: "1px solid #e2e8f0",
|
|
1011
|
+
borderRadius: "2px",
|
|
1012
|
+
background: "#f8fafc"
|
|
1013
|
+
},
|
|
1014
|
+
children: /* @__PURE__ */ jsx2(
|
|
1015
|
+
"img",
|
|
1016
|
+
{
|
|
1017
|
+
src: footprintPreviewUrl,
|
|
1018
|
+
alt: `${sourceComponent.name} ${footprinterString} PCB footprint`,
|
|
1019
|
+
loading: "lazy",
|
|
1020
|
+
referrerPolicy: "no-referrer",
|
|
1021
|
+
style: {
|
|
1022
|
+
display: "block",
|
|
1023
|
+
width: "100%",
|
|
1024
|
+
height: "100%",
|
|
1025
|
+
objectFit: "contain"
|
|
1026
|
+
}
|
|
1027
|
+
}
|
|
1028
|
+
)
|
|
1029
|
+
}
|
|
1030
|
+
) })
|
|
1031
|
+
]
|
|
1032
|
+
}
|
|
1033
|
+
);
|
|
1034
|
+
};
|
|
1035
|
+
|
|
767
1036
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
768
1037
|
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef4, useState as useState3 } from "react";
|
|
769
1038
|
|
|
@@ -772,7 +1041,7 @@ import {
|
|
|
772
1041
|
useContext as useContext2,
|
|
773
1042
|
useEffect as useEffect6,
|
|
774
1043
|
useId,
|
|
775
|
-
useMemo as
|
|
1044
|
+
useMemo as useMemo3,
|
|
776
1045
|
useRef as useRef3,
|
|
777
1046
|
useSyncExternalStore
|
|
778
1047
|
} from "react";
|
|
@@ -786,7 +1055,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
786
1055
|
const id = useId();
|
|
787
1056
|
const latestOptionsRef = useRef3(options);
|
|
788
1057
|
latestOptionsRef.current = options;
|
|
789
|
-
const handleClick =
|
|
1058
|
+
const handleClick = useMemo3(
|
|
790
1059
|
() => (event) => {
|
|
791
1060
|
latestOptionsRef.current.onClick?.(event);
|
|
792
1061
|
},
|
|
@@ -825,7 +1094,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
825
1094
|
};
|
|
826
1095
|
|
|
827
1096
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
828
|
-
import { jsx as
|
|
1097
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
829
1098
|
var areMeasurementsEqual = (a, b) => {
|
|
830
1099
|
if (!a && !b) return true;
|
|
831
1100
|
if (!a || !b) return false;
|
|
@@ -938,7 +1207,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
938
1207
|
return null;
|
|
939
1208
|
}
|
|
940
1209
|
const rect = measurement.rect;
|
|
941
|
-
return /* @__PURE__ */
|
|
1210
|
+
return /* @__PURE__ */ jsx3(
|
|
942
1211
|
"div",
|
|
943
1212
|
{
|
|
944
1213
|
style: {
|
|
@@ -957,7 +1226,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
957
1226
|
|
|
958
1227
|
// lib/components/SchematicPortMouseTarget.tsx
|
|
959
1228
|
import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef5, useState as useState4 } from "react";
|
|
960
|
-
import { Fragment as Fragment2, jsx as
|
|
1229
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
961
1230
|
var areMeasurementsEqual2 = (a, b) => {
|
|
962
1231
|
if (!a && !b) return true;
|
|
963
1232
|
if (!a || !b) return false;
|
|
@@ -1072,8 +1341,8 @@ var SchematicPortMouseTarget = ({
|
|
|
1072
1341
|
return null;
|
|
1073
1342
|
}
|
|
1074
1343
|
const rect = measurement.rect;
|
|
1075
|
-
return /* @__PURE__ */
|
|
1076
|
-
/* @__PURE__ */
|
|
1344
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1345
|
+
/* @__PURE__ */ jsx4(
|
|
1077
1346
|
"div",
|
|
1078
1347
|
{
|
|
1079
1348
|
style: {
|
|
@@ -1091,7 +1360,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1091
1360
|
}
|
|
1092
1361
|
}
|
|
1093
1362
|
),
|
|
1094
|
-
hovering && portLabel && /* @__PURE__ */
|
|
1363
|
+
hovering && portLabel && /* @__PURE__ */ jsx4(
|
|
1095
1364
|
"div",
|
|
1096
1365
|
{
|
|
1097
1366
|
style: {
|
|
@@ -1118,7 +1387,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1118
1387
|
// lib/components/SchematicSheetSelector.tsx
|
|
1119
1388
|
import { useState as useState5 } from "react";
|
|
1120
1389
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
1121
|
-
import { Fragment as Fragment3, jsx as
|
|
1390
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1122
1391
|
var FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1123
1392
|
var contentStyles = {
|
|
1124
1393
|
backgroundColor: "#ffffff",
|
|
@@ -1168,7 +1437,7 @@ var MENU_CSS = `
|
|
|
1168
1437
|
.sv-sheet-chevron { transition: transform 0.2s ease; }
|
|
1169
1438
|
[data-state="open"] > .sv-sheet-chevron { transform: rotate(180deg); }
|
|
1170
1439
|
`;
|
|
1171
|
-
var CheckIcon = () => /* @__PURE__ */
|
|
1440
|
+
var CheckIcon = () => /* @__PURE__ */ jsx5(
|
|
1172
1441
|
"svg",
|
|
1173
1442
|
{
|
|
1174
1443
|
width: "14",
|
|
@@ -1180,10 +1449,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx4(
|
|
|
1180
1449
|
strokeLinecap: "round",
|
|
1181
1450
|
strokeLinejoin: "round",
|
|
1182
1451
|
"aria-hidden": "true",
|
|
1183
|
-
children: /* @__PURE__ */
|
|
1452
|
+
children: /* @__PURE__ */ jsx5("path", { d: "M20 6 9 17l-5-5" })
|
|
1184
1453
|
}
|
|
1185
1454
|
);
|
|
1186
|
-
var ChevronDownIcon = ({ className }) => /* @__PURE__ */
|
|
1455
|
+
var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx5(
|
|
1187
1456
|
"svg",
|
|
1188
1457
|
{
|
|
1189
1458
|
className,
|
|
@@ -1197,7 +1466,7 @@ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx4(
|
|
|
1197
1466
|
strokeLinejoin: "round",
|
|
1198
1467
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
1199
1468
|
"aria-hidden": "true",
|
|
1200
|
-
children: /* @__PURE__ */
|
|
1469
|
+
children: /* @__PURE__ */ jsx5("path", { d: "m6 9 6 6 6-6" })
|
|
1201
1470
|
}
|
|
1202
1471
|
);
|
|
1203
1472
|
var SchematicSheetSelector = ({
|
|
@@ -1211,10 +1480,10 @@ var SchematicSheetSelector = ({
|
|
|
1211
1480
|
(s) => s.schematic_sheet_id === selectedSheetId
|
|
1212
1481
|
);
|
|
1213
1482
|
const selectedLabel = selectedSheet?.name ?? "Select sheet";
|
|
1214
|
-
return /* @__PURE__ */
|
|
1215
|
-
/* @__PURE__ */
|
|
1216
|
-
/* @__PURE__ */
|
|
1217
|
-
/* @__PURE__ */
|
|
1483
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
1484
|
+
/* @__PURE__ */ jsx5("style", { children: MENU_CSS }),
|
|
1485
|
+
/* @__PURE__ */ jsxs3(DropdownMenu.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
1486
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
|
|
1218
1487
|
"button",
|
|
1219
1488
|
{
|
|
1220
1489
|
type: "button",
|
|
@@ -1241,13 +1510,13 @@ var SchematicSheetSelector = ({
|
|
|
1241
1510
|
zIndex: zIndexMap.viewMenuIcon
|
|
1242
1511
|
},
|
|
1243
1512
|
children: [
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1246
|
-
/* @__PURE__ */
|
|
1513
|
+
/* @__PURE__ */ jsx5("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
|
|
1514
|
+
/* @__PURE__ */ jsx5("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
|
|
1515
|
+
/* @__PURE__ */ jsx5(ChevronDownIcon, { className: "sv-sheet-chevron" })
|
|
1247
1516
|
]
|
|
1248
1517
|
}
|
|
1249
1518
|
) }),
|
|
1250
|
-
/* @__PURE__ */
|
|
1519
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx5(
|
|
1251
1520
|
DropdownMenu.Content,
|
|
1252
1521
|
{
|
|
1253
1522
|
style: contentStyles,
|
|
@@ -1257,7 +1526,7 @@ var SchematicSheetSelector = ({
|
|
|
1257
1526
|
collisionPadding: 10,
|
|
1258
1527
|
children: sheets.map((sheet) => {
|
|
1259
1528
|
const selected = sheet.schematic_sheet_id === selectedSheetId;
|
|
1260
|
-
return /* @__PURE__ */
|
|
1529
|
+
return /* @__PURE__ */ jsxs3(
|
|
1261
1530
|
DropdownMenu.Item,
|
|
1262
1531
|
{
|
|
1263
1532
|
className: "sv-sheet-item",
|
|
@@ -1269,8 +1538,8 @@ var SchematicSheetSelector = ({
|
|
|
1269
1538
|
setOpen(false);
|
|
1270
1539
|
},
|
|
1271
1540
|
children: [
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1541
|
+
/* @__PURE__ */ jsx5("span", { style: iconSlotStyles, children: selected && /* @__PURE__ */ jsx5(CheckIcon, {}) }),
|
|
1542
|
+
/* @__PURE__ */ jsx5("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
|
|
1274
1543
|
]
|
|
1275
1544
|
},
|
|
1276
1545
|
sheet.schematic_sheet_id
|
|
@@ -1285,12 +1554,12 @@ var SchematicSheetSelector = ({
|
|
|
1285
1554
|
// lib/components/ViewMenu.tsx
|
|
1286
1555
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
1287
1556
|
import { su as su3 } from "@tscircuit/soup-util";
|
|
1288
|
-
import { useMemo as
|
|
1557
|
+
import { useMemo as useMemo4 } from "react";
|
|
1289
1558
|
|
|
1290
1559
|
// package.json
|
|
1291
1560
|
var package_default = {
|
|
1292
1561
|
name: "@tscircuit/schematic-viewer",
|
|
1293
|
-
version: "2.0.
|
|
1562
|
+
version: "2.0.80",
|
|
1294
1563
|
main: "dist/index.js",
|
|
1295
1564
|
type: "module",
|
|
1296
1565
|
scripts: {
|
|
@@ -1329,16 +1598,18 @@ var package_default = {
|
|
|
1329
1598
|
},
|
|
1330
1599
|
dependencies: {
|
|
1331
1600
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
1601
|
+
"@tscircuit/circuit-json-util": "^0.0.108",
|
|
1332
1602
|
"circuit-json": "^0.0.465",
|
|
1333
1603
|
"circuit-to-svg": "^0.0.393",
|
|
1334
1604
|
debug: "^4.4.0",
|
|
1605
|
+
fflate: "^0.8.3",
|
|
1335
1606
|
"performance-now": "^2.1.0",
|
|
1336
1607
|
"use-mouse-matrix-transform": "^1.2.2"
|
|
1337
1608
|
}
|
|
1338
1609
|
};
|
|
1339
1610
|
|
|
1340
1611
|
// lib/components/ViewMenu.tsx
|
|
1341
|
-
import { jsx as
|
|
1612
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1342
1613
|
var FONT_FAMILY2 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1343
1614
|
var contentStyles2 = {
|
|
1344
1615
|
backgroundColor: "#262626",
|
|
@@ -1387,7 +1658,7 @@ var HIGHLIGHT_CSS = `
|
|
|
1387
1658
|
.sv-vm-item:hover:not([data-disabled]) { background-color: #404040; }
|
|
1388
1659
|
.sv-vm-item[data-disabled] { opacity: 0.45; cursor: not-allowed; }
|
|
1389
1660
|
`;
|
|
1390
|
-
var CheckIcon2 = () => /* @__PURE__ */
|
|
1661
|
+
var CheckIcon2 = () => /* @__PURE__ */ jsx6(
|
|
1391
1662
|
"svg",
|
|
1392
1663
|
{
|
|
1393
1664
|
width: "14",
|
|
@@ -1399,7 +1670,7 @@ var CheckIcon2 = () => /* @__PURE__ */ jsx5(
|
|
|
1399
1670
|
strokeLinecap: "round",
|
|
1400
1671
|
strokeLinejoin: "round",
|
|
1401
1672
|
"aria-hidden": "true",
|
|
1402
|
-
children: /* @__PURE__ */
|
|
1673
|
+
children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
|
|
1403
1674
|
}
|
|
1404
1675
|
);
|
|
1405
1676
|
var ViewMenu = ({
|
|
@@ -1415,7 +1686,7 @@ var ViewMenu = ({
|
|
|
1415
1686
|
showPorts,
|
|
1416
1687
|
onTogglePorts
|
|
1417
1688
|
}) => {
|
|
1418
|
-
const hasGroups =
|
|
1689
|
+
const hasGroups = useMemo4(() => {
|
|
1419
1690
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1420
1691
|
try {
|
|
1421
1692
|
const sourceGroups = su3(circuitJson).source_group?.list() || [];
|
|
@@ -1439,7 +1710,7 @@ var ViewMenu = ({
|
|
|
1439
1710
|
return false;
|
|
1440
1711
|
}
|
|
1441
1712
|
}, [circuitJsonKey]);
|
|
1442
|
-
const hasPorts =
|
|
1713
|
+
const hasPorts = useMemo4(() => {
|
|
1443
1714
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1444
1715
|
try {
|
|
1445
1716
|
return (su3(circuitJson).schematic_port?.list() || []).length > 0;
|
|
@@ -1448,7 +1719,7 @@ var ViewMenu = ({
|
|
|
1448
1719
|
return false;
|
|
1449
1720
|
}
|
|
1450
1721
|
}, [circuitJsonKey]);
|
|
1451
|
-
return /* @__PURE__ */
|
|
1722
|
+
return /* @__PURE__ */ jsx6(
|
|
1452
1723
|
"div",
|
|
1453
1724
|
{
|
|
1454
1725
|
ref: menuRef,
|
|
@@ -1459,9 +1730,9 @@ var ViewMenu = ({
|
|
|
1459
1730
|
width: 0,
|
|
1460
1731
|
height: 0
|
|
1461
1732
|
},
|
|
1462
|
-
children: /* @__PURE__ */
|
|
1463
|
-
/* @__PURE__ */
|
|
1464
|
-
/* @__PURE__ */
|
|
1733
|
+
children: /* @__PURE__ */ jsxs4(DropdownMenu2.Root, { open: true, onOpenChange, modal: false, children: [
|
|
1734
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx6("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
|
|
1735
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs4(
|
|
1465
1736
|
DropdownMenu2.Content,
|
|
1466
1737
|
{
|
|
1467
1738
|
style: contentStyles2,
|
|
@@ -1470,8 +1741,8 @@ var ViewMenu = ({
|
|
|
1470
1741
|
collisionPadding: 10,
|
|
1471
1742
|
avoidCollisions: true,
|
|
1472
1743
|
children: [
|
|
1473
|
-
/* @__PURE__ */
|
|
1474
|
-
/* @__PURE__ */
|
|
1744
|
+
/* @__PURE__ */ jsx6("style", { children: HIGHLIGHT_CSS }),
|
|
1745
|
+
/* @__PURE__ */ jsxs4(
|
|
1475
1746
|
DropdownMenu2.Item,
|
|
1476
1747
|
{
|
|
1477
1748
|
className: "sv-vm-item",
|
|
@@ -1484,12 +1755,12 @@ var ViewMenu = ({
|
|
|
1484
1755
|
if (hasPorts) onTogglePorts(!showPorts);
|
|
1485
1756
|
},
|
|
1486
1757
|
children: [
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1758
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showPorts && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1759
|
+
/* @__PURE__ */ jsx6("span", { children: "Show Schematic Ports" })
|
|
1489
1760
|
]
|
|
1490
1761
|
}
|
|
1491
1762
|
),
|
|
1492
|
-
/* @__PURE__ */
|
|
1763
|
+
/* @__PURE__ */ jsxs4(
|
|
1493
1764
|
DropdownMenu2.Item,
|
|
1494
1765
|
{
|
|
1495
1766
|
className: "sv-vm-item",
|
|
@@ -1502,12 +1773,12 @@ var ViewMenu = ({
|
|
|
1502
1773
|
if (hasGroups) onToggleGroups(!showGroups);
|
|
1503
1774
|
},
|
|
1504
1775
|
children: [
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1776
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showGroups && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1777
|
+
/* @__PURE__ */ jsx6("span", { children: "View Schematic Groups" })
|
|
1507
1778
|
]
|
|
1508
1779
|
}
|
|
1509
1780
|
),
|
|
1510
|
-
/* @__PURE__ */
|
|
1781
|
+
/* @__PURE__ */ jsxs4(
|
|
1511
1782
|
DropdownMenu2.Item,
|
|
1512
1783
|
{
|
|
1513
1784
|
className: "sv-vm-item",
|
|
@@ -1518,13 +1789,13 @@ var ViewMenu = ({
|
|
|
1518
1789
|
onToggleGrid(!showGrid);
|
|
1519
1790
|
},
|
|
1520
1791
|
children: [
|
|
1521
|
-
/* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
1792
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showGrid && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1793
|
+
/* @__PURE__ */ jsx6("span", { children: "Show Grid" })
|
|
1523
1794
|
]
|
|
1524
1795
|
}
|
|
1525
1796
|
),
|
|
1526
|
-
/* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
1797
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Separator, { style: separatorStyles }),
|
|
1798
|
+
/* @__PURE__ */ jsxs4(
|
|
1528
1799
|
"div",
|
|
1529
1800
|
{
|
|
1530
1801
|
style: {
|
|
@@ -1550,7 +1821,7 @@ var ViewMenu = ({
|
|
|
1550
1821
|
};
|
|
1551
1822
|
|
|
1552
1823
|
// lib/components/SchematicViewer.tsx
|
|
1553
|
-
import { jsx as
|
|
1824
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1554
1825
|
var SchematicViewer = ({
|
|
1555
1826
|
circuitJson,
|
|
1556
1827
|
containerStyle,
|
|
@@ -1573,11 +1844,11 @@ var SchematicViewer = ({
|
|
|
1573
1844
|
const getCircuitHash = (circuitJson2) => {
|
|
1574
1845
|
return `${circuitJson2?.length || 0}_${circuitJson2?.editCount || 0}`;
|
|
1575
1846
|
};
|
|
1576
|
-
const circuitJsonKey =
|
|
1847
|
+
const circuitJsonKey = useMemo5(
|
|
1577
1848
|
() => getCircuitHash(circuitJson),
|
|
1578
1849
|
[circuitJson]
|
|
1579
1850
|
);
|
|
1580
|
-
const schematicSheets =
|
|
1851
|
+
const schematicSheets = useMemo5(() => {
|
|
1581
1852
|
try {
|
|
1582
1853
|
return circuitJson.filter((elm) => elm?.type === "schematic_sheet").slice().sort((a, b) => (a.sheet_index ?? 0) - (b.sheet_index ?? 0));
|
|
1583
1854
|
} catch (err) {
|
|
@@ -1630,6 +1901,7 @@ var SchematicViewer = ({
|
|
|
1630
1901
|
}, [showSchematicPorts]);
|
|
1631
1902
|
const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState6(false);
|
|
1632
1903
|
const hoveringComponentsRef = useRef6(/* @__PURE__ */ new Set());
|
|
1904
|
+
const [selectedSchematicComponent, setSelectedSchematicComponent] = useState6(null);
|
|
1633
1905
|
const handleComponentHoverChange = useCallback6(
|
|
1634
1906
|
(componentId, isHovering) => {
|
|
1635
1907
|
if (isHovering) {
|
|
@@ -1656,7 +1928,8 @@ var SchematicViewer = ({
|
|
|
1656
1928
|
);
|
|
1657
1929
|
const svgDivRef = useRef6(null);
|
|
1658
1930
|
const touchStartRef = useRef6(null);
|
|
1659
|
-
const
|
|
1931
|
+
const zoomScaleRef = useRef6({ x: 1, y: 1 });
|
|
1932
|
+
const schematicComponentIds = useMemo5(() => {
|
|
1660
1933
|
try {
|
|
1661
1934
|
const components = su4(circuitJson).schematic_component?.list() ?? [];
|
|
1662
1935
|
return components.filter(
|
|
@@ -1667,7 +1940,7 @@ var SchematicViewer = ({
|
|
|
1667
1940
|
return [];
|
|
1668
1941
|
}
|
|
1669
1942
|
}, [circuitJsonKey, circuitJson, activeSheetId]);
|
|
1670
|
-
const schematicPortsInfo =
|
|
1943
|
+
const schematicPortsInfo = useMemo5(() => {
|
|
1671
1944
|
if (!showSchematicPortsInternal) return [];
|
|
1672
1945
|
try {
|
|
1673
1946
|
const ports = (su4(circuitJson).schematic_port?.list() ?? []).filter(
|
|
@@ -1716,6 +1989,11 @@ var SchematicViewer = ({
|
|
|
1716
1989
|
);
|
|
1717
1990
|
const { ref: containerRef } = useMouseMatrixTransform({
|
|
1718
1991
|
onSetTransform(transform) {
|
|
1992
|
+
const zoomChanged = transform.a !== zoomScaleRef.current.x || transform.d !== zoomScaleRef.current.y;
|
|
1993
|
+
zoomScaleRef.current = { x: transform.a, y: transform.d };
|
|
1994
|
+
if (zoomChanged) {
|
|
1995
|
+
setSelectedSchematicComponent(null);
|
|
1996
|
+
}
|
|
1719
1997
|
if (!svgDivRef.current) return;
|
|
1720
1998
|
svgDivRef.current.style.transform = transformToString(transform);
|
|
1721
1999
|
},
|
|
@@ -1731,7 +2009,77 @@ var SchematicViewer = ({
|
|
|
1731
2009
|
contextMenuEventHandlers
|
|
1732
2010
|
} = useContextMenu({ containerRef });
|
|
1733
2011
|
const { containerWidth, containerHeight } = useResizeHandling(containerRef);
|
|
1734
|
-
const
|
|
2012
|
+
const selectedComponentDetails = useMemo5(
|
|
2013
|
+
() => selectedSchematicComponent ? getSchematicComponentDetails(
|
|
2014
|
+
circuitJson,
|
|
2015
|
+
selectedSchematicComponent.schematicComponentId
|
|
2016
|
+
) : null,
|
|
2017
|
+
[circuitJsonKey, circuitJson, selectedSchematicComponent]
|
|
2018
|
+
);
|
|
2019
|
+
const componentTooltipLayout = useMemo5(() => {
|
|
2020
|
+
if (!selectedSchematicComponent || !containerWidth || !containerHeight) {
|
|
2021
|
+
return null;
|
|
2022
|
+
}
|
|
2023
|
+
const margin = 12;
|
|
2024
|
+
const gap = 14;
|
|
2025
|
+
const width = Math.min(420, containerWidth - margin * 2);
|
|
2026
|
+
const maxHeight = Math.min(520, containerHeight - margin * 2);
|
|
2027
|
+
const { anchorX, anchorY } = selectedSchematicComponent;
|
|
2028
|
+
const rightOfAnchor = anchorX + gap;
|
|
2029
|
+
const leftOfAnchor = anchorX - width - gap;
|
|
2030
|
+
const left = rightOfAnchor + width <= containerWidth - margin ? rightOfAnchor : leftOfAnchor >= margin ? leftOfAnchor : Math.max(
|
|
2031
|
+
margin,
|
|
2032
|
+
Math.min(anchorX - width / 2, containerWidth - width - margin)
|
|
2033
|
+
);
|
|
2034
|
+
const top = Math.max(
|
|
2035
|
+
margin,
|
|
2036
|
+
Math.min(anchorY - 24, containerHeight - maxHeight - margin)
|
|
2037
|
+
);
|
|
2038
|
+
return { left, top, width, maxHeight };
|
|
2039
|
+
}, [selectedSchematicComponent, containerWidth, containerHeight]);
|
|
2040
|
+
const handleSchematicComponentClick = useCallback6(
|
|
2041
|
+
(schematicComponentId, event) => {
|
|
2042
|
+
if (event.target instanceof Element && event.target.closest("[data-schematic-component-details-tooltip]")) {
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
const containerRect = containerRef.current?.getBoundingClientRect();
|
|
2046
|
+
if (!containerRect) return;
|
|
2047
|
+
setSelectedSchematicComponent({
|
|
2048
|
+
schematicComponentId,
|
|
2049
|
+
anchorX: event.clientX - containerRect.left,
|
|
2050
|
+
anchorY: event.clientY - containerRect.top
|
|
2051
|
+
});
|
|
2052
|
+
onSchematicComponentClicked?.({
|
|
2053
|
+
schematicComponentId,
|
|
2054
|
+
event
|
|
2055
|
+
});
|
|
2056
|
+
},
|
|
2057
|
+
[containerRef, onSchematicComponentClicked]
|
|
2058
|
+
);
|
|
2059
|
+
useEffect9(() => {
|
|
2060
|
+
setSelectedSchematicComponent(null);
|
|
2061
|
+
}, [circuitJsonKey, activeSheetId]);
|
|
2062
|
+
useEffect9(() => {
|
|
2063
|
+
if (!selectedSchematicComponent) return;
|
|
2064
|
+
const handleKeyDown = (event) => {
|
|
2065
|
+
if (event.key === "Escape") {
|
|
2066
|
+
setSelectedSchematicComponent(null);
|
|
2067
|
+
}
|
|
2068
|
+
};
|
|
2069
|
+
const handleDocumentMouseDown = (event) => {
|
|
2070
|
+
if (event.target instanceof Element && event.target.closest("[data-schematic-component-details-tooltip]")) {
|
|
2071
|
+
return;
|
|
2072
|
+
}
|
|
2073
|
+
setSelectedSchematicComponent(null);
|
|
2074
|
+
};
|
|
2075
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2076
|
+
document.addEventListener("mousedown", handleDocumentMouseDown);
|
|
2077
|
+
return () => {
|
|
2078
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2079
|
+
document.removeEventListener("mousedown", handleDocumentMouseDown);
|
|
2080
|
+
};
|
|
2081
|
+
}, [selectedSchematicComponent]);
|
|
2082
|
+
const svgString = useMemo5(() => {
|
|
1735
2083
|
if (!containerWidth || !containerHeight) return "";
|
|
1736
2084
|
return convertCircuitJsonToSchematicSvg(circuitJson, {
|
|
1737
2085
|
width: containerWidth,
|
|
@@ -1754,7 +2102,7 @@ var SchematicViewer = ({
|
|
|
1754
2102
|
showSchematicPortsInternal,
|
|
1755
2103
|
activeSheetId
|
|
1756
2104
|
]);
|
|
1757
|
-
const containerBackgroundColor =
|
|
2105
|
+
const containerBackgroundColor = useMemo5(() => {
|
|
1758
2106
|
const match = svgString.match(
|
|
1759
2107
|
/<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
|
|
1760
2108
|
);
|
|
@@ -1772,8 +2120,8 @@ var SchematicViewer = ({
|
|
|
1772
2120
|
circuitJsonKey: `${circuitJsonKey}_${activeSheetId ?? ""}`,
|
|
1773
2121
|
enabled: netHoverHighlightEnabled
|
|
1774
2122
|
});
|
|
1775
|
-
const svgDiv =
|
|
1776
|
-
() => /* @__PURE__ */
|
|
2123
|
+
const svgDiv = useMemo5(
|
|
2124
|
+
() => /* @__PURE__ */ jsx7(
|
|
1777
2125
|
"div",
|
|
1778
2126
|
{
|
|
1779
2127
|
ref: svgDivRef,
|
|
@@ -1781,18 +2129,18 @@ var SchematicViewer = ({
|
|
|
1781
2129
|
pointerEvents: clickToInteractEnabled ? isInteractionEnabled ? "auto" : "none" : "auto",
|
|
1782
2130
|
transformOrigin: "0 0"
|
|
1783
2131
|
},
|
|
1784
|
-
className:
|
|
2132
|
+
className: "schematic-component-clickable",
|
|
1785
2133
|
dangerouslySetInnerHTML: { __html: svgString }
|
|
1786
2134
|
}
|
|
1787
2135
|
),
|
|
1788
2136
|
[svgString, isInteractionEnabled, clickToInteractEnabled]
|
|
1789
2137
|
);
|
|
1790
|
-
return /* @__PURE__ */
|
|
1791
|
-
netHoverHighlightEnabled && /* @__PURE__ */
|
|
2138
|
+
return /* @__PURE__ */ jsxs5(MouseTracker, { children: [
|
|
2139
|
+
netHoverHighlightEnabled && /* @__PURE__ */ jsx7("style", { children: `.sch-net-faded { opacity: 0.35; }
|
|
1792
2140
|
svg :is(g.trace, g.trace-overlays, g[data-schematic-component-id], [data-schematic-net-label-id]) { transition: opacity 0.12s ease-in-out; }` }),
|
|
1793
|
-
|
|
1794
|
-
onSchematicPortClicked && /* @__PURE__ */
|
|
1795
|
-
/* @__PURE__ */
|
|
2141
|
+
/* @__PURE__ */ jsx7("style", { children: ".schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }" }),
|
|
2142
|
+
onSchematicPortClicked && /* @__PURE__ */ jsx7("style", { children: "[data-schematic-port-id]:hover { cursor: pointer !important; }" }),
|
|
2143
|
+
/* @__PURE__ */ jsxs5(
|
|
1796
2144
|
"div",
|
|
1797
2145
|
{
|
|
1798
2146
|
ref: containerRef,
|
|
@@ -1800,7 +2148,7 @@ var SchematicViewer = ({
|
|
|
1800
2148
|
position: "relative",
|
|
1801
2149
|
backgroundColor: containerBackgroundColor,
|
|
1802
2150
|
overflow: "hidden",
|
|
1803
|
-
cursor: clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent
|
|
2151
|
+
cursor: clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent ? "pointer" : isHoveringClickablePort && onSchematicPortClicked ? "pointer" : "grab",
|
|
1804
2152
|
minHeight: "300px",
|
|
1805
2153
|
userSelect: "none",
|
|
1806
2154
|
WebkitUserSelect: "none",
|
|
@@ -1827,7 +2175,7 @@ var SchematicViewer = ({
|
|
|
1827
2175
|
},
|
|
1828
2176
|
onTouchCancel: contextMenuEventHandlers.onTouchCancel,
|
|
1829
2177
|
children: [
|
|
1830
|
-
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */
|
|
2178
|
+
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx7(
|
|
1831
2179
|
"div",
|
|
1832
2180
|
{
|
|
1833
2181
|
onClick: (e) => {
|
|
@@ -1846,7 +2194,7 @@ var SchematicViewer = ({
|
|
|
1846
2194
|
pointerEvents: "all",
|
|
1847
2195
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
1848
2196
|
},
|
|
1849
|
-
children: /* @__PURE__ */
|
|
2197
|
+
children: /* @__PURE__ */ jsx7(
|
|
1850
2198
|
"div",
|
|
1851
2199
|
{
|
|
1852
2200
|
style: {
|
|
@@ -1863,7 +2211,7 @@ var SchematicViewer = ({
|
|
|
1863
2211
|
)
|
|
1864
2212
|
}
|
|
1865
2213
|
),
|
|
1866
|
-
menuVisible && /* @__PURE__ */
|
|
2214
|
+
menuVisible && /* @__PURE__ */ jsx7(
|
|
1867
2215
|
ViewMenu,
|
|
1868
2216
|
{
|
|
1869
2217
|
circuitJson,
|
|
@@ -1890,7 +2238,7 @@ var SchematicViewer = ({
|
|
|
1890
2238
|
onToggleGrid: setShowGridInternal
|
|
1891
2239
|
}
|
|
1892
2240
|
),
|
|
1893
|
-
/* @__PURE__ */
|
|
2241
|
+
/* @__PURE__ */ jsx7(
|
|
1894
2242
|
SchematicSheetSelector,
|
|
1895
2243
|
{
|
|
1896
2244
|
sheets: schematicSheets,
|
|
@@ -1898,7 +2246,7 @@ var SchematicViewer = ({
|
|
|
1898
2246
|
onSelectSheet: handleSelectSheet
|
|
1899
2247
|
}
|
|
1900
2248
|
),
|
|
1901
|
-
|
|
2249
|
+
schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx7(
|
|
1902
2250
|
SchematicComponentMouseTarget,
|
|
1903
2251
|
{
|
|
1904
2252
|
componentId,
|
|
@@ -1907,17 +2255,22 @@ var SchematicViewer = ({
|
|
|
1907
2255
|
showOutline: true,
|
|
1908
2256
|
circuitJsonKey,
|
|
1909
2257
|
onHoverChange: handleComponentHoverChange,
|
|
1910
|
-
onComponentClick:
|
|
1911
|
-
onSchematicComponentClicked?.({
|
|
1912
|
-
schematicComponentId: id,
|
|
1913
|
-
event
|
|
1914
|
-
});
|
|
1915
|
-
}
|
|
2258
|
+
onComponentClick: handleSchematicComponentClick
|
|
1916
2259
|
},
|
|
1917
2260
|
componentId
|
|
1918
2261
|
)),
|
|
1919
2262
|
svgDiv,
|
|
1920
|
-
|
|
2263
|
+
selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */ jsx7(
|
|
2264
|
+
SchematicComponentDetailsTooltip,
|
|
2265
|
+
{
|
|
2266
|
+
sourceComponent: selectedComponentDetails.sourceComponent,
|
|
2267
|
+
footprinterString: selectedComponentDetails.footprinterString,
|
|
2268
|
+
footprintPreviewCircuitJson: selectedComponentDetails.footprintPreviewCircuitJson,
|
|
2269
|
+
footprintPreviewViewBox: selectedComponentDetails.footprintPreviewViewBox,
|
|
2270
|
+
...componentTooltipLayout
|
|
2271
|
+
}
|
|
2272
|
+
),
|
|
2273
|
+
showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx7(
|
|
1921
2274
|
SchematicPortMouseTarget,
|
|
1922
2275
|
{
|
|
1923
2276
|
portId,
|
|
@@ -1947,7 +2300,7 @@ import {
|
|
|
1947
2300
|
convertCircuitJsonToSchematicSimulationSvg,
|
|
1948
2301
|
convertCircuitJsonToSimulationGraphSvg
|
|
1949
2302
|
} from "circuit-to-svg";
|
|
1950
|
-
import { useEffect as useEffect10, useMemo as
|
|
2303
|
+
import { useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState8 } from "react";
|
|
1951
2304
|
import { toString as transformToString2 } from "transformation-matrix";
|
|
1952
2305
|
import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
|
|
1953
2306
|
|
|
@@ -1966,7 +2319,7 @@ var getAnalogSimulationBackgroundColor = (simulationSvg, colorOverrides) => getR
|
|
|
1966
2319
|
// lib/components/AnalogSimulationSelector.tsx
|
|
1967
2320
|
import * as DropdownMenu3 from "@radix-ui/react-dropdown-menu";
|
|
1968
2321
|
import { useState as useState7 } from "react";
|
|
1969
|
-
import { Fragment as Fragment4, jsx as
|
|
2322
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1970
2323
|
var FONT_FAMILY3 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1971
2324
|
var contentStyles3 = {
|
|
1972
2325
|
backgroundColor: "#ffffff",
|
|
@@ -2016,7 +2369,7 @@ var MENU_CSS2 = `
|
|
|
2016
2369
|
.sv-simulation-chevron { transition: transform 0.2s ease; }
|
|
2017
2370
|
[data-state="open"] > .sv-simulation-chevron { transform: rotate(180deg); }
|
|
2018
2371
|
`;
|
|
2019
|
-
var CheckIcon3 = () => /* @__PURE__ */
|
|
2372
|
+
var CheckIcon3 = () => /* @__PURE__ */ jsx8(
|
|
2020
2373
|
"svg",
|
|
2021
2374
|
{
|
|
2022
2375
|
width: "14",
|
|
@@ -2028,10 +2381,10 @@ var CheckIcon3 = () => /* @__PURE__ */ jsx7(
|
|
|
2028
2381
|
strokeLinecap: "round",
|
|
2029
2382
|
strokeLinejoin: "round",
|
|
2030
2383
|
"aria-hidden": "true",
|
|
2031
|
-
children: /* @__PURE__ */
|
|
2384
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
|
|
2032
2385
|
}
|
|
2033
2386
|
);
|
|
2034
|
-
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */
|
|
2387
|
+
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx8(
|
|
2035
2388
|
"svg",
|
|
2036
2389
|
{
|
|
2037
2390
|
className,
|
|
@@ -2045,7 +2398,7 @@ var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx7(
|
|
|
2045
2398
|
strokeLinejoin: "round",
|
|
2046
2399
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
2047
2400
|
"aria-hidden": "true",
|
|
2048
|
-
children: /* @__PURE__ */
|
|
2401
|
+
children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" })
|
|
2049
2402
|
}
|
|
2050
2403
|
);
|
|
2051
2404
|
var getSimulationLabels = (simulations) => {
|
|
@@ -2071,10 +2424,10 @@ var AnalogSimulationSelector = ({
|
|
|
2071
2424
|
({ simulation }) => simulation.simulation_experiment_id === selectedSimulationExperimentId
|
|
2072
2425
|
);
|
|
2073
2426
|
const selectedLabel = selectedSimulation?.label ?? "Select simulation";
|
|
2074
|
-
return /* @__PURE__ */
|
|
2075
|
-
/* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2077
|
-
/* @__PURE__ */
|
|
2427
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2428
|
+
/* @__PURE__ */ jsx8("style", { children: MENU_CSS2 }),
|
|
2429
|
+
/* @__PURE__ */ jsxs6(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
2430
|
+
/* @__PURE__ */ jsx8(DropdownMenu3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
|
|
2078
2431
|
"button",
|
|
2079
2432
|
{
|
|
2080
2433
|
type: "button",
|
|
@@ -2101,13 +2454,13 @@ var AnalogSimulationSelector = ({
|
|
|
2101
2454
|
zIndex: zIndexMap.viewMenuIcon
|
|
2102
2455
|
},
|
|
2103
2456
|
children: [
|
|
2104
|
-
/* @__PURE__ */
|
|
2105
|
-
/* @__PURE__ */
|
|
2106
|
-
/* @__PURE__ */
|
|
2457
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888888", flexShrink: 0 }, children: "Simulation:" }),
|
|
2458
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: selectedLabel }),
|
|
2459
|
+
/* @__PURE__ */ jsx8(ChevronDownIcon2, { className: "sv-simulation-chevron" })
|
|
2107
2460
|
]
|
|
2108
2461
|
}
|
|
2109
2462
|
) }),
|
|
2110
|
-
/* @__PURE__ */
|
|
2463
|
+
/* @__PURE__ */ jsx8(DropdownMenu3.Portal, { children: /* @__PURE__ */ jsx8(
|
|
2111
2464
|
DropdownMenu3.Content,
|
|
2112
2465
|
{
|
|
2113
2466
|
style: contentStyles3,
|
|
@@ -2117,7 +2470,7 @@ var AnalogSimulationSelector = ({
|
|
|
2117
2470
|
collisionPadding: 10,
|
|
2118
2471
|
children: simulationLabels.map(({ simulation, label }) => {
|
|
2119
2472
|
const selected = simulation.simulation_experiment_id === selectedSimulationExperimentId;
|
|
2120
|
-
return /* @__PURE__ */
|
|
2473
|
+
return /* @__PURE__ */ jsxs6(
|
|
2121
2474
|
DropdownMenu3.Item,
|
|
2122
2475
|
{
|
|
2123
2476
|
className: "sv-simulation-item",
|
|
@@ -2129,8 +2482,8 @@ var AnalogSimulationSelector = ({
|
|
|
2129
2482
|
setOpen(false);
|
|
2130
2483
|
},
|
|
2131
2484
|
children: [
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2485
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles3, children: selected && /* @__PURE__ */ jsx8(CheckIcon3, {}) }),
|
|
2486
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: label })
|
|
2134
2487
|
]
|
|
2135
2488
|
},
|
|
2136
2489
|
simulation.simulation_experiment_id
|
|
@@ -2143,7 +2496,7 @@ var AnalogSimulationSelector = ({
|
|
|
2143
2496
|
};
|
|
2144
2497
|
|
|
2145
2498
|
// lib/components/AnalogSimulationViewer.tsx
|
|
2146
|
-
import { jsx as
|
|
2499
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2147
2500
|
var DEFAULT_RENDER_WIDTH = 1200;
|
|
2148
2501
|
var DEFAULT_COMBINED_RENDER_ASPECT_RATIO = 1;
|
|
2149
2502
|
var DEFAULT_GRAPH_ONLY_RENDER_ASPECT_RATIO = 2;
|
|
@@ -2189,7 +2542,7 @@ var AnalogSimulationViewer = ({
|
|
|
2189
2542
|
setCircuitJson(inputCircuitJson);
|
|
2190
2543
|
setIsLoading(false);
|
|
2191
2544
|
}, [inputCircuitJson]);
|
|
2192
|
-
const simulationExperiments =
|
|
2545
|
+
const simulationExperiments = useMemo6(() => {
|
|
2193
2546
|
if (!circuitJson) return [];
|
|
2194
2547
|
return circuitJson.filter(
|
|
2195
2548
|
(element) => element.type === "simulation_experiment"
|
|
@@ -2208,7 +2561,7 @@ var AnalogSimulationViewer = ({
|
|
|
2208
2561
|
setSelectedSimulationExperimentId(nextSimulationExperimentId);
|
|
2209
2562
|
onSimulationChange?.(nextSimulationExperimentId);
|
|
2210
2563
|
};
|
|
2211
|
-
const simulationSvg =
|
|
2564
|
+
const simulationSvg = useMemo6(() => {
|
|
2212
2565
|
if (!circuitJson || !effectiveWidth || !effectiveHeight || !simulationExperimentId)
|
|
2213
2566
|
return "";
|
|
2214
2567
|
try {
|
|
@@ -2253,7 +2606,7 @@ var AnalogSimulationViewer = ({
|
|
|
2253
2606
|
setSvgObjectUrl(null);
|
|
2254
2607
|
}
|
|
2255
2608
|
}, [simulationSvg]);
|
|
2256
|
-
const containerBackgroundColor =
|
|
2609
|
+
const containerBackgroundColor = useMemo6(() => {
|
|
2257
2610
|
return getAnalogSimulationBackgroundColor(simulationSvg, colorOverrides);
|
|
2258
2611
|
}, [simulationSvg, colorOverrides]);
|
|
2259
2612
|
const handleMouseDown = (_e) => {
|
|
@@ -2277,7 +2630,7 @@ var AnalogSimulationViewer = ({
|
|
|
2277
2630
|
};
|
|
2278
2631
|
}, []);
|
|
2279
2632
|
if (isLoading) {
|
|
2280
|
-
return /* @__PURE__ */
|
|
2633
|
+
return /* @__PURE__ */ jsx9(
|
|
2281
2634
|
"div",
|
|
2282
2635
|
{
|
|
2283
2636
|
style: {
|
|
@@ -2297,7 +2650,7 @@ var AnalogSimulationViewer = ({
|
|
|
2297
2650
|
);
|
|
2298
2651
|
}
|
|
2299
2652
|
if (error) {
|
|
2300
|
-
return /* @__PURE__ */
|
|
2653
|
+
return /* @__PURE__ */ jsx9(
|
|
2301
2654
|
"div",
|
|
2302
2655
|
{
|
|
2303
2656
|
style: {
|
|
@@ -2312,15 +2665,15 @@ var AnalogSimulationViewer = ({
|
|
|
2312
2665
|
...containerStyle
|
|
2313
2666
|
},
|
|
2314
2667
|
className,
|
|
2315
|
-
children: /* @__PURE__ */
|
|
2316
|
-
/* @__PURE__ */
|
|
2317
|
-
/* @__PURE__ */
|
|
2668
|
+
children: /* @__PURE__ */ jsxs7("div", { style: { textAlign: "center", padding: "20px" }, children: [
|
|
2669
|
+
/* @__PURE__ */ jsx9("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
|
|
2670
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: "14px" }, children: error })
|
|
2318
2671
|
] })
|
|
2319
2672
|
}
|
|
2320
2673
|
);
|
|
2321
2674
|
}
|
|
2322
2675
|
if (!simulationSvg) {
|
|
2323
|
-
return /* @__PURE__ */
|
|
2676
|
+
return /* @__PURE__ */ jsxs7(
|
|
2324
2677
|
"div",
|
|
2325
2678
|
{
|
|
2326
2679
|
style: {
|
|
@@ -2336,11 +2689,11 @@ var AnalogSimulationViewer = ({
|
|
|
2336
2689
|
},
|
|
2337
2690
|
className,
|
|
2338
2691
|
children: [
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
/* @__PURE__ */
|
|
2692
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
|
|
2693
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
|
|
2341
2694
|
"Use",
|
|
2342
2695
|
" ",
|
|
2343
|
-
/* @__PURE__ */
|
|
2696
|
+
/* @__PURE__ */ jsx9(
|
|
2344
2697
|
"code",
|
|
2345
2698
|
{
|
|
2346
2699
|
style: {
|
|
@@ -2360,7 +2713,7 @@ var AnalogSimulationViewer = ({
|
|
|
2360
2713
|
}
|
|
2361
2714
|
);
|
|
2362
2715
|
}
|
|
2363
|
-
return /* @__PURE__ */
|
|
2716
|
+
return /* @__PURE__ */ jsxs7(
|
|
2364
2717
|
"div",
|
|
2365
2718
|
{
|
|
2366
2719
|
ref: (node) => {
|
|
@@ -2379,7 +2732,7 @@ var AnalogSimulationViewer = ({
|
|
|
2379
2732
|
onMouseDown: handleMouseDown,
|
|
2380
2733
|
onTouchStart: handleTouchStart,
|
|
2381
2734
|
children: [
|
|
2382
|
-
/* @__PURE__ */
|
|
2735
|
+
/* @__PURE__ */ jsx9(
|
|
2383
2736
|
AnalogSimulationSelector,
|
|
2384
2737
|
{
|
|
2385
2738
|
simulations: simulationExperiments,
|
|
@@ -2387,7 +2740,7 @@ var AnalogSimulationViewer = ({
|
|
|
2387
2740
|
onSelectSimulation: handleSelectSimulation
|
|
2388
2741
|
}
|
|
2389
2742
|
),
|
|
2390
|
-
svgObjectUrl ? /* @__PURE__ */
|
|
2743
|
+
svgObjectUrl ? /* @__PURE__ */ jsx9(
|
|
2391
2744
|
"img",
|
|
2392
2745
|
{
|
|
2393
2746
|
ref: imgRef,
|
|
@@ -2401,7 +2754,7 @@ var AnalogSimulationViewer = ({
|
|
|
2401
2754
|
objectFit: "contain"
|
|
2402
2755
|
}
|
|
2403
2756
|
}
|
|
2404
|
-
) : /* @__PURE__ */
|
|
2757
|
+
) : /* @__PURE__ */ jsx9(
|
|
2405
2758
|
"div",
|
|
2406
2759
|
{
|
|
2407
2760
|
style: {
|