@tscircuit/schematic-viewer 1.2.8 → 1.2.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tscircuit/schematic-viewer",
3
- "version": "1.2.8",
3
+ "version": "1.2.10",
4
4
  "main": "dist/index.js",
5
5
  "license": "MIT",
6
6
  "repository": "tscircuit/schematic-viewer",
@@ -58,7 +58,7 @@
58
58
  "zustand": "^4.0.0"
59
59
  },
60
60
  "dependencies": {
61
- "@tscircuit/soup": "^0.0.7",
61
+ "@tscircuit/soup": "^0.0.16",
62
62
  "convert-units": "^2.3.4",
63
63
  "react-error-boundary": "^4.0.4",
64
64
  "react-supergrid": "^1.0.10",
package/src/Schematic.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import { useCallback, useEffect, useState } from "react"
2
- import { ProjectComponent } from "schematic-components"
2
+ import { ContextProviders, ProjectComponent } from "schematic-components"
3
3
  import { SuperGrid, toMMSI } from "react-supergrid"
4
4
  import {
5
5
  AnyElement,
@@ -15,7 +15,7 @@ import { collectElementRefs } from "lib/utils/collect-element-refs"
15
15
  import { useMouseMatrixTransform } from "use-mouse-matrix-transform"
16
16
  import { ErrorBoundary as TypedErrorBoundary } from "react-error-boundary"
17
17
  import { identity, compose, scale, translate } from "transformation-matrix"
18
- import { useRenderContext } from "lib/render-context"
18
+ import { useGlobalStore } from "lib/render-context"
19
19
  import useMeasure from "react-use-measure"
20
20
  import { TableViewer } from "./schematic-components/TableViewer"
21
21
 
@@ -34,16 +34,10 @@ const fallbackRender: any =
34
34
  const toMMSINeg = (v: number, z: number) =>
35
35
  v >= 0 ? toMMSI(v, z) : `-${toMMSI(-v, z)}`
36
36
 
37
- export const Schematic = ({
38
- children,
39
- elements: initialElements,
40
- soup: initialSoup,
41
- style,
42
- showTable = false,
43
- }: {
37
+ export interface SchematicProps {
44
38
  children?: any
45
39
 
46
- /** @deprecated */
40
+ /** @deprecated use soup */
47
41
  elements?: any
48
42
 
49
43
  soup?: any
@@ -51,13 +45,29 @@ export const Schematic = ({
51
45
  style?: any
52
46
 
53
47
  showTable?: boolean
54
- }) => {
48
+ }
49
+
50
+ export const Schematic = (props: SchematicProps) => {
51
+ return (
52
+ <ContextProviders>
53
+ <SchematicWithoutContext {...props} />
54
+ </ContextProviders>
55
+ )
56
+ }
57
+
58
+ export const SchematicWithoutContext = ({
59
+ children,
60
+ elements: initialElements,
61
+ soup: initialSoup,
62
+ style,
63
+ showTable = false,
64
+ }: SchematicProps) => {
55
65
  initialSoup = initialSoup ?? initialElements ?? []
56
66
 
57
67
  const [elements, setElements] = useState<any>(initialSoup ?? [])
58
68
  const [project, setProject] = useState<any>(null)
59
- const setCameraTransform = useRenderContext((s) => s.setCameraTransform)
60
- const cameraTransform = useRenderContext((s) => s.camera_transform)
69
+ const { setCameraTransform, camera_transform: cameraTransform } =
70
+ useGlobalStore()
61
71
  const [boundsRef, bounds] = useMeasure()
62
72
  const { ref, setTransform } = useMouseMatrixTransform({
63
73
  onSetTransform: (transform) => {
@@ -82,13 +92,11 @@ export const Schematic = ({
82
92
  (elmBounds.height ?? 0) / height,
83
93
  100
84
94
  )
85
- // console.log(elements)
86
95
  setElements(elements)
87
96
  setProject(createProjectFromElements(elements))
88
97
  setTransform(
89
98
  compose(
90
99
  translate((elmBounds.width ?? 0) / 2, (elmBounds.height ?? 0) / 2),
91
- // translate(100, 0),
92
100
  scale(scaleFactor, -scaleFactor, 0, 0),
93
101
  translate(-center.x, -center.y)
94
102
  )
@@ -1,16 +1,28 @@
1
- import createStore from "zustand"
1
+ import {
2
+ createStore as createZustandStore,
3
+ useStore as useZustandStore,
4
+ UseBoundStore,
5
+ } from "zustand"
2
6
  import { Matrix, compose, scale } from "transformation-matrix"
7
+ import { useContext } from "react"
8
+ import { StoreContext } from "schematic-components/"
3
9
 
4
10
  interface RenderContextState {
5
11
  camera_transform: Matrix
6
12
  setCameraTransform: (transform: Matrix) => void
7
13
  }
8
14
 
9
- export const useRenderContext = createStore<RenderContextState>((set, get) => ({
10
- camera_transform: compose(scale(100, 100, 0, 0)),
11
- setCameraTransform: (transform: Matrix) =>
12
- set({ camera_transform: transform }),
13
- }))
15
+ export const createRenderContextStore = () =>
16
+ createZustandStore<RenderContextState>((set) => ({
17
+ camera_transform: compose(scale(100, 100, 0, 0)),
18
+ setCameraTransform: (transform: Matrix) =>
19
+ set({ camera_transform: transform }),
20
+ }))
14
21
 
15
- export const useCameraTransform = () =>
16
- useRenderContext((s) => s.camera_transform)
22
+ export const useGlobalStore = <T = RenderContextState>(
23
+ s?: (state: RenderContextState) => T
24
+ ): T => {
25
+ const store = useContext(StoreContext)
26
+
27
+ return useZustandStore(store as any, s as any)
28
+ }
@@ -1,6 +1,9 @@
1
- import { AnyElement, SourcePort } from "@tscircuit/builder"
1
+ import { AnySoupElement, SourcePort } from "@tscircuit/soup"
2
2
 
3
- export const collectElementRefs = (elm: AnyElement, allElms: AnyElement[]) => {
3
+ export const collectElementRefs = (
4
+ elm: AnySoupElement,
5
+ allElms: AnySoupElement[]
6
+ ) => {
4
7
  const source_port = allElms.find(
5
8
  (e) =>
6
9
  e.type === "source_port" &&
@@ -0,0 +1,15 @@
1
+ import { createRenderContextStore } from "lib/render-context"
2
+ import { useMemo } from "react"
3
+ import { createContext } from "react"
4
+
5
+ export const StoreContext = createContext(null)
6
+
7
+ export const ContextProviders = ({ children }: { children?: any }) => {
8
+ const store = useMemo(() => createRenderContextStore(), [])
9
+
10
+ return (
11
+ <StoreContext.Provider value={store as any}>
12
+ {children}
13
+ </StoreContext.Provider>
14
+ )
15
+ }
@@ -1,4 +1,4 @@
1
- import { useCameraTransform } from "lib/render-context"
1
+ import { useGlobalStore } from "lib/render-context"
2
2
  import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
3
3
  import { useCallback, useState } from "react"
4
4
 
@@ -37,7 +37,7 @@ export const SVGPathComponent = ({
37
37
  shiftToBottom,
38
38
  hoverContent,
39
39
  }: Props) => {
40
- const ct = useCameraTransform()
40
+ const ct = useGlobalStore((s) => s.camera_transform)
41
41
  const pathBounds = getSVGPathBounds(paths.map((p) => p.d))
42
42
  // Margin in SVG Space
43
43
  const badRatio =
@@ -1,4 +1,4 @@
1
- import { useCameraTransform } from "lib/render-context"
1
+ import { useGlobalStore } from "lib/render-context"
2
2
  import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
3
3
  import { useCallback, useState } from "react"
4
4
 
@@ -37,7 +37,7 @@ export const SVGPathComponent2 = ({
37
37
  shiftToBottom,
38
38
  hoverContent,
39
39
  }: Props) => {
40
- const ct = useCameraTransform()
40
+ const ct = useGlobalStore((c) => c.camera_transform)
41
41
  const pathBounds = getSVGPathBounds(paths.map((p) => p.d))
42
42
  // Margin in SVG Space
43
43
 
@@ -1,4 +1,4 @@
1
- import { AnyElement } from "@tscircuit/builder"
1
+ import { AnySoupElement } from "@tscircuit/soup"
2
2
  import { collectElementRefs } from "lib/utils/collect-element-refs"
3
3
  import SchematicComponent from "./SchematicComponent"
4
4
  import SchematicPort from "./SchematicPort"
@@ -8,6 +8,7 @@ import SchematicTrace from "./SchematicTrace"
8
8
  import SchematicLine from "./SchematicLine"
9
9
  import RenderError from "./RenderError"
10
10
  import SchematicPath from "./SchematicPath"
11
+ import { SchematicNetLabel } from "./SchematicNetLabel"
11
12
 
12
13
  /**
13
14
  * Render any @tsbuilder/builder AnyElement that can be put on a schematic.
@@ -16,8 +17,8 @@ export const SchematicElement = ({
16
17
  element,
17
18
  allElements,
18
19
  }: {
19
- element: AnyElement
20
- allElements: AnyElement[]
20
+ element: AnySoupElement
21
+ allElements: AnySoupElement[]
21
22
  }) => {
22
23
  // A lot of the split logic for element types into a project is here:
23
24
  // https://github.com/tscircuit/builder/blob/7e7bef9c0aadd11999795003b8986f0d244c111f/src/lib/project/create-project-from-elements.ts#L13
@@ -63,6 +64,10 @@ export const SchematicElement = ({
63
64
  return <SchematicText schematic_text={element} />
64
65
  }
65
66
 
67
+ if (element.type === "schematic_net_label") {
68
+ return <SchematicNetLabel net_label={element} />
69
+ }
70
+
66
71
  if (element.type === "source_error") {
67
72
  // TODO use the ids on the source error to put this in the right place
68
73
  return <RenderError text={element.message} />
@@ -0,0 +1,47 @@
1
+ import type { SchematicNetLabel as SchematicNetLabelObject } from "@tscircuit/soup"
2
+ import SVGPathComponent from "./SVGPathComponent"
3
+ import SchematicText from "./SchematicText"
4
+
5
+ export const SchematicNetLabel = ({
6
+ net_label,
7
+ }: {
8
+ net_label: SchematicNetLabelObject
9
+ }) => {
10
+ console.log({ net_label })
11
+ const text_width = net_label.text.length * 0.15
12
+ // TODO add text
13
+ const path_width = 31 + net_label.text.length * 5
14
+ return (
15
+ <>
16
+ <SVGPathComponent
17
+ rotation={0}
18
+ center={net_label.center}
19
+ // fixed size?
20
+ size={{
21
+ width: 0.05 + text_width,
22
+ height: 0.175,
23
+ }}
24
+ paths={[
25
+ {
26
+ stroke: "gray",
27
+ strokeWidth: 0.75,
28
+ d: `M 0 15 L 5 15 L 11 9 L ${path_width} 9 L ${path_width} 21 L 11 21 L 5 15`,
29
+ },
30
+ ]}
31
+ />
32
+ <SchematicText
33
+ schematic_text={{
34
+ anchor: "left",
35
+ position: {
36
+ x: net_label.center.x - text_width / 4 + 0.025,
37
+ y: net_label.center.y,
38
+ },
39
+ schematic_component_id: "SYNTHETIC",
40
+ schematic_text_id: "SYNTHETIC",
41
+ text: net_label.text,
42
+ type: "schematic_text",
43
+ }}
44
+ />
45
+ </>
46
+ )
47
+ }
@@ -2,7 +2,7 @@ import * as Type from "lib/types"
2
2
  import SVGPathComponent from "./SVGPathComponent"
3
3
  import Path from "svg-path-generator"
4
4
  import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
5
- import { useCameraTransform } from "lib/render-context"
5
+ import { useGlobalStore } from "lib/render-context"
6
6
  import { applyToPoint } from "transformation-matrix"
7
7
  import useMeasure from "react-use-measure"
8
8
 
@@ -11,7 +11,7 @@ interface Props {
11
11
  }
12
12
 
13
13
  export const SchematicText = ({ schematic_text }: Props) => {
14
- const ct = useCameraTransform()
14
+ const ct = useGlobalStore((s) => s.camera_transform)
15
15
  const { text, position, anchor } = schematic_text
16
16
  const tPos = applyToPoint(ct, position)
17
17
  const [boundsRef, bounds] = useMeasure()
@@ -14,3 +14,4 @@ export * from "./SimpleGround"
14
14
  export * from "./SimpleInductor"
15
15
  export * from "./RenderError"
16
16
  export * from "./SimpleDiode"
17
+ export * from "./ContextProviders"
@@ -0,0 +1,190 @@
1
+ import { Schematic } from "../../Schematic"
2
+
3
+ export const SchematicNetLabel = () => {
4
+ return (
5
+ <Schematic
6
+ style={{ height: 500 }}
7
+ soup={
8
+ {
9
+ elements: [
10
+ {
11
+ type: "source_component",
12
+ source_component_id: "simple_resistor_0",
13
+ name: "R1",
14
+ supplier_part_numbers: {},
15
+ ftype: "simple_resistor",
16
+ resistance: 100,
17
+ source: {
18
+ type: "source_component",
19
+ source_component_id: "simple_resistor_0",
20
+ name: "R1",
21
+ supplier_part_numbers: {},
22
+ ftype: "simple_resistor",
23
+ resistance: 100,
24
+ },
25
+ },
26
+ {
27
+ type: "schematic_component",
28
+ source_component_id: "simple_resistor_0",
29
+ schematic_component_id: "schematic_component_simple_resistor_0",
30
+ rotation: 0,
31
+ size: {
32
+ width: 1,
33
+ height: 0.3,
34
+ },
35
+ center: {
36
+ x: 0,
37
+ y: 0,
38
+ },
39
+ source: {
40
+ type: "source_component",
41
+ source_component_id: "simple_resistor_0",
42
+ name: "R1",
43
+ supplier_part_numbers: {},
44
+ ftype: "simple_resistor",
45
+ resistance: 100,
46
+ },
47
+ },
48
+ {
49
+ type: "source_port",
50
+ name: "left",
51
+ source_port_id: "source_port_0",
52
+ source_component_id: "simple_resistor_0",
53
+ source: {
54
+ type: "source_component",
55
+ source_component_id: "simple_resistor_0",
56
+ name: "R1",
57
+ supplier_part_numbers: {},
58
+ ftype: "simple_resistor",
59
+ resistance: 100,
60
+ },
61
+ },
62
+ {
63
+ type: "schematic_port",
64
+ schematic_port_id: "schematic_port_0",
65
+ source_port_id: "source_port_0",
66
+ center: {
67
+ x: -0.5,
68
+ y: 0,
69
+ },
70
+ facing_direction: "left",
71
+ schematic_component_id: "schematic_component_simple_resistor_0",
72
+ source: {
73
+ type: "source_port",
74
+ name: "left",
75
+ source_port_id: "source_port_0",
76
+ source_component_id: "simple_resistor_0",
77
+ },
78
+ },
79
+ {
80
+ type: "source_port",
81
+ name: "right",
82
+ source_port_id: "source_port_1",
83
+ source_component_id: "simple_resistor_0",
84
+ source: {
85
+ type: "source_component",
86
+ source_component_id: "simple_resistor_0",
87
+ name: "R1",
88
+ supplier_part_numbers: {},
89
+ ftype: "simple_resistor",
90
+ resistance: 100,
91
+ },
92
+ },
93
+ {
94
+ type: "schematic_port",
95
+ schematic_port_id: "schematic_port_1",
96
+ source_port_id: "source_port_1",
97
+ center: {
98
+ x: 0.5,
99
+ y: 0,
100
+ },
101
+ facing_direction: "right",
102
+ schematic_component_id: "schematic_component_simple_resistor_0",
103
+ source: {
104
+ type: "source_port",
105
+ name: "right",
106
+ source_port_id: "source_port_1",
107
+ source_component_id: "simple_resistor_0",
108
+ },
109
+ },
110
+ {
111
+ type: "schematic_text",
112
+ text: "R1",
113
+ schematic_text_id: "schematic_text_0",
114
+ schematic_component_id: "schematic_component_simple_resistor_0",
115
+ anchor: "left",
116
+ position: {
117
+ x: -0.2,
118
+ y: -0.5,
119
+ },
120
+ rotation: 0,
121
+ source: null,
122
+ },
123
+ {
124
+ type: "schematic_text",
125
+ text: 100,
126
+ schematic_text_id: "schematic_text_1",
127
+ schematic_component_id: "schematic_component_simple_resistor_0",
128
+ anchor: "left",
129
+ position: {
130
+ x: -0.2,
131
+ y: -0.3,
132
+ },
133
+ rotation: 0,
134
+ source: null,
135
+ },
136
+ {
137
+ type: "source_net",
138
+ member_source_group_ids: [],
139
+ source_net_id: "net_0",
140
+ name: "N1",
141
+ source: null,
142
+ },
143
+ {
144
+ type: "source_trace",
145
+ connected_source_port_ids: ["source_port_1"],
146
+ connected_source_net_ids: ["net_0"],
147
+ source_trace_id: "source_trace_0",
148
+ source: null,
149
+ },
150
+ {
151
+ type: "schematic_net_label",
152
+ source_net_id: "net_0",
153
+ text: "N1",
154
+ anchor_side: "left",
155
+ center: {
156
+ x: 1.5,
157
+ y: 0,
158
+ },
159
+ source: null,
160
+ },
161
+ {
162
+ type: "schematic_trace",
163
+ schematic_trace_id: "schematic_trace_0",
164
+ source_trace_id: "source_trace_0",
165
+ edges: [
166
+ {
167
+ from: {
168
+ x: 0.5,
169
+ y: 0,
170
+ },
171
+ to: {
172
+ x: 1.5,
173
+ y: 0,
174
+ },
175
+ from_schematic_port_id: "schematic_port_1",
176
+ },
177
+ ],
178
+ source: null,
179
+ },
180
+ ],
181
+ }.elements
182
+ }
183
+ />
184
+ )
185
+ }
186
+
187
+ export default {
188
+ title: "Basics/SchematicNetLabel",
189
+ component: SchematicNetLabel,
190
+ }
@@ -0,0 +1,23 @@
1
+ import { Schematic } from "../../Schematic"
2
+
3
+ export const Bug7MultipleSchematicPanning = () => {
4
+ return (
5
+ <div>
6
+ <Schematic style={{ height: 500 }}>
7
+ <resistor name="R1" resistance="10 ohm" schX={2} schY={1} />
8
+ <resistor resistance="1k" schX={1} schY={2} name="main_power" />
9
+ <trace path={[".main_power > port.right", ".R1 > port.left"]} />
10
+ </Schematic>
11
+ <Schematic style={{ height: 500 }}>
12
+ <resistor name="R1" resistance="10 ohm" schX={2} schY={1} />
13
+ <resistor resistance="1k" schX={1} schY={2} name="main_power" />
14
+ <trace path={[".main_power > port.right", ".R1 > port.left"]} />
15
+ </Schematic>
16
+ </div>
17
+ )
18
+ }
19
+
20
+ export default {
21
+ title: "Bugs/Bug7MultipleSchematicPanning",
22
+ component: Bug7MultipleSchematicPanning,
23
+ }