@tscircuit/pcb-viewer 1.10.25 → 1.10.26

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 CHANGED
@@ -1042,6 +1042,9 @@ __export(dist_exports, {
1042
1042
  source_simple_inductor: function() {
1043
1043
  return source_simple_inductor;
1044
1044
  },
1045
+ source_simple_mosfet: function() {
1046
+ return source_simple_mosfet;
1047
+ },
1045
1048
  source_simple_pin_header: function() {
1046
1049
  return source_simple_pin_header;
1047
1050
  },
@@ -1060,6 +1063,9 @@ __export(dist_exports, {
1060
1063
  source_simple_resonator: function() {
1061
1064
  return source_simple_resonator;
1062
1065
  },
1066
+ source_simple_transistor: function() {
1067
+ return source_simple_transistor;
1068
+ },
1063
1069
  source_trace: function() {
1064
1070
  return source_trace;
1065
1071
  },
@@ -7621,12 +7627,15 @@ var source_component_base = z.object({
7621
7627
  expectTypesMatch(true);
7622
7628
  var source_simple_capacitor = source_component_base.extend({
7623
7629
  ftype: z.literal("simple_capacitor"),
7624
- capacitance: capacitance
7630
+ capacitance: capacitance,
7631
+ display_capacitance: z.string().optional(),
7632
+ max_decoupling_trace_length: distance.optional()
7625
7633
  });
7626
7634
  expectTypesMatch(true);
7627
7635
  var source_simple_resistor = source_component_base.extend({
7628
7636
  ftype: z.literal("simple_resistor"),
7629
- resistance: resistance
7637
+ resistance: resistance,
7638
+ display_resistance: z.string().optional()
7630
7639
  });
7631
7640
  expectTypesMatch(true);
7632
7641
  var source_simple_diode = source_component_base.extend({
@@ -7692,6 +7701,26 @@ var source_simple_resonator = source_component_base.extend({
7692
7701
  frequency: frequency
7693
7702
  });
7694
7703
  expectTypesMatch(true);
7704
+ var source_simple_transistor = source_component_base.extend({
7705
+ ftype: z.literal("simple_transistor"),
7706
+ transistor_type: z.enum([
7707
+ "npn",
7708
+ "pnp"
7709
+ ])
7710
+ });
7711
+ expectTypesMatch(true);
7712
+ var source_simple_mosfet = source_component_base.extend({
7713
+ ftype: z.literal("simple_mosfet"),
7714
+ channel_type: z.enum([
7715
+ "n",
7716
+ "p"
7717
+ ]),
7718
+ mosfet_mode: z.enum([
7719
+ "enhancement",
7720
+ "depletion"
7721
+ ])
7722
+ });
7723
+ expectTypesMatch(true);
7695
7724
  var any_source_component = z.union([
7696
7725
  source_simple_resistor,
7697
7726
  source_simple_capacitor,
@@ -7707,7 +7736,9 @@ var any_source_component = z.union([
7707
7736
  source_simple_potentiometer,
7708
7737
  source_simple_crystal,
7709
7738
  source_simple_pin_header,
7710
- source_simple_resonator
7739
+ source_simple_resonator,
7740
+ source_simple_transistor,
7741
+ source_simple_mosfet
7711
7742
  ]);
7712
7743
  var source_port = z.object({
7713
7744
  type: z.literal("source_port"),
@@ -7723,7 +7754,9 @@ var source_trace = z.object({
7723
7754
  source_trace_id: z.string(),
7724
7755
  connected_source_port_ids: z.array(z.string()),
7725
7756
  connected_source_net_ids: z.array(z.string()),
7726
- subcircuit_connectivity_map_key: z.string().optional()
7757
+ subcircuit_connectivity_map_key: z.string().optional(),
7758
+ max_length: z.number().optional(),
7759
+ display_name: z.string().optional()
7727
7760
  });
7728
7761
  expectTypesMatch(true);
7729
7762
  var source_group = z.object({
@@ -7778,6 +7811,7 @@ expectTypesMatch(true);
7778
7811
  var schematic_component_port_arrangement_by_sides = z.object({
7779
7812
  left_side: z.object({
7780
7813
  pins: z.array(z.number()),
7814
+ // @ts-ignore
7781
7815
  direction: z.enum([
7782
7816
  "top-to-bottom",
7783
7817
  "bottom-to-top"
@@ -7785,6 +7819,7 @@ var schematic_component_port_arrangement_by_sides = z.object({
7785
7819
  }).optional(),
7786
7820
  right_side: z.object({
7787
7821
  pins: z.array(z.number()),
7822
+ // @ts-ignore
7788
7823
  direction: z.enum([
7789
7824
  "top-to-bottom",
7790
7825
  "bottom-to-top"
@@ -7792,6 +7827,7 @@ var schematic_component_port_arrangement_by_sides = z.object({
7792
7827
  }).optional(),
7793
7828
  top_side: z.object({
7794
7829
  pins: z.array(z.number()),
7830
+ // @ts-ignore
7795
7831
  direction: z.enum([
7796
7832
  "left-to-right",
7797
7833
  "right-to-left"
@@ -7799,6 +7835,7 @@ var schematic_component_port_arrangement_by_sides = z.object({
7799
7835
  }).optional(),
7800
7836
  bottom_side: z.object({
7801
7837
  pins: z.array(z.number()),
7838
+ // @ts-ignore
7802
7839
  direction: z.enum([
7803
7840
  "left-to-right",
7804
7841
  "right-to-left"
@@ -8060,12 +8097,30 @@ var pcb_plated_hole_oval = z.object({
8060
8097
  pcb_port_id: z.string().optional(),
8061
8098
  pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
8062
8099
  });
8100
+ var pcb_circular_hole_with_rect_pad = z.object({
8101
+ type: z.literal("pcb_plated_hole"),
8102
+ shape: z.literal("circular_hole_with_rect_pad"),
8103
+ hole_shape: z.literal("circle"),
8104
+ pad_shape: z.literal("rect"),
8105
+ hole_diameter: z.number(),
8106
+ rect_pad_width: z.number(),
8107
+ rect_pad_height: z.number(),
8108
+ x: distance,
8109
+ y: distance,
8110
+ layers: z.array(layer_ref),
8111
+ port_hints: z.array(z.string()).optional(),
8112
+ pcb_component_id: z.string().optional(),
8113
+ pcb_port_id: z.string().optional(),
8114
+ pcb_plated_hole_id: getZodPrefixedIdWithDefault("pcb_plated_hole")
8115
+ });
8063
8116
  var pcb_plated_hole = z.union([
8064
8117
  pcb_plated_hole_circle,
8065
- pcb_plated_hole_oval
8118
+ pcb_plated_hole_oval,
8119
+ pcb_circular_hole_with_rect_pad
8066
8120
  ]);
8067
8121
  expectTypesMatch(true);
8068
8122
  expectTypesMatch(true);
8123
+ expectTypesMatch(true);
8069
8124
  var pcb_port = z.object({
8070
8125
  type: z.literal("pcb_port"),
8071
8126
  pcb_port_id: getZodPrefixedIdWithDefault("pcb_port"),
@@ -8161,6 +8216,7 @@ var pcb_text = z.object({
8161
8216
  width: length,
8162
8217
  height: length,
8163
8218
  lines: z.number(),
8219
+ // @ts-ignore
8164
8220
  align: z.enum([
8165
8221
  "bottom-left"
8166
8222
  ])
@@ -8197,6 +8253,7 @@ var pcb_trace = z.object({
8197
8253
  ]).default("constant").optional(),
8198
8254
  route_order_index: z.number().optional(),
8199
8255
  should_round_corners: z.boolean().optional(),
8256
+ trace_length: z.number().optional(),
8200
8257
  route: z.array(z.union([
8201
8258
  z.object({
8202
8259
  route_type: z.literal("wire"),
@@ -8460,6 +8517,8 @@ var any_circuit_element = z.union([
8460
8517
  source_simple_inductor,
8461
8518
  source_simple_pin_header,
8462
8519
  source_simple_resonator,
8520
+ source_simple_transistor,
8521
+ source_simple_mosfet,
8463
8522
  source_simple_potentiometer,
8464
8523
  source_simple_push_button,
8465
8524
  pcb_component,
@@ -11368,6 +11427,50 @@ var import_react10 = require("react");
11368
11427
  var import_transformation_matrix5 = require("transformation-matrix");
11369
11428
  // src/components/ElementOverlayBox.tsx
11370
11429
  var import_react8 = require("react");
11430
+ // src/lib/get-trace-overlay-text.ts
11431
+ function getTraceOverlayInfo(param) {
11432
+ var primitiveElement = param.primitiveElement, elements = param.elements;
11433
+ var text = primitiveElement.trace_length ? "".concat(primitiveElement.trace_length.toFixed(3)) : "";
11434
+ var trace = su_default(elements).source_trace.get(primitiveElement === null || primitiveElement === void 0 ? void 0 : primitiveElement.source_trace_id);
11435
+ if (trace === null || trace === void 0 ? void 0 : trace.display_name) {
11436
+ if (trace === null || trace === void 0 ? void 0 : trace.max_length) {
11437
+ text += " / ".concat(trace.max_length, "mm ");
11438
+ } else {
11439
+ text += " mm ";
11440
+ }
11441
+ text += "(".concat(trace.display_name, ")");
11442
+ }
11443
+ if (!text) return null;
11444
+ var isOverLength = primitiveElement.trace_length && (trace === null || trace === void 0 ? void 0 : trace.max_length) && primitiveElement.trace_length > trace.max_length;
11445
+ return {
11446
+ text: text,
11447
+ isOverLength: isOverLength
11448
+ };
11449
+ }
11450
+ // src/lib/filter-traces-if-multiple.ts
11451
+ function filterTracesIfMultiple(primitives) {
11452
+ var DISPLAY_ALL_TRACE_LENGTHS = false;
11453
+ var traces = primitives.filter(function(p) {
11454
+ return p._element.type === "pcb_trace";
11455
+ });
11456
+ if (traces.length > 1) {
11457
+ if (!DISPLAY_ALL_TRACE_LENGTHS) return primitives.filter(function(p) {
11458
+ return p._element.type !== "pcb_trace";
11459
+ });
11460
+ var shortestTrace = traces.reduce(function(shortest, current2) {
11461
+ var shortestLength = shortest._element.trace_length;
11462
+ var currentLength = current2._element.trace_length;
11463
+ return currentLength < shortestLength ? current2 : shortest;
11464
+ }, traces[0]);
11465
+ return primitives.filter(function(p) {
11466
+ return p._element.type !== "pcb_trace";
11467
+ }).concat([
11468
+ shortestTrace
11469
+ ]);
11470
+ }
11471
+ return primitives;
11472
+ }
11473
+ // src/components/ElementOverlayBox.tsx
11371
11474
  var import_jsx_runtime4 = require("react/jsx-runtime");
11372
11475
  var containerStyle = {
11373
11476
  position: "absolute",
@@ -11382,6 +11485,13 @@ var containerStyle = {
11382
11485
  var getTextForHighlightedPrimitive = function(prim) {
11383
11486
  var element = prim._element, _parent_pcb_component = prim._parent_pcb_component, _parent_source_component = prim._parent_source_component, _source_port = prim._source_port;
11384
11487
  switch(element.type){
11488
+ case "pcb_trace":
11489
+ {
11490
+ if (element.trace_length) {
11491
+ return "".concat(element.trace_length.toFixed(3));
11492
+ }
11493
+ return "";
11494
+ }
11385
11495
  case "pcb_smtpad":
11386
11496
  case "pcb_plated_hole":
11387
11497
  {
@@ -11409,7 +11519,7 @@ var layerColorHightlightMap = {
11409
11519
  bottom: "aqua"
11410
11520
  };
11411
11521
  var HighlightedPrimitiveBoxWithText = function(param) {
11412
- var primitive = param.primitive;
11522
+ var primitive = param.primitive, mousePos = param.mousePos, elements = param.elements;
11413
11523
  var _primitive__element;
11414
11524
  var _ref = _sliced_to_array((0, import_react8.useState)(false), 2), finalState = _ref[0], setFinalState = _ref[1];
11415
11525
  var primitiveElement = primitive._element;
@@ -11433,6 +11543,42 @@ var HighlightedPrimitiveBoxWithText = function(param) {
11433
11543
  if (primitiveElement.type === "pcb_smtpad" && (primitiveElement === null || primitiveElement === void 0 ? void 0 : primitiveElement.shape) === "rotated_rect") {
11434
11544
  rotation2 = primitiveElement === null || primitiveElement === void 0 ? void 0 : primitiveElement.ccw_rotation;
11435
11545
  }
11546
+ if (primitiveElement.type === "pcb_trace") {
11547
+ var traceTextContext = {
11548
+ primitiveElement: primitiveElement,
11549
+ elements: elements
11550
+ };
11551
+ var overlayInfo = getTraceOverlayInfo(traceTextContext);
11552
+ if (!overlayInfo) return null;
11553
+ var yOffset = mousePos.y - 35;
11554
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
11555
+ style: {
11556
+ zIndex: zIndexMap.elementOverlay,
11557
+ position: "absolute",
11558
+ left: mousePos.x,
11559
+ top: yOffset,
11560
+ color: color2,
11561
+ pointerEvents: "none",
11562
+ transform: "translateX(-50%)"
11563
+ },
11564
+ children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
11565
+ style: {
11566
+ backgroundColor: "#f2efcc",
11567
+ color: overlayInfo.isOverLength ? "red" : "black",
11568
+ textShadow: "none",
11569
+ WebkitFontSmoothing: "antialiased",
11570
+ MozOsxFontSmoothing: "grayscale",
11571
+ padding: "6px 6px",
11572
+ borderRadius: "6px",
11573
+ fontSize: "14px",
11574
+ minWidth: "45px",
11575
+ textAlign: "center",
11576
+ whiteSpace: "nowrap"
11577
+ },
11578
+ children: overlayInfo.text
11579
+ })
11580
+ });
11581
+ }
11436
11582
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
11437
11583
  style: {
11438
11584
  zIndex: zIndexMap.elementOverlay,
@@ -11484,15 +11630,29 @@ var HighlightedPrimitiveBoxWithText = function(param) {
11484
11630
  });
11485
11631
  };
11486
11632
  var ElementOverlayBox = function(param) {
11487
- var highlightedPrimitives = param.highlightedPrimitives;
11633
+ var highlightedPrimitives = param.highlightedPrimitives, mousePos = param.mousePos, elements = param.elements;
11488
11634
  var is_moving_component = useGlobalStore(function(s) {
11489
11635
  return s.is_moving_component;
11490
11636
  });
11637
+ var hasSmtPadAndTrace = highlightedPrimitives.some(function(p) {
11638
+ return p._element.type === "pcb_smtpad";
11639
+ }) && highlightedPrimitives.some(function(p) {
11640
+ return p._element.type === "pcb_trace";
11641
+ });
11642
+ var primitives = highlightedPrimitives;
11643
+ if (hasSmtPadAndTrace) {
11644
+ primitives = primitives.filter(function(p) {
11645
+ return p._element.type === "pcb_smtpad";
11646
+ });
11647
+ }
11648
+ primitives = filterTracesIfMultiple(primitives);
11491
11649
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", {
11492
11650
  style: containerStyle,
11493
- children: !is_moving_component && highlightedPrimitives.map(function(primitive, i) {
11651
+ children: !is_moving_component && primitives.map(function(primitive, i) {
11494
11652
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(HighlightedPrimitiveBoxWithText, {
11495
- primitive: primitive
11653
+ primitive: primitive,
11654
+ mousePos: mousePos,
11655
+ elements: elements
11496
11656
  }, i);
11497
11657
  })
11498
11658
  });
@@ -11505,10 +11665,15 @@ function ifSetsMatchExactly(set1, set2) {
11505
11665
  });
11506
11666
  }
11507
11667
  // src/components/MouseElementTracker.tsx
11668
+ var import_math_utils = require("@tscircuit/math-utils");
11508
11669
  var import_jsx_runtime5 = require("react/jsx-runtime");
11509
11670
  var MouseElementTracker = function(param) {
11510
- var children = param.children, transform = param.transform, primitives = param.primitives, onMouseHoverOverPrimitives = param.onMouseHoverOverPrimitives;
11671
+ var elements = param.elements, children = param.children, transform = param.transform, primitives = param.primitives, onMouseHoverOverPrimitives = param.onMouseHoverOverPrimitives;
11511
11672
  var _ref = _sliced_to_array((0, import_react9.useState)([]), 2), mousedPrimitives = _ref[0], setMousedPrimitives = _ref[1];
11673
+ var _ref1 = _sliced_to_array((0, import_react9.useState)({
11674
+ x: 0,
11675
+ y: 0
11676
+ }), 2), mousePos = _ref1[0], setMousePos = _ref1[1];
11512
11677
  var highlightedPrimitives = (0, import_react10.useMemo)(function() {
11513
11678
  var highlightedPrimitives2 = [];
11514
11679
  var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
@@ -11566,6 +11731,10 @@ var MouseElementTracker = function(param) {
11566
11731
  var rect = e.currentTarget.getBoundingClientRect();
11567
11732
  var x = e.clientX - rect.left;
11568
11733
  var y = e.clientY - rect.top;
11734
+ setMousePos({
11735
+ x: x,
11736
+ y: y
11737
+ });
11569
11738
  var rwPoint = (0, import_transformation_matrix5.applyToPoint)((0, import_transformation_matrix5.inverse)(transform), {
11570
11739
  x: x,
11571
11740
  y: y
@@ -11575,10 +11744,37 @@ var MouseElementTracker = function(param) {
11575
11744
  try {
11576
11745
  for(var _iterator = primitives[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
11577
11746
  var primitive = _step.value;
11578
- if (!("x" in primitive && "y" in primitive && ("w" in primitive && "h" in primitive || "r" in primitive))) continue;
11747
+ var _primitive__element;
11579
11748
  if (!primitive._element) continue;
11580
- var w = "w" in primitive ? primitive.w : primitive.r * 2;
11581
- var h = "h" in primitive ? primitive.h : primitive.r * 2;
11749
+ if ("x1" in primitive && ((_primitive__element = primitive._element) === null || _primitive__element === void 0 ? void 0 : _primitive__element.type) === "pcb_trace") {
11750
+ var distance2 = (0, import_math_utils.pointToSegmentDistance)({
11751
+ x: rwPoint.x,
11752
+ y: rwPoint.y
11753
+ }, {
11754
+ x: primitive.x1,
11755
+ y: primitive.y1
11756
+ }, {
11757
+ x: primitive.x2,
11758
+ y: primitive.y2
11759
+ });
11760
+ var lineWidth = primitive.width || 0.5;
11761
+ var detectionThreshold = Math.max(lineWidth * 25, 2) / transform.a;
11762
+ if (distance2 < detectionThreshold) {
11763
+ newMousedPrimitives.push(primitive);
11764
+ }
11765
+ continue;
11766
+ }
11767
+ if (!("x" in primitive && "y" in primitive)) continue;
11768
+ var w = 0, h = 0;
11769
+ if ("w" in primitive && "h" in primitive) {
11770
+ w = primitive.w;
11771
+ h = primitive.h;
11772
+ } else if ("r" in primitive) {
11773
+ w = primitive.r * 2;
11774
+ h = primitive.r * 2;
11775
+ } else {
11776
+ continue;
11777
+ }
11582
11778
  if (Math.abs(primitive.x - rwPoint.x) < w / 2 && Math.abs(primitive.y - rwPoint.y) < h / 2) {
11583
11779
  newMousedPrimitives.push(primitive);
11584
11780
  }
@@ -11611,6 +11807,8 @@ var MouseElementTracker = function(param) {
11611
11807
  children: [
11612
11808
  children,
11613
11809
  /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ElementOverlayBox, {
11810
+ elements: elements,
11811
+ mousePos: mousePos,
11614
11812
  highlightedPrimitives: highlightedPrimitives
11615
11813
  })
11616
11814
  ]
@@ -11886,7 +12084,7 @@ var import_css = require("@emotion/css");
11886
12084
  // package.json
11887
12085
  var package_default = {
11888
12086
  name: "@tscircuit/pcb-viewer",
11889
- version: "1.10.24",
12087
+ version: "1.10.25",
11890
12088
  main: "dist/index.js",
11891
12089
  repository: "tscircuit/pcb-viewer",
11892
12090
  license: "MIT",
@@ -11911,14 +12109,14 @@ var package_default = {
11911
12109
  "@storybook/nextjs": "^8.0.6",
11912
12110
  "@storybook/react": "^8.0.6",
11913
12111
  "@swc/core": "^1.4.12",
11914
- "@tscircuit/core": "0.0.236",
12112
+ "@tscircuit/core": "0.0.253",
11915
12113
  "@tscircuit/eagle-xml-converter": "^0.0.6",
11916
- "@tscircuit/props": "^0.0.108",
12114
+ "@tscircuit/props": "^0.0.124",
11917
12115
  "@tscircuit/soup-util": "^0.0.38",
11918
12116
  "@types/color": "^3.0.6",
11919
12117
  "@types/node": "18.7.23",
11920
12118
  "@types/react": "^18.3.3",
11921
- "circuit-json": "^0.0.120",
12119
+ "circuit-json": "^0.0.128",
11922
12120
  next: "^14.1.4",
11923
12121
  react: "^18.2.0",
11924
12122
  "react-dom": "^18.2.0",
@@ -11936,6 +12134,7 @@ var package_default = {
11936
12134
  },
11937
12135
  dependencies: {
11938
12136
  "@emotion/css": "^11.11.2",
12137
+ "@tscircuit/math-utils": "^0.0.7",
11939
12138
  "circuit-json-to-connectivity-map": "^0.0.16",
11940
12139
  "circuit-to-svg": "^0.0.36",
11941
12140
  color: "^4.2.3",
@@ -13075,6 +13274,7 @@ var CanvasElementsRenderer = function(props) {
13075
13274
  ]), 2), primitivesWithoutInteractionMetadata = _ref[0], connectivityMap = _ref[1];
13076
13275
  var _ref1 = _sliced_to_array((0, import_react19.useState)(primitivesWithoutInteractionMetadata), 2), primitives = _ref1[0], setPrimitives = _ref1[1];
13077
13276
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(MouseElementTracker, {
13277
+ elements: elements,
13078
13278
  transform: transform,
13079
13279
  primitives: primitivesWithoutInteractionMetadata,
13080
13280
  onMouseHoverOverPrimitives: function(primitivesHoveredOver) {