@tscircuit/schematic-viewer 2.0.79 → 2.0.80
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 +525 -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,145 @@ 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
|
+
"name",
|
|
590
|
+
"display_name",
|
|
591
|
+
"ftype",
|
|
592
|
+
"are_pins_interchangeable"
|
|
593
|
+
]);
|
|
594
|
+
var priorityKeys = [
|
|
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 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
|
+
var formatComponentValue = (sourceComponent, key, value) => {
|
|
617
|
+
const displayValue = sourceComponent[`display_${key}`];
|
|
618
|
+
if (typeof displayValue === "string" && displayValue.trim()) {
|
|
619
|
+
return displayValue;
|
|
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);
|
|
625
|
+
}
|
|
626
|
+
return String(value);
|
|
627
|
+
};
|
|
628
|
+
var getSourceComponentInfoEntries = (sourceComponent) => Object.entries(sourceComponent).filter(([key, value]) => {
|
|
629
|
+
if (hiddenSourceComponentKeys.has(key)) return false;
|
|
630
|
+
if (key.startsWith("display_") && key.slice("display_".length) in sourceComponent) {
|
|
631
|
+
return false;
|
|
632
|
+
}
|
|
633
|
+
return value !== void 0 && value !== null && value !== "";
|
|
634
|
+
}).sort(([keyA], [keyB]) => {
|
|
635
|
+
const priorityDifference = getKeyPriority(keyA) - getKeyPriority(keyB);
|
|
636
|
+
return priorityDifference || keyA.localeCompare(keyB);
|
|
637
|
+
}).map(([key, value]) => ({
|
|
638
|
+
key,
|
|
639
|
+
label: humanizeComponentField(key),
|
|
640
|
+
value: formatComponentValue(sourceComponent, key, value)
|
|
641
|
+
}));
|
|
642
|
+
var getSchematicComponentDetails = (circuitJson, schematicComponentId) => {
|
|
643
|
+
const schematicComponent = circuitJson.find(
|
|
644
|
+
(element) => element.type === "schematic_component" && element.schematic_component_id === schematicComponentId
|
|
645
|
+
);
|
|
646
|
+
if (!schematicComponent) return null;
|
|
647
|
+
const sourceComponent = circuitJson.find(
|
|
648
|
+
(element) => element.type === "source_component" && element.source_component_id === schematicComponent.source_component_id
|
|
649
|
+
);
|
|
650
|
+
if (!sourceComponent) return null;
|
|
651
|
+
const pcbComponent = circuitJson.find(
|
|
652
|
+
(element) => element.type === "pcb_component" && element.source_component_id === sourceComponent.source_component_id
|
|
653
|
+
);
|
|
654
|
+
const cadComponent = circuitJson.find(
|
|
655
|
+
(element) => element.type === "cad_component" && element.source_component_id === sourceComponent.source_component_id && (!pcbComponent || element.pcb_component_id === pcbComponent.pcb_component_id)
|
|
656
|
+
);
|
|
657
|
+
const footprinterString = pcbComponent?.footprinter_string ?? cadComponent?.footprinter_string;
|
|
658
|
+
const footprintPreview = pcbComponent ? getPcbComponentPreview(circuitJson, pcbComponent.pcb_component_id) : null;
|
|
659
|
+
return {
|
|
660
|
+
schematicComponent,
|
|
661
|
+
sourceComponent,
|
|
662
|
+
pcbComponent,
|
|
663
|
+
footprinterString,
|
|
664
|
+
footprintPreviewCircuitJson: footprintPreview?.circuitJson,
|
|
665
|
+
footprintPreviewViewBox: footprintPreview?.viewBox
|
|
666
|
+
};
|
|
667
|
+
};
|
|
668
|
+
var PCB_PREVIEW_PADDING_MM = 2;
|
|
669
|
+
var getPcbComponentPreview = (circuitJson, pcbComponentId) => {
|
|
670
|
+
const pcbComponent = circuitJson.find(
|
|
671
|
+
(element) => element.type === "pcb_component" && element.pcb_component_id === pcbComponentId
|
|
672
|
+
);
|
|
673
|
+
if (!pcbComponent) return null;
|
|
674
|
+
const componentBounds = getPcbElementBounds(pcbComponent);
|
|
675
|
+
if (!componentBounds) return null;
|
|
676
|
+
const viewBox = {
|
|
677
|
+
minX: componentBounds.minX - PCB_PREVIEW_PADDING_MM,
|
|
678
|
+
minY: componentBounds.minY - PCB_PREVIEW_PADDING_MM,
|
|
679
|
+
maxX: componentBounds.maxX + PCB_PREVIEW_PADDING_MM,
|
|
680
|
+
maxY: componentBounds.maxY + PCB_PREVIEW_PADDING_MM
|
|
681
|
+
};
|
|
682
|
+
return {
|
|
683
|
+
circuitJson: getPcbElementsWithinBounds(circuitJson, viewBox),
|
|
684
|
+
viewBox
|
|
685
|
+
};
|
|
686
|
+
};
|
|
687
|
+
var bytesToBase64 = (bytes) => {
|
|
688
|
+
let binary = "";
|
|
689
|
+
const chunkSize = 8192;
|
|
690
|
+
for (let index = 0; index < bytes.length; index += chunkSize) {
|
|
691
|
+
binary += String.fromCharCode(...bytes.subarray(index, index + chunkSize));
|
|
692
|
+
}
|
|
693
|
+
return btoa(binary);
|
|
694
|
+
};
|
|
695
|
+
var getFootprintPreviewUrl = (footprintPreviewCircuitJson, viewBox) => {
|
|
696
|
+
const encodedCircuitJson = bytesToBase64(
|
|
697
|
+
gzipSync(strToU8(JSON.stringify(footprintPreviewCircuitJson)))
|
|
698
|
+
);
|
|
699
|
+
const url = new URL("https://svg.tscircuit.com/");
|
|
700
|
+
url.searchParams.set("svg_type", "pcb");
|
|
701
|
+
url.searchParams.set("circuit_json", encodedCircuitJson);
|
|
702
|
+
url.searchParams.set(
|
|
703
|
+
"viewbox",
|
|
704
|
+
[viewBox.minX, viewBox.minY, viewBox.maxX, viewBox.maxY].join(",")
|
|
705
|
+
);
|
|
706
|
+
url.searchParams.set("background_color", "#f8fafc");
|
|
707
|
+
return url.toString();
|
|
708
|
+
};
|
|
709
|
+
|
|
578
710
|
// lib/utils/z-index-map.ts
|
|
579
711
|
var zIndexMap = {
|
|
580
712
|
contextMenu: 110,
|
|
581
713
|
viewMenu: 55,
|
|
582
714
|
viewMenuIcon: 48,
|
|
583
715
|
clickToInteractOverlay: 100,
|
|
716
|
+
schematicComponentDetailsTooltip: 105,
|
|
584
717
|
schematicComponentHoverOutline: 47,
|
|
585
718
|
schematicPortHoverOutline: 48
|
|
586
719
|
};
|
|
@@ -764,6 +897,209 @@ var MouseTrackerProvider = ({ children }) => {
|
|
|
764
897
|
return /* @__PURE__ */ jsx(MouseTrackerContext.Provider, { value, children });
|
|
765
898
|
};
|
|
766
899
|
|
|
900
|
+
// lib/components/SchematicComponentDetailsTooltip.tsx
|
|
901
|
+
import { useMemo as useMemo2 } from "react";
|
|
902
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
903
|
+
var detailLabelStyle = {
|
|
904
|
+
color: "#64748b",
|
|
905
|
+
fontSize: "11px",
|
|
906
|
+
fontWeight: 700,
|
|
907
|
+
letterSpacing: "0.04em",
|
|
908
|
+
textTransform: "uppercase"
|
|
909
|
+
};
|
|
910
|
+
var SchematicComponentDetailsTooltip = ({
|
|
911
|
+
sourceComponent,
|
|
912
|
+
footprinterString,
|
|
913
|
+
footprintPreviewCircuitJson,
|
|
914
|
+
footprintPreviewViewBox,
|
|
915
|
+
left,
|
|
916
|
+
top,
|
|
917
|
+
width,
|
|
918
|
+
maxHeight,
|
|
919
|
+
onClose
|
|
920
|
+
}) => {
|
|
921
|
+
const infoEntries = useMemo2(
|
|
922
|
+
() => getSourceComponentInfoEntries(sourceComponent),
|
|
923
|
+
[sourceComponent]
|
|
924
|
+
);
|
|
925
|
+
const footprintPreviewUrl = useMemo2(
|
|
926
|
+
() => footprintPreviewCircuitJson?.length && footprintPreviewViewBox ? getFootprintPreviewUrl(
|
|
927
|
+
footprintPreviewCircuitJson,
|
|
928
|
+
footprintPreviewViewBox
|
|
929
|
+
) : void 0,
|
|
930
|
+
[footprintPreviewCircuitJson, footprintPreviewViewBox]
|
|
931
|
+
);
|
|
932
|
+
const componentType = sourceComponent.ftype ? humanizeComponentField(sourceComponent.ftype) : "Component";
|
|
933
|
+
return /* @__PURE__ */ jsxs(
|
|
934
|
+
"dialog",
|
|
935
|
+
{
|
|
936
|
+
open: true,
|
|
937
|
+
"aria-label": `${sourceComponent.name} component details`,
|
|
938
|
+
"data-schematic-component-details-tooltip": true,
|
|
939
|
+
style: {
|
|
940
|
+
position: "absolute",
|
|
941
|
+
left,
|
|
942
|
+
right: "auto",
|
|
943
|
+
top,
|
|
944
|
+
bottom: "auto",
|
|
945
|
+
width,
|
|
946
|
+
maxHeight,
|
|
947
|
+
margin: 0,
|
|
948
|
+
padding: 0,
|
|
949
|
+
overflowY: "auto",
|
|
950
|
+
boxSizing: "border-box",
|
|
951
|
+
border: "1px solid #cbd5e1",
|
|
952
|
+
borderRadius: "12px",
|
|
953
|
+
backgroundColor: "rgba(255, 255, 255, 0.98)",
|
|
954
|
+
boxShadow: "0 20px 25px -5px rgba(15, 23, 42, 0.18), 0 8px 10px -6px rgba(15, 23, 42, 0.12)",
|
|
955
|
+
color: "#0f172a",
|
|
956
|
+
fontFamily: 'Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif',
|
|
957
|
+
pointerEvents: "auto",
|
|
958
|
+
userSelect: "text",
|
|
959
|
+
WebkitUserSelect: "text",
|
|
960
|
+
zIndex: zIndexMap.schematicComponentDetailsTooltip
|
|
961
|
+
},
|
|
962
|
+
onMouseDown: (event) => event.stopPropagation(),
|
|
963
|
+
onClick: (event) => event.stopPropagation(),
|
|
964
|
+
children: [
|
|
965
|
+
/* @__PURE__ */ jsxs(
|
|
966
|
+
"div",
|
|
967
|
+
{
|
|
968
|
+
style: {
|
|
969
|
+
display: "flex",
|
|
970
|
+
alignItems: "flex-start",
|
|
971
|
+
justifyContent: "space-between",
|
|
972
|
+
gap: "16px",
|
|
973
|
+
padding: "18px 18px 14px",
|
|
974
|
+
borderBottom: "1px solid #e2e8f0"
|
|
975
|
+
},
|
|
976
|
+
children: [
|
|
977
|
+
/* @__PURE__ */ jsxs("div", { style: { minWidth: 0 }, children: [
|
|
978
|
+
/* @__PURE__ */ jsx2(
|
|
979
|
+
"div",
|
|
980
|
+
{
|
|
981
|
+
style: {
|
|
982
|
+
fontSize: "20px",
|
|
983
|
+
fontWeight: 750,
|
|
984
|
+
lineHeight: 1.2,
|
|
985
|
+
overflowWrap: "anywhere"
|
|
986
|
+
},
|
|
987
|
+
children: sourceComponent.display_name ?? sourceComponent.name
|
|
988
|
+
}
|
|
989
|
+
),
|
|
990
|
+
/* @__PURE__ */ jsx2("div", { style: { color: "#64748b", fontSize: "13px", marginTop: 4 }, children: componentType })
|
|
991
|
+
] }),
|
|
992
|
+
/* @__PURE__ */ jsx2(
|
|
993
|
+
"button",
|
|
994
|
+
{
|
|
995
|
+
type: "button",
|
|
996
|
+
"aria-label": "Close component details",
|
|
997
|
+
onClick: onClose,
|
|
998
|
+
style: {
|
|
999
|
+
display: "grid",
|
|
1000
|
+
placeItems: "center",
|
|
1001
|
+
flex: "0 0 auto",
|
|
1002
|
+
width: "30px",
|
|
1003
|
+
height: "30px",
|
|
1004
|
+
padding: 0,
|
|
1005
|
+
border: "1px solid #e2e8f0",
|
|
1006
|
+
borderRadius: "8px",
|
|
1007
|
+
background: "#f8fafc",
|
|
1008
|
+
color: "#475569",
|
|
1009
|
+
cursor: "pointer",
|
|
1010
|
+
fontSize: "20px",
|
|
1011
|
+
lineHeight: 1
|
|
1012
|
+
},
|
|
1013
|
+
children: "\xD7"
|
|
1014
|
+
}
|
|
1015
|
+
)
|
|
1016
|
+
]
|
|
1017
|
+
}
|
|
1018
|
+
),
|
|
1019
|
+
infoEntries.length > 0 && /* @__PURE__ */ jsx2(
|
|
1020
|
+
"dl",
|
|
1021
|
+
{
|
|
1022
|
+
style: {
|
|
1023
|
+
display: "grid",
|
|
1024
|
+
gridTemplateColumns: "minmax(110px, 0.8fr) minmax(0, 1.2fr)",
|
|
1025
|
+
gap: "10px 18px",
|
|
1026
|
+
margin: 0,
|
|
1027
|
+
padding: "16px 18px",
|
|
1028
|
+
borderBottom: footprinterString ? "1px solid #e2e8f0" : void 0
|
|
1029
|
+
},
|
|
1030
|
+
children: infoEntries.map((entry) => /* @__PURE__ */ jsxs("div", { style: { display: "contents" }, children: [
|
|
1031
|
+
/* @__PURE__ */ jsx2("dt", { style: detailLabelStyle, children: entry.label }),
|
|
1032
|
+
/* @__PURE__ */ jsx2(
|
|
1033
|
+
"dd",
|
|
1034
|
+
{
|
|
1035
|
+
style: {
|
|
1036
|
+
minWidth: 0,
|
|
1037
|
+
margin: 0,
|
|
1038
|
+
color: "#1e293b",
|
|
1039
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", monospace',
|
|
1040
|
+
fontSize: "12px",
|
|
1041
|
+
lineHeight: 1.45,
|
|
1042
|
+
overflowWrap: "anywhere"
|
|
1043
|
+
},
|
|
1044
|
+
children: entry.value
|
|
1045
|
+
}
|
|
1046
|
+
)
|
|
1047
|
+
] }, entry.key))
|
|
1048
|
+
}
|
|
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
|
+
] })
|
|
1098
|
+
]
|
|
1099
|
+
}
|
|
1100
|
+
);
|
|
1101
|
+
};
|
|
1102
|
+
|
|
767
1103
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
768
1104
|
import { useCallback as useCallback4, useEffect as useEffect7, useRef as useRef4, useState as useState3 } from "react";
|
|
769
1105
|
|
|
@@ -772,7 +1108,7 @@ import {
|
|
|
772
1108
|
useContext as useContext2,
|
|
773
1109
|
useEffect as useEffect6,
|
|
774
1110
|
useId,
|
|
775
|
-
useMemo as
|
|
1111
|
+
useMemo as useMemo3,
|
|
776
1112
|
useRef as useRef3,
|
|
777
1113
|
useSyncExternalStore
|
|
778
1114
|
} from "react";
|
|
@@ -786,7 +1122,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
786
1122
|
const id = useId();
|
|
787
1123
|
const latestOptionsRef = useRef3(options);
|
|
788
1124
|
latestOptionsRef.current = options;
|
|
789
|
-
const handleClick =
|
|
1125
|
+
const handleClick = useMemo3(
|
|
790
1126
|
() => (event) => {
|
|
791
1127
|
latestOptionsRef.current.onClick?.(event);
|
|
792
1128
|
},
|
|
@@ -825,7 +1161,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
825
1161
|
};
|
|
826
1162
|
|
|
827
1163
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
828
|
-
import { jsx as
|
|
1164
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
829
1165
|
var areMeasurementsEqual = (a, b) => {
|
|
830
1166
|
if (!a && !b) return true;
|
|
831
1167
|
if (!a || !b) return false;
|
|
@@ -938,7 +1274,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
938
1274
|
return null;
|
|
939
1275
|
}
|
|
940
1276
|
const rect = measurement.rect;
|
|
941
|
-
return /* @__PURE__ */
|
|
1277
|
+
return /* @__PURE__ */ jsx3(
|
|
942
1278
|
"div",
|
|
943
1279
|
{
|
|
944
1280
|
style: {
|
|
@@ -957,7 +1293,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
957
1293
|
|
|
958
1294
|
// lib/components/SchematicPortMouseTarget.tsx
|
|
959
1295
|
import { useCallback as useCallback5, useEffect as useEffect8, useRef as useRef5, useState as useState4 } from "react";
|
|
960
|
-
import { Fragment as Fragment2, jsx as
|
|
1296
|
+
import { Fragment as Fragment2, jsx as jsx4, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
961
1297
|
var areMeasurementsEqual2 = (a, b) => {
|
|
962
1298
|
if (!a && !b) return true;
|
|
963
1299
|
if (!a || !b) return false;
|
|
@@ -1072,8 +1408,8 @@ var SchematicPortMouseTarget = ({
|
|
|
1072
1408
|
return null;
|
|
1073
1409
|
}
|
|
1074
1410
|
const rect = measurement.rect;
|
|
1075
|
-
return /* @__PURE__ */
|
|
1076
|
-
/* @__PURE__ */
|
|
1411
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
1412
|
+
/* @__PURE__ */ jsx4(
|
|
1077
1413
|
"div",
|
|
1078
1414
|
{
|
|
1079
1415
|
style: {
|
|
@@ -1091,7 +1427,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1091
1427
|
}
|
|
1092
1428
|
}
|
|
1093
1429
|
),
|
|
1094
|
-
hovering && portLabel && /* @__PURE__ */
|
|
1430
|
+
hovering && portLabel && /* @__PURE__ */ jsx4(
|
|
1095
1431
|
"div",
|
|
1096
1432
|
{
|
|
1097
1433
|
style: {
|
|
@@ -1118,7 +1454,7 @@ var SchematicPortMouseTarget = ({
|
|
|
1118
1454
|
// lib/components/SchematicSheetSelector.tsx
|
|
1119
1455
|
import { useState as useState5 } from "react";
|
|
1120
1456
|
import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
1121
|
-
import { Fragment as Fragment3, jsx as
|
|
1457
|
+
import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
1122
1458
|
var FONT_FAMILY = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1123
1459
|
var contentStyles = {
|
|
1124
1460
|
backgroundColor: "#ffffff",
|
|
@@ -1168,7 +1504,7 @@ var MENU_CSS = `
|
|
|
1168
1504
|
.sv-sheet-chevron { transition: transform 0.2s ease; }
|
|
1169
1505
|
[data-state="open"] > .sv-sheet-chevron { transform: rotate(180deg); }
|
|
1170
1506
|
`;
|
|
1171
|
-
var CheckIcon = () => /* @__PURE__ */
|
|
1507
|
+
var CheckIcon = () => /* @__PURE__ */ jsx5(
|
|
1172
1508
|
"svg",
|
|
1173
1509
|
{
|
|
1174
1510
|
width: "14",
|
|
@@ -1180,10 +1516,10 @@ var CheckIcon = () => /* @__PURE__ */ jsx4(
|
|
|
1180
1516
|
strokeLinecap: "round",
|
|
1181
1517
|
strokeLinejoin: "round",
|
|
1182
1518
|
"aria-hidden": "true",
|
|
1183
|
-
children: /* @__PURE__ */
|
|
1519
|
+
children: /* @__PURE__ */ jsx5("path", { d: "M20 6 9 17l-5-5" })
|
|
1184
1520
|
}
|
|
1185
1521
|
);
|
|
1186
|
-
var ChevronDownIcon = ({ className }) => /* @__PURE__ */
|
|
1522
|
+
var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx5(
|
|
1187
1523
|
"svg",
|
|
1188
1524
|
{
|
|
1189
1525
|
className,
|
|
@@ -1197,7 +1533,7 @@ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx4(
|
|
|
1197
1533
|
strokeLinejoin: "round",
|
|
1198
1534
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
1199
1535
|
"aria-hidden": "true",
|
|
1200
|
-
children: /* @__PURE__ */
|
|
1536
|
+
children: /* @__PURE__ */ jsx5("path", { d: "m6 9 6 6 6-6" })
|
|
1201
1537
|
}
|
|
1202
1538
|
);
|
|
1203
1539
|
var SchematicSheetSelector = ({
|
|
@@ -1211,10 +1547,10 @@ var SchematicSheetSelector = ({
|
|
|
1211
1547
|
(s) => s.schematic_sheet_id === selectedSheetId
|
|
1212
1548
|
);
|
|
1213
1549
|
const selectedLabel = selectedSheet?.name ?? "Select sheet";
|
|
1214
|
-
return /* @__PURE__ */
|
|
1215
|
-
/* @__PURE__ */
|
|
1216
|
-
/* @__PURE__ */
|
|
1217
|
-
/* @__PURE__ */
|
|
1550
|
+
return /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
1551
|
+
/* @__PURE__ */ jsx5("style", { children: MENU_CSS }),
|
|
1552
|
+
/* @__PURE__ */ jsxs3(DropdownMenu.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
1553
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs3(
|
|
1218
1554
|
"button",
|
|
1219
1555
|
{
|
|
1220
1556
|
type: "button",
|
|
@@ -1241,13 +1577,13 @@ var SchematicSheetSelector = ({
|
|
|
1241
1577
|
zIndex: zIndexMap.viewMenuIcon
|
|
1242
1578
|
},
|
|
1243
1579
|
children: [
|
|
1244
|
-
/* @__PURE__ */
|
|
1245
|
-
/* @__PURE__ */
|
|
1246
|
-
/* @__PURE__ */
|
|
1580
|
+
/* @__PURE__ */ jsx5("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
|
|
1581
|
+
/* @__PURE__ */ jsx5("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
|
|
1582
|
+
/* @__PURE__ */ jsx5(ChevronDownIcon, { className: "sv-sheet-chevron" })
|
|
1247
1583
|
]
|
|
1248
1584
|
}
|
|
1249
1585
|
) }),
|
|
1250
|
-
/* @__PURE__ */
|
|
1586
|
+
/* @__PURE__ */ jsx5(DropdownMenu.Portal, { children: /* @__PURE__ */ jsx5(
|
|
1251
1587
|
DropdownMenu.Content,
|
|
1252
1588
|
{
|
|
1253
1589
|
style: contentStyles,
|
|
@@ -1257,7 +1593,7 @@ var SchematicSheetSelector = ({
|
|
|
1257
1593
|
collisionPadding: 10,
|
|
1258
1594
|
children: sheets.map((sheet) => {
|
|
1259
1595
|
const selected = sheet.schematic_sheet_id === selectedSheetId;
|
|
1260
|
-
return /* @__PURE__ */
|
|
1596
|
+
return /* @__PURE__ */ jsxs3(
|
|
1261
1597
|
DropdownMenu.Item,
|
|
1262
1598
|
{
|
|
1263
1599
|
className: "sv-sheet-item",
|
|
@@ -1269,8 +1605,8 @@ var SchematicSheetSelector = ({
|
|
|
1269
1605
|
setOpen(false);
|
|
1270
1606
|
},
|
|
1271
1607
|
children: [
|
|
1272
|
-
/* @__PURE__ */
|
|
1273
|
-
/* @__PURE__ */
|
|
1608
|
+
/* @__PURE__ */ jsx5("span", { style: iconSlotStyles, children: selected && /* @__PURE__ */ jsx5(CheckIcon, {}) }),
|
|
1609
|
+
/* @__PURE__ */ jsx5("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
|
|
1274
1610
|
]
|
|
1275
1611
|
},
|
|
1276
1612
|
sheet.schematic_sheet_id
|
|
@@ -1285,12 +1621,12 @@ var SchematicSheetSelector = ({
|
|
|
1285
1621
|
// lib/components/ViewMenu.tsx
|
|
1286
1622
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
1287
1623
|
import { su as su3 } from "@tscircuit/soup-util";
|
|
1288
|
-
import { useMemo as
|
|
1624
|
+
import { useMemo as useMemo4 } from "react";
|
|
1289
1625
|
|
|
1290
1626
|
// package.json
|
|
1291
1627
|
var package_default = {
|
|
1292
1628
|
name: "@tscircuit/schematic-viewer",
|
|
1293
|
-
version: "2.0.
|
|
1629
|
+
version: "2.0.79",
|
|
1294
1630
|
main: "dist/index.js",
|
|
1295
1631
|
type: "module",
|
|
1296
1632
|
scripts: {
|
|
@@ -1329,16 +1665,18 @@ var package_default = {
|
|
|
1329
1665
|
},
|
|
1330
1666
|
dependencies: {
|
|
1331
1667
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
1668
|
+
"@tscircuit/circuit-json-util": "^0.0.108",
|
|
1332
1669
|
"circuit-json": "^0.0.465",
|
|
1333
1670
|
"circuit-to-svg": "^0.0.393",
|
|
1334
1671
|
debug: "^4.4.0",
|
|
1672
|
+
fflate: "^0.8.3",
|
|
1335
1673
|
"performance-now": "^2.1.0",
|
|
1336
1674
|
"use-mouse-matrix-transform": "^1.2.2"
|
|
1337
1675
|
}
|
|
1338
1676
|
};
|
|
1339
1677
|
|
|
1340
1678
|
// lib/components/ViewMenu.tsx
|
|
1341
|
-
import { jsx as
|
|
1679
|
+
import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1342
1680
|
var FONT_FAMILY2 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1343
1681
|
var contentStyles2 = {
|
|
1344
1682
|
backgroundColor: "#262626",
|
|
@@ -1387,7 +1725,7 @@ var HIGHLIGHT_CSS = `
|
|
|
1387
1725
|
.sv-vm-item:hover:not([data-disabled]) { background-color: #404040; }
|
|
1388
1726
|
.sv-vm-item[data-disabled] { opacity: 0.45; cursor: not-allowed; }
|
|
1389
1727
|
`;
|
|
1390
|
-
var CheckIcon2 = () => /* @__PURE__ */
|
|
1728
|
+
var CheckIcon2 = () => /* @__PURE__ */ jsx6(
|
|
1391
1729
|
"svg",
|
|
1392
1730
|
{
|
|
1393
1731
|
width: "14",
|
|
@@ -1399,7 +1737,7 @@ var CheckIcon2 = () => /* @__PURE__ */ jsx5(
|
|
|
1399
1737
|
strokeLinecap: "round",
|
|
1400
1738
|
strokeLinejoin: "round",
|
|
1401
1739
|
"aria-hidden": "true",
|
|
1402
|
-
children: /* @__PURE__ */
|
|
1740
|
+
children: /* @__PURE__ */ jsx6("path", { d: "M20 6 9 17l-5-5" })
|
|
1403
1741
|
}
|
|
1404
1742
|
);
|
|
1405
1743
|
var ViewMenu = ({
|
|
@@ -1415,7 +1753,7 @@ var ViewMenu = ({
|
|
|
1415
1753
|
showPorts,
|
|
1416
1754
|
onTogglePorts
|
|
1417
1755
|
}) => {
|
|
1418
|
-
const hasGroups =
|
|
1756
|
+
const hasGroups = useMemo4(() => {
|
|
1419
1757
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1420
1758
|
try {
|
|
1421
1759
|
const sourceGroups = su3(circuitJson).source_group?.list() || [];
|
|
@@ -1439,7 +1777,7 @@ var ViewMenu = ({
|
|
|
1439
1777
|
return false;
|
|
1440
1778
|
}
|
|
1441
1779
|
}, [circuitJsonKey]);
|
|
1442
|
-
const hasPorts =
|
|
1780
|
+
const hasPorts = useMemo4(() => {
|
|
1443
1781
|
if (!circuitJson || circuitJson.length === 0) return false;
|
|
1444
1782
|
try {
|
|
1445
1783
|
return (su3(circuitJson).schematic_port?.list() || []).length > 0;
|
|
@@ -1448,7 +1786,7 @@ var ViewMenu = ({
|
|
|
1448
1786
|
return false;
|
|
1449
1787
|
}
|
|
1450
1788
|
}, [circuitJsonKey]);
|
|
1451
|
-
return /* @__PURE__ */
|
|
1789
|
+
return /* @__PURE__ */ jsx6(
|
|
1452
1790
|
"div",
|
|
1453
1791
|
{
|
|
1454
1792
|
ref: menuRef,
|
|
@@ -1459,9 +1797,9 @@ var ViewMenu = ({
|
|
|
1459
1797
|
width: 0,
|
|
1460
1798
|
height: 0
|
|
1461
1799
|
},
|
|
1462
|
-
children: /* @__PURE__ */
|
|
1463
|
-
/* @__PURE__ */
|
|
1464
|
-
/* @__PURE__ */
|
|
1800
|
+
children: /* @__PURE__ */ jsxs4(DropdownMenu2.Root, { open: true, onOpenChange, modal: false, children: [
|
|
1801
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsx6("div", { style: { position: "absolute", width: 1, height: 1 } }) }),
|
|
1802
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs4(
|
|
1465
1803
|
DropdownMenu2.Content,
|
|
1466
1804
|
{
|
|
1467
1805
|
style: contentStyles2,
|
|
@@ -1470,8 +1808,8 @@ var ViewMenu = ({
|
|
|
1470
1808
|
collisionPadding: 10,
|
|
1471
1809
|
avoidCollisions: true,
|
|
1472
1810
|
children: [
|
|
1473
|
-
/* @__PURE__ */
|
|
1474
|
-
/* @__PURE__ */
|
|
1811
|
+
/* @__PURE__ */ jsx6("style", { children: HIGHLIGHT_CSS }),
|
|
1812
|
+
/* @__PURE__ */ jsxs4(
|
|
1475
1813
|
DropdownMenu2.Item,
|
|
1476
1814
|
{
|
|
1477
1815
|
className: "sv-vm-item",
|
|
@@ -1484,12 +1822,12 @@ var ViewMenu = ({
|
|
|
1484
1822
|
if (hasPorts) onTogglePorts(!showPorts);
|
|
1485
1823
|
},
|
|
1486
1824
|
children: [
|
|
1487
|
-
/* @__PURE__ */
|
|
1488
|
-
/* @__PURE__ */
|
|
1825
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showPorts && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1826
|
+
/* @__PURE__ */ jsx6("span", { children: "Show Schematic Ports" })
|
|
1489
1827
|
]
|
|
1490
1828
|
}
|
|
1491
1829
|
),
|
|
1492
|
-
/* @__PURE__ */
|
|
1830
|
+
/* @__PURE__ */ jsxs4(
|
|
1493
1831
|
DropdownMenu2.Item,
|
|
1494
1832
|
{
|
|
1495
1833
|
className: "sv-vm-item",
|
|
@@ -1502,12 +1840,12 @@ var ViewMenu = ({
|
|
|
1502
1840
|
if (hasGroups) onToggleGroups(!showGroups);
|
|
1503
1841
|
},
|
|
1504
1842
|
children: [
|
|
1505
|
-
/* @__PURE__ */
|
|
1506
|
-
/* @__PURE__ */
|
|
1843
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showGroups && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1844
|
+
/* @__PURE__ */ jsx6("span", { children: "View Schematic Groups" })
|
|
1507
1845
|
]
|
|
1508
1846
|
}
|
|
1509
1847
|
),
|
|
1510
|
-
/* @__PURE__ */
|
|
1848
|
+
/* @__PURE__ */ jsxs4(
|
|
1511
1849
|
DropdownMenu2.Item,
|
|
1512
1850
|
{
|
|
1513
1851
|
className: "sv-vm-item",
|
|
@@ -1518,13 +1856,13 @@ var ViewMenu = ({
|
|
|
1518
1856
|
onToggleGrid(!showGrid);
|
|
1519
1857
|
},
|
|
1520
1858
|
children: [
|
|
1521
|
-
/* @__PURE__ */
|
|
1522
|
-
/* @__PURE__ */
|
|
1859
|
+
/* @__PURE__ */ jsx6("span", { style: iconSlotStyles2, children: showGrid && /* @__PURE__ */ jsx6(CheckIcon2, {}) }),
|
|
1860
|
+
/* @__PURE__ */ jsx6("span", { children: "Show Grid" })
|
|
1523
1861
|
]
|
|
1524
1862
|
}
|
|
1525
1863
|
),
|
|
1526
|
-
/* @__PURE__ */
|
|
1527
|
-
/* @__PURE__ */
|
|
1864
|
+
/* @__PURE__ */ jsx6(DropdownMenu2.Separator, { style: separatorStyles }),
|
|
1865
|
+
/* @__PURE__ */ jsxs4(
|
|
1528
1866
|
"div",
|
|
1529
1867
|
{
|
|
1530
1868
|
style: {
|
|
@@ -1550,7 +1888,7 @@ var ViewMenu = ({
|
|
|
1550
1888
|
};
|
|
1551
1889
|
|
|
1552
1890
|
// lib/components/SchematicViewer.tsx
|
|
1553
|
-
import { jsx as
|
|
1891
|
+
import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1554
1892
|
var SchematicViewer = ({
|
|
1555
1893
|
circuitJson,
|
|
1556
1894
|
containerStyle,
|
|
@@ -1573,11 +1911,11 @@ var SchematicViewer = ({
|
|
|
1573
1911
|
const getCircuitHash = (circuitJson2) => {
|
|
1574
1912
|
return `${circuitJson2?.length || 0}_${circuitJson2?.editCount || 0}`;
|
|
1575
1913
|
};
|
|
1576
|
-
const circuitJsonKey =
|
|
1914
|
+
const circuitJsonKey = useMemo5(
|
|
1577
1915
|
() => getCircuitHash(circuitJson),
|
|
1578
1916
|
[circuitJson]
|
|
1579
1917
|
);
|
|
1580
|
-
const schematicSheets =
|
|
1918
|
+
const schematicSheets = useMemo5(() => {
|
|
1581
1919
|
try {
|
|
1582
1920
|
return circuitJson.filter((elm) => elm?.type === "schematic_sheet").slice().sort((a, b) => (a.sheet_index ?? 0) - (b.sheet_index ?? 0));
|
|
1583
1921
|
} catch (err) {
|
|
@@ -1630,6 +1968,7 @@ var SchematicViewer = ({
|
|
|
1630
1968
|
}, [showSchematicPorts]);
|
|
1631
1969
|
const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState6(false);
|
|
1632
1970
|
const hoveringComponentsRef = useRef6(/* @__PURE__ */ new Set());
|
|
1971
|
+
const [selectedSchematicComponent, setSelectedSchematicComponent] = useState6(null);
|
|
1633
1972
|
const handleComponentHoverChange = useCallback6(
|
|
1634
1973
|
(componentId, isHovering) => {
|
|
1635
1974
|
if (isHovering) {
|
|
@@ -1656,7 +1995,7 @@ var SchematicViewer = ({
|
|
|
1656
1995
|
);
|
|
1657
1996
|
const svgDivRef = useRef6(null);
|
|
1658
1997
|
const touchStartRef = useRef6(null);
|
|
1659
|
-
const schematicComponentIds =
|
|
1998
|
+
const schematicComponentIds = useMemo5(() => {
|
|
1660
1999
|
try {
|
|
1661
2000
|
const components = su4(circuitJson).schematic_component?.list() ?? [];
|
|
1662
2001
|
return components.filter(
|
|
@@ -1667,7 +2006,7 @@ var SchematicViewer = ({
|
|
|
1667
2006
|
return [];
|
|
1668
2007
|
}
|
|
1669
2008
|
}, [circuitJsonKey, circuitJson, activeSheetId]);
|
|
1670
|
-
const schematicPortsInfo =
|
|
2009
|
+
const schematicPortsInfo = useMemo5(() => {
|
|
1671
2010
|
if (!showSchematicPortsInternal) return [];
|
|
1672
2011
|
try {
|
|
1673
2012
|
const ports = (su4(circuitJson).schematic_port?.list() ?? []).filter(
|
|
@@ -1731,7 +2070,77 @@ var SchematicViewer = ({
|
|
|
1731
2070
|
contextMenuEventHandlers
|
|
1732
2071
|
} = useContextMenu({ containerRef });
|
|
1733
2072
|
const { containerWidth, containerHeight } = useResizeHandling(containerRef);
|
|
1734
|
-
const
|
|
2073
|
+
const selectedComponentDetails = useMemo5(
|
|
2074
|
+
() => selectedSchematicComponent ? getSchematicComponentDetails(
|
|
2075
|
+
circuitJson,
|
|
2076
|
+
selectedSchematicComponent.schematicComponentId
|
|
2077
|
+
) : null,
|
|
2078
|
+
[circuitJsonKey, circuitJson, selectedSchematicComponent]
|
|
2079
|
+
);
|
|
2080
|
+
const componentTooltipLayout = useMemo5(() => {
|
|
2081
|
+
if (!selectedSchematicComponent || !containerWidth || !containerHeight) {
|
|
2082
|
+
return null;
|
|
2083
|
+
}
|
|
2084
|
+
const margin = 12;
|
|
2085
|
+
const gap = 14;
|
|
2086
|
+
const width = Math.min(420, containerWidth - margin * 2);
|
|
2087
|
+
const maxHeight = Math.min(520, containerHeight - margin * 2);
|
|
2088
|
+
const { anchorX, anchorY } = selectedSchematicComponent;
|
|
2089
|
+
const rightOfAnchor = anchorX + gap;
|
|
2090
|
+
const leftOfAnchor = anchorX - width - gap;
|
|
2091
|
+
const left = rightOfAnchor + width <= containerWidth - margin ? rightOfAnchor : leftOfAnchor >= margin ? leftOfAnchor : Math.max(
|
|
2092
|
+
margin,
|
|
2093
|
+
Math.min(anchorX - width / 2, containerWidth - width - margin)
|
|
2094
|
+
);
|
|
2095
|
+
const top = Math.max(
|
|
2096
|
+
margin,
|
|
2097
|
+
Math.min(anchorY - 24, containerHeight - maxHeight - margin)
|
|
2098
|
+
);
|
|
2099
|
+
return { left, top, width, maxHeight };
|
|
2100
|
+
}, [selectedSchematicComponent, containerWidth, containerHeight]);
|
|
2101
|
+
const handleSchematicComponentClick = useCallback6(
|
|
2102
|
+
(schematicComponentId, event) => {
|
|
2103
|
+
if (event.target instanceof Element && event.target.closest("[data-schematic-component-details-tooltip]")) {
|
|
2104
|
+
return;
|
|
2105
|
+
}
|
|
2106
|
+
const containerRect = containerRef.current?.getBoundingClientRect();
|
|
2107
|
+
if (!containerRect) return;
|
|
2108
|
+
setSelectedSchematicComponent({
|
|
2109
|
+
schematicComponentId,
|
|
2110
|
+
anchorX: event.clientX - containerRect.left,
|
|
2111
|
+
anchorY: event.clientY - containerRect.top
|
|
2112
|
+
});
|
|
2113
|
+
onSchematicComponentClicked?.({
|
|
2114
|
+
schematicComponentId,
|
|
2115
|
+
event
|
|
2116
|
+
});
|
|
2117
|
+
},
|
|
2118
|
+
[containerRef, onSchematicComponentClicked]
|
|
2119
|
+
);
|
|
2120
|
+
useEffect9(() => {
|
|
2121
|
+
setSelectedSchematicComponent(null);
|
|
2122
|
+
}, [circuitJsonKey, activeSheetId]);
|
|
2123
|
+
useEffect9(() => {
|
|
2124
|
+
if (!selectedSchematicComponent) return;
|
|
2125
|
+
const handleKeyDown = (event) => {
|
|
2126
|
+
if (event.key === "Escape") {
|
|
2127
|
+
setSelectedSchematicComponent(null);
|
|
2128
|
+
}
|
|
2129
|
+
};
|
|
2130
|
+
const handleDocumentMouseDown = (event) => {
|
|
2131
|
+
if (event.target instanceof Element && event.target.closest("[data-schematic-component-details-tooltip]")) {
|
|
2132
|
+
return;
|
|
2133
|
+
}
|
|
2134
|
+
setSelectedSchematicComponent(null);
|
|
2135
|
+
};
|
|
2136
|
+
window.addEventListener("keydown", handleKeyDown);
|
|
2137
|
+
document.addEventListener("mousedown", handleDocumentMouseDown);
|
|
2138
|
+
return () => {
|
|
2139
|
+
window.removeEventListener("keydown", handleKeyDown);
|
|
2140
|
+
document.removeEventListener("mousedown", handleDocumentMouseDown);
|
|
2141
|
+
};
|
|
2142
|
+
}, [selectedSchematicComponent]);
|
|
2143
|
+
const svgString = useMemo5(() => {
|
|
1735
2144
|
if (!containerWidth || !containerHeight) return "";
|
|
1736
2145
|
return convertCircuitJsonToSchematicSvg(circuitJson, {
|
|
1737
2146
|
width: containerWidth,
|
|
@@ -1754,7 +2163,7 @@ var SchematicViewer = ({
|
|
|
1754
2163
|
showSchematicPortsInternal,
|
|
1755
2164
|
activeSheetId
|
|
1756
2165
|
]);
|
|
1757
|
-
const containerBackgroundColor =
|
|
2166
|
+
const containerBackgroundColor = useMemo5(() => {
|
|
1758
2167
|
const match = svgString.match(
|
|
1759
2168
|
/<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
|
|
1760
2169
|
);
|
|
@@ -1772,8 +2181,8 @@ var SchematicViewer = ({
|
|
|
1772
2181
|
circuitJsonKey: `${circuitJsonKey}_${activeSheetId ?? ""}`,
|
|
1773
2182
|
enabled: netHoverHighlightEnabled
|
|
1774
2183
|
});
|
|
1775
|
-
const svgDiv =
|
|
1776
|
-
() => /* @__PURE__ */
|
|
2184
|
+
const svgDiv = useMemo5(
|
|
2185
|
+
() => /* @__PURE__ */ jsx7(
|
|
1777
2186
|
"div",
|
|
1778
2187
|
{
|
|
1779
2188
|
ref: svgDivRef,
|
|
@@ -1781,18 +2190,18 @@ var SchematicViewer = ({
|
|
|
1781
2190
|
pointerEvents: clickToInteractEnabled ? isInteractionEnabled ? "auto" : "none" : "auto",
|
|
1782
2191
|
transformOrigin: "0 0"
|
|
1783
2192
|
},
|
|
1784
|
-
className:
|
|
2193
|
+
className: "schematic-component-clickable",
|
|
1785
2194
|
dangerouslySetInnerHTML: { __html: svgString }
|
|
1786
2195
|
}
|
|
1787
2196
|
),
|
|
1788
2197
|
[svgString, isInteractionEnabled, clickToInteractEnabled]
|
|
1789
2198
|
);
|
|
1790
|
-
return /* @__PURE__ */
|
|
1791
|
-
netHoverHighlightEnabled && /* @__PURE__ */
|
|
2199
|
+
return /* @__PURE__ */ jsxs5(MouseTracker, { children: [
|
|
2200
|
+
netHoverHighlightEnabled && /* @__PURE__ */ jsx7("style", { children: `.sch-net-faded { opacity: 0.35; }
|
|
1792
2201
|
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__ */
|
|
2202
|
+
/* @__PURE__ */ jsx7("style", { children: ".schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }" }),
|
|
2203
|
+
onSchematicPortClicked && /* @__PURE__ */ jsx7("style", { children: "[data-schematic-port-id]:hover { cursor: pointer !important; }" }),
|
|
2204
|
+
/* @__PURE__ */ jsxs5(
|
|
1796
2205
|
"div",
|
|
1797
2206
|
{
|
|
1798
2207
|
ref: containerRef,
|
|
@@ -1800,7 +2209,7 @@ var SchematicViewer = ({
|
|
|
1800
2209
|
position: "relative",
|
|
1801
2210
|
backgroundColor: containerBackgroundColor,
|
|
1802
2211
|
overflow: "hidden",
|
|
1803
|
-
cursor: clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent
|
|
2212
|
+
cursor: clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent ? "pointer" : isHoveringClickablePort && onSchematicPortClicked ? "pointer" : "grab",
|
|
1804
2213
|
minHeight: "300px",
|
|
1805
2214
|
userSelect: "none",
|
|
1806
2215
|
WebkitUserSelect: "none",
|
|
@@ -1827,7 +2236,7 @@ var SchematicViewer = ({
|
|
|
1827
2236
|
},
|
|
1828
2237
|
onTouchCancel: contextMenuEventHandlers.onTouchCancel,
|
|
1829
2238
|
children: [
|
|
1830
|
-
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */
|
|
2239
|
+
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx7(
|
|
1831
2240
|
"div",
|
|
1832
2241
|
{
|
|
1833
2242
|
onClick: (e) => {
|
|
@@ -1846,7 +2255,7 @@ var SchematicViewer = ({
|
|
|
1846
2255
|
pointerEvents: "all",
|
|
1847
2256
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
1848
2257
|
},
|
|
1849
|
-
children: /* @__PURE__ */
|
|
2258
|
+
children: /* @__PURE__ */ jsx7(
|
|
1850
2259
|
"div",
|
|
1851
2260
|
{
|
|
1852
2261
|
style: {
|
|
@@ -1863,7 +2272,7 @@ var SchematicViewer = ({
|
|
|
1863
2272
|
)
|
|
1864
2273
|
}
|
|
1865
2274
|
),
|
|
1866
|
-
menuVisible && /* @__PURE__ */
|
|
2275
|
+
menuVisible && /* @__PURE__ */ jsx7(
|
|
1867
2276
|
ViewMenu,
|
|
1868
2277
|
{
|
|
1869
2278
|
circuitJson,
|
|
@@ -1890,7 +2299,7 @@ var SchematicViewer = ({
|
|
|
1890
2299
|
onToggleGrid: setShowGridInternal
|
|
1891
2300
|
}
|
|
1892
2301
|
),
|
|
1893
|
-
/* @__PURE__ */
|
|
2302
|
+
/* @__PURE__ */ jsx7(
|
|
1894
2303
|
SchematicSheetSelector,
|
|
1895
2304
|
{
|
|
1896
2305
|
sheets: schematicSheets,
|
|
@@ -1898,7 +2307,7 @@ var SchematicViewer = ({
|
|
|
1898
2307
|
onSelectSheet: handleSelectSheet
|
|
1899
2308
|
}
|
|
1900
2309
|
),
|
|
1901
|
-
|
|
2310
|
+
schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx7(
|
|
1902
2311
|
SchematicComponentMouseTarget,
|
|
1903
2312
|
{
|
|
1904
2313
|
componentId,
|
|
@@ -1907,17 +2316,23 @@ var SchematicViewer = ({
|
|
|
1907
2316
|
showOutline: true,
|
|
1908
2317
|
circuitJsonKey,
|
|
1909
2318
|
onHoverChange: handleComponentHoverChange,
|
|
1910
|
-
onComponentClick:
|
|
1911
|
-
onSchematicComponentClicked?.({
|
|
1912
|
-
schematicComponentId: id,
|
|
1913
|
-
event
|
|
1914
|
-
});
|
|
1915
|
-
}
|
|
2319
|
+
onComponentClick: handleSchematicComponentClick
|
|
1916
2320
|
},
|
|
1917
2321
|
componentId
|
|
1918
2322
|
)),
|
|
1919
2323
|
svgDiv,
|
|
1920
|
-
|
|
2324
|
+
selectedComponentDetails && componentTooltipLayout && /* @__PURE__ */ jsx7(
|
|
2325
|
+
SchematicComponentDetailsTooltip,
|
|
2326
|
+
{
|
|
2327
|
+
sourceComponent: selectedComponentDetails.sourceComponent,
|
|
2328
|
+
footprinterString: selectedComponentDetails.footprinterString,
|
|
2329
|
+
footprintPreviewCircuitJson: selectedComponentDetails.footprintPreviewCircuitJson,
|
|
2330
|
+
footprintPreviewViewBox: selectedComponentDetails.footprintPreviewViewBox,
|
|
2331
|
+
...componentTooltipLayout,
|
|
2332
|
+
onClose: () => setSelectedSchematicComponent(null)
|
|
2333
|
+
}
|
|
2334
|
+
),
|
|
2335
|
+
showSchematicPortsInternal && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx7(
|
|
1921
2336
|
SchematicPortMouseTarget,
|
|
1922
2337
|
{
|
|
1923
2338
|
portId,
|
|
@@ -1947,7 +2362,7 @@ import {
|
|
|
1947
2362
|
convertCircuitJsonToSchematicSimulationSvg,
|
|
1948
2363
|
convertCircuitJsonToSimulationGraphSvg
|
|
1949
2364
|
} from "circuit-to-svg";
|
|
1950
|
-
import { useEffect as useEffect10, useMemo as
|
|
2365
|
+
import { useEffect as useEffect10, useMemo as useMemo6, useRef as useRef7, useState as useState8 } from "react";
|
|
1951
2366
|
import { toString as transformToString2 } from "transformation-matrix";
|
|
1952
2367
|
import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
|
|
1953
2368
|
|
|
@@ -1966,7 +2381,7 @@ var getAnalogSimulationBackgroundColor = (simulationSvg, colorOverrides) => getR
|
|
|
1966
2381
|
// lib/components/AnalogSimulationSelector.tsx
|
|
1967
2382
|
import * as DropdownMenu3 from "@radix-ui/react-dropdown-menu";
|
|
1968
2383
|
import { useState as useState7 } from "react";
|
|
1969
|
-
import { Fragment as Fragment4, jsx as
|
|
2384
|
+
import { Fragment as Fragment4, jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1970
2385
|
var FONT_FAMILY3 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
1971
2386
|
var contentStyles3 = {
|
|
1972
2387
|
backgroundColor: "#ffffff",
|
|
@@ -2016,7 +2431,7 @@ var MENU_CSS2 = `
|
|
|
2016
2431
|
.sv-simulation-chevron { transition: transform 0.2s ease; }
|
|
2017
2432
|
[data-state="open"] > .sv-simulation-chevron { transform: rotate(180deg); }
|
|
2018
2433
|
`;
|
|
2019
|
-
var CheckIcon3 = () => /* @__PURE__ */
|
|
2434
|
+
var CheckIcon3 = () => /* @__PURE__ */ jsx8(
|
|
2020
2435
|
"svg",
|
|
2021
2436
|
{
|
|
2022
2437
|
width: "14",
|
|
@@ -2028,10 +2443,10 @@ var CheckIcon3 = () => /* @__PURE__ */ jsx7(
|
|
|
2028
2443
|
strokeLinecap: "round",
|
|
2029
2444
|
strokeLinejoin: "round",
|
|
2030
2445
|
"aria-hidden": "true",
|
|
2031
|
-
children: /* @__PURE__ */
|
|
2446
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
|
|
2032
2447
|
}
|
|
2033
2448
|
);
|
|
2034
|
-
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */
|
|
2449
|
+
var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx8(
|
|
2035
2450
|
"svg",
|
|
2036
2451
|
{
|
|
2037
2452
|
className,
|
|
@@ -2045,7 +2460,7 @@ var ChevronDownIcon2 = ({ className }) => /* @__PURE__ */ jsx7(
|
|
|
2045
2460
|
strokeLinejoin: "round",
|
|
2046
2461
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
2047
2462
|
"aria-hidden": "true",
|
|
2048
|
-
children: /* @__PURE__ */
|
|
2463
|
+
children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" })
|
|
2049
2464
|
}
|
|
2050
2465
|
);
|
|
2051
2466
|
var getSimulationLabels = (simulations) => {
|
|
@@ -2071,10 +2486,10 @@ var AnalogSimulationSelector = ({
|
|
|
2071
2486
|
({ simulation }) => simulation.simulation_experiment_id === selectedSimulationExperimentId
|
|
2072
2487
|
);
|
|
2073
2488
|
const selectedLabel = selectedSimulation?.label ?? "Select simulation";
|
|
2074
|
-
return /* @__PURE__ */
|
|
2075
|
-
/* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2077
|
-
/* @__PURE__ */
|
|
2489
|
+
return /* @__PURE__ */ jsxs6(Fragment4, { children: [
|
|
2490
|
+
/* @__PURE__ */ jsx8("style", { children: MENU_CSS2 }),
|
|
2491
|
+
/* @__PURE__ */ jsxs6(DropdownMenu3.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
2492
|
+
/* @__PURE__ */ jsx8(DropdownMenu3.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs6(
|
|
2078
2493
|
"button",
|
|
2079
2494
|
{
|
|
2080
2495
|
type: "button",
|
|
@@ -2101,13 +2516,13 @@ var AnalogSimulationSelector = ({
|
|
|
2101
2516
|
zIndex: zIndexMap.viewMenuIcon
|
|
2102
2517
|
},
|
|
2103
2518
|
children: [
|
|
2104
|
-
/* @__PURE__ */
|
|
2105
|
-
/* @__PURE__ */
|
|
2106
|
-
/* @__PURE__ */
|
|
2519
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888888", flexShrink: 0 }, children: "Simulation:" }),
|
|
2520
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: selectedLabel }),
|
|
2521
|
+
/* @__PURE__ */ jsx8(ChevronDownIcon2, { className: "sv-simulation-chevron" })
|
|
2107
2522
|
]
|
|
2108
2523
|
}
|
|
2109
2524
|
) }),
|
|
2110
|
-
/* @__PURE__ */
|
|
2525
|
+
/* @__PURE__ */ jsx8(DropdownMenu3.Portal, { children: /* @__PURE__ */ jsx8(
|
|
2111
2526
|
DropdownMenu3.Content,
|
|
2112
2527
|
{
|
|
2113
2528
|
style: contentStyles3,
|
|
@@ -2117,7 +2532,7 @@ var AnalogSimulationSelector = ({
|
|
|
2117
2532
|
collisionPadding: 10,
|
|
2118
2533
|
children: simulationLabels.map(({ simulation, label }) => {
|
|
2119
2534
|
const selected = simulation.simulation_experiment_id === selectedSimulationExperimentId;
|
|
2120
|
-
return /* @__PURE__ */
|
|
2535
|
+
return /* @__PURE__ */ jsxs6(
|
|
2121
2536
|
DropdownMenu3.Item,
|
|
2122
2537
|
{
|
|
2123
2538
|
className: "sv-simulation-item",
|
|
@@ -2129,8 +2544,8 @@ var AnalogSimulationSelector = ({
|
|
|
2129
2544
|
setOpen(false);
|
|
2130
2545
|
},
|
|
2131
2546
|
children: [
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2547
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles3, children: selected && /* @__PURE__ */ jsx8(CheckIcon3, {}) }),
|
|
2548
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles2, minWidth: 0 }, children: label })
|
|
2134
2549
|
]
|
|
2135
2550
|
},
|
|
2136
2551
|
simulation.simulation_experiment_id
|
|
@@ -2143,7 +2558,7 @@ var AnalogSimulationSelector = ({
|
|
|
2143
2558
|
};
|
|
2144
2559
|
|
|
2145
2560
|
// lib/components/AnalogSimulationViewer.tsx
|
|
2146
|
-
import { jsx as
|
|
2561
|
+
import { jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2147
2562
|
var DEFAULT_RENDER_WIDTH = 1200;
|
|
2148
2563
|
var DEFAULT_COMBINED_RENDER_ASPECT_RATIO = 1;
|
|
2149
2564
|
var DEFAULT_GRAPH_ONLY_RENDER_ASPECT_RATIO = 2;
|
|
@@ -2189,7 +2604,7 @@ var AnalogSimulationViewer = ({
|
|
|
2189
2604
|
setCircuitJson(inputCircuitJson);
|
|
2190
2605
|
setIsLoading(false);
|
|
2191
2606
|
}, [inputCircuitJson]);
|
|
2192
|
-
const simulationExperiments =
|
|
2607
|
+
const simulationExperiments = useMemo6(() => {
|
|
2193
2608
|
if (!circuitJson) return [];
|
|
2194
2609
|
return circuitJson.filter(
|
|
2195
2610
|
(element) => element.type === "simulation_experiment"
|
|
@@ -2208,7 +2623,7 @@ var AnalogSimulationViewer = ({
|
|
|
2208
2623
|
setSelectedSimulationExperimentId(nextSimulationExperimentId);
|
|
2209
2624
|
onSimulationChange?.(nextSimulationExperimentId);
|
|
2210
2625
|
};
|
|
2211
|
-
const simulationSvg =
|
|
2626
|
+
const simulationSvg = useMemo6(() => {
|
|
2212
2627
|
if (!circuitJson || !effectiveWidth || !effectiveHeight || !simulationExperimentId)
|
|
2213
2628
|
return "";
|
|
2214
2629
|
try {
|
|
@@ -2253,7 +2668,7 @@ var AnalogSimulationViewer = ({
|
|
|
2253
2668
|
setSvgObjectUrl(null);
|
|
2254
2669
|
}
|
|
2255
2670
|
}, [simulationSvg]);
|
|
2256
|
-
const containerBackgroundColor =
|
|
2671
|
+
const containerBackgroundColor = useMemo6(() => {
|
|
2257
2672
|
return getAnalogSimulationBackgroundColor(simulationSvg, colorOverrides);
|
|
2258
2673
|
}, [simulationSvg, colorOverrides]);
|
|
2259
2674
|
const handleMouseDown = (_e) => {
|
|
@@ -2277,7 +2692,7 @@ var AnalogSimulationViewer = ({
|
|
|
2277
2692
|
};
|
|
2278
2693
|
}, []);
|
|
2279
2694
|
if (isLoading) {
|
|
2280
|
-
return /* @__PURE__ */
|
|
2695
|
+
return /* @__PURE__ */ jsx9(
|
|
2281
2696
|
"div",
|
|
2282
2697
|
{
|
|
2283
2698
|
style: {
|
|
@@ -2297,7 +2712,7 @@ var AnalogSimulationViewer = ({
|
|
|
2297
2712
|
);
|
|
2298
2713
|
}
|
|
2299
2714
|
if (error) {
|
|
2300
|
-
return /* @__PURE__ */
|
|
2715
|
+
return /* @__PURE__ */ jsx9(
|
|
2301
2716
|
"div",
|
|
2302
2717
|
{
|
|
2303
2718
|
style: {
|
|
@@ -2312,15 +2727,15 @@ var AnalogSimulationViewer = ({
|
|
|
2312
2727
|
...containerStyle
|
|
2313
2728
|
},
|
|
2314
2729
|
className,
|
|
2315
|
-
children: /* @__PURE__ */
|
|
2316
|
-
/* @__PURE__ */
|
|
2317
|
-
/* @__PURE__ */
|
|
2730
|
+
children: /* @__PURE__ */ jsxs7("div", { style: { textAlign: "center", padding: "20px" }, children: [
|
|
2731
|
+
/* @__PURE__ */ jsx9("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
|
|
2732
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: "14px" }, children: error })
|
|
2318
2733
|
] })
|
|
2319
2734
|
}
|
|
2320
2735
|
);
|
|
2321
2736
|
}
|
|
2322
2737
|
if (!simulationSvg) {
|
|
2323
|
-
return /* @__PURE__ */
|
|
2738
|
+
return /* @__PURE__ */ jsxs7(
|
|
2324
2739
|
"div",
|
|
2325
2740
|
{
|
|
2326
2741
|
style: {
|
|
@@ -2336,11 +2751,11 @@ var AnalogSimulationViewer = ({
|
|
|
2336
2751
|
},
|
|
2337
2752
|
className,
|
|
2338
2753
|
children: [
|
|
2339
|
-
/* @__PURE__ */
|
|
2340
|
-
/* @__PURE__ */
|
|
2754
|
+
/* @__PURE__ */ jsx9("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
|
|
2755
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
|
|
2341
2756
|
"Use",
|
|
2342
2757
|
" ",
|
|
2343
|
-
/* @__PURE__ */
|
|
2758
|
+
/* @__PURE__ */ jsx9(
|
|
2344
2759
|
"code",
|
|
2345
2760
|
{
|
|
2346
2761
|
style: {
|
|
@@ -2360,7 +2775,7 @@ var AnalogSimulationViewer = ({
|
|
|
2360
2775
|
}
|
|
2361
2776
|
);
|
|
2362
2777
|
}
|
|
2363
|
-
return /* @__PURE__ */
|
|
2778
|
+
return /* @__PURE__ */ jsxs7(
|
|
2364
2779
|
"div",
|
|
2365
2780
|
{
|
|
2366
2781
|
ref: (node) => {
|
|
@@ -2379,7 +2794,7 @@ var AnalogSimulationViewer = ({
|
|
|
2379
2794
|
onMouseDown: handleMouseDown,
|
|
2380
2795
|
onTouchStart: handleTouchStart,
|
|
2381
2796
|
children: [
|
|
2382
|
-
/* @__PURE__ */
|
|
2797
|
+
/* @__PURE__ */ jsx9(
|
|
2383
2798
|
AnalogSimulationSelector,
|
|
2384
2799
|
{
|
|
2385
2800
|
simulations: simulationExperiments,
|
|
@@ -2387,7 +2802,7 @@ var AnalogSimulationViewer = ({
|
|
|
2387
2802
|
onSelectSimulation: handleSelectSimulation
|
|
2388
2803
|
}
|
|
2389
2804
|
),
|
|
2390
|
-
svgObjectUrl ? /* @__PURE__ */
|
|
2805
|
+
svgObjectUrl ? /* @__PURE__ */ jsx9(
|
|
2391
2806
|
"img",
|
|
2392
2807
|
{
|
|
2393
2808
|
ref: imgRef,
|
|
@@ -2401,7 +2816,7 @@ var AnalogSimulationViewer = ({
|
|
|
2401
2816
|
objectFit: "contain"
|
|
2402
2817
|
}
|
|
2403
2818
|
}
|
|
2404
|
-
) : /* @__PURE__ */
|
|
2819
|
+
) : /* @__PURE__ */ jsx9(
|
|
2405
2820
|
"div",
|
|
2406
2821
|
{
|
|
2407
2822
|
style: {
|