@tscircuit/pcb-viewer 1.11.420 → 1.11.422
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 +30 -3
- package/dist/index.js +240 -110
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
package/dist/index.d.ts
CHANGED
|
@@ -80,10 +80,32 @@ interface BoundsSelection {
|
|
|
80
80
|
maxY: number;
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
interface PcbViewerController {
|
|
84
|
+
/** @internal Pending command, consumed after the viewer focuses the component. */
|
|
85
|
+
focusRequest: {
|
|
86
|
+
pcbComponentId: string;
|
|
87
|
+
} | null;
|
|
88
|
+
/** @internal Acknowledge only this request, preserving newer commands. */
|
|
89
|
+
onFocusRequestHandled: (request: {
|
|
90
|
+
pcbComponentId: string;
|
|
91
|
+
}) => void;
|
|
92
|
+
}
|
|
93
|
+
/** Focus commands may be issued before the PCB viewer mounts, such as when switching tabs. */
|
|
94
|
+
declare const usePcbViewerController: () => {
|
|
95
|
+
controller: {
|
|
96
|
+
focusRequest: {
|
|
97
|
+
pcbComponentId: string;
|
|
98
|
+
};
|
|
99
|
+
onFocusRequestHandled: (request: NonNullable<PcbViewerController["focusRequest"]>) => void;
|
|
100
|
+
};
|
|
101
|
+
focusPcbComponent: (pcbComponentId: string) => void;
|
|
102
|
+
};
|
|
103
|
+
|
|
83
104
|
type Props = {
|
|
84
105
|
circuitJson?: AnyCircuitElement[];
|
|
85
106
|
height?: number;
|
|
86
|
-
/** Initial engine;
|
|
107
|
+
/** Initial engine override; otherwise restores the saved user preference.
|
|
108
|
+
* Users can switch via the context menu. Prop changes reset it.
|
|
87
109
|
* WebGPU runs in a worker and reports failures without changing engines. */
|
|
88
110
|
renderer?: "webgpu" | "canvas";
|
|
89
111
|
allowEditing?: boolean;
|
|
@@ -99,8 +121,10 @@ type Props = {
|
|
|
99
121
|
clickToInteractEnabled?: boolean;
|
|
100
122
|
debugGraphics?: GraphicsObject | null;
|
|
101
123
|
disablePcbGroups?: boolean;
|
|
124
|
+
/** Connect the controller returned by usePcbViewerController. */
|
|
125
|
+
controller?: PcbViewerController;
|
|
102
126
|
};
|
|
103
|
-
declare const PCBViewer: ({ circuitJson, debugGraphics, height, renderer, initialState, allowEditing, editEvents: editEventsProp, onEditEventsChanged, onRenderComplete, onBoundsSelected, onViewSchematicComponent, focusOnHover, clickToInteractEnabled, disablePcbGroups, }: Props) => react_jsx_runtime.JSX.Element;
|
|
127
|
+
declare const PCBViewer: ({ circuitJson, debugGraphics, height, renderer, initialState, allowEditing, editEvents: editEventsProp, onEditEventsChanged, onRenderComplete, onBoundsSelected, onViewSchematicComponent, focusOnHover, clickToInteractEnabled, disablePcbGroups, controller, }: Props) => react_jsx_runtime.JSX.Element;
|
|
104
128
|
|
|
105
129
|
interface CanvasElementsRendererProps {
|
|
106
130
|
elements: AnyCircuitElement[];
|
|
@@ -113,6 +137,9 @@ interface CanvasElementsRendererProps {
|
|
|
113
137
|
grid?: GridConfig;
|
|
114
138
|
allowEditing: boolean;
|
|
115
139
|
focusOnHover?: boolean;
|
|
140
|
+
focusedPcbComponent?: {
|
|
141
|
+
pcbComponentId: string;
|
|
142
|
+
} | null;
|
|
116
143
|
onViewSchematicComponent?: (event: ViewSchematicComponentEvent) => void;
|
|
117
144
|
onBoundsSelected?: (bounds: BoundsSelection) => void;
|
|
118
145
|
onContextMenuOpenChange?: (open: boolean) => void;
|
|
@@ -123,4 +150,4 @@ interface CanvasElementsRendererProps {
|
|
|
123
150
|
}
|
|
124
151
|
declare const CanvasElementsRenderer: (props: CanvasElementsRendererProps) => react_jsx_runtime.JSX.Element;
|
|
125
152
|
|
|
126
|
-
export { CanvasElementsRenderer, PCBViewer, type ViewSchematicComponentEvent };
|
|
153
|
+
export { CanvasElementsRenderer, PCBViewer, type PcbViewerController, type ViewSchematicComponentEvent, usePcbViewerController };
|
package/dist/index.js
CHANGED
|
@@ -9596,6 +9596,7 @@ import { useContext as useContext2 } from "react";
|
|
|
9596
9596
|
// src/hooks/useLocalStorage.ts
|
|
9597
9597
|
import { useCallback } from "react";
|
|
9598
9598
|
var STORAGE_KEYS = {
|
|
9599
|
+
RENDERING_ENGINE: "pcb_viewer_rendering_engine",
|
|
9599
9600
|
COPPER_POUR_OPACITY: "pcb_viewer_copper_pour_opacity",
|
|
9600
9601
|
HIDDEN_LAYER_OPACITY: "pcb_viewer_hidden_layer_opacity",
|
|
9601
9602
|
IS_SHOWING_PCB_GROUPS: "pcb_viewer_is_showing_pcb_groups",
|
|
@@ -9827,7 +9828,7 @@ var ToastContainer = () => {
|
|
|
9827
9828
|
};
|
|
9828
9829
|
|
|
9829
9830
|
// src/PCBViewer.tsx
|
|
9830
|
-
import { useCallback as useCallback12, useEffect as
|
|
9831
|
+
import { useCallback as useCallback12, useEffect as useEffect21, useMemo as useMemo11, useRef as useRef17, useState as useState14 } from "react";
|
|
9831
9832
|
|
|
9832
9833
|
// node_modules/react-use/esm/useMountedState.js
|
|
9833
9834
|
import { useCallback as useCallback2, useEffect as useEffect2, useRef } from "react";
|
|
@@ -11665,8 +11666,8 @@ var animateTransform = ({
|
|
|
11665
11666
|
};
|
|
11666
11667
|
|
|
11667
11668
|
// src/components/CanvasElementsRenderer.tsx
|
|
11668
|
-
import { useCallback as useCallback11, useEffect as
|
|
11669
|
-
import { applyToPoint as
|
|
11669
|
+
import { useCallback as useCallback11, useEffect as useEffect20, useMemo as useMemo10, useRef as useRef16, useState as useState13 } from "react";
|
|
11670
|
+
import { applyToPoint as applyToPoint20, inverse as inverse6 } from "transformation-matrix";
|
|
11670
11671
|
|
|
11671
11672
|
// src/lib/get-trace-overlay-text.ts
|
|
11672
11673
|
var getNonEmptyName = (name) => name?.trim() || null;
|
|
@@ -18585,7 +18586,7 @@ import { css as css3 } from "@emotion/css";
|
|
|
18585
18586
|
// package.json
|
|
18586
18587
|
var package_default = {
|
|
18587
18588
|
name: "@tscircuit/pcb-viewer",
|
|
18588
|
-
version: "1.11.
|
|
18589
|
+
version: "1.11.421",
|
|
18589
18590
|
main: "dist/index.js",
|
|
18590
18591
|
type: "module",
|
|
18591
18592
|
repository: {
|
|
@@ -18602,6 +18603,7 @@ var package_default = {
|
|
|
18602
18603
|
cosmos: "cosmos",
|
|
18603
18604
|
"cosmos-export": "cosmos-export",
|
|
18604
18605
|
"test:x-ray-net": "bun run build && bun tests/x-ray-net/run.ts",
|
|
18606
|
+
"test:component-focus": "bun run build && bun tests/component-focus/run.ts",
|
|
18605
18607
|
"test:measurement-context-menu": "bun run build && bun tests/measurement-context-menu/run.ts",
|
|
18606
18608
|
"test:copper-pour-opacity": "bun run build && bun tests/copper-pour-opacity/run.ts",
|
|
18607
18609
|
"test:webgpu": "bun run build && bun tests/webgpu/run.ts"
|
|
@@ -20574,8 +20576,66 @@ var WarningGraphicsOverlay = ({
|
|
|
20574
20576
|
);
|
|
20575
20577
|
};
|
|
20576
20578
|
|
|
20577
|
-
// src/components/
|
|
20579
|
+
// src/components/FocusedPcbComponentOverlay.tsx
|
|
20580
|
+
import { useEffect as useEffect19 } from "react";
|
|
20581
|
+
import { applyToPoint as applyToPoint19 } from "transformation-matrix";
|
|
20582
|
+
|
|
20583
|
+
// src/lib/get-pcb-component-focus.ts
|
|
20584
|
+
var getPcbComponentFocus = (elements, pcbComponentId, width, height) => {
|
|
20585
|
+
if (width <= 0 || height <= 0) return;
|
|
20586
|
+
const component = elements.find(
|
|
20587
|
+
(element) => element.type === "pcb_component" && element.pcb_component_id === pcbComponentId
|
|
20588
|
+
);
|
|
20589
|
+
if (component?.type !== "pcb_component") return;
|
|
20590
|
+
const bounds = getPcbElementBounds(component);
|
|
20591
|
+
if (!bounds) return;
|
|
20592
|
+
return {
|
|
20593
|
+
component,
|
|
20594
|
+
bounds,
|
|
20595
|
+
transform: createTransformForBounds({ bounds, width, height })
|
|
20596
|
+
};
|
|
20597
|
+
};
|
|
20598
|
+
|
|
20599
|
+
// src/components/FocusedPcbComponentOverlay.tsx
|
|
20578
20600
|
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
20601
|
+
var FocusedPcbComponentOverlay = ({
|
|
20602
|
+
focusRequest,
|
|
20603
|
+
elements,
|
|
20604
|
+
transform
|
|
20605
|
+
}) => {
|
|
20606
|
+
const componentId = focusRequest?.pcbComponentId;
|
|
20607
|
+
const selectLayer = useGlobalStore((state) => state.selectLayer);
|
|
20608
|
+
const focus = componentId ? getPcbComponentFocus(elements, componentId, 1, 1) : void 0;
|
|
20609
|
+
const layer = focus?.component.layer;
|
|
20610
|
+
useEffect19(() => {
|
|
20611
|
+
if (layer) selectLayer(layer);
|
|
20612
|
+
}, [focusRequest, layer, selectLayer]);
|
|
20613
|
+
if (!focus || !transform) return null;
|
|
20614
|
+
const { bounds } = focus;
|
|
20615
|
+
const a = applyToPoint19(transform, { x: bounds.minX, y: bounds.minY });
|
|
20616
|
+
const b = applyToPoint19(transform, { x: bounds.maxX, y: bounds.maxY });
|
|
20617
|
+
return /* @__PURE__ */ jsx25(
|
|
20618
|
+
"div",
|
|
20619
|
+
{
|
|
20620
|
+
"data-focused-pcb-component-id": componentId,
|
|
20621
|
+
style: {
|
|
20622
|
+
position: "absolute",
|
|
20623
|
+
left: Math.min(a.x, b.x) - 4,
|
|
20624
|
+
top: Math.min(a.y, b.y) - 4,
|
|
20625
|
+
width: Math.abs(b.x - a.x) + 8,
|
|
20626
|
+
height: Math.abs(b.y - a.y) + 8,
|
|
20627
|
+
border: "2px solid #3399ff",
|
|
20628
|
+
borderRadius: 4,
|
|
20629
|
+
boxSizing: "border-box",
|
|
20630
|
+
pointerEvents: "none",
|
|
20631
|
+
zIndex: zIndexMap.elementOverlay
|
|
20632
|
+
}
|
|
20633
|
+
}
|
|
20634
|
+
);
|
|
20635
|
+
};
|
|
20636
|
+
|
|
20637
|
+
// src/components/CanvasElementsRenderer.tsx
|
|
20638
|
+
import { jsx as jsx26, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
20579
20639
|
var CanvasElementsRenderer = (props) => {
|
|
20580
20640
|
const { transform, elements } = props;
|
|
20581
20641
|
const {
|
|
@@ -20605,8 +20665,8 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20605
20665
|
[elements]
|
|
20606
20666
|
);
|
|
20607
20667
|
const [xRayNetIds, setXRayNetIds] = useState13([]);
|
|
20608
|
-
|
|
20609
|
-
|
|
20668
|
+
useEffect20(() => setXRayNetIds([]), [connectivityMap]);
|
|
20669
|
+
useEffect20(() => {
|
|
20610
20670
|
if (xRayNetIds.length === 0) return;
|
|
20611
20671
|
const onKeyDown = (event) => {
|
|
20612
20672
|
if (event.key === "Escape") setXRayNetIds([]);
|
|
@@ -20633,7 +20693,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20633
20693
|
if (!transform) return;
|
|
20634
20694
|
const hits = getPrimitivesUnderPoint(
|
|
20635
20695
|
primitivesWithoutInteractionMetadata,
|
|
20636
|
-
|
|
20696
|
+
applyToPoint20(inverse6(transform), point2),
|
|
20637
20697
|
transform,
|
|
20638
20698
|
selectedLayer
|
|
20639
20699
|
).filter(
|
|
@@ -20653,7 +20713,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20653
20713
|
});
|
|
20654
20714
|
const hits = getPrimitivesUnderPoint(
|
|
20655
20715
|
primitivesWithoutInteractionMetadata,
|
|
20656
|
-
|
|
20716
|
+
applyToPoint20(inverse6(transform), point2),
|
|
20657
20717
|
transform,
|
|
20658
20718
|
selectedLayer,
|
|
20659
20719
|
xRayNetIds.length > 0
|
|
@@ -20696,17 +20756,17 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20696
20756
|
if (!activeError) return [];
|
|
20697
20757
|
return getRelatedIdsForError(activeError);
|
|
20698
20758
|
}, [activeErrorId, elements]);
|
|
20699
|
-
|
|
20759
|
+
useEffect20(() => {
|
|
20700
20760
|
if (transform) {
|
|
20701
20761
|
currentTransformRef.current = transform;
|
|
20702
20762
|
}
|
|
20703
20763
|
}, [transform]);
|
|
20704
|
-
|
|
20764
|
+
useEffect20(() => {
|
|
20705
20765
|
return () => {
|
|
20706
20766
|
cancelTransformAnimation(zoomAnimationFrameRef.current);
|
|
20707
20767
|
};
|
|
20708
20768
|
}, []);
|
|
20709
|
-
|
|
20769
|
+
useEffect20(() => {
|
|
20710
20770
|
if (!props.width || !props.height || !props.setTransform || !focusedErrorId)
|
|
20711
20771
|
return;
|
|
20712
20772
|
const focusedError = findErrorElementById(elements, focusedErrorId);
|
|
@@ -20794,7 +20854,7 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20794
20854
|
},
|
|
20795
20855
|
[connectivityMap]
|
|
20796
20856
|
);
|
|
20797
|
-
return /* @__PURE__ */
|
|
20857
|
+
return /* @__PURE__ */ jsxs19(
|
|
20798
20858
|
MouseElementTracker,
|
|
20799
20859
|
{
|
|
20800
20860
|
elements: elementsToRender,
|
|
@@ -20802,87 +20862,97 @@ var CanvasElementsRenderer = (props) => {
|
|
|
20802
20862
|
primitives: hoverPrimitives,
|
|
20803
20863
|
selectedLayer,
|
|
20804
20864
|
onMouseHoverOverPrimitives: onMouseOverPrimitives,
|
|
20805
|
-
children:
|
|
20806
|
-
|
|
20807
|
-
|
|
20808
|
-
|
|
20809
|
-
|
|
20810
|
-
|
|
20811
|
-
|
|
20812
|
-
|
|
20813
|
-
|
|
20814
|
-
|
|
20815
|
-
|
|
20816
|
-
|
|
20817
|
-
|
|
20818
|
-
|
|
20819
|
-
|
|
20820
|
-
|
|
20821
|
-
|
|
20822
|
-
|
|
20823
|
-
|
|
20824
|
-
|
|
20825
|
-
|
|
20826
|
-
|
|
20827
|
-
|
|
20828
|
-
|
|
20829
|
-
|
|
20830
|
-
|
|
20831
|
-
|
|
20832
|
-
|
|
20833
|
-
|
|
20834
|
-
|
|
20835
|
-
|
|
20836
|
-
|
|
20837
|
-
|
|
20838
|
-
|
|
20839
|
-
|
|
20840
|
-
|
|
20841
|
-
|
|
20842
|
-
|
|
20843
|
-
|
|
20844
|
-
|
|
20845
|
-
|
|
20846
|
-
|
|
20847
|
-
|
|
20848
|
-
|
|
20849
|
-
|
|
20850
|
-
|
|
20851
|
-
|
|
20852
|
-
|
|
20853
|
-
|
|
20854
|
-
|
|
20855
|
-
|
|
20856
|
-
|
|
20857
|
-
|
|
20858
|
-
|
|
20859
|
-
|
|
20860
|
-
|
|
20861
|
-
|
|
20862
|
-
|
|
20863
|
-
|
|
20864
|
-
|
|
20865
|
-
|
|
20866
|
-
|
|
20867
|
-
|
|
20868
|
-
|
|
20869
|
-
|
|
20870
|
-
|
|
20871
|
-
|
|
20872
|
-
|
|
20873
|
-
|
|
20874
|
-
|
|
20875
|
-
|
|
20876
|
-
|
|
20877
|
-
|
|
20878
|
-
|
|
20879
|
-
|
|
20880
|
-
|
|
20881
|
-
|
|
20882
|
-
|
|
20883
|
-
|
|
20884
|
-
|
|
20885
|
-
|
|
20865
|
+
children: [
|
|
20866
|
+
/* @__PURE__ */ jsx26(
|
|
20867
|
+
FocusedPcbComponentOverlay,
|
|
20868
|
+
{
|
|
20869
|
+
focusRequest: props.focusedPcbComponent,
|
|
20870
|
+
elements,
|
|
20871
|
+
transform
|
|
20872
|
+
}
|
|
20873
|
+
),
|
|
20874
|
+
/* @__PURE__ */ jsx26(
|
|
20875
|
+
EditPlacementOverlay,
|
|
20876
|
+
{
|
|
20877
|
+
disabled: !props.allowEditing,
|
|
20878
|
+
transform,
|
|
20879
|
+
soup: elements,
|
|
20880
|
+
cancelPanDrag: props.cancelPanDrag,
|
|
20881
|
+
onCreateEditEvent: props.onCreateEditEvent,
|
|
20882
|
+
onModifyEditEvent: props.onModifyEditEvent,
|
|
20883
|
+
children: /* @__PURE__ */ jsx26(
|
|
20884
|
+
DimensionOverlay,
|
|
20885
|
+
{
|
|
20886
|
+
transform,
|
|
20887
|
+
focusOnHover: props.focusOnHover,
|
|
20888
|
+
primitives: primitivesWithoutInteractionMetadata,
|
|
20889
|
+
onBoundsSelected: props.onBoundsSelected,
|
|
20890
|
+
cancelPanDrag: props.cancelPanDrag,
|
|
20891
|
+
children: /* @__PURE__ */ jsx26(
|
|
20892
|
+
ToolbarOverlay,
|
|
20893
|
+
{
|
|
20894
|
+
elements,
|
|
20895
|
+
getNetAtPoint,
|
|
20896
|
+
xRayNetIds,
|
|
20897
|
+
onXRayNetsChange: setXRayNetIds,
|
|
20898
|
+
onContextMenuOpenChange: props.onContextMenuOpenChange,
|
|
20899
|
+
getComponentAtPoint,
|
|
20900
|
+
onViewSchematicComponent: props.onViewSchematicComponent,
|
|
20901
|
+
children: /* @__PURE__ */ jsx26(ErrorOverlay, { transform, elements, children: /* @__PURE__ */ jsx26(RatsNestOverlay, { transform, soup: elements, children: /* @__PURE__ */ jsx26(
|
|
20902
|
+
PcbGroupOverlay,
|
|
20903
|
+
{
|
|
20904
|
+
transform,
|
|
20905
|
+
elements,
|
|
20906
|
+
hoveredComponentIds,
|
|
20907
|
+
children: /* @__PURE__ */ jsx26(
|
|
20908
|
+
DebugGraphicsOverlay,
|
|
20909
|
+
{
|
|
20910
|
+
transform,
|
|
20911
|
+
debugGraphics: props.debugGraphics,
|
|
20912
|
+
children: /* @__PURE__ */ jsx26(
|
|
20913
|
+
WarningGraphicsOverlay,
|
|
20914
|
+
{
|
|
20915
|
+
transform,
|
|
20916
|
+
elements,
|
|
20917
|
+
children: props.renderer === "canvas" ? /* @__PURE__ */ jsx26(
|
|
20918
|
+
CanvasPrimitiveRenderer,
|
|
20919
|
+
{
|
|
20920
|
+
transform,
|
|
20921
|
+
primitives,
|
|
20922
|
+
elements: elementsToRender,
|
|
20923
|
+
circuitJson: elements,
|
|
20924
|
+
xRayElements,
|
|
20925
|
+
width: props.width,
|
|
20926
|
+
height: props.height,
|
|
20927
|
+
grid: props.grid,
|
|
20928
|
+
onRenderComplete: props.onRenderComplete
|
|
20929
|
+
}
|
|
20930
|
+
) : /* @__PURE__ */ jsx26(
|
|
20931
|
+
WebGpuElementsRenderer,
|
|
20932
|
+
{
|
|
20933
|
+
transform,
|
|
20934
|
+
primitives,
|
|
20935
|
+
elements,
|
|
20936
|
+
xRayElements,
|
|
20937
|
+
width: props.width,
|
|
20938
|
+
height: props.height,
|
|
20939
|
+
grid: props.grid,
|
|
20940
|
+
onRenderComplete: props.onRenderComplete
|
|
20941
|
+
}
|
|
20942
|
+
)
|
|
20943
|
+
}
|
|
20944
|
+
)
|
|
20945
|
+
}
|
|
20946
|
+
)
|
|
20947
|
+
}
|
|
20948
|
+
) }) })
|
|
20949
|
+
}
|
|
20950
|
+
)
|
|
20951
|
+
}
|
|
20952
|
+
)
|
|
20953
|
+
}
|
|
20954
|
+
)
|
|
20955
|
+
]
|
|
20886
20956
|
}
|
|
20887
20957
|
);
|
|
20888
20958
|
};
|
|
@@ -21008,13 +21078,17 @@ function applyEditEvents({
|
|
|
21008
21078
|
}
|
|
21009
21079
|
|
|
21010
21080
|
// src/PCBViewer.tsx
|
|
21011
|
-
import { jsx as
|
|
21081
|
+
import { jsx as jsx27, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
21012
21082
|
var defaultTransform = compose9(translate14(400, 300), scale6(40, -40));
|
|
21083
|
+
var getPreferredRenderer = () => {
|
|
21084
|
+
const stored = getStoredString(STORAGE_KEYS.RENDERING_ENGINE, "webgpu");
|
|
21085
|
+
return stored === "canvas" || stored === "webgpu" ? stored : "webgpu";
|
|
21086
|
+
};
|
|
21013
21087
|
var PCBViewer = ({
|
|
21014
21088
|
circuitJson,
|
|
21015
21089
|
debugGraphics,
|
|
21016
21090
|
height = 600,
|
|
21017
|
-
renderer
|
|
21091
|
+
renderer,
|
|
21018
21092
|
initialState,
|
|
21019
21093
|
allowEditing = true,
|
|
21020
21094
|
editEvents: editEventsProp,
|
|
@@ -21024,13 +21098,24 @@ var PCBViewer = ({
|
|
|
21024
21098
|
onViewSchematicComponent,
|
|
21025
21099
|
focusOnHover = false,
|
|
21026
21100
|
clickToInteractEnabled = false,
|
|
21027
|
-
disablePcbGroups = false
|
|
21101
|
+
disablePcbGroups = false,
|
|
21102
|
+
controller
|
|
21028
21103
|
}) => {
|
|
21029
|
-
const [activeRenderer, setActiveRenderer] = useState14(
|
|
21030
|
-
|
|
21104
|
+
const [activeRenderer, setActiveRenderer] = useState14(
|
|
21105
|
+
() => renderer ?? getPreferredRenderer()
|
|
21106
|
+
);
|
|
21107
|
+
const [focusedPcbComponent, setFocusedPcbComponent] = useState14(null);
|
|
21108
|
+
useEffect21(
|
|
21109
|
+
() => setActiveRenderer(renderer ?? getPreferredRenderer()),
|
|
21110
|
+
[renderer]
|
|
21111
|
+
);
|
|
21112
|
+
const setPreferredRenderer = useCallback12((engine) => {
|
|
21113
|
+
setActiveRenderer(engine);
|
|
21114
|
+
setStoredString(STORAGE_KEYS.RENDERING_ENGINE, engine);
|
|
21115
|
+
}, []);
|
|
21031
21116
|
const renderingEngine = useMemo11(
|
|
21032
|
-
() => ({ renderer: activeRenderer, setRenderer:
|
|
21033
|
-
[activeRenderer]
|
|
21117
|
+
() => ({ renderer: activeRenderer, setRenderer: setPreferredRenderer }),
|
|
21118
|
+
[activeRenderer, setPreferredRenderer]
|
|
21034
21119
|
);
|
|
21035
21120
|
const [isInteractionEnabled, setIsInteractionEnabled] = useState14(
|
|
21036
21121
|
!clickToInteractEnabled
|
|
@@ -21097,7 +21182,7 @@ var PCBViewer = ({
|
|
|
21097
21182
|
setTransform(targetTransform);
|
|
21098
21183
|
return;
|
|
21099
21184
|
};
|
|
21100
|
-
|
|
21185
|
+
useEffect21(() => {
|
|
21101
21186
|
if (!refDimensions?.width) return;
|
|
21102
21187
|
if (!circuitJson) return;
|
|
21103
21188
|
if (circuitJson.length === 0) return;
|
|
@@ -21106,7 +21191,7 @@ var PCBViewer = ({
|
|
|
21106
21191
|
initialRenderCompleted.current = true;
|
|
21107
21192
|
}
|
|
21108
21193
|
}, [circuitJson, refDimensions]);
|
|
21109
|
-
|
|
21194
|
+
useEffect21(() => {
|
|
21110
21195
|
if (initialRenderCompleted.current === true) {
|
|
21111
21196
|
resetTransform();
|
|
21112
21197
|
}
|
|
@@ -21122,6 +21207,29 @@ var PCBViewer = ({
|
|
|
21122
21207
|
editEvents
|
|
21123
21208
|
});
|
|
21124
21209
|
}, [pcbElmsPreEdit, editEvents]);
|
|
21210
|
+
useEffect21(() => {
|
|
21211
|
+
const request = controller?.focusRequest;
|
|
21212
|
+
if (!request || !refDimensions.width || !height || !elements.length) return;
|
|
21213
|
+
const focus = getPcbComponentFocus(
|
|
21214
|
+
elements,
|
|
21215
|
+
request.pcbComponentId,
|
|
21216
|
+
refDimensions.width,
|
|
21217
|
+
height
|
|
21218
|
+
);
|
|
21219
|
+
if (focus) {
|
|
21220
|
+
cancelPanDrag();
|
|
21221
|
+
setTransform(focus.transform);
|
|
21222
|
+
setFocusedPcbComponent(request);
|
|
21223
|
+
}
|
|
21224
|
+
controller.onFocusRequestHandled(request);
|
|
21225
|
+
}, [
|
|
21226
|
+
controller,
|
|
21227
|
+
elements,
|
|
21228
|
+
refDimensions.width,
|
|
21229
|
+
height,
|
|
21230
|
+
cancelPanDrag,
|
|
21231
|
+
setTransform
|
|
21232
|
+
]);
|
|
21125
21233
|
const onCreateEditEvent = (event) => {
|
|
21126
21234
|
setEditEvents([...editEvents, event]);
|
|
21127
21235
|
onEditEventsChanged?.([...editEvents, event]);
|
|
@@ -21140,20 +21248,20 @@ var PCBViewer = ({
|
|
|
21140
21248
|
}),
|
|
21141
21249
|
[initialState, disablePcbGroups]
|
|
21142
21250
|
);
|
|
21143
|
-
return /* @__PURE__ */
|
|
21251
|
+
return /* @__PURE__ */ jsx27(RenderingEngineContext.Provider, { value: renderingEngine, children: /* @__PURE__ */ jsxs20(
|
|
21144
21252
|
"div",
|
|
21145
21253
|
{
|
|
21146
21254
|
ref: transformRef,
|
|
21147
21255
|
style: { position: "relative" },
|
|
21148
21256
|
onContextMenu: (event) => event.preventDefault(),
|
|
21149
21257
|
children: [
|
|
21150
|
-
/* @__PURE__ */
|
|
21258
|
+
/* @__PURE__ */ jsx27("div", { ref, children: /* @__PURE__ */ jsxs20(
|
|
21151
21259
|
ContextProviders,
|
|
21152
21260
|
{
|
|
21153
21261
|
initialState: mergedInitialState,
|
|
21154
21262
|
disablePcbGroups,
|
|
21155
21263
|
children: [
|
|
21156
|
-
/* @__PURE__ */
|
|
21264
|
+
/* @__PURE__ */ jsx27(
|
|
21157
21265
|
CanvasElementsRenderer,
|
|
21158
21266
|
{
|
|
21159
21267
|
renderer: activeRenderer,
|
|
@@ -21165,6 +21273,7 @@ var PCBViewer = ({
|
|
|
21165
21273
|
focusOnHover,
|
|
21166
21274
|
onBoundsSelected,
|
|
21167
21275
|
onViewSchematicComponent,
|
|
21276
|
+
focusedPcbComponent,
|
|
21168
21277
|
cancelPanDrag,
|
|
21169
21278
|
onContextMenuOpenChange,
|
|
21170
21279
|
onCreateEditEvent,
|
|
@@ -21183,11 +21292,11 @@ var PCBViewer = ({
|
|
|
21183
21292
|
debugGraphics
|
|
21184
21293
|
}
|
|
21185
21294
|
),
|
|
21186
|
-
/* @__PURE__ */
|
|
21295
|
+
/* @__PURE__ */ jsx27(ToastContainer, {})
|
|
21187
21296
|
]
|
|
21188
21297
|
}
|
|
21189
21298
|
) }),
|
|
21190
|
-
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */
|
|
21299
|
+
clickToInteractEnabled && !isInteractionEnabled && /* @__PURE__ */ jsx27(
|
|
21191
21300
|
"div",
|
|
21192
21301
|
{
|
|
21193
21302
|
onClick: () => {
|
|
@@ -21224,7 +21333,7 @@ var PCBViewer = ({
|
|
|
21224
21333
|
justifyContent: "center",
|
|
21225
21334
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
21226
21335
|
},
|
|
21227
|
-
children: /* @__PURE__ */
|
|
21336
|
+
children: /* @__PURE__ */ jsx27(
|
|
21228
21337
|
"div",
|
|
21229
21338
|
{
|
|
21230
21339
|
style: {
|
|
@@ -21244,9 +21353,30 @@ var PCBViewer = ({
|
|
|
21244
21353
|
}
|
|
21245
21354
|
) });
|
|
21246
21355
|
};
|
|
21356
|
+
|
|
21357
|
+
// src/hooks/usePcbViewerController.ts
|
|
21358
|
+
import { useCallback as useCallback13, useMemo as useMemo12, useState as useState15 } from "react";
|
|
21359
|
+
var usePcbViewerController = () => {
|
|
21360
|
+
const [focusRequest, setFocusRequest] = useState15(null);
|
|
21361
|
+
const focusPcbComponent = useCallback13((pcbComponentId) => {
|
|
21362
|
+
setFocusRequest({ pcbComponentId });
|
|
21363
|
+
}, []);
|
|
21364
|
+
const onFocusRequestHandled = useCallback13(
|
|
21365
|
+
(request) => {
|
|
21366
|
+
setFocusRequest((current) => current === request ? null : current);
|
|
21367
|
+
},
|
|
21368
|
+
[]
|
|
21369
|
+
);
|
|
21370
|
+
const controller = useMemo12(
|
|
21371
|
+
() => ({ focusRequest, onFocusRequestHandled }),
|
|
21372
|
+
[focusRequest, onFocusRequestHandled]
|
|
21373
|
+
);
|
|
21374
|
+
return { controller, focusPcbComponent };
|
|
21375
|
+
};
|
|
21247
21376
|
export {
|
|
21248
21377
|
CanvasElementsRenderer,
|
|
21249
|
-
PCBViewer
|
|
21378
|
+
PCBViewer,
|
|
21379
|
+
usePcbViewerController
|
|
21250
21380
|
};
|
|
21251
21381
|
/*! Bundled license information:
|
|
21252
21382
|
|