@tscircuit/3d-viewer 0.0.531 → 0.0.533

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.
Files changed (2) hide show
  1. package/dist/index.js +189 -124
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -14432,7 +14432,7 @@ var require_browser = __commonJS({
14432
14432
  });
14433
14433
 
14434
14434
  // src/CadViewer.tsx
14435
- import { useState as useState36, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect44 } from "react";
14435
+ import { useState as useState36, useCallback as useCallback21, useRef as useRef26, useEffect as useEffect45 } from "react";
14436
14436
  import * as THREE39 from "three";
14437
14437
 
14438
14438
  // src/CadViewerJscad.tsx
@@ -14441,7 +14441,7 @@ import { forwardRef as forwardRef3, useMemo as useMemo20 } from "react";
14441
14441
 
14442
14442
  // src/AnyCadComponent.tsx
14443
14443
  import { su as su2 } from "@tscircuit/circuit-json-util";
14444
- import { useCallback as useCallback3, useMemo as useMemo8, useState as useState7 } from "react";
14444
+ import { useCallback as useCallback3, useEffect as useEffect11, useMemo as useMemo8, useState as useState7 } from "react";
14445
14445
 
14446
14446
  // src/contexts/LayerVisibilityContext.tsx
14447
14447
  import {
@@ -28577,8 +28577,35 @@ var resolveModelUrl = (modelUrl, resolveStaticAsset) => {
28577
28577
  // src/utils/tuple.ts
28578
28578
  var tuple = (...args) => args;
28579
28579
 
28580
+ // src/three-components/ThreeErrorBoundary.tsx
28581
+ import React6 from "react";
28582
+ var ThreeErrorBoundary = class extends React6.Component {
28583
+ constructor(props) {
28584
+ super(props);
28585
+ this.state = { hasError: false, error: null };
28586
+ }
28587
+ static getDerivedStateFromError(error) {
28588
+ return { hasError: true, error };
28589
+ }
28590
+ render() {
28591
+ if (this.state.hasError && this.state.error) {
28592
+ return this.props.fallback({ error: this.state.error });
28593
+ }
28594
+ return this.props.children;
28595
+ }
28596
+ };
28597
+
28580
28598
  // src/AnyCadComponent.tsx
28581
28599
  import { Fragment as Fragment4, jsx as jsx10, jsxs as jsxs2 } from "react/jsx-runtime";
28600
+ var ModelLoadErrorReporter = ({
28601
+ error,
28602
+ onError
28603
+ }) => {
28604
+ useEffect11(() => {
28605
+ onError(error);
28606
+ }, [error, onError]);
28607
+ return null;
28608
+ };
28582
28609
  var AnyCadComponent = ({
28583
28610
  cad_component,
28584
28611
  circuitJson,
@@ -28625,6 +28652,12 @@ var AnyCadComponent = ({
28625
28652
  const stepUrl = resolveModelUrlWithStaticResolver(
28626
28653
  cad_component.model_step_url
28627
28654
  );
28655
+ const [fallbackModelIndex, setFallbackModelIndex] = useState7(0);
28656
+ const [lastModelError, setLastModelError] = useState7(null);
28657
+ useEffect11(() => {
28658
+ setFallbackModelIndex(0);
28659
+ setLastModelError(null);
28660
+ }, [cad_component.cad_component_id, url, gltfUrl, stepUrl]);
28628
28661
  const pcbComponent = circuitJson.find(
28629
28662
  (elm) => elm.type === "pcb_component" && elm.source_component_id === cad_component.source_component_id
28630
28663
  );
@@ -28641,60 +28674,110 @@ var AnyCadComponent = ({
28641
28674
  }, [cad_component.rotation, layer]);
28642
28675
  const adjustedPosition = useMemo8(() => {
28643
28676
  if (!cad_component.position) return void 0;
28644
- let z18;
28645
- if (layer === "top") {
28646
- z18 = cad_component.position.z;
28647
- } else if (layer === "bottom") {
28648
- z18 = -(cad_component.position.z + pcbThickness);
28649
- } else {
28650
- z18 = cad_component.position.z;
28677
+ let z18 = cad_component.position.z + pcbThickness / 2;
28678
+ if (layer === "bottom") {
28679
+ z18 = -cad_component.position.z - pcbThickness / 2;
28651
28680
  }
28652
28681
  return [cad_component.position.x, cad_component.position.y, z18];
28653
28682
  }, [cad_component.position, layer, pcbThickness]);
28683
+ const fallbackModelComponents = useMemo8(() => {
28684
+ const components = [];
28685
+ if (url) {
28686
+ components.push(
28687
+ /* @__PURE__ */ jsx10(
28688
+ MixedStlModel,
28689
+ {
28690
+ url,
28691
+ position: adjustedPosition,
28692
+ rotation: rotationOffset,
28693
+ scale: cad_component.model_unit_to_mm_scale_factor,
28694
+ onHover: handleHover,
28695
+ onUnhover: handleUnhover,
28696
+ isHovered,
28697
+ isTranslucent: cad_component.show_as_translucent_model
28698
+ },
28699
+ `${cad_component.cad_component_id}-mixed-${url}`
28700
+ )
28701
+ );
28702
+ }
28703
+ if (gltfUrl) {
28704
+ components.push(
28705
+ /* @__PURE__ */ jsx10(
28706
+ GltfModel,
28707
+ {
28708
+ gltfUrl,
28709
+ position: adjustedPosition,
28710
+ rotation: rotationOffset,
28711
+ scale: cad_component.model_unit_to_mm_scale_factor,
28712
+ onHover: handleHover,
28713
+ onUnhover: handleUnhover,
28714
+ isHovered,
28715
+ isTranslucent: cad_component.show_as_translucent_model
28716
+ },
28717
+ `${cad_component.cad_component_id}-gltf-${gltfUrl}`
28718
+ )
28719
+ );
28720
+ }
28721
+ if (stepUrl && !cad_component.model_jscad && !cad_component.footprinter_string) {
28722
+ components.push(
28723
+ /* @__PURE__ */ jsx10(
28724
+ StepModel,
28725
+ {
28726
+ stepUrl,
28727
+ position: adjustedPosition,
28728
+ rotation: rotationOffset,
28729
+ scale: cad_component.model_unit_to_mm_scale_factor,
28730
+ onHover: handleHover,
28731
+ onUnhover: handleUnhover,
28732
+ isHovered,
28733
+ isTranslucent: cad_component.show_as_translucent_model
28734
+ },
28735
+ `${cad_component.cad_component_id}-step-${stepUrl}`
28736
+ )
28737
+ );
28738
+ }
28739
+ return components;
28740
+ }, [
28741
+ adjustedPosition,
28742
+ cad_component.cad_component_id,
28743
+ cad_component.footprinter_string,
28744
+ cad_component.model_jscad,
28745
+ cad_component.model_unit_to_mm_scale_factor,
28746
+ cad_component.show_as_translucent_model,
28747
+ gltfUrl,
28748
+ handleHover,
28749
+ handleUnhover,
28750
+ isHovered,
28751
+ rotationOffset,
28752
+ stepUrl,
28753
+ url
28754
+ ]);
28654
28755
  let modelComponent = null;
28655
- if (url) {
28656
- modelComponent = /* @__PURE__ */ jsx10(
28657
- MixedStlModel,
28658
- {
28659
- url,
28660
- position: adjustedPosition,
28661
- rotation: rotationOffset,
28662
- scale: cad_component.model_unit_to_mm_scale_factor,
28663
- onHover: handleHover,
28664
- onUnhover: handleUnhover,
28665
- isHovered,
28666
- isTranslucent: cad_component.show_as_translucent_model
28667
- },
28668
- cad_component.cad_component_id
28669
- );
28670
- } else if (gltfUrl) {
28756
+ if (fallbackModelComponents.length > 0) {
28757
+ if (fallbackModelIndex >= fallbackModelComponents.length) {
28758
+ if (lastModelError) {
28759
+ throw lastModelError;
28760
+ }
28761
+ return null;
28762
+ }
28671
28763
  modelComponent = /* @__PURE__ */ jsx10(
28672
- GltfModel,
28764
+ ThreeErrorBoundary,
28673
28765
  {
28674
- gltfUrl,
28675
- position: adjustedPosition,
28676
- rotation: rotationOffset,
28677
- scale: cad_component.model_unit_to_mm_scale_factor,
28678
- onHover: handleHover,
28679
- onUnhover: handleUnhover,
28680
- isHovered,
28681
- isTranslucent: cad_component.show_as_translucent_model
28766
+ fallback: ({ error }) => /* @__PURE__ */ jsx10(
28767
+ ModelLoadErrorReporter,
28768
+ {
28769
+ error,
28770
+ onError: (nextError) => {
28771
+ setLastModelError(nextError);
28772
+ setFallbackModelIndex(
28773
+ (current) => Math.max(current, fallbackModelIndex + 1)
28774
+ );
28775
+ }
28776
+ }
28777
+ ),
28778
+ children: fallbackModelComponents[fallbackModelIndex]
28682
28779
  },
28683
- cad_component.cad_component_id
28684
- );
28685
- } else if (stepUrl && !cad_component.model_jscad && !cad_component.footprinter_string) {
28686
- modelComponent = /* @__PURE__ */ jsx10(
28687
- StepModel,
28688
- {
28689
- stepUrl,
28690
- position: adjustedPosition,
28691
- rotation: rotationOffset,
28692
- scale: cad_component.model_unit_to_mm_scale_factor,
28693
- onHover: handleHover,
28694
- onUnhover: handleUnhover,
28695
- isHovered,
28696
- isTranslucent: cad_component.show_as_translucent_model
28697
- }
28780
+ `${cad_component.cad_component_id}-fallback-${fallbackModelIndex}`
28698
28781
  );
28699
28782
  } else if (cad_component.model_jscad) {
28700
28783
  modelComponent = /* @__PURE__ */ jsx10(
@@ -28763,13 +28846,13 @@ var AnyCadComponent = ({
28763
28846
  };
28764
28847
 
28765
28848
  // src/CadViewerContainer.tsx
28766
- import { forwardRef as forwardRef2, useEffect as useEffect17, useMemo as useMemo14, useState as useState10 } from "react";
28849
+ import { forwardRef as forwardRef2, useEffect as useEffect18, useMemo as useMemo14, useState as useState10 } from "react";
28767
28850
  import * as THREE16 from "three";
28768
28851
 
28769
28852
  // package.json
28770
28853
  var package_default = {
28771
28854
  name: "@tscircuit/3d-viewer",
28772
- version: "0.0.530",
28855
+ version: "0.0.532",
28773
28856
  main: "./dist/index.js",
28774
28857
  module: "./dist/index.js",
28775
28858
  type: "module",
@@ -28847,7 +28930,7 @@ var package_default = {
28847
28930
  // src/react-three/Canvas.tsx
28848
28931
  import {
28849
28932
  useRef as useRef4,
28850
- useEffect as useEffect11,
28933
+ useEffect as useEffect12,
28851
28934
  useState as useState9,
28852
28935
  useCallback as useCallback5,
28853
28936
  forwardRef,
@@ -29114,7 +29197,7 @@ var Canvas = forwardRef(
29114
29197
  }
29115
29198
  const rootObject = useRef4(new THREE10.Object3D());
29116
29199
  useImperativeHandle(ref, () => rootObject.current);
29117
- useEffect11(() => {
29200
+ useEffect12(() => {
29118
29201
  if (!mountRef.current) return;
29119
29202
  removeExistingCanvases(mountRef.current);
29120
29203
  const renderer = new THREE10.WebGLRenderer({ antialias: true, alpha: true });
@@ -29214,7 +29297,7 @@ var Canvas = forwardRef(
29214
29297
  );
29215
29298
 
29216
29299
  // src/react-three/OrbitControls.tsx
29217
- import { useEffect as useEffect12, useMemo as useMemo11 } from "react";
29300
+ import { useEffect as useEffect13, useMemo as useMemo11 } from "react";
29218
29301
  import * as THREE11 from "three";
29219
29302
  import { OrbitControls as ThreeOrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
29220
29303
  var OrbitControls = ({
@@ -29234,11 +29317,11 @@ var OrbitControls = ({
29234
29317
  if (!camera || !renderer) return null;
29235
29318
  return new ThreeOrbitControls(camera, renderer.domElement);
29236
29319
  }, [camera, renderer]);
29237
- useEffect12(() => {
29320
+ useEffect13(() => {
29238
29321
  onControlsChange?.(controls ?? null);
29239
29322
  return () => onControlsChange?.(null);
29240
29323
  }, [controls, onControlsChange]);
29241
- useEffect12(() => {
29324
+ useEffect13(() => {
29242
29325
  if (!controls) return;
29243
29326
  const handleChange = () => {
29244
29327
  onControlsChange?.(controls);
@@ -29248,7 +29331,7 @@ var OrbitControls = ({
29248
29331
  controls.removeEventListener("change", handleChange);
29249
29332
  };
29250
29333
  }, [controls, onControlsChange]);
29251
- useEffect12(() => {
29334
+ useEffect13(() => {
29252
29335
  if (!controls) return;
29253
29336
  controls.autoRotate = autoRotate || false;
29254
29337
  controls.autoRotateSpeed = autoRotateSpeed || 1;
@@ -29281,14 +29364,14 @@ var OrbitControls = ({
29281
29364
  dampingFactor,
29282
29365
  target
29283
29366
  ]);
29284
- useEffect12(() => {
29367
+ useEffect13(() => {
29285
29368
  if (!controls || !onStart) return;
29286
29369
  controls.addEventListener("start", onStart);
29287
29370
  return () => {
29288
29371
  controls.removeEventListener("start", onStart);
29289
29372
  };
29290
29373
  }, [controls, onStart]);
29291
- useEffect12(() => {
29374
+ useEffect13(() => {
29292
29375
  if (!controls) return;
29293
29376
  return () => {
29294
29377
  controls.dispose();
@@ -29301,7 +29384,7 @@ var OrbitControls = ({
29301
29384
  };
29302
29385
 
29303
29386
  // src/react-three/Grid.tsx
29304
- import { useEffect as useEffect13, useMemo as useMemo12 } from "react";
29387
+ import { useEffect as useEffect14, useMemo as useMemo12 } from "react";
29305
29388
  import * as THREE12 from "three";
29306
29389
  var vertexShader = `
29307
29390
  varying vec3 worldPosition;
@@ -29376,7 +29459,7 @@ var Grid = ({
29376
29459
  gridMesh.position.set(camera.position.x, camera.position.y, 0);
29377
29460
  }
29378
29461
  });
29379
- useEffect13(() => {
29462
+ useEffect14(() => {
29380
29463
  if (!scene || !gridMesh) return;
29381
29464
  scene.add(gridMesh);
29382
29465
  return () => {
@@ -29393,7 +29476,7 @@ var Grid = ({
29393
29476
  };
29394
29477
 
29395
29478
  // src/react-three/Lights.tsx
29396
- import { useEffect as useEffect14, useMemo as useMemo13 } from "react";
29479
+ import { useEffect as useEffect15, useMemo as useMemo13 } from "react";
29397
29480
  import * as THREE13 from "three";
29398
29481
  var Lights = () => {
29399
29482
  const { scene } = useThree();
@@ -29407,7 +29490,7 @@ var Lights = () => {
29407
29490
  light.decay = 0;
29408
29491
  return light;
29409
29492
  }, []);
29410
- useEffect14(() => {
29493
+ useEffect15(() => {
29411
29494
  if (!scene) return;
29412
29495
  scene.add(ambientLight);
29413
29496
  scene.add(pointLight);
@@ -29420,7 +29503,7 @@ var Lights = () => {
29420
29503
  };
29421
29504
 
29422
29505
  // src/hooks/cameraAnimation.ts
29423
- import { useCallback as useCallback6, useEffect as useEffect15, useRef as useRef5 } from "react";
29506
+ import { useCallback as useCallback6, useEffect as useEffect16, useRef as useRef5 } from "react";
29424
29507
  import * as THREE14 from "three";
29425
29508
  var easeInOutCubic = (t) => t < 0.5 ? 4 * t * t * t : 1 - Math.pow(-2 * t + 2, 3) / 2;
29426
29509
  var CameraAnimatorWithContext = () => {
@@ -29492,7 +29575,7 @@ var CameraAnimatorWithContext = () => {
29492
29575
  },
29493
29576
  [animateTo, getPresetConfig]
29494
29577
  );
29495
- useEffect15(() => {
29578
+ useEffect16(() => {
29496
29579
  if (!mainCameraRef.current) return;
29497
29580
  const controller = {
29498
29581
  animateTo,
@@ -29605,7 +29688,7 @@ var useCameraSession = () => {
29605
29688
  };
29606
29689
 
29607
29690
  // src/three-components/OrientationCubeCanvas.tsx
29608
- import { useEffect as useEffect16, useRef as useRef7 } from "react";
29691
+ import { useEffect as useEffect17, useRef as useRef7 } from "react";
29609
29692
  import * as THREE15 from "three";
29610
29693
  import { Text as TroikaText } from "troika-three-text";
29611
29694
  import { jsx as jsx13 } from "react/jsx-runtime";
@@ -29626,7 +29709,7 @@ var OrientationCubeCanvas = () => {
29626
29709
  const sceneRef = useRef7(null);
29627
29710
  const cameraRef = useRef7(null);
29628
29711
  const animationFrameRef = useRef7(null);
29629
- useEffect16(() => {
29712
+ useEffect17(() => {
29630
29713
  if (!containerRef.current) return;
29631
29714
  const canvas = document.createElement("canvas");
29632
29715
  canvasRef.current = canvas;
@@ -29793,7 +29876,7 @@ var CadViewerContainer = forwardRef2(
29793
29876
  handleCameraCreated,
29794
29877
  handleControlsChange: handleSessionControlsChange
29795
29878
  } = useCameraSession();
29796
- useEffect17(() => {
29879
+ useEffect18(() => {
29797
29880
  if (onCameraControllerReady) {
29798
29881
  onCameraControllerReady(controller);
29799
29882
  }
@@ -29930,12 +30013,12 @@ var useConvertChildrenToCircuitJson = (children) => {
29930
30013
  };
29931
30014
 
29932
30015
  // src/hooks/use-stls-from-geom.ts
29933
- import { useState as useState11, useEffect as useEffect18 } from "react";
30016
+ import { useState as useState11, useEffect as useEffect19 } from "react";
29934
30017
  import stlSerializer from "@jscad/stl-serializer";
29935
30018
  var useStlsFromGeom = (geom) => {
29936
30019
  const [stls, setStls] = useState11([]);
29937
30020
  const [loading, setLoading] = useState11(true);
29938
- useEffect18(() => {
30021
+ useEffect19(() => {
29939
30022
  if (!geom) return;
29940
30023
  const generateStls = async () => {
29941
30024
  setLoading(true);
@@ -29964,7 +30047,7 @@ var useStlsFromGeom = (geom) => {
29964
30047
  };
29965
30048
 
29966
30049
  // src/hooks/useBoardGeomBuilder.ts
29967
- import { useState as useState12, useEffect as useEffect19, useRef as useRef8 } from "react";
30050
+ import { useState as useState12, useEffect as useEffect20, useRef as useRef8 } from "react";
29968
30051
 
29969
30052
  // src/soup-to-3d/index.ts
29970
30053
  var import_primitives2 = __toESM(require_primitives(), 1);
@@ -31309,7 +31392,7 @@ var BoardGeomBuilder = class {
31309
31392
  var useBoardGeomBuilder = (circuitJson) => {
31310
31393
  const [boardGeom, setBoardGeom] = useState12(null);
31311
31394
  const isProcessingRef = useRef8(false);
31312
- useEffect19(() => {
31395
+ useEffect20(() => {
31313
31396
  let isCancelled = false;
31314
31397
  if (!circuitJson) {
31315
31398
  setBoardGeom(null);
@@ -31355,10 +31438,10 @@ var useBoardGeomBuilder = (circuitJson) => {
31355
31438
  };
31356
31439
 
31357
31440
  // src/three-components/Error3d.tsx
31358
- import { useState as useState13, useCallback as useCallback8, useEffect as useEffect21, useMemo as useMemo17 } from "react";
31441
+ import { useState as useState13, useCallback as useCallback8, useEffect as useEffect22, useMemo as useMemo17 } from "react";
31359
31442
 
31360
31443
  // src/react-three/Text.tsx
31361
- import { useEffect as useEffect20, useMemo as useMemo16 } from "react";
31444
+ import { useEffect as useEffect21, useMemo as useMemo16 } from "react";
31362
31445
  import { Text as TroikaText2 } from "troika-three-text";
31363
31446
  var Text = ({
31364
31447
  children,
@@ -31398,7 +31481,7 @@ var Text = ({
31398
31481
  anchorY,
31399
31482
  depthOffset
31400
31483
  ]);
31401
- useEffect20(() => {
31484
+ useEffect21(() => {
31402
31485
  const parentObject = parent || rootObject;
31403
31486
  if (!parentObject || !mesh) return;
31404
31487
  parentObject.add(mesh);
@@ -31449,7 +31532,7 @@ var Error3d = ({
31449
31532
  g.position.fromArray(position);
31450
31533
  return g;
31451
31534
  }, [position]);
31452
- useEffect21(() => {
31535
+ useEffect22(() => {
31453
31536
  if (!rootObject) return;
31454
31537
  rootObject.add(group);
31455
31538
  return () => {
@@ -31518,7 +31601,7 @@ var ErrorBox = ({ parent }) => {
31518
31601
  m.rotation.fromArray([Math.PI / 4, Math.PI / 4, 0]);
31519
31602
  return m;
31520
31603
  }, []);
31521
- useEffect21(() => {
31604
+ useEffect22(() => {
31522
31605
  parent.add(mesh);
31523
31606
  return () => {
31524
31607
  parent.remove(mesh);
@@ -31528,7 +31611,7 @@ var ErrorBox = ({ parent }) => {
31528
31611
  };
31529
31612
 
31530
31613
  // src/three-components/STLModel.tsx
31531
- import { useState as useState14, useEffect as useEffect22, useMemo as useMemo18 } from "react";
31614
+ import { useState as useState14, useEffect as useEffect23, useMemo as useMemo18 } from "react";
31532
31615
  import * as THREE18 from "three";
31533
31616
  import { STLLoader } from "three-stdlib";
31534
31617
  function STLModel({
@@ -31541,7 +31624,7 @@ function STLModel({
31541
31624
  }) {
31542
31625
  const { rootObject } = useThree();
31543
31626
  const [geom, setGeom] = useState14(null);
31544
- useEffect22(() => {
31627
+ useEffect23(() => {
31545
31628
  const loader = new STLLoader();
31546
31629
  if (stlData) {
31547
31630
  try {
@@ -31574,7 +31657,7 @@ function STLModel({
31574
31657
  createdMesh.renderOrder = isBoardLayer ? -1 : 1;
31575
31658
  return createdMesh;
31576
31659
  }, [geom, color, opacity, layerType]);
31577
- useEffect22(() => {
31660
+ useEffect23(() => {
31578
31661
  if (!rootObject || !mesh) return;
31579
31662
  rootObject.add(mesh);
31580
31663
  return () => {
@@ -31625,27 +31708,9 @@ function VisibleSTLModel({
31625
31708
  );
31626
31709
  }
31627
31710
 
31628
- // src/three-components/ThreeErrorBoundary.tsx
31629
- import React11 from "react";
31630
- var ThreeErrorBoundary = class extends React11.Component {
31631
- constructor(props) {
31632
- super(props);
31633
- this.state = { hasError: false, error: null };
31634
- }
31635
- static getDerivedStateFromError(error) {
31636
- return { hasError: true, error };
31637
- }
31638
- render() {
31639
- if (this.state.hasError && this.state.error) {
31640
- return this.props.fallback({ error: this.state.error });
31641
- }
31642
- return this.props.children;
31643
- }
31644
- };
31645
-
31646
31711
  // src/three-components/JscadBoardTextures.tsx
31647
31712
  import { su as su8 } from "@tscircuit/circuit-json-util";
31648
- import { useEffect as useEffect23, useMemo as useMemo19 } from "react";
31713
+ import { useEffect as useEffect24, useMemo as useMemo19 } from "react";
31649
31714
 
31650
31715
  // src/textures/create-combined-board-textures.ts
31651
31716
  import * as THREE28 from "three";
@@ -33219,7 +33284,7 @@ function JscadBoardTextures({
33219
33284
  visibility
33220
33285
  });
33221
33286
  }, [circuitJson, boardData, traceTextureResolution, visibility]);
33222
- useEffect23(() => {
33287
+ useEffect24(() => {
33223
33288
  if (!rootObject || !boardData || !textures) return;
33224
33289
  const meshes = [];
33225
33290
  const disposeTextureMaterial = (material) => {
@@ -33541,12 +33606,12 @@ var CadViewerJscad = forwardRef3(
33541
33606
 
33542
33607
  // src/CadViewerManifold.tsx
33543
33608
  import { su as su17 } from "@tscircuit/circuit-json-util";
33544
- import { useEffect as useEffect25, useMemo as useMemo22, useState as useState16 } from "react";
33609
+ import { useEffect as useEffect26, useMemo as useMemo22, useState as useState16 } from "react";
33545
33610
  import * as THREE38 from "three";
33546
33611
 
33547
33612
  // src/hooks/useManifoldBoardBuilder.ts
33548
33613
  import { su as su16 } from "@tscircuit/circuit-json-util";
33549
- import { useEffect as useEffect24, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33614
+ import { useEffect as useEffect25, useMemo as useMemo21, useRef as useRef9, useState as useState15 } from "react";
33550
33615
  import * as THREE35 from "three";
33551
33616
 
33552
33617
  // src/utils/manifold/create-manifold-board.ts
@@ -34692,7 +34757,7 @@ var useManifoldBoardBuilder = (manifoldJSModule, circuitJson, visibility) => {
34692
34757
  if (!boardData) return TRACE_TEXTURE_RESOLUTION;
34693
34758
  return getLayerTextureResolution(boardData, TRACE_TEXTURE_RESOLUTION);
34694
34759
  }, [boardData]);
34695
- useEffect24(() => {
34760
+ useEffect25(() => {
34696
34761
  if (!manifoldJSModule || !boardData) {
34697
34762
  setGeoms(null);
34698
34763
  setPcbThickness(null);
@@ -35016,7 +35081,7 @@ var BoardMeshes = ({
35016
35081
  material.dispose();
35017
35082
  }
35018
35083
  };
35019
- useEffect25(() => {
35084
+ useEffect26(() => {
35020
35085
  if (!rootObject) return;
35021
35086
  geometryMeshes.forEach((mesh) => {
35022
35087
  let shouldShow = true;
@@ -35038,7 +35103,7 @@ var BoardMeshes = ({
35038
35103
  });
35039
35104
  };
35040
35105
  }, [rootObject, geometryMeshes, visibility]);
35041
- useEffect25(() => {
35106
+ useEffect26(() => {
35042
35107
  if (!rootObject) return;
35043
35108
  textureMeshes.forEach((mesh) => {
35044
35109
  rootObject.add(mesh);
@@ -35072,7 +35137,7 @@ var CadViewerManifold = ({
35072
35137
  const [manifoldJSModule, setManifoldJSModule] = useState16(null);
35073
35138
  const [manifoldLoadingError, setManifoldLoadingError] = useState16(null);
35074
35139
  const { visibility } = useLayerVisibility();
35075
- useEffect25(() => {
35140
+ useEffect26(() => {
35076
35141
  if (window.ManifoldModule && typeof window.ManifoldModule === "object" && window.ManifoldModule.setup) {
35077
35142
  setManifoldJSModule(window.ManifoldModule);
35078
35143
  return;
@@ -35258,7 +35323,7 @@ try {
35258
35323
  var CadViewerManifold_default = CadViewerManifold;
35259
35324
 
35260
35325
  // src/hooks/useContextMenu.ts
35261
- import { useState as useState17, useCallback as useCallback9, useRef as useRef10, useEffect as useEffect26 } from "react";
35326
+ import { useState as useState17, useCallback as useCallback9, useRef as useRef10, useEffect as useEffect27 } from "react";
35262
35327
  var useContextMenu = ({ containerRef }) => {
35263
35328
  const [menuVisible, setMenuVisible] = useState17(false);
35264
35329
  const [menuPos, setMenuPos] = useState17({
@@ -35373,7 +35438,7 @@ var useContextMenu = ({ containerRef }) => {
35373
35438
  }
35374
35439
  setMenuVisible(false);
35375
35440
  }, []);
35376
- useEffect26(() => {
35441
+ useEffect27(() => {
35377
35442
  if (menuVisible) {
35378
35443
  document.addEventListener("mousedown", handleClickAway);
35379
35444
  document.addEventListener("touchstart", handleClickAway);
@@ -35476,7 +35541,7 @@ var useGlobalDownloadGltf = () => {
35476
35541
  };
35477
35542
 
35478
35543
  // src/hooks/useRegisteredHotkey.ts
35479
- import { useEffect as useEffect27, useMemo as useMemo23, useRef as useRef11, useState as useState18 } from "react";
35544
+ import { useEffect as useEffect28, useMemo as useMemo23, useRef as useRef11, useState as useState18 } from "react";
35480
35545
  var hotkeyRegistry = /* @__PURE__ */ new Map();
35481
35546
  var subscribers = /* @__PURE__ */ new Set();
35482
35547
  var isListenerAttached = false;
@@ -35607,7 +35672,7 @@ var useRegisteredHotkey = (id, handler, metadata) => {
35607
35672
  }),
35608
35673
  [metadata.shortcut, metadata.description]
35609
35674
  );
35610
- useEffect27(() => {
35675
+ useEffect28(() => {
35611
35676
  const registration = {
35612
35677
  id,
35613
35678
  ...normalizedMetadata,
@@ -35623,7 +35688,7 @@ var useHotkeyRegistry = () => {
35623
35688
  const [entries, setEntries] = useState18(
35624
35689
  () => Array.from(hotkeyRegistry.values())
35625
35690
  );
35626
- useEffect27(() => subscribeToRegistry(setEntries), []);
35691
+ useEffect28(() => subscribeToRegistry(setEntries), []);
35627
35692
  return entries;
35628
35693
  };
35629
35694
  var registerHotkeyViewer = (element) => {
@@ -41759,7 +41824,7 @@ var ContextMenu = ({
41759
41824
  };
41760
41825
 
41761
41826
  // src/components/KeyboardShortcutsDialog.tsx
41762
- import { useEffect as useEffect43, useMemo as useMemo29, useRef as useRef25, useState as useState35 } from "react";
41827
+ import { useEffect as useEffect44, useMemo as useMemo29, useRef as useRef25, useState as useState35 } from "react";
41763
41828
  import { jsx as jsx37, jsxs as jsxs10 } from "react/jsx-runtime";
41764
41829
  var KeyboardShortcutsDialog = ({
41765
41830
  open,
@@ -41768,7 +41833,7 @@ var KeyboardShortcutsDialog = ({
41768
41833
  const [query, setQuery] = useState35("");
41769
41834
  const inputRef = useRef25(null);
41770
41835
  const hotkeys = useHotkeyRegistry();
41771
- useEffect43(() => {
41836
+ useEffect44(() => {
41772
41837
  if (!open) return void 0;
41773
41838
  const handleKeyDown = (event) => {
41774
41839
  if (event.key === "Escape") {
@@ -41779,7 +41844,7 @@ var KeyboardShortcutsDialog = ({
41779
41844
  window.addEventListener("keydown", handleKeyDown);
41780
41845
  return () => window.removeEventListener("keydown", handleKeyDown);
41781
41846
  }, [open, onClose]);
41782
- useEffect43(() => {
41847
+ useEffect44(() => {
41783
41848
  if (open) {
41784
41849
  setTimeout(() => {
41785
41850
  inputRef.current?.focus();
@@ -42075,36 +42140,36 @@ var CadViewerInner = (props) => {
42075
42140
  description: "Toggle translucent components"
42076
42141
  }
42077
42142
  );
42078
- useEffect44(() => {
42143
+ useEffect45(() => {
42079
42144
  if (containerRef.current) {
42080
42145
  registerHotkeyViewer(containerRef.current);
42081
42146
  }
42082
42147
  }, []);
42083
- useEffect44(() => {
42148
+ useEffect45(() => {
42084
42149
  const stored = window.localStorage.getItem("cadViewerEngine");
42085
42150
  if (stored === "jscad" || stored === "manifold") {
42086
42151
  setEngine(stored);
42087
42152
  }
42088
42153
  }, []);
42089
- useEffect44(() => {
42154
+ useEffect45(() => {
42090
42155
  window.localStorage.setItem("cadViewerEngine", engine);
42091
42156
  }, [engine]);
42092
- useEffect44(() => {
42157
+ useEffect45(() => {
42093
42158
  window.localStorage.setItem("cadViewerAutoRotate", String(autoRotate));
42094
42159
  }, [autoRotate]);
42095
- useEffect44(() => {
42160
+ useEffect45(() => {
42096
42161
  window.localStorage.setItem(
42097
42162
  "cadViewerAutoRotateUserToggled",
42098
42163
  String(autoRotateUserToggled)
42099
42164
  );
42100
42165
  }, [autoRotateUserToggled]);
42101
- useEffect44(() => {
42166
+ useEffect45(() => {
42102
42167
  const stored = window.localStorage.getItem("cadViewerCameraType");
42103
42168
  if (stored === "orthographic" || stored === "perspective") {
42104
42169
  setCameraType(stored);
42105
42170
  }
42106
42171
  }, [setCameraType]);
42107
- useEffect44(() => {
42172
+ useEffect45(() => {
42108
42173
  window.localStorage.setItem("cadViewerCameraType", cameraType);
42109
42174
  }, [cameraType]);
42110
42175
  const viewerKey = props.circuitJson ? JSON.stringify(props.circuitJson) : void 0;
@@ -42504,7 +42569,7 @@ async function convertCircuitJsonTo3dSvg(circuitJson, options = {}) {
42504
42569
 
42505
42570
  // src/hooks/exporter/gltf.ts
42506
42571
  import { GLTFExporter as GLTFExporter3 } from "three-stdlib";
42507
- import { useEffect as useEffect45, useState as useState37, useMemo as useMemo30, useCallback as useCallback22 } from "react";
42572
+ import { useEffect as useEffect46, useState as useState37, useMemo as useMemo30, useCallback as useCallback22 } from "react";
42508
42573
  function useSaveGltfAs(options = {}) {
42509
42574
  const parse2 = useParser(options);
42510
42575
  const link = useMemo30(() => document.createElement("a"), []);
@@ -42517,7 +42582,7 @@ function useSaveGltfAs(options = {}) {
42517
42582
  link.dispatchEvent(new MouseEvent("click"));
42518
42583
  URL.revokeObjectURL(url);
42519
42584
  };
42520
- useEffect45(
42585
+ useEffect46(
42521
42586
  () => () => {
42522
42587
  link.remove();
42523
42588
  instance = null;
@@ -42538,7 +42603,7 @@ function useExportGltfUrl(options = {}) {
42538
42603
  (instance) => parse2(instance).then(setUrl).catch(setError),
42539
42604
  []
42540
42605
  );
42541
- useEffect45(() => () => URL.revokeObjectURL(url), [url]);
42606
+ useEffect46(() => () => URL.revokeObjectURL(url), [url]);
42542
42607
  return [ref, url, error];
42543
42608
  }
42544
42609
  function useParser(options = {}) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/3d-viewer",
3
- "version": "0.0.531",
3
+ "version": "0.0.533",
4
4
  "main": "./dist/index.js",
5
5
  "module": "./dist/index.js",
6
6
  "type": "module",