@tscircuit/pcb-viewer 1.11.259 → 1.11.260

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
@@ -6421,7 +6421,7 @@ var ToastContainer = () => {
6421
6421
  };
6422
6422
 
6423
6423
  // src/PCBViewer.tsx
6424
- import { useEffect as useEffect16, useMemo as useMemo7, useRef as useRef11, useState as useState11 } from "react";
6424
+ import { useEffect as useEffect16, useMemo as useMemo8, useRef as useRef11, useState as useState11 } from "react";
6425
6425
 
6426
6426
  // node_modules/react-use/esm/misc/util.js
6427
6427
  var noop = function() {
@@ -6972,7 +6972,7 @@ function addInteractionMetadataToPrimitives({
6972
6972
  }
6973
6973
 
6974
6974
  // src/components/CanvasElementsRenderer.tsx
6975
- import { useCallback as useCallback5, useMemo as useMemo6, useState as useState10 } from "react";
6975
+ import { useCallback as useCallback5, useMemo as useMemo7, useState as useState10 } from "react";
6976
6976
 
6977
6977
  // src/lib/util/expand-stroke.ts
6978
6978
  function getExpandedStroke(strokeInput, defaultWidth) {
@@ -9902,7 +9902,7 @@ var WarningGraphicsOverlay = ({
9902
9902
  };
9903
9903
 
9904
9904
  // src/components/DimensionOverlay.tsx
9905
- import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef5, useState as useState3 } from "react";
9905
+ import { useCallback as useCallback3, useEffect as useEffect7, useMemo as useMemo4, useRef as useRef5, useState as useState3 } from "react";
9906
9906
  import { applyToPoint as applyToPoint8, identity as identity4, inverse as inverse2 } from "transformation-matrix";
9907
9907
 
9908
9908
  // src/lib/util/get-primitive-bounding-box.ts
@@ -10055,6 +10055,101 @@ var getPrimitiveBoundingBox = (primitive) => {
10055
10055
  }
10056
10056
  };
10057
10057
 
10058
+ // src/hooks/useDiagonalLabel.ts
10059
+ import { useMemo as useMemo3 } from "react";
10060
+
10061
+ // src/lib/util/calculate-diagonal-label.ts
10062
+ function calculateDiagonalLabel(params) {
10063
+ const {
10064
+ dimensionStart,
10065
+ dimensionEnd,
10066
+ screenDimensionStart,
10067
+ screenDimensionEnd,
10068
+ flipX,
10069
+ flipY
10070
+ } = params;
10071
+ const deltaX = dimensionEnd.x - dimensionStart.x;
10072
+ const deltaY = dimensionEnd.y - dimensionStart.y;
10073
+ const distance5 = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
10074
+ const screenDeltaX = screenDimensionEnd.x - screenDimensionStart.x;
10075
+ const screenDeltaY = screenDimensionEnd.y - screenDimensionStart.y;
10076
+ const screenDistance = Math.sqrt(
10077
+ screenDeltaX * screenDeltaX + screenDeltaY * screenDeltaY
10078
+ );
10079
+ const angle = Math.atan2(screenDeltaY, screenDeltaX) * (180 / Math.PI);
10080
+ const normalizedAngle = Math.abs(angle) % 90;
10081
+ const angleFromAxis = Math.min(normalizedAngle, 90 - normalizedAngle);
10082
+ const isDiagonal = angleFromAxis > 15;
10083
+ const midX = (screenDimensionStart.x + screenDimensionEnd.x) / 2;
10084
+ const midY = (screenDimensionStart.y + screenDimensionEnd.y) / 2;
10085
+ const offsetDistance = 15;
10086
+ const perpendicularAngle = angle + 90;
10087
+ let offsetX = Math.cos(perpendicularAngle * Math.PI / 180) * offsetDistance;
10088
+ let offsetY = Math.sin(perpendicularAngle * Math.PI / 180) * offsetDistance;
10089
+ const isNE = screenDeltaX > 0 && screenDeltaY < 0;
10090
+ const isNW = screenDeltaX < 0 && screenDeltaY < 0;
10091
+ const isSE = screenDeltaX > 0 && screenDeltaY > 0;
10092
+ const isSW = screenDeltaX < 0 && screenDeltaY > 0;
10093
+ if (flipX !== flipY && !isNE) {
10094
+ offsetX = -offsetX;
10095
+ offsetY = -offsetY;
10096
+ }
10097
+ if (isNE) {
10098
+ const lessOffset = -45;
10099
+ offsetX += Math.cos(perpendicularAngle * Math.PI / 180) * lessOffset;
10100
+ offsetY += Math.sin(perpendicularAngle * Math.PI / 180) * lessOffset;
10101
+ }
10102
+ if (isSE) {
10103
+ const seAdjust = -10;
10104
+ offsetX += Math.cos(perpendicularAngle * Math.PI / 180) + seAdjust * 2;
10105
+ offsetY += Math.sin(perpendicularAngle * Math.PI / 180) + seAdjust;
10106
+ }
10107
+ if (isSW) {
10108
+ const reduceOffset = 10;
10109
+ offsetX += Math.cos(perpendicularAngle * Math.PI / 180) * reduceOffset;
10110
+ offsetY += Math.sin(perpendicularAngle * Math.PI / 180) * reduceOffset;
10111
+ }
10112
+ const x = midX + offsetX;
10113
+ const y = midY + offsetY;
10114
+ return {
10115
+ distance: distance5,
10116
+ screenDistance,
10117
+ x,
10118
+ y,
10119
+ show: distance5 > 0.01 && screenDistance > 30 && isDiagonal
10120
+ };
10121
+ }
10122
+
10123
+ // src/hooks/useDiagonalLabel.ts
10124
+ function useDiagonalLabel(params) {
10125
+ const {
10126
+ dimensionStart,
10127
+ dimensionEnd,
10128
+ screenDimensionStart,
10129
+ screenDimensionEnd,
10130
+ flipX,
10131
+ flipY
10132
+ } = params;
10133
+ return useMemo3(
10134
+ () => calculateDiagonalLabel({
10135
+ dimensionStart,
10136
+ dimensionEnd,
10137
+ screenDimensionStart,
10138
+ screenDimensionEnd,
10139
+ flipX,
10140
+ flipY
10141
+ }),
10142
+ [
10143
+ dimensionStart,
10144
+ dimensionEnd,
10145
+ screenDimensionStart,
10146
+ screenDimensionEnd,
10147
+ flipX,
10148
+ flipY
10149
+ ]
10150
+ );
10151
+ }
10152
+
10058
10153
  // src/components/DimensionOverlay.tsx
10059
10154
  import { Fragment, jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
10060
10155
  var SNAP_THRESHOLD_PX = 16;
@@ -10101,7 +10196,7 @@ var DimensionOverlay = ({
10101
10196
  const containerRef = useRef5(null);
10102
10197
  const container = containerRef.current;
10103
10198
  const containerBounds = container?.getBoundingClientRect();
10104
- const elementBoundingBoxes = useMemo3(() => {
10199
+ const elementBoundingBoxes = useMemo4(() => {
10105
10200
  const boundingBoxes = /* @__PURE__ */ new Map();
10106
10201
  for (const primitive of primitives) {
10107
10202
  if (!primitive._element) continue;
@@ -10116,7 +10211,7 @@ var DimensionOverlay = ({
10116
10211
  }
10117
10212
  return boundingBoxes;
10118
10213
  }, [primitives]);
10119
- const snappingPoints = useMemo3(() => {
10214
+ const snappingPoints = useMemo4(() => {
10120
10215
  const points = [];
10121
10216
  elementBoundingBoxes.forEach((bounds, element) => {
10122
10217
  if (!bounds) return;
@@ -10148,7 +10243,7 @@ var DimensionOverlay = ({
10148
10243
  });
10149
10244
  return points;
10150
10245
  }, [elementBoundingBoxes]);
10151
- const snappingPointsWithScreen = useMemo3(() => {
10246
+ const snappingPointsWithScreen = useMemo4(() => {
10152
10247
  return snappingPoints.map((snap, index) => ({
10153
10248
  ...snap,
10154
10249
  id: `${index}-${snap.anchor}`,
@@ -10255,6 +10350,14 @@ var DimensionOverlay = ({
10255
10350
  };
10256
10351
  arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left;
10257
10352
  arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top;
10353
+ const diagonalLabel = useDiagonalLabel({
10354
+ dimensionStart: dStart,
10355
+ dimensionEnd: dEnd,
10356
+ screenDimensionStart: screenDStart,
10357
+ screenDimensionEnd: screenDEnd,
10358
+ flipX: arrowScreenBounds.flipX,
10359
+ flipY: arrowScreenBounds.flipY
10360
+ });
10258
10361
  return /* @__PURE__ */ jsxs4(
10259
10362
  "div",
10260
10363
  {
@@ -10308,6 +10411,24 @@ var DimensionOverlay = ({
10308
10411
  children: [
10309
10412
  children,
10310
10413
  dimensionToolVisible && /* @__PURE__ */ jsxs4(Fragment, { children: [
10414
+ diagonalLabel.show && /* @__PURE__ */ jsx6(
10415
+ "div",
10416
+ {
10417
+ style: {
10418
+ position: "absolute",
10419
+ left: diagonalLabel.x,
10420
+ top: diagonalLabel.y,
10421
+ color: "red",
10422
+ mixBlendMode: "difference",
10423
+ pointerEvents: "none",
10424
+ fontSize: 12,
10425
+ fontFamily: "sans-serif",
10426
+ whiteSpace: "nowrap",
10427
+ zIndex: zIndexMap.dimensionOverlay
10428
+ },
10429
+ children: diagonalLabel.distance.toFixed(2)
10430
+ }
10431
+ ),
10311
10432
  /* @__PURE__ */ jsx6(
10312
10433
  "div",
10313
10434
  {
@@ -11572,7 +11693,7 @@ var ErrorOverlay = ({
11572
11693
  };
11573
11694
 
11574
11695
  // src/components/MouseElementTracker.tsx
11575
- import { useState as useState7, useMemo as useMemo4 } from "react";
11696
+ import { useState as useState7, useMemo as useMemo5 } from "react";
11576
11697
  import { applyToPoint as applyToPoint12, inverse as inverse5 } from "transformation-matrix";
11577
11698
 
11578
11699
  // src/components/ElementOverlayBox.tsx
@@ -11989,7 +12110,7 @@ var MouseElementTracker = ({
11989
12110
  }) => {
11990
12111
  const [mousedPrimitives, setMousedPrimitives] = useState7([]);
11991
12112
  const [mousePos, setMousePos] = useState7({ x: 0, y: 0 });
11992
- const highlightedPrimitives = useMemo4(() => {
12113
+ const highlightedPrimitives = useMemo5(() => {
11993
12114
  const highlightedPrimitives2 = [];
11994
12115
  for (const primitive of mousedPrimitives) {
11995
12116
  if (primitive._element?.type === "pcb_via") continue;
@@ -12353,15 +12474,15 @@ var PcbGroupOverlay = ({
12353
12474
 
12354
12475
  // src/components/RatsNestOverlay.tsx
12355
12476
  import { applyToPoint as applyToPoint14, identity as identity9 } from "transformation-matrix";
12356
- import { useMemo as useMemo5 } from "react";
12477
+ import { useMemo as useMemo6 } from "react";
12357
12478
  import { jsx as jsx14, jsxs as jsxs11 } from "react/jsx-runtime";
12358
12479
  var RatsNestOverlay = ({ transform, soup, children }) => {
12359
12480
  const isShowingRatsNest = useGlobalStore((s) => s.is_showing_rats_nest);
12360
- const { netMap, idToNetMap } = useMemo5(
12481
+ const { netMap, idToNetMap } = useMemo6(
12361
12482
  () => getFullConnectivityMapFromCircuitJson(soup || []),
12362
12483
  [soup]
12363
12484
  );
12364
- const ratsNestLines = useMemo5(() => {
12485
+ const ratsNestLines = useMemo6(() => {
12365
12486
  if (!soup || !isShowingRatsNest) return [];
12366
12487
  const getElementPosition = (id) => {
12367
12488
  const element = su(soup)[id.replace(/_\d+$/, "")].get(id);
@@ -12466,7 +12587,7 @@ import { css as css3 } from "@emotion/css";
12466
12587
  // package.json
12467
12588
  var package_default = {
12468
12589
  name: "@tscircuit/pcb-viewer",
12469
- version: "1.11.258",
12590
+ version: "1.11.259",
12470
12591
  main: "dist/index.js",
12471
12592
  type: "module",
12472
12593
  repository: "tscircuit/pcb-viewer",
@@ -13300,11 +13421,11 @@ var CanvasElementsRenderer = (props) => {
13300
13421
  const isShowingCopperPours = useGlobalStore(
13301
13422
  (state) => state.is_showing_copper_pours
13302
13423
  );
13303
- const elementsToRender = useMemo6(
13424
+ const elementsToRender = useMemo7(
13304
13425
  () => isShowingCopperPours ? elements : elements.filter((elm) => elm.type !== "pcb_copper_pour"),
13305
13426
  [elements, isShowingCopperPours]
13306
13427
  );
13307
- const [primitivesWithoutInteractionMetadata, connectivityMap] = useMemo6(() => {
13428
+ const [primitivesWithoutInteractionMetadata, connectivityMap] = useMemo7(() => {
13308
13429
  const primitivesWithoutInteractionMetadata2 = elementsToRender.flatMap(
13309
13430
  (elm) => convertElementToPrimitives(elm, props.elements)
13310
13431
  );
@@ -13317,7 +13438,7 @@ var CanvasElementsRenderer = (props) => {
13317
13438
  drawingObjectIdsWithMouseOver: /* @__PURE__ */ new Set(),
13318
13439
  primitiveIdsInMousedOverNet: []
13319
13440
  });
13320
- const errorRelatedIds = useMemo6(() => {
13441
+ const errorRelatedIds = useMemo7(() => {
13321
13442
  if (!hoveredErrorId) return [];
13322
13443
  const errorElements = elements.filter(
13323
13444
  (el) => el.type.includes("error")
@@ -13336,7 +13457,7 @@ var CanvasElementsRenderer = (props) => {
13336
13457
  }
13337
13458
  return relatedIds;
13338
13459
  }, [hoveredErrorId, elements]);
13339
- const primitives = useMemo6(() => {
13460
+ const primitives = useMemo7(() => {
13340
13461
  const combinedPrimitiveIds = [
13341
13462
  ...hoverState.primitiveIdsInMousedOverNet,
13342
13463
  ...errorRelatedIds
@@ -13510,7 +13631,7 @@ var PCBViewer = ({
13510
13631
  editEvents = editEventsProp ?? editEvents;
13511
13632
  const initialRenderCompleted = useRef11(false);
13512
13633
  const touchStartRef = useRef11(null);
13513
- const circuitJsonKey = useMemo7(
13634
+ const circuitJsonKey = useMemo8(
13514
13635
  () => calculateCircuitJsonKey(circuitJson),
13515
13636
  [circuitJson]
13516
13637
  );
@@ -13543,12 +13664,12 @@ var PCBViewer = ({
13543
13664
  initialRenderCompleted.current = true;
13544
13665
  }
13545
13666
  }, [circuitJson, refDimensions]);
13546
- const pcbElmsPreEdit = useMemo7(() => {
13667
+ const pcbElmsPreEdit = useMemo8(() => {
13547
13668
  return circuitJson?.filter(
13548
13669
  (e) => e.type.startsWith("pcb_") || e.type.startsWith("source_")
13549
13670
  ) ?? [];
13550
13671
  }, [circuitJsonKey]);
13551
- const elements = useMemo7(() => {
13672
+ const elements = useMemo8(() => {
13552
13673
  return applyEditEvents({
13553
13674
  circuitJson: pcbElmsPreEdit,
13554
13675
  editEvents
@@ -13565,7 +13686,7 @@ var PCBViewer = ({
13565
13686
  setEditEvents(newEditEvents);
13566
13687
  onEditEventsChanged?.(newEditEvents);
13567
13688
  };
13568
- const mergedInitialState = useMemo7(
13689
+ const mergedInitialState = useMemo8(
13569
13690
  () => ({
13570
13691
  ...initialState,
13571
13692
  ...disablePcbGroups && { is_showing_pcb_groups: false }