@tscircuit/pcb-viewer 1.11.2 → 1.11.4

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.d.ts CHANGED
@@ -11,6 +11,7 @@ interface State {
11
11
  is_mouse_over_container: boolean;
12
12
  is_moving_component: boolean;
13
13
  is_drawing_trace: boolean;
14
+ is_showing_multiple_traces_length: boolean;
14
15
  is_showing_rats_nest: boolean;
15
16
  selectLayer: (layer: LayerRef) => void;
16
17
  setEditMode: (mode: "off" | "move_footprint" | "draw_trace") => void;
@@ -18,6 +19,7 @@ interface State {
18
19
  setIsDrawingTrace: (is_drawing: boolean) => void;
19
20
  setIsShowingRatsNest: (is_showing: boolean) => void;
20
21
  setIsMouseOverContainer: (is_focused: boolean) => void;
22
+ setIsShowingMultipleTracesLength: (is_showing: boolean) => void;
21
23
  }
22
24
  type StateProps = {
23
25
  [key in keyof State]: State[key] extends boolean ? boolean : never;
package/dist/index.js CHANGED
@@ -227,7 +227,7 @@ __export(dist_exports, {
227
227
  inductance: () => inductance,
228
228
  layer_ref: () => layer_ref,
229
229
  layer_string: () => layer_string,
230
- length: () => length,
230
+ length: () => length2,
231
231
  pcb_board: () => pcb_board,
232
232
  pcb_component: () => pcb_component,
233
233
  pcb_fabrication_note_path: () => pcb_fabrication_note_path,
@@ -4587,9 +4587,9 @@ var resistance = z.string().or(z.number()).transform((v) => parseAndConvertSiUni
4587
4587
  var capacitance = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4588
4588
  var inductance = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4589
4589
  var voltage = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4590
- var length = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4590
+ var length2 = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4591
4591
  var frequency = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4592
- var distance = length;
4592
+ var distance = length2;
4593
4593
  var current = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4594
4594
  var time = z.string().or(z.number()).transform((v) => parseAndConvertSiUnit(v).value);
4595
4595
  var rotation = z.string().or(z.number()).transform((arg) => {
@@ -4812,10 +4812,10 @@ var schematic_path = z.object({
4812
4812
  expectTypesMatch(true);
4813
4813
  var schematic_pin_styles = z.record(
4814
4814
  z.object({
4815
- left_margin: length.optional(),
4816
- right_margin: length.optional(),
4817
- top_margin: length.optional(),
4818
- bottom_margin: length.optional()
4815
+ left_margin: length2.optional(),
4816
+ right_margin: length2.optional(),
4817
+ top_margin: length2.optional(),
4818
+ bottom_margin: length2.optional()
4819
4819
  })
4820
4820
  );
4821
4821
  var schematic_component_port_arrangement_by_size = z.object({
@@ -4859,9 +4859,9 @@ var schematic_component = z.object({
4859
4859
  center: point,
4860
4860
  source_component_id: z.string(),
4861
4861
  schematic_component_id: z.string(),
4862
- pin_spacing: length.optional(),
4862
+ pin_spacing: length2.optional(),
4863
4863
  pin_styles: schematic_pin_styles.optional(),
4864
- box_width: length.optional(),
4864
+ box_width: length2.optional(),
4865
4865
  symbol_name: z.string().optional(),
4866
4866
  port_arrangement: port_arrangement.optional(),
4867
4867
  port_labels: z.record(z.string()).optional(),
@@ -5024,8 +5024,8 @@ var pcb_component = z.object({
5024
5024
  center: point,
5025
5025
  layer: layer_ref,
5026
5026
  rotation,
5027
- width: length,
5028
- height: length
5027
+ width: length2,
5028
+ height: length2
5029
5029
  }).describe("Defines a component on the PCB");
5030
5030
  expectTypesMatch(true);
5031
5031
  var pcb_hole_circle_or_square = z.object({
@@ -5193,8 +5193,8 @@ var pcb_text = z.object({
5193
5193
  text: z.string(),
5194
5194
  center: point,
5195
5195
  layer: layer_ref,
5196
- width: length,
5197
- height: length,
5196
+ width: length2,
5197
+ height: length2,
5198
5198
  lines: z.number(),
5199
5199
  // @ts-ignore
5200
5200
  align: z.enum(["bottom-left"])
@@ -5289,10 +5289,10 @@ expectTypesMatch(true);
5289
5289
  var pcb_board = z.object({
5290
5290
  type: z.literal("pcb_board"),
5291
5291
  pcb_board_id: getZodPrefixedIdWithDefault("pcb_board"),
5292
- width: length,
5293
- height: length,
5292
+ width: length2,
5293
+ height: length2,
5294
5294
  center: point,
5295
- thickness: length.optional().default(1.4),
5295
+ thickness: length2.optional().default(1.4),
5296
5296
  num_layers: z.number().optional().default(4),
5297
5297
  outline: z.array(point).optional()
5298
5298
  }).describe("Defines the board outline of the PCB");
@@ -5329,7 +5329,7 @@ var pcb_silkscreen_path = z.object({
5329
5329
  pcb_component_id: z.string(),
5330
5330
  layer: visible_layer,
5331
5331
  route: z.array(point),
5332
- stroke_width: length
5332
+ stroke_width: length2
5333
5333
  }).describe("Defines a silkscreen path on the PCB");
5334
5334
  expectTypesMatch(true);
5335
5335
  var pcb_silkscreen_text = z.object({
@@ -5351,8 +5351,8 @@ var pcb_silkscreen_rect = z.object({
5351
5351
  pcb_silkscreen_rect_id: getZodPrefixedIdWithDefault("pcb_silkscreen_rect"),
5352
5352
  pcb_component_id: z.string(),
5353
5353
  center: point,
5354
- width: length,
5355
- height: length,
5354
+ width: length2,
5355
+ height: length2,
5356
5356
  layer: layer_ref
5357
5357
  }).describe("Defines a silkscreen rect on the PCB");
5358
5358
  expectTypesMatch(true);
@@ -5363,7 +5363,7 @@ var pcb_silkscreen_circle = z.object({
5363
5363
  ),
5364
5364
  pcb_component_id: z.string(),
5365
5365
  center: point,
5366
- radius: length,
5366
+ radius: length2,
5367
5367
  layer: visible_layer
5368
5368
  }).describe("Defines a silkscreen circle on the PCB");
5369
5369
  expectTypesMatch(true);
@@ -5402,7 +5402,7 @@ var pcb_fabrication_note_path = z.object({
5402
5402
  pcb_component_id: z.string(),
5403
5403
  layer: layer_ref,
5404
5404
  route: z.array(point),
5405
- stroke_width: length,
5405
+ stroke_width: length2,
5406
5406
  color: z.string().optional()
5407
5407
  }).describe(
5408
5408
  "Defines a fabrication path on the PCB for fabricators or assemblers"
@@ -5457,8 +5457,8 @@ expectTypesMatch(true);
5457
5457
  var pcb_group = z.object({
5458
5458
  type: z.literal("pcb_group"),
5459
5459
  pcb_group_id: getZodPrefixedIdWithDefault("pcb_group"),
5460
- width: length,
5461
- height: length,
5460
+ width: length2,
5461
+ height: length2,
5462
5462
  center: point,
5463
5463
  pcb_component_ids: z.array(z.string()),
5464
5464
  name: z.string().optional(),
@@ -5913,6 +5913,7 @@ var createStore = (initialState = {}) => createZustandStore(
5913
5913
  is_moving_component: false,
5914
5914
  is_drawing_trace: false,
5915
5915
  is_mouse_over_container: false,
5916
+ is_showing_multiple_traces_length: false,
5916
5917
  is_showing_rats_nest: false,
5917
5918
  ...initialState,
5918
5919
  selectLayer: (layer) => set({ selected_layer: layer }),
@@ -5926,7 +5927,8 @@ var createStore = (initialState = {}) => createZustandStore(
5926
5927
  setIsShowingRatsNest: (is_showing) => set({ is_showing_rats_nest: is_showing }),
5927
5928
  setIsMovingComponent: (is_moving) => set({ is_moving_component: is_moving }),
5928
5929
  setIsDrawingTrace: (is_drawing) => set({ is_drawing_trace: is_drawing }),
5929
- setIsMouseOverContainer: (is_focused) => set({ is_mouse_over_container: is_focused })
5930
+ setIsMouseOverContainer: (is_focused) => set({ is_mouse_over_container: is_focused }),
5931
+ setIsShowingMultipleTracesLength: (is_showing) => set({ is_showing_multiple_traces_length: is_showing })
5930
5932
  })
5931
5933
  );
5932
5934
  var useGlobalStore = (s) => {
@@ -6996,8 +6998,8 @@ function getExpandedStroke(strokeInput, defaultWidth) {
6996
6998
  function getNormal(p1, p2) {
6997
6999
  const dx = p2.x - p1.x;
6998
7000
  const dy = p2.y - p1.y;
6999
- const length2 = Math.sqrt(dx * dx + dy * dy);
7000
- return { x: -dy / length2, y: dx / length2 };
7001
+ const length3 = Math.sqrt(dx * dx + dy * dy);
7002
+ return { x: -dy / length3, y: dx / length3 };
7001
7003
  }
7002
7004
  function addPoint(point2, normal, factor, width) {
7003
7005
  const halfWidth = width / 2;
@@ -7592,20 +7594,29 @@ function getTraceOverlayInfo({
7592
7594
  }
7593
7595
 
7594
7596
  // src/lib/filter-traces-if-multiple.ts
7595
- function filterTracesIfMultiple(primitives) {
7596
- const DISPLAY_ALL_TRACE_LENGTHS = false;
7597
+ function filterTracesIfMultiple(filterTraces) {
7598
+ const { primitives, is_showing_multiple_traces_length, elements } = filterTraces;
7597
7599
  const traces = primitives.filter(
7598
7600
  (p) => p._element.type === "pcb_trace"
7599
7601
  );
7602
+ const sourceTraces = elements.filter((e) => e.type === "source_trace");
7603
+ const nonTraces = primitives.filter((p) => p._element.type !== "pcb_trace");
7604
+ const tracesWithMaxLength = traces.filter(
7605
+ (trace) => sourceTraces.some(
7606
+ (sourceTrace) => trace._element.type === "pcb_trace" && trace._element.source_trace_id === sourceTrace.source_trace_id && sourceTrace.max_length !== void 0
7607
+ )
7608
+ );
7609
+ length;
7610
+ if (!is_showing_multiple_traces_length) {
7611
+ return [...nonTraces, ...tracesWithMaxLength];
7612
+ }
7600
7613
  if (traces.length > 1) {
7601
- if (!DISPLAY_ALL_TRACE_LENGTHS)
7602
- return primitives.filter((p) => p._element.type !== "pcb_trace");
7603
7614
  const shortestTrace = traces.reduce((shortest, current2) => {
7604
7615
  const shortestLength = shortest._element.trace_length;
7605
7616
  const currentLength = current2._element.trace_length;
7606
7617
  return currentLength < shortestLength ? current2 : shortest;
7607
7618
  }, traces[0]);
7608
- return primitives.filter((p) => p._element.type !== "pcb_trace").concat([shortestTrace]);
7619
+ return [...nonTraces, shortestTrace];
7609
7620
  }
7610
7621
  return primitives;
7611
7622
  }
@@ -7789,13 +7800,20 @@ var ElementOverlayBox = ({
7789
7800
  mousePos,
7790
7801
  elements
7791
7802
  }) => {
7792
- const is_moving_component = useGlobalStore((s) => s.is_moving_component);
7803
+ const [is_moving_component, is_showing_multiple_traces_length] = useGlobalStore((s) => [
7804
+ s.is_moving_component,
7805
+ s.is_showing_multiple_traces_length
7806
+ ]);
7793
7807
  const hasSmtPadAndTrace = highlightedPrimitives.some((p) => p._element.type === "pcb_smtpad") && highlightedPrimitives.some((p) => p._element.type === "pcb_trace");
7794
7808
  let primitives = highlightedPrimitives;
7795
7809
  if (hasSmtPadAndTrace) {
7796
7810
  primitives = primitives.filter((p) => p._element.type === "pcb_smtpad");
7797
7811
  }
7798
- primitives = filterTracesIfMultiple(primitives);
7812
+ primitives = filterTracesIfMultiple({
7813
+ primitives,
7814
+ is_showing_multiple_traces_length,
7815
+ elements
7816
+ });
7799
7817
  return /* @__PURE__ */ jsx4("div", { style: containerStyle, children: !is_moving_component && primitives.map((primitive, i) => /* @__PURE__ */ jsx4(
7800
7818
  HighlightedPrimitiveBoxWithText,
7801
7819
  {
@@ -8191,7 +8209,7 @@ import { css } from "@emotion/css";
8191
8209
  // package.json
8192
8210
  var package_default = {
8193
8211
  name: "@tscircuit/pcb-viewer",
8194
- version: "1.11.0",
8212
+ version: "1.11.3",
8195
8213
  main: "dist/index.js",
8196
8214
  type: "module",
8197
8215
  repository: "tscircuit/pcb-viewer",
@@ -8242,8 +8260,8 @@ var package_default = {
8242
8260
  },
8243
8261
  dependencies: {
8244
8262
  "@emotion/css": "^11.11.2",
8263
+ "circuit-json-to-connectivity-map": "^0.0.18",
8245
8264
  "@tscircuit/math-utils": "^0.0.7",
8246
- "circuit-json-to-connectivity-map": "^0.0.16",
8247
8265
  "circuit-to-svg": "^0.0.36",
8248
8266
  color: "^4.2.3",
8249
8267
  "react-supergrid": "^1.0.10",
@@ -8339,22 +8357,65 @@ var ToolbarButton = ({ children, ...props }) => /* @__PURE__ */ jsx7(
8339
8357
  children
8340
8358
  }
8341
8359
  );
8360
+ var CheckboxMenuItem = ({
8361
+ label,
8362
+ checked,
8363
+ onClick
8364
+ }) => {
8365
+ return /* @__PURE__ */ jsxs4(
8366
+ "div",
8367
+ {
8368
+ className: css`
8369
+ margin-top: 2px;
8370
+ padding: 4px;
8371
+ padding-left: 8px;
8372
+ padding-right: 18px;
8373
+ cursor: pointer;
8374
+ display: flex;
8375
+ align-items: center;
8376
+ gap: 8px;
8377
+
8378
+ &:hover {
8379
+ background-color: rgba(255, 255, 255, 0.1);
8380
+ }
8381
+ `,
8382
+ onClick: (e) => {
8383
+ e.stopPropagation();
8384
+ onClick();
8385
+ },
8386
+ children: [
8387
+ /* @__PURE__ */ jsx7("input", { type: "checkbox", checked }),
8388
+ /* @__PURE__ */ jsx7("span", { style: { color: "#eee" }, children: label })
8389
+ ]
8390
+ }
8391
+ );
8392
+ };
8342
8393
  var ToolbarOverlay = ({ children, elements }) => {
8343
8394
  const [isMouseOverContainer, setIsMouseOverContainer] = useGlobalStore(
8344
8395
  (s) => [s.is_mouse_over_container, s.setIsMouseOverContainer]
8345
8396
  );
8397
+ const [isViewMenuOpen, setViewMenuOpen] = useState5(false);
8346
8398
  const [isLayerMenuOpen, setLayerMenuOpen] = useState5(false);
8347
8399
  const [isErrorsOpen, setErrorsOpen] = useState5(false);
8348
8400
  const [selectedLayer, selectLayer] = useGlobalStore(
8349
8401
  (s) => [s.selected_layer, s.selectLayer]
8350
8402
  );
8351
- const [in_move_footprint_mode, in_draw_trace_mode, is_showing_rats_nest] = useGlobalStore((s) => [
8403
+ const [
8404
+ in_move_footprint_mode,
8405
+ in_draw_trace_mode,
8406
+ is_showing_rats_nest,
8407
+ is_showing_multiple_traces_length
8408
+ ] = useGlobalStore((s) => [
8352
8409
  s.in_move_footprint_mode,
8353
8410
  s.in_draw_trace_mode,
8354
- s.is_showing_rats_nest
8411
+ s.is_showing_rats_nest,
8412
+ s.is_showing_multiple_traces_length
8355
8413
  ]);
8356
8414
  const setEditMode = useGlobalStore((s) => s.setEditMode);
8357
8415
  const setIsShowingRatsNest = useGlobalStore((s) => s.setIsShowingRatsNest);
8416
+ const setIsShowingMultipleTracesLength = useGlobalStore(
8417
+ (s) => s.setIsShowingMultipleTracesLength
8418
+ );
8358
8419
  useHotKey("1", () => selectLayer("top"));
8359
8420
  useHotKey("2", () => selectLayer("bottom"));
8360
8421
  useHotKey("3", () => selectLayer("inner1"));
@@ -8518,6 +8579,54 @@ var ToolbarOverlay = ({ children, elements }) => {
8518
8579
  "Rats Nest"
8519
8580
  ] })
8520
8581
  }
8582
+ ),
8583
+ /* @__PURE__ */ jsx7(
8584
+ ToolbarButton,
8585
+ {
8586
+ onClick: () => {
8587
+ setViewMenuOpen(!isViewMenuOpen);
8588
+ },
8589
+ children: /* @__PURE__ */ jsxs4("div", { children: [
8590
+ /* @__PURE__ */ jsxs4(
8591
+ "div",
8592
+ {
8593
+ style: {
8594
+ display: "flex",
8595
+ alignItems: "center",
8596
+ gap: "4px"
8597
+ },
8598
+ children: [
8599
+ "View",
8600
+ " ",
8601
+ /* @__PURE__ */ jsx7(
8602
+ "span",
8603
+ {
8604
+ style: {
8605
+ fontSize: "8px",
8606
+ transform: isViewMenuOpen ? "rotate(180deg)" : "rotate(0)",
8607
+ transition: "transform 0.1s ease",
8608
+ display: "inline-block"
8609
+ },
8610
+ children: "\u25BC"
8611
+ }
8612
+ )
8613
+ ]
8614
+ }
8615
+ ),
8616
+ isViewMenuOpen && /* @__PURE__ */ jsx7("div", { style: { marginTop: 4, minWidth: 120 }, children: /* @__PURE__ */ jsx7(
8617
+ CheckboxMenuItem,
8618
+ {
8619
+ label: "Show All Trace Lengths",
8620
+ checked: is_showing_multiple_traces_length,
8621
+ onClick: () => {
8622
+ setIsShowingMultipleTracesLength(
8623
+ !is_showing_multiple_traces_length
8624
+ );
8625
+ }
8626
+ }
8627
+ ) })
8628
+ ] })
8629
+ }
8521
8630
  )
8522
8631
  ]
8523
8632
  }