@tscircuit/schematic-viewer 1.2.12 → 1.2.14

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.12",
3
+ "version": "1.2.14",
4
4
  "main": "dist/index.js",
5
5
  "license": "MIT",
6
6
  "repository": "tscircuit/schematic-viewer",
@@ -28,37 +28,42 @@
28
28
  "@semantic-release/github": "^9.0.3",
29
29
  "@semantic-release/npm": "^10.0.4",
30
30
  "@semantic-release/release-notes-generator": "^11.0.4",
31
- "@storybook/blocks": "^7.0.26",
32
- "@storybook/nextjs": "^7.4.0",
33
- "@storybook/react": "^7.4.0",
31
+ "@storybook/nextjs": "^8.1.3",
32
+ "@storybook/react": "^8.1.3",
34
33
  "@storybook/testing-library": "^0.0.14-next.2",
35
- "@tscircuit/builder": "^1.5.100",
36
- "@tscircuit/react-fiber": "^1.1.8",
34
+ "@tscircuit/builder": "^1.5.126",
35
+ "@tscircuit/react-fiber": "^1.1.29",
37
36
  "@tscircuit/routing": "^1.3.0",
37
+ "@tscircuit/soup": "^0.0.34",
38
38
  "@tscircuit/table-viewer": "^0.0.6",
39
39
  "@types/node": "^18.6.0",
40
40
  "@types/react": "^18.0.15",
41
+ "@vitejs/plugin-react": "^4.3.0",
41
42
  "ava": "^4.3.1",
42
43
  "esbuild": "^0.20.2",
43
44
  "esbuild-register": "^3.5.0",
44
- "next": "^12.2.3",
45
+ "next": "^14.2.3",
45
46
  "parse-svg-path": "^0.1.2",
46
47
  "react": "^18.2.0",
47
48
  "react-dom": "^18.2.0",
48
49
  "react-use-measure": "^2.1.1",
49
- "rectilinear-router": "^1.0.1",
50
50
  "semantic-release": "^21.0.6",
51
- "storybook": "^7.4.0",
51
+ "storybook": "^8.1.3",
52
52
  "svg-path-bounds": "^1.0.2",
53
53
  "svg-path-generator": "^1.1.0",
54
54
  "transformation-matrix": "^2.12.0",
55
55
  "tsup": "^6.7.0",
56
56
  "type-fest": "^2.17.0",
57
57
  "typescript": "^5.4.3",
58
+ "vite": "^5.2.11",
59
+ "vite-tsconfig-paths": "^4.3.2",
60
+ "zod": "^3.23.8",
58
61
  "zustand": "^4.0.0"
59
62
  },
60
63
  "dependencies": {
61
- "@tscircuit/soup": "^0.0.16",
64
+ "@storybook/react-vite": "^8.1.3",
65
+ "@tscircuit/layout": "^0.0.17",
66
+ "@tscircuit/props": "^0.0.15",
62
67
  "convert-units": "^2.3.4",
63
68
  "react-error-boundary": "^4.0.4",
64
69
  "react-supergrid": "^1.0.10",
package/renovate.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "https://docs.renovatebot.com/renovate-schema.json",
3
+ "extends": [
4
+ "config:recommended"
5
+ ]
6
+ }
package/src/Schematic.tsx CHANGED
@@ -18,6 +18,7 @@ import { identity, compose, scale, translate } from "transformation-matrix"
18
18
  import { useGlobalStore } from "lib/render-context"
19
19
  import useMeasure from "react-use-measure"
20
20
  import { TableViewer } from "./schematic-components/TableViewer"
21
+ import { AnySoupElement } from "@tscircuit/soup"
21
22
 
22
23
  const ErrorBoundary = TypedErrorBoundary as any
23
24
 
@@ -40,11 +41,13 @@ export interface SchematicProps {
40
41
  /** @deprecated use soup */
41
42
  elements?: any
42
43
 
43
- soup?: any
44
+ soup?: AnySoupElement[]
44
45
 
45
46
  style?: any
46
47
 
47
48
  showTable?: boolean
49
+
50
+ _soupPostProcessor?: (soup: AnySoupElement[]) => AnySoupElement[]
48
51
  }
49
52
 
50
53
  export const Schematic = (props: SchematicProps) => {
@@ -61,6 +64,7 @@ export const SchematicWithoutContext = ({
61
64
  soup: initialSoup,
62
65
  style,
63
66
  showTable = false,
67
+ _soupPostProcessor,
64
68
  }: SchematicProps) => {
65
69
  initialSoup = initialSoup ?? initialElements ?? []
66
70
 
@@ -107,13 +111,16 @@ export const SchematicWithoutContext = ({
107
111
 
108
112
  useEffect(() => {
109
113
  if (initialSoup.length > 0) {
110
- setElementsAndCamera(initialSoup)
114
+ setElementsAndCamera(initialSoup as any)
111
115
  return
112
116
  }
113
117
  const projectBuilder = createProjectBuilder()
114
118
  ;((createRoot ?? TscReactFiber.createRoot) as any)()
115
119
  .render(children, projectBuilder as any)
116
120
  .then(async (elements) => {
121
+ if (_soupPostProcessor) {
122
+ elements = _soupPostProcessor(elements)
123
+ }
117
124
  setElementsAndCamera(elements)
118
125
  })
119
126
  .catch((e) => {
@@ -0,0 +1,11 @@
1
+ import type { SchematicNetLabel } from "@tscircuit/soup"
2
+
3
+ type AnchorSide = SchematicNetLabel["anchor_side"]
4
+
5
+ export const getRotationFromAnchorSide = (anchor_side: AnchorSide) => {
6
+ if (anchor_side === "left") return 0
7
+ if (anchor_side === "top") return (Math.PI * 3) / 2
8
+ if (anchor_side === "right") return Math.PI
9
+ if (anchor_side === "bottom") return Math.PI / 2
10
+ return 0
11
+ }
@@ -0,0 +1,11 @@
1
+ import type { SchematicNetLabel } from "@tscircuit/soup"
2
+
3
+ type AnchorSide = SchematicNetLabel["anchor_side"]
4
+
5
+ export const getVecFromAnchorSide = (anchor_side: AnchorSide) => {
6
+ if (anchor_side === "left") return { x: -1, y: 0 }
7
+ if (anchor_side === "top") return { x: 0, y: -1 }
8
+ if (anchor_side === "right") return { x: 1, y: 0 }
9
+ if (anchor_side === "bottom") return { x: 0, y: 1 }
10
+ throw new Error(`invalid anchor side "${anchor_side}"`)
11
+ }
@@ -0,0 +1,25 @@
1
+ import React from "react"
2
+ import { SVGPathComponent } from "./SVGPathComponent"
3
+
4
+ export const DebugPoint = ({
5
+ center,
6
+ }: {
7
+ center: { x: number; y: number }
8
+ }) => {
9
+ return (
10
+ <SVGPathComponent
11
+ rotation={0}
12
+ center={center}
13
+ size={{ width: 0.02, height: 0.02 }}
14
+ paths={[
15
+ {
16
+ stroke: "red",
17
+ strokeWidth: 0.5,
18
+ // d: "M -1 -1 l 1 1 M -1 1 l 1 -1",
19
+ //square
20
+ d: "M -1 -1 l 2 0 l 0 2 l -2 0 l 0 -2",
21
+ },
22
+ ]}
23
+ />
24
+ )
25
+ }
@@ -6,12 +6,13 @@ import {
6
6
  getPortArrangementSize,
7
7
  getPortIndices,
8
8
  } from "@tscircuit/builder"
9
+ import type { SchematicComponent } from "@tscircuit/soup"
9
10
  import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
10
11
 
11
12
  interface Props {
12
13
  component: {
13
14
  source: Type.SimpleBug
14
- schematic: Type.SchematicComponent
15
+ schematic: SchematicComponent
15
16
  }
16
17
  }
17
18
 
@@ -24,6 +25,7 @@ export const SchematicBug = ({ component: { source, schematic } }: Props) => {
24
25
  // const port_labels = schematic.port_labels!
25
26
  let bugw = schematic.size.width // bug width
26
27
  let bugh = schematic.size.height
28
+
27
29
  const { total_ports, width, height } =
28
30
  getPortArrangementSize(port_arrangement)
29
31
  const port_indices = getPortIndices(port_arrangement)
@@ -42,20 +44,24 @@ export const SchematicBug = ({ component: { source, schematic } }: Props) => {
42
44
  } ${bugh / 2} L ${-bugw / 2} ${bugh / 2}Z`,
43
45
  },
44
46
  ...port_indices.map((portNum) => {
45
- const pos = getPortPosition(port_arrangement, portNum)
47
+ // TODO get the ports passed to the components and use those positions
48
+ const pos = getPortPosition(
49
+ { ...port_arrangement, pin_spacing: schematic.pin_spacing },
50
+ portNum,
51
+ )
46
52
 
47
53
  const x2 =
48
54
  pos.side === "left"
49
55
  ? -bugw / 2
50
56
  : pos.side === "right"
51
- ? bugw / 2
52
- : pos.x
57
+ ? bugw / 2
58
+ : pos.x
53
59
  const y2 =
54
60
  pos.side === "top"
55
61
  ? bugh / 2
56
62
  : pos.side === "bottom"
57
- ? -bugh / 2
58
- : pos.y
63
+ ? -bugh / 2
64
+ : pos.y
59
65
 
60
66
  return {
61
67
  stroke: "red",
@@ -1,40 +1,53 @@
1
1
  import type { SchematicNetLabel as SchematicNetLabelObject } from "@tscircuit/soup"
2
2
  import SVGPathComponent from "./SVGPathComponent"
3
3
  import SchematicText from "./SchematicText"
4
+ import { getRotationFromAnchorSide } from "lib/utils/get-rotation-from-anchor-side"
5
+ import { getVecFromAnchorSide } from "lib/utils/get-vec-from-anchor-side"
4
6
 
5
7
  export const SchematicNetLabel = ({
6
8
  net_label,
7
9
  }: {
8
10
  net_label: SchematicNetLabelObject
9
11
  }) => {
10
- console.log({ net_label })
11
- const text_width = net_label.text.length * 0.15
12
+ const anchor_side = net_label.anchor_side
13
+ const is_vertical = anchor_side === "top" || anchor_side === "bottom"
14
+ const text_width = is_vertical ? 0.3 : net_label.text.length * 0.15
12
15
  // TODO add text
13
16
  const path_width = 31 + net_label.text.length * 5
17
+
18
+ const anchor_vec = getVecFromAnchorSide(anchor_side)
19
+ // const anchor_dist = 0 // text_width / 4 - 0.025
20
+ const anchor_dist = is_vertical ? 0.04 : text_width / 4 // - 0.025
21
+ anchor_vec.x *= anchor_dist
22
+ anchor_vec.y *= anchor_dist
23
+
14
24
  return (
15
25
  <>
16
26
  <SVGPathComponent
17
- rotation={0}
27
+ rotation={getRotationFromAnchorSide(anchor_side)}
18
28
  center={net_label.center}
19
29
  // fixed size?
20
30
  size={{
21
31
  width: 0.05 + text_width,
22
- height: 0.175,
32
+ height:
33
+ 0.2 +
34
+ (is_vertical ? 0.1 * Math.max(1, net_label.text.length - 2) : 0),
23
35
  }}
24
36
  paths={[
25
37
  {
26
38
  stroke: "gray",
27
39
  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`,
40
+ // d: `M 0 15 L 5 15 L 11 9 L ${path_width} 9 L ${path_width} 21 L 11 21 L 5 15`,
41
+ d: `M 0 15 L 5 15 L 11 5 L ${path_width} 5 L ${path_width} 26 L 11 26 L 5 15`,
29
42
  },
30
43
  ]}
31
44
  />
32
45
  <SchematicText
33
46
  schematic_text={{
34
- anchor: "left",
47
+ anchor: is_vertical ? "center" : anchor_side,
35
48
  position: {
36
- x: net_label.center.x - text_width / 4 + 0.025,
37
- y: net_label.center.y,
49
+ x: net_label.center.x + anchor_vec.x,
50
+ y: net_label.center.y + anchor_vec.y,
38
51
  },
39
52
  schematic_component_id: "SYNTHETIC",
40
53
  schematic_text_id: "SYNTHETIC",
@@ -0,0 +1,33 @@
1
+ import { Schematic } from "../../Schematic"
2
+
3
+ export const SchematicNetLabel2 = () => {
4
+ return (
5
+ <Schematic style={{ height: 500 }}>
6
+ <resistor resistance="1k" name="R1" schX={-2} schY={0} />
7
+ <resistor resistance="1k" name="R2" schX={2} schY={0} />
8
+ <resistor
9
+ schRotation="90deg"
10
+ resistance="1k"
11
+ name="R3"
12
+ schX={0}
13
+ schY={2}
14
+ />
15
+ <resistor
16
+ schRotation="90deg"
17
+ resistance="1k"
18
+ name="R4"
19
+ schX={0}
20
+ schY={-2}
21
+ />
22
+ <trace from=".R1 > .right" to="net.N1" />
23
+ <trace from=".R2 > .left" to="net.N2" />
24
+ <trace from=".R3 > .left" to="net.N3" />
25
+ <trace from=".R4 > .right" to="net.GND2" />
26
+ </Schematic>
27
+ )
28
+ }
29
+
30
+ export default {
31
+ title: "Basics/SchematicNetLabel2",
32
+ component: SchematicNetLabel2,
33
+ }
@@ -3,12 +3,13 @@ import { Schematic } from "Schematic"
3
3
  const OneSidedBugExample = () => (
4
4
  <bug
5
5
  name="U2"
6
- port_arrangement={{
7
- left_size: 0,
8
- right_size: 4,
6
+ schPortArrangement={{
7
+ leftSize: 0,
8
+ rightSize: 4,
9
9
  }}
10
- center={[-10, 0]}
11
- port_labels={{
10
+ schX={-10}
11
+ schY={0}
12
+ pinLabels={{
12
13
  "1": "GND",
13
14
  "2": "VBUS",
14
15
  "3": "D-",
@@ -0,0 +1,49 @@
1
+ import { Schematic } from "Schematic"
2
+
3
+ const BugPinSpacingExample = () => (
4
+ <bug
5
+ name="U2"
6
+ schPortArrangement={{
7
+ leftSize: 2,
8
+ rightSize: 2,
9
+ }}
10
+ schX={-10}
11
+ schY={0}
12
+ schPinSpacing="1.5mm"
13
+ pinLabels={{
14
+ "1": "GND",
15
+ "2": "VBUS",
16
+ "3": "D-",
17
+ "4": "D+",
18
+ }}
19
+ />
20
+ )
21
+
22
+ export const BugPinSpacing = () => {
23
+ return (
24
+ <Schematic
25
+ style={{ height: 600 }}
26
+ _soupPostProcessor={(soup) => {
27
+ return soup.map((elm) => {
28
+ if (elm.type === "schematic_component") {
29
+ // return {
30
+ // ...elm,
31
+ // size: { width: 3, height: 3 },
32
+ // pin_spacing: 1.5,
33
+ // }
34
+ console.log(elm)
35
+ return elm
36
+ }
37
+ return elm
38
+ })
39
+ }}
40
+ >
41
+ <BugPinSpacingExample />
42
+ </Schematic>
43
+ )
44
+ }
45
+
46
+ export default {
47
+ title: "BugPinSpacing",
48
+ component: BugPinSpacing,
49
+ }
@@ -0,0 +1,52 @@
1
+ import { Schematic } from "../../Schematic"
2
+ import { layout } from "@tscircuit/layout"
3
+ import { useBug, useResistor, useCapacitor } from "@tscircuit/react-fiber"
4
+
5
+ export const Bug8Autolayout = () => {
6
+ const U1 = useBug("U1", {
7
+ pinLabels: {
8
+ 1: "VCC",
9
+ 2: "D0",
10
+ 3: "D1",
11
+ 4: "GND",
12
+ 5: "INP",
13
+ 6: "THR",
14
+ },
15
+ schPortArrangement: {
16
+ leftSize: 3,
17
+ topSize: 0,
18
+ bottomSize: 0,
19
+ rightSize: 3,
20
+ },
21
+ })
22
+
23
+ const R1 = useResistor("R1", { resistance: "10k" })
24
+ const R2 = useResistor("R2", { resistance: "1k" })
25
+ const R3 = useResistor("R3", { resistance: "5k" })
26
+ const C1 = useCapacitor("C1", { capacitance: "1uF" })
27
+
28
+ return (
29
+ <div>
30
+ <Schematic style={{ height: 500 }}>
31
+ <board
32
+ layout={layout().autoLayoutSchematic()}
33
+ pcbCenterX={0}
34
+ pcbCenterY={0}
35
+ width={"10mm"}
36
+ height={"10mm"}
37
+ >
38
+ <U1 />
39
+ <R1 left={U1.D1} right={U1.VCC} />
40
+ <R2 left={U1.D0} right={U1.GND} />
41
+ <R3 left={U1.INP} right={U1.THR} />
42
+ <C1 left={U1.INP} right={U1.THR} />
43
+ </board>
44
+ </Schematic>
45
+ </div>
46
+ )
47
+ }
48
+
49
+ export default {
50
+ title: "Bugs/Bug8Autolayout",
51
+ component: Bug8Autolayout,
52
+ }
@@ -0,0 +1,14 @@
1
+ import { Schematic } from "../../Schematic"
2
+
3
+ export const NetAlias = () => {
4
+ return (
5
+ <Schematic style={{ height: 500 }}>
6
+ <netalias net="GND" />
7
+ </Schematic>
8
+ )
9
+ }
10
+
11
+ export default {
12
+ title: "Circuit Components/NetAlias",
13
+ component: NetAlias,
14
+ }
package/vite.config.js ADDED
@@ -0,0 +1,7 @@
1
+ import { defineConfig } from "vite"
2
+ import react from "@vitejs/plugin-react"
3
+ import tsconfigPaths from "vite-tsconfig-paths"
4
+
5
+ export default {
6
+ plugins: [react(), tsconfigPaths()]
7
+ }