@tscircuit/schematic-viewer 2.0.33 → 2.0.35
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 +2 -1
- package/dist/index.js +122 -36
- package/dist/index.js.map +1 -1
- package/examples/example13-disablegroups.fixture.tsx +30 -0
- package/lib/components/EditIcon.tsx +7 -1
- package/lib/components/GridIcon.tsx +7 -1
- package/lib/components/SchematicViewer.tsx +42 -16
- package/lib/hooks/useComponentDragging.ts +57 -24
- package/lib/hooks/useLocalStorage.ts +63 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -15,7 +15,8 @@ interface Props {
|
|
|
15
15
|
clickToInteractEnabled?: boolean;
|
|
16
16
|
colorOverrides?: ColorOverrides;
|
|
17
17
|
spiceSimulationEnabled?: boolean;
|
|
18
|
+
disableGroups?: boolean;
|
|
18
19
|
}
|
|
19
|
-
declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, }: Props) => react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare const SchematicViewer: ({ circuitJson, containerStyle, editEvents: unappliedEditEvents, onEditEvent, defaultEditMode, debugGrid, editingEnabled, debug, clickToInteractEnabled, colorOverrides, spiceSimulationEnabled, disableGroups, }: Props) => react_jsx_runtime.JSX.Element;
|
|
20
21
|
|
|
21
22
|
export { SchematicViewer };
|
package/dist/index.js
CHANGED
|
@@ -523,27 +523,23 @@ var useComponentDragging = ({
|
|
|
523
523
|
}
|
|
524
524
|
});
|
|
525
525
|
}, [editEvents]);
|
|
526
|
-
const
|
|
527
|
-
(
|
|
528
|
-
if (!enabled) return;
|
|
529
|
-
const target = e.target;
|
|
526
|
+
const startDrag = useCallback(
|
|
527
|
+
(clientX, clientY, target) => {
|
|
528
|
+
if (!enabled) return false;
|
|
530
529
|
const componentGroup = target.closest(
|
|
531
530
|
'[data-circuit-json-type="schematic_component"]'
|
|
532
531
|
);
|
|
533
|
-
if (!componentGroup) return;
|
|
532
|
+
if (!componentGroup) return false;
|
|
534
533
|
const schematic_component_id = componentGroup.getAttribute(
|
|
535
534
|
"data-schematic-component-id"
|
|
536
535
|
);
|
|
537
|
-
if (!schematic_component_id) return;
|
|
536
|
+
if (!schematic_component_id) return false;
|
|
538
537
|
if (cancelDrag) cancelDrag();
|
|
539
538
|
const schematic_component = su4(circuitJson).schematic_component.get(
|
|
540
539
|
schematic_component_id
|
|
541
540
|
);
|
|
542
|
-
if (!schematic_component) return;
|
|
543
|
-
dragStartPosRef.current = {
|
|
544
|
-
x: e.clientX,
|
|
545
|
-
y: e.clientY
|
|
546
|
-
};
|
|
541
|
+
if (!schematic_component) return false;
|
|
542
|
+
dragStartPosRef.current = { x: clientX, y: clientY };
|
|
547
543
|
let current_position;
|
|
548
544
|
const trackedPosition = componentPositionsRef.current.get(
|
|
549
545
|
schematic_component_id
|
|
@@ -575,15 +571,32 @@ var useComponentDragging = ({
|
|
|
575
571
|
};
|
|
576
572
|
activeEditEventRef.current = newEditEvent;
|
|
577
573
|
setActiveEditEvent(newEditEvent);
|
|
574
|
+
return true;
|
|
578
575
|
},
|
|
579
576
|
[cancelDrag, enabled, circuitJson, editEvents]
|
|
580
577
|
);
|
|
581
|
-
const
|
|
578
|
+
const handleMouseDown = useCallback(
|
|
579
|
+
(e) => {
|
|
580
|
+
startDrag(e.clientX, e.clientY, e.target);
|
|
581
|
+
},
|
|
582
|
+
[startDrag]
|
|
583
|
+
);
|
|
584
|
+
const handleTouchStart = useCallback(
|
|
582
585
|
(e) => {
|
|
586
|
+
if (e.touches.length !== 1) return;
|
|
587
|
+
const touch = e.touches[0];
|
|
588
|
+
if (startDrag(touch.clientX, touch.clientY, e.target)) {
|
|
589
|
+
e.preventDefault();
|
|
590
|
+
}
|
|
591
|
+
},
|
|
592
|
+
[startDrag]
|
|
593
|
+
);
|
|
594
|
+
const updateDragPosition = useCallback(
|
|
595
|
+
(clientX, clientY) => {
|
|
583
596
|
if (!activeEditEventRef.current || !dragStartPosRef.current) return;
|
|
584
597
|
const screenDelta = {
|
|
585
|
-
x:
|
|
586
|
-
y:
|
|
598
|
+
x: clientX - dragStartPosRef.current.x,
|
|
599
|
+
y: clientY - dragStartPosRef.current.y
|
|
587
600
|
};
|
|
588
601
|
const mmDelta = {
|
|
589
602
|
x: screenDelta.x / realToScreenProjection.a,
|
|
@@ -606,7 +619,20 @@ var useComponentDragging = ({
|
|
|
606
619
|
},
|
|
607
620
|
[realToScreenProjection, snapToGrid]
|
|
608
621
|
);
|
|
609
|
-
const
|
|
622
|
+
const handleMouseMove = useCallback(
|
|
623
|
+
(e) => updateDragPosition(e.clientX, e.clientY),
|
|
624
|
+
[updateDragPosition]
|
|
625
|
+
);
|
|
626
|
+
const handleTouchMove = useCallback(
|
|
627
|
+
(e) => {
|
|
628
|
+
if (e.touches.length !== 1 || !activeEditEventRef.current) return;
|
|
629
|
+
e.preventDefault();
|
|
630
|
+
const touch = e.touches[0];
|
|
631
|
+
updateDragPosition(touch.clientX, touch.clientY);
|
|
632
|
+
},
|
|
633
|
+
[updateDragPosition]
|
|
634
|
+
);
|
|
635
|
+
const endDrag = useCallback(() => {
|
|
610
636
|
if (!activeEditEventRef.current) return;
|
|
611
637
|
const finalEvent = {
|
|
612
638
|
...activeEditEventRef.current,
|
|
@@ -615,7 +641,7 @@ var useComponentDragging = ({
|
|
|
615
641
|
componentPositionsRef.current.set(finalEvent.schematic_component_id, {
|
|
616
642
|
...finalEvent.new_center
|
|
617
643
|
});
|
|
618
|
-
debug2("
|
|
644
|
+
debug2("endDrag calling onEditEvent with new edit event", {
|
|
619
645
|
newEditEvent: finalEvent
|
|
620
646
|
});
|
|
621
647
|
if (onEditEvent) onEditEvent(finalEvent);
|
|
@@ -623,16 +649,23 @@ var useComponentDragging = ({
|
|
|
623
649
|
dragStartPosRef.current = null;
|
|
624
650
|
setActiveEditEvent(null);
|
|
625
651
|
}, [onEditEvent]);
|
|
652
|
+
const handleMouseUp = useCallback(() => endDrag(), [endDrag]);
|
|
653
|
+
const handleTouchEnd = useCallback(() => endDrag(), [endDrag]);
|
|
626
654
|
useEffect5(() => {
|
|
627
655
|
window.addEventListener("mousemove", handleMouseMove);
|
|
628
656
|
window.addEventListener("mouseup", handleMouseUp);
|
|
657
|
+
window.addEventListener("touchmove", handleTouchMove, { passive: false });
|
|
658
|
+
window.addEventListener("touchend", handleTouchEnd);
|
|
629
659
|
return () => {
|
|
630
660
|
window.removeEventListener("mousemove", handleMouseMove);
|
|
631
661
|
window.removeEventListener("mouseup", handleMouseUp);
|
|
662
|
+
window.removeEventListener("touchmove", handleTouchMove);
|
|
663
|
+
window.removeEventListener("touchend", handleTouchEnd);
|
|
632
664
|
};
|
|
633
|
-
}, [handleMouseMove, handleMouseUp]);
|
|
665
|
+
}, [handleMouseMove, handleMouseUp, handleTouchMove, handleTouchEnd]);
|
|
634
666
|
return {
|
|
635
667
|
handleMouseDown,
|
|
668
|
+
handleTouchStart,
|
|
636
669
|
isDragging: !!activeEditEventRef.current,
|
|
637
670
|
activeEditEvent
|
|
638
671
|
};
|
|
@@ -655,10 +688,15 @@ var EditIcon = ({
|
|
|
655
688
|
onClick,
|
|
656
689
|
active
|
|
657
690
|
}) => {
|
|
691
|
+
const handleInteraction = (e) => {
|
|
692
|
+
e.preventDefault();
|
|
693
|
+
onClick();
|
|
694
|
+
};
|
|
658
695
|
return /* @__PURE__ */ jsx(
|
|
659
696
|
"div",
|
|
660
697
|
{
|
|
661
|
-
onClick,
|
|
698
|
+
onClick: handleInteraction,
|
|
699
|
+
onTouchEnd: handleInteraction,
|
|
662
700
|
style: {
|
|
663
701
|
position: "absolute",
|
|
664
702
|
top: "16px",
|
|
@@ -699,10 +737,15 @@ var GridIcon = ({
|
|
|
699
737
|
onClick,
|
|
700
738
|
active
|
|
701
739
|
}) => {
|
|
740
|
+
const handleInteraction = (e) => {
|
|
741
|
+
e.preventDefault();
|
|
742
|
+
onClick();
|
|
743
|
+
};
|
|
702
744
|
return /* @__PURE__ */ jsx2(
|
|
703
745
|
"div",
|
|
704
746
|
{
|
|
705
|
-
onClick,
|
|
747
|
+
onClick: handleInteraction,
|
|
748
|
+
onTouchEnd: handleInteraction,
|
|
706
749
|
style: {
|
|
707
750
|
position: "absolute",
|
|
708
751
|
top: "56px",
|
|
@@ -1618,6 +1661,25 @@ var getSpiceFromCircuitJson = (circuitJson, options) => {
|
|
|
1618
1661
|
return finalLines.join("\n");
|
|
1619
1662
|
};
|
|
1620
1663
|
|
|
1664
|
+
// lib/hooks/useLocalStorage.ts
|
|
1665
|
+
import { useCallback as useCallback2 } from "react";
|
|
1666
|
+
var getStoredBoolean = (key, defaultValue) => {
|
|
1667
|
+
if (typeof window === "undefined") return defaultValue;
|
|
1668
|
+
try {
|
|
1669
|
+
const stored = localStorage.getItem(key);
|
|
1670
|
+
return stored !== null ? JSON.parse(stored) : defaultValue;
|
|
1671
|
+
} catch {
|
|
1672
|
+
return defaultValue;
|
|
1673
|
+
}
|
|
1674
|
+
};
|
|
1675
|
+
var setStoredBoolean = (key, value) => {
|
|
1676
|
+
if (typeof window === "undefined") return;
|
|
1677
|
+
try {
|
|
1678
|
+
localStorage.setItem(key, JSON.stringify(value));
|
|
1679
|
+
} catch {
|
|
1680
|
+
}
|
|
1681
|
+
};
|
|
1682
|
+
|
|
1621
1683
|
// lib/components/SchematicViewer.tsx
|
|
1622
1684
|
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1623
1685
|
var SchematicViewer = ({
|
|
@@ -1631,7 +1693,8 @@ var SchematicViewer = ({
|
|
|
1631
1693
|
debug: debug3 = false,
|
|
1632
1694
|
clickToInteractEnabled = false,
|
|
1633
1695
|
colorOverrides,
|
|
1634
|
-
spiceSimulationEnabled = false
|
|
1696
|
+
spiceSimulationEnabled = false,
|
|
1697
|
+
disableGroups = false
|
|
1635
1698
|
}) => {
|
|
1636
1699
|
if (debug3) {
|
|
1637
1700
|
enableDebug();
|
|
@@ -1678,7 +1741,10 @@ var SchematicViewer = ({
|
|
|
1678
1741
|
!clickToInteractEnabled
|
|
1679
1742
|
);
|
|
1680
1743
|
const [showViewMenu, setShowViewMenu] = useState5(false);
|
|
1681
|
-
const [showSchematicGroups, setShowSchematicGroups] = useState5(
|
|
1744
|
+
const [showSchematicGroups, setShowSchematicGroups] = useState5(() => {
|
|
1745
|
+
if (disableGroups) return false;
|
|
1746
|
+
return getStoredBoolean("schematic_viewer_show_groups", false);
|
|
1747
|
+
});
|
|
1682
1748
|
const svgDivRef = useRef4(null);
|
|
1683
1749
|
const touchStartRef = useRef4(null);
|
|
1684
1750
|
const handleTouchStart = (e) => {
|
|
@@ -1762,18 +1828,21 @@ var SchematicViewer = ({
|
|
|
1762
1828
|
const editEventsWithUnappliedEditEvents = useMemo3(() => {
|
|
1763
1829
|
return [...unappliedEditEvents, ...internalEditEvents];
|
|
1764
1830
|
}, [unappliedEditEvents, internalEditEvents]);
|
|
1765
|
-
const {
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1831
|
+
const {
|
|
1832
|
+
handleMouseDown,
|
|
1833
|
+
handleTouchStart: handleComponentTouchStart,
|
|
1834
|
+
isDragging,
|
|
1835
|
+
activeEditEvent
|
|
1836
|
+
} = useComponentDragging({
|
|
1837
|
+
onEditEvent: handleEditEvent,
|
|
1838
|
+
cancelDrag,
|
|
1839
|
+
realToSvgProjection,
|
|
1840
|
+
svgToScreenProjection,
|
|
1841
|
+
circuitJson,
|
|
1842
|
+
editEvents: editEventsWithUnappliedEditEvents,
|
|
1843
|
+
enabled: editModeEnabled && isInteractionEnabled && !showSpiceOverlay,
|
|
1844
|
+
snapToGrid
|
|
1845
|
+
});
|
|
1777
1846
|
useChangeSchematicComponentLocationsInSvg({
|
|
1778
1847
|
svgDivRef,
|
|
1779
1848
|
editEvents: editEventsWithUnappliedEditEvents,
|
|
@@ -1791,7 +1860,7 @@ var SchematicViewer = ({
|
|
|
1791
1860
|
svgDivRef,
|
|
1792
1861
|
circuitJson,
|
|
1793
1862
|
circuitJsonKey,
|
|
1794
|
-
showGroups: showSchematicGroups
|
|
1863
|
+
showGroups: showSchematicGroups && !disableGroups
|
|
1795
1864
|
});
|
|
1796
1865
|
const svgDiv = useMemo3(
|
|
1797
1866
|
() => /* @__PURE__ */ jsx9(
|
|
@@ -1802,10 +1871,22 @@ var SchematicViewer = ({
|
|
|
1802
1871
|
pointerEvents: clickToInteractEnabled ? isInteractionEnabled ? "auto" : "none" : "auto",
|
|
1803
1872
|
transformOrigin: "0 0"
|
|
1804
1873
|
},
|
|
1874
|
+
onTouchStart: (e) => {
|
|
1875
|
+
if (editModeEnabled && isInteractionEnabled && !showSpiceOverlay) {
|
|
1876
|
+
handleComponentTouchStart(e);
|
|
1877
|
+
}
|
|
1878
|
+
},
|
|
1805
1879
|
dangerouslySetInnerHTML: { __html: svgString }
|
|
1806
1880
|
}
|
|
1807
1881
|
),
|
|
1808
|
-
[
|
|
1882
|
+
[
|
|
1883
|
+
svgString,
|
|
1884
|
+
isInteractionEnabled,
|
|
1885
|
+
clickToInteractEnabled,
|
|
1886
|
+
editModeEnabled,
|
|
1887
|
+
showSpiceOverlay,
|
|
1888
|
+
handleComponentTouchStart
|
|
1889
|
+
]
|
|
1809
1890
|
);
|
|
1810
1891
|
return /* @__PURE__ */ jsxs6(
|
|
1811
1892
|
"div",
|
|
@@ -1913,7 +1994,12 @@ var SchematicViewer = ({
|
|
|
1913
1994
|
isVisible: showViewMenu,
|
|
1914
1995
|
onClose: () => setShowViewMenu(false),
|
|
1915
1996
|
showGroups: showSchematicGroups,
|
|
1916
|
-
onToggleGroups:
|
|
1997
|
+
onToggleGroups: (value) => {
|
|
1998
|
+
if (!disableGroups) {
|
|
1999
|
+
setShowSchematicGroups(value);
|
|
2000
|
+
setStoredBoolean("schematic_viewer_show_groups", value);
|
|
2001
|
+
}
|
|
2002
|
+
}
|
|
1917
2003
|
}
|
|
1918
2004
|
),
|
|
1919
2005
|
spiceSimulationEnabled && /* @__PURE__ */ jsx9(SpiceSimulationIcon, { onClick: () => setShowSpiceOverlay(true) }),
|