@tscircuit/pcb-viewer 1.11.401 → 1.11.403
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 +119 -75
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -4258,6 +4258,52 @@ var animateTransform = ({
|
|
|
4258
4258
|
import { useCallback as useCallback11, useEffect as useEffect19, useMemo as useMemo10, useRef as useRef16, useState as useState13 } from "react";
|
|
4259
4259
|
import { applyToPoint as applyToPoint19, inverse as inverse6 } from "transformation-matrix";
|
|
4260
4260
|
|
|
4261
|
+
// src/lib/get-trace-overlay-text.ts
|
|
4262
|
+
var getNonEmptyName = (name) => name?.trim() || null;
|
|
4263
|
+
function getAssociatedTraceName({
|
|
4264
|
+
primitiveElement,
|
|
4265
|
+
elements
|
|
4266
|
+
}) {
|
|
4267
|
+
const sourceElementId = primitiveElement.source_trace_id;
|
|
4268
|
+
if (!sourceElementId) return null;
|
|
4269
|
+
const circuitJson = su(elements);
|
|
4270
|
+
const sourceTrace = circuitJson.source_trace.get(sourceElementId);
|
|
4271
|
+
const sourceTraceName = getNonEmptyName(sourceTrace?.name);
|
|
4272
|
+
if (sourceTraceName) return sourceTraceName;
|
|
4273
|
+
const sourceNet = circuitJson.source_net.get(sourceElementId);
|
|
4274
|
+
const sourceNetName = getNonEmptyName(sourceNet?.name);
|
|
4275
|
+
if (sourceNetName) return sourceNetName;
|
|
4276
|
+
for (const sourceNetId of sourceTrace?.connected_source_net_ids ?? []) {
|
|
4277
|
+
const connectedSourceNetName = getNonEmptyName(
|
|
4278
|
+
circuitJson.source_net.get(sourceNetId)?.name
|
|
4279
|
+
);
|
|
4280
|
+
if (connectedSourceNetName) return connectedSourceNetName;
|
|
4281
|
+
}
|
|
4282
|
+
return null;
|
|
4283
|
+
}
|
|
4284
|
+
function getTraceOverlayInfo({
|
|
4285
|
+
primitiveElement,
|
|
4286
|
+
elements
|
|
4287
|
+
}) {
|
|
4288
|
+
const trace = su(elements).source_trace.get(
|
|
4289
|
+
primitiveElement?.source_trace_id
|
|
4290
|
+
);
|
|
4291
|
+
const traceLength = primitiveElement.trace_length;
|
|
4292
|
+
const hasTraceLength = typeof traceLength === "number";
|
|
4293
|
+
const maxLength = trace?.max_length;
|
|
4294
|
+
const text = hasTraceLength ? `${traceLength.toFixed(3)}${typeof maxLength === "number" ? ` / ${maxLength}` : ""} mm` : "";
|
|
4295
|
+
const name = getAssociatedTraceName({ primitiveElement, elements }) ?? getNonEmptyName(trace?.display_name);
|
|
4296
|
+
if (!text && !name) return null;
|
|
4297
|
+
const isOverLength = Boolean(
|
|
4298
|
+
hasTraceLength && typeof maxLength === "number" && traceLength > maxLength
|
|
4299
|
+
);
|
|
4300
|
+
return {
|
|
4301
|
+
text,
|
|
4302
|
+
name,
|
|
4303
|
+
isOverLength
|
|
4304
|
+
};
|
|
4305
|
+
}
|
|
4306
|
+
|
|
4261
4307
|
// src/lib/x-ray-net.ts
|
|
4262
4308
|
function getElementNetId(element, connectivityMap) {
|
|
4263
4309
|
if (!element) return;
|
|
@@ -4282,6 +4328,32 @@ function isXRayCopper(element) {
|
|
|
4282
4328
|
element.type
|
|
4283
4329
|
);
|
|
4284
4330
|
}
|
|
4331
|
+
function getXRayDisplayName(element, elements, connectivityMap) {
|
|
4332
|
+
const directName = element.type === "pcb_trace" ? getAssociatedTraceName({ primitiveElement: element, elements }) : null;
|
|
4333
|
+
if (directName) return directName;
|
|
4334
|
+
const netId = getElementNetId(element, connectivityMap);
|
|
4335
|
+
const connected = netId ? elements.filter(
|
|
4336
|
+
(candidate) => getElementNetId(candidate, connectivityMap) === netId
|
|
4337
|
+
) : [];
|
|
4338
|
+
for (const type of ["source_net", "source_trace"]) {
|
|
4339
|
+
for (const candidate of connected) {
|
|
4340
|
+
if (candidate.type === type && "name" in candidate && typeof candidate.name === "string" && candidate.name.trim())
|
|
4341
|
+
return candidate.name.trim();
|
|
4342
|
+
}
|
|
4343
|
+
}
|
|
4344
|
+
if (element.type === "pcb_trace") {
|
|
4345
|
+
const label = getTraceOverlayInfo({
|
|
4346
|
+
primitiveElement: element,
|
|
4347
|
+
elements
|
|
4348
|
+
})?.name;
|
|
4349
|
+
if (label) return label;
|
|
4350
|
+
}
|
|
4351
|
+
for (const candidate of connected) {
|
|
4352
|
+
if (candidate.type === "source_trace" && candidate.display_name?.trim())
|
|
4353
|
+
return candidate.display_name.trim();
|
|
4354
|
+
}
|
|
4355
|
+
return "Net";
|
|
4356
|
+
}
|
|
4285
4357
|
|
|
4286
4358
|
// src/lib/webgpu/create-worker.ts
|
|
4287
4359
|
var createWebGpuWorker = async () => {
|
|
@@ -10073,52 +10145,6 @@ var PanelAnchorOffsetOverlay = ({
|
|
|
10073
10145
|
);
|
|
10074
10146
|
};
|
|
10075
10147
|
|
|
10076
|
-
// src/lib/get-trace-overlay-text.ts
|
|
10077
|
-
var getNonEmptyName = (name) => name?.trim() || null;
|
|
10078
|
-
function getAssociatedTraceName({
|
|
10079
|
-
primitiveElement,
|
|
10080
|
-
elements
|
|
10081
|
-
}) {
|
|
10082
|
-
const sourceElementId = primitiveElement.source_trace_id;
|
|
10083
|
-
if (!sourceElementId) return null;
|
|
10084
|
-
const circuitJson = su(elements);
|
|
10085
|
-
const sourceTrace = circuitJson.source_trace.get(sourceElementId);
|
|
10086
|
-
const sourceTraceName = getNonEmptyName(sourceTrace?.name);
|
|
10087
|
-
if (sourceTraceName) return sourceTraceName;
|
|
10088
|
-
const sourceNet = circuitJson.source_net.get(sourceElementId);
|
|
10089
|
-
const sourceNetName = getNonEmptyName(sourceNet?.name);
|
|
10090
|
-
if (sourceNetName) return sourceNetName;
|
|
10091
|
-
for (const sourceNetId of sourceTrace?.connected_source_net_ids ?? []) {
|
|
10092
|
-
const connectedSourceNetName = getNonEmptyName(
|
|
10093
|
-
circuitJson.source_net.get(sourceNetId)?.name
|
|
10094
|
-
);
|
|
10095
|
-
if (connectedSourceNetName) return connectedSourceNetName;
|
|
10096
|
-
}
|
|
10097
|
-
return null;
|
|
10098
|
-
}
|
|
10099
|
-
function getTraceOverlayInfo({
|
|
10100
|
-
primitiveElement,
|
|
10101
|
-
elements
|
|
10102
|
-
}) {
|
|
10103
|
-
const trace = su(elements).source_trace.get(
|
|
10104
|
-
primitiveElement?.source_trace_id
|
|
10105
|
-
);
|
|
10106
|
-
const traceLength = primitiveElement.trace_length;
|
|
10107
|
-
const hasTraceLength = typeof traceLength === "number";
|
|
10108
|
-
const maxLength = trace?.max_length;
|
|
10109
|
-
const text = hasTraceLength ? `${traceLength.toFixed(3)}${typeof maxLength === "number" ? ` / ${maxLength}` : ""} mm` : "";
|
|
10110
|
-
const name = getAssociatedTraceName({ primitiveElement, elements }) ?? getNonEmptyName(trace?.display_name);
|
|
10111
|
-
if (!text && !name) return null;
|
|
10112
|
-
const isOverLength = Boolean(
|
|
10113
|
-
hasTraceLength && typeof maxLength === "number" && traceLength > maxLength
|
|
10114
|
-
);
|
|
10115
|
-
return {
|
|
10116
|
-
text,
|
|
10117
|
-
name,
|
|
10118
|
-
isOverLength
|
|
10119
|
-
};
|
|
10120
|
-
}
|
|
10121
|
-
|
|
10122
10148
|
// src/lib/filter-traces-if-multiple.ts
|
|
10123
10149
|
function filterTracesIfMultiple(filterTraces) {
|
|
10124
10150
|
const { primitives, is_showing_multiple_traces_length, elements } = filterTraces;
|
|
@@ -11047,7 +11073,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
11047
11073
|
// package.json
|
|
11048
11074
|
var package_default = {
|
|
11049
11075
|
name: "@tscircuit/pcb-viewer",
|
|
11050
|
-
version: "1.11.
|
|
11076
|
+
version: "1.11.402",
|
|
11051
11077
|
main: "dist/index.js",
|
|
11052
11078
|
type: "module",
|
|
11053
11079
|
repository: {
|
|
@@ -11244,6 +11270,7 @@ var VisibilityContextMenu = ({
|
|
|
11244
11270
|
position,
|
|
11245
11271
|
onClose,
|
|
11246
11272
|
onXRayNet,
|
|
11273
|
+
xRayDisplayName = "Net",
|
|
11247
11274
|
onExitXRayNet
|
|
11248
11275
|
}) => {
|
|
11249
11276
|
const engine = useRenderingEngine();
|
|
@@ -11348,17 +11375,21 @@ var VisibilityContextMenu = ({
|
|
|
11348
11375
|
...stacked ? { overflowY: "auto" } : {}
|
|
11349
11376
|
},
|
|
11350
11377
|
children: [
|
|
11351
|
-
onXRayNet && /* @__PURE__ */
|
|
11378
|
+
onXRayNet && /* @__PURE__ */ jsxs15(
|
|
11352
11379
|
"button",
|
|
11353
11380
|
{
|
|
11354
11381
|
type: "button",
|
|
11355
11382
|
role: "menuitem",
|
|
11356
11383
|
className: itemStyle,
|
|
11384
|
+
style: { whiteSpace: "normal", overflowWrap: "anywhere" },
|
|
11357
11385
|
onClick: () => {
|
|
11358
11386
|
onXRayNet();
|
|
11359
11387
|
onClose();
|
|
11360
11388
|
},
|
|
11361
|
-
children:
|
|
11389
|
+
children: [
|
|
11390
|
+
"X-Ray ",
|
|
11391
|
+
xRayDisplayName
|
|
11392
|
+
]
|
|
11362
11393
|
}
|
|
11363
11394
|
),
|
|
11364
11395
|
onExitXRayNet && /* @__PURE__ */ jsx20(
|
|
@@ -12132,8 +12163,8 @@ var ToolbarOverlay = ({
|
|
|
12132
12163
|
elements,
|
|
12133
12164
|
onContextMenuOpenChange,
|
|
12134
12165
|
getNetAtPoint,
|
|
12135
|
-
|
|
12136
|
-
|
|
12166
|
+
xRayNetIds = [],
|
|
12167
|
+
onXRayNetsChange
|
|
12137
12168
|
}) => {
|
|
12138
12169
|
const isSmallScreen = useIsSmallScreen();
|
|
12139
12170
|
const {
|
|
@@ -12198,6 +12229,7 @@ var ToolbarOverlay = ({
|
|
|
12198
12229
|
}));
|
|
12199
12230
|
const [contextMenuPosition, setContextMenuPosition] = useState12(null);
|
|
12200
12231
|
const [contextNetId, setContextNetId] = useState12();
|
|
12232
|
+
const [contextNetDisplayName, setContextNetDisplayName] = useState12("Net");
|
|
12201
12233
|
const pointerStart = useRef14(null);
|
|
12202
12234
|
const inEditMode = useGlobalStore((s) => s.in_edit_mode);
|
|
12203
12235
|
const netAtEvent = (event) => {
|
|
@@ -12357,25 +12389,29 @@ var ToolbarOverlay = ({
|
|
|
12357
12389
|
const start = pointerStart.current;
|
|
12358
12390
|
if (!start || Math.hypot(event.clientX - start.x, event.clientY - start.y) > 4)
|
|
12359
12391
|
return;
|
|
12360
|
-
const
|
|
12361
|
-
if (!
|
|
12362
|
-
|
|
12363
|
-
|
|
12392
|
+
const hit = netAtEvent(event);
|
|
12393
|
+
if (!hit) return;
|
|
12394
|
+
const net = hit.netId;
|
|
12395
|
+
if (xRayNetIds.includes(net)) {
|
|
12396
|
+
onXRayNetsChange?.(xRayNetIds.filter((id) => id !== net));
|
|
12364
12397
|
closeContextMenu();
|
|
12365
12398
|
} else {
|
|
12366
12399
|
setContextNetId(net);
|
|
12400
|
+
setContextNetDisplayName(hit.displayName);
|
|
12367
12401
|
onContextMenuOpenChange?.(true);
|
|
12368
12402
|
setContextMenuPosition({ x: event.clientX, y: event.clientY });
|
|
12369
12403
|
}
|
|
12370
12404
|
},
|
|
12371
12405
|
onDoubleClick: () => {
|
|
12372
|
-
|
|
12406
|
+
onXRayNetsChange?.([]);
|
|
12373
12407
|
closeContextMenu();
|
|
12374
12408
|
},
|
|
12375
12409
|
onContextMenu: (event) => {
|
|
12376
12410
|
event.preventDefault();
|
|
12377
12411
|
event.stopPropagation();
|
|
12378
|
-
|
|
12412
|
+
const hit = netAtEvent(event);
|
|
12413
|
+
setContextNetId(hit?.netId);
|
|
12414
|
+
setContextNetDisplayName(hit?.displayName ?? "Net");
|
|
12379
12415
|
onContextMenuOpenChange?.(true);
|
|
12380
12416
|
setContextMenuPosition({ x: event.clientX, y: event.clientY });
|
|
12381
12417
|
},
|
|
@@ -12390,8 +12426,9 @@ var ToolbarOverlay = ({
|
|
|
12390
12426
|
{
|
|
12391
12427
|
position: contextMenuPosition,
|
|
12392
12428
|
onClose: closeContextMenu,
|
|
12393
|
-
|
|
12394
|
-
|
|
12429
|
+
xRayDisplayName: contextNetDisplayName,
|
|
12430
|
+
onXRayNet: contextNetId && !xRayNetIds.includes(contextNetId) ? () => onXRayNetsChange?.([...xRayNetIds, contextNetId]) : void 0,
|
|
12431
|
+
onExitXRayNet: xRayNetIds.length > 0 ? () => onXRayNetsChange?.([]) : void 0
|
|
12395
12432
|
}
|
|
12396
12433
|
),
|
|
12397
12434
|
/* @__PURE__ */ jsxs17(
|
|
@@ -12866,36 +12903,43 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12866
12903
|
() => getFullConnectivityMapFromCircuitJson(elements),
|
|
12867
12904
|
[elements]
|
|
12868
12905
|
);
|
|
12869
|
-
const [
|
|
12870
|
-
useEffect19(() =>
|
|
12906
|
+
const [xRayNetIds, setXRayNetIds] = useState13([]);
|
|
12907
|
+
useEffect19(() => setXRayNetIds([]), [connectivityMap]);
|
|
12871
12908
|
const xRayElements = useMemo10(
|
|
12872
|
-
() =>
|
|
12873
|
-
(element) => isXRayCopper(element) &&
|
|
12909
|
+
() => xRayNetIds.length > 0 ? elementsToRender.filter(
|
|
12910
|
+
(element) => isXRayCopper(element) && xRayNetIds.includes(
|
|
12911
|
+
getElementNetId(element, connectivityMap) ?? ""
|
|
12912
|
+
)
|
|
12874
12913
|
) : void 0,
|
|
12875
|
-
[elementsToRender, connectivityMap,
|
|
12914
|
+
[elementsToRender, connectivityMap, xRayNetIds]
|
|
12876
12915
|
);
|
|
12877
12916
|
const getNetAtPoint = (point) => {
|
|
12878
12917
|
if (!transform) return void 0;
|
|
12918
|
+
const describeNet = (netId, element) => ({
|
|
12919
|
+
netId,
|
|
12920
|
+
displayName: getXRayDisplayName(element, elements, connectivityMap)
|
|
12921
|
+
});
|
|
12879
12922
|
const hits = getPrimitivesUnderPoint(
|
|
12880
12923
|
primitivesWithoutInteractionMetadata,
|
|
12881
12924
|
applyToPoint19(inverse6(transform), point),
|
|
12882
12925
|
transform,
|
|
12883
12926
|
selectedLayer,
|
|
12884
|
-
|
|
12927
|
+
xRayNetIds.length > 0
|
|
12885
12928
|
);
|
|
12886
12929
|
const copper = hits.filter(
|
|
12887
12930
|
(p) => isXRayCopper(p._element) && p.layer !== "drill"
|
|
12888
12931
|
);
|
|
12889
|
-
if (xRayNetId && copper.some(
|
|
12890
|
-
(p) => getElementNetId(p._element, connectivityMap) === xRayNetId
|
|
12891
|
-
))
|
|
12892
|
-
return xRayNetId;
|
|
12893
12932
|
copper.sort(
|
|
12894
12933
|
(a, b) => Number(b.layer === selectedLayer) - Number(a.layer === selectedLayer)
|
|
12895
12934
|
);
|
|
12896
12935
|
for (const primitive of copper) {
|
|
12897
12936
|
const net = getElementNetId(primitive._element, connectivityMap);
|
|
12898
|
-
if (net
|
|
12937
|
+
if (net && xRayNetIds.includes(net))
|
|
12938
|
+
return describeNet(net, primitive._element);
|
|
12939
|
+
}
|
|
12940
|
+
for (const primitive of copper) {
|
|
12941
|
+
const net = getElementNetId(primitive._element, connectivityMap);
|
|
12942
|
+
if (net) return describeNet(net, primitive._element);
|
|
12899
12943
|
}
|
|
12900
12944
|
};
|
|
12901
12945
|
const [hoverState, setHoverState] = useState13({
|
|
@@ -12969,7 +13013,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12969
13013
|
props.width
|
|
12970
13014
|
]);
|
|
12971
13015
|
const primitives = useMemo10(() => {
|
|
12972
|
-
if (
|
|
13016
|
+
if (xRayNetIds.length > 0) return primitivesWithoutInteractionMetadata;
|
|
12973
13017
|
const combinedPrimitiveIds = [
|
|
12974
13018
|
...hoverState.primitiveIdsInMousedOverNet,
|
|
12975
13019
|
...errorRelatedIds
|
|
@@ -12983,7 +13027,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
12983
13027
|
primitivesWithoutInteractionMetadata,
|
|
12984
13028
|
hoverState,
|
|
12985
13029
|
errorRelatedIds,
|
|
12986
|
-
|
|
13030
|
+
xRayNetIds
|
|
12987
13031
|
]);
|
|
12988
13032
|
const onMouseOverPrimitives = useCallback11(
|
|
12989
13033
|
(primitivesHoveredOver) => {
|
|
@@ -13025,7 +13069,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
13025
13069
|
transform,
|
|
13026
13070
|
primitives: primitivesWithoutInteractionMetadata,
|
|
13027
13071
|
selectedLayer,
|
|
13028
|
-
disableHoverHighlights:
|
|
13072
|
+
disableHoverHighlights: xRayNetIds.length > 0,
|
|
13029
13073
|
onMouseHoverOverPrimitives: onMouseOverPrimitives,
|
|
13030
13074
|
children: /* @__PURE__ */ jsx25(
|
|
13031
13075
|
EditPlacementOverlay,
|
|
@@ -13049,8 +13093,8 @@ var CanvasElementsRenderer = (props) => {
|
|
|
13049
13093
|
{
|
|
13050
13094
|
elements,
|
|
13051
13095
|
getNetAtPoint,
|
|
13052
|
-
|
|
13053
|
-
|
|
13096
|
+
xRayNetIds,
|
|
13097
|
+
onXRayNetsChange: setXRayNetIds,
|
|
13054
13098
|
onContextMenuOpenChange: props.onContextMenuOpenChange,
|
|
13055
13099
|
children: /* @__PURE__ */ jsx25(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx25(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx25(
|
|
13056
13100
|
PcbGroupOverlay,
|