@tscircuit/schematic-viewer 1.3.0 → 1.4.0

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 (41) hide show
  1. package/README.md +1 -1
  2. package/dist/index.d.ts +3 -4
  3. package/dist/index.js +694 -687
  4. package/dist/index.js.map +1 -1
  5. package/package.json +5 -6
  6. package/src/Schematic.tsx +139 -65
  7. package/src/lib/types/core.ts +14 -49
  8. package/src/lib/types/source-component.ts +5 -0
  9. package/src/lib/utils/collect-element-refs.ts +1 -0
  10. package/src/lib/utils/colors.ts +236 -0
  11. package/src/schematic-components/SVGPathComponent.tsx +84 -144
  12. package/src/schematic-components/SchematicChip.tsx +183 -0
  13. package/src/schematic-components/SchematicComponent.tsx +18 -24
  14. package/src/schematic-components/SchematicComponentFromSymbol.tsx +44 -0
  15. package/src/schematic-components/SchematicElement.tsx +0 -28
  16. package/src/schematic-components/SchematicTrace.tsx +4 -3
  17. package/src/schematic-components/index.tsx +7 -14
  18. package/src/stories/basics/schematic-net-labels-2.stories.tsx +22 -20
  19. package/src/stories/bug-connections.stories.tsx +3 -0
  20. package/src/stories/bug-high-port-numbers.stories.tsx +99 -85
  21. package/src/stories/bugs/bug3-scaling-trace.stories.tsx +11 -5
  22. package/src/stories/bugs/bug4-schematic-line.stories.tsx +0 -1
  23. package/src/stories/bugs/bug5-diode.stories.tsx +0 -1
  24. package/src/stories/bugs/bug8-autolayout.stories.tsx +20 -29
  25. package/src/stories/circuit-components/diode.stories.tsx +3 -1
  26. package/src/stories/circuit-components/resistor.stories.tsx +3 -1
  27. package/src/stories/led-circuit-react.stories.tsx +40 -48
  28. package/src/pages/led-circuit.tsx +0 -96
  29. package/src/schematic-components/ProjectComponent.tsx +0 -70
  30. package/src/schematic-components/SchematicBox.tsx +0 -29
  31. package/src/schematic-components/SchematicBug.tsx +0 -107
  32. package/src/schematic-components/SchematicLine.tsx +0 -48
  33. package/src/schematic-components/SchematicPath.tsx +0 -51
  34. package/src/schematic-components/SchematicPort.tsx +0 -63
  35. package/src/schematic-components/SimpleCapacitor.tsx +0 -29
  36. package/src/schematic-components/SimpleDiode.tsx +0 -42
  37. package/src/schematic-components/SimpleGround.tsx +0 -30
  38. package/src/schematic-components/SimpleInductor.tsx +0 -29
  39. package/src/schematic-components/SimplePowerSource.tsx +0 -43
  40. package/src/schematic-components/SimpleResistor.tsx +0 -28
  41. package/src/stories/led-circuit-builder.stories.tsx +0 -104
@@ -1,29 +0,0 @@
1
- import * as Type from "lib/types"
2
- import { directionToVec } from "lib/utils/direction-to-vec"
3
- import * as Component from "./"
4
-
5
- interface Props {
6
- box: {
7
- schematic: Type.SchematicBox
8
- }
9
- }
10
-
11
- export const SchematicBox = ({ box: { schematic } }: Props) => {
12
- const { width: w, height: h } = schematic
13
- return (
14
- <Component.SVGPathComponent
15
- rotation={0}
16
- center={schematic}
17
- size={{ width: schematic.width, height: schematic.height }}
18
- paths={[
19
- {
20
- stroke: "red",
21
- strokeWidth: 0.02,
22
- d: `M 0 0 l ${w} 0 l 0 ${h} l -${w} 0 z`,
23
- },
24
- ]}
25
- />
26
- )
27
- }
28
-
29
- export default SchematicBox
@@ -1,107 +0,0 @@
1
- import {
2
- getPortArrangementSize,
3
- getPortIndices,
4
- getPortPosition,
5
- } from "@tscircuit/builder"
6
- import type { SchematicComponent } from "@tscircuit/soup"
7
- import * as Type from "lib/types"
8
- import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
9
- import SVGPathComponent from "./SVGPathComponent"
10
- import SchematicText from "./SchematicText"
11
-
12
- interface Props {
13
- component: {
14
- source: Type.SimpleBug
15
- schematic: SchematicComponent
16
- }
17
- }
18
-
19
- export const SchematicBug = ({ component: { source, schematic } }: Props) => {
20
- const location = schematic.center
21
- const port_arrangement = {
22
- top_size: 0,
23
- bottom_size: 0,
24
- ...schematic.port_arrangement,
25
- }
26
- const manufacturerPartNumber = source.manufacturerPartNumber
27
- // const port_labels = schematic.port_labels!
28
- let bugw = schematic.size.width // bug width
29
- let bugh = schematic.size.height
30
-
31
- const { total_ports, width, height } =
32
- getPortArrangementSize(port_arrangement)
33
- const port_indices = getPortIndices(port_arrangement)
34
-
35
- // TODO remove, this seems to be due to a builder bug
36
- if (isNaN(bugw)) bugw = width
37
- if (isNaN(bugh)) bugh = height
38
- // TODO throw if schematic.size doesn't match computed port_arrangement size
39
-
40
- const paths = [
41
- {
42
- stroke: "red",
43
- strokeWidth: 0.02,
44
- d: `M ${-bugw / 2} ${-bugh / 2} L ${bugw / 2} ${-bugh / 2} L ${
45
- bugw / 2
46
- } ${bugh / 2} L ${-bugw / 2} ${bugh / 2}Z`,
47
- },
48
- ...port_indices.map((portNum) => {
49
- // TODO get the ports passed to the components and use those positions
50
- const pos = getPortPosition(
51
- { ...port_arrangement, pin_spacing: schematic.pin_spacing },
52
- portNum,
53
- )
54
-
55
- const x2 =
56
- pos.side === "left"
57
- ? -bugw / 2
58
- : pos.side === "right"
59
- ? bugw / 2
60
- : pos.x
61
- const y2 =
62
- pos.side === "top"
63
- ? bugh / 2
64
- : pos.side === "bottom"
65
- ? -bugh / 2
66
- : pos.y
67
-
68
- return {
69
- stroke: "red",
70
- strokeWidth: 0.02,
71
- d: `M ${pos.x} ${pos.y} L ${x2} ${y2}`,
72
- }
73
- }),
74
- ]
75
-
76
- const actualSize = getSVGPathBounds(paths.map((p) => p.d).join(" "))
77
- const actualCenter = {
78
- x: schematic.center.x + (actualSize.minX + actualSize.maxX) / 2,
79
- y: schematic.center.y + (actualSize.minY + actualSize.maxY) / 2,
80
- }
81
-
82
- return (
83
- <>
84
- <SVGPathComponent
85
- rotation={schematic.rotation}
86
- center={actualCenter}
87
- size={actualSize}
88
- paths={paths}
89
- />
90
- <SchematicText
91
- schematic_text={{
92
- anchor: "bottom",
93
- position: {
94
- x: location.x + actualSize.minX / 1.5,
95
- y: location.y + actualSize.minY,
96
- },
97
- schematic_component_id: "SYNTHETIC",
98
- schematic_text_id: "SYNTHETIC",
99
- text: manufacturerPartNumber,
100
- type: "schematic_text",
101
- }}
102
- />
103
- </>
104
- )
105
- }
106
-
107
- export default SchematicBug
@@ -1,48 +0,0 @@
1
- import * as Type from "lib/types"
2
- import { directionToVec } from "lib/utils/direction-to-vec"
3
- import * as Component from "."
4
- import Path from "svg-path-generator"
5
- import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
6
-
7
- interface Props {
8
- line: {
9
- schematic: Type.SchematicLine
10
- }
11
- }
12
-
13
- export const SchematicLine = ({ line: { schematic } }: Props) => {
14
- const { x1, x2, y1, y2 } = schematic
15
- const dx = x2 - x1
16
- const dy = y2 - y1
17
- // const width = Math.abs(dx) + 0.1
18
- // const height = Math.abs(dy) + 0.1
19
- // const center = { x: x1 + dx / 2, y: y1 + dy / 2 }
20
- const path = Path()
21
- path.moveTo(x1, y1)
22
- path.lineTo(x2, y2)
23
- const d = path.toString()
24
- const pathBounds = getSVGPathBounds(d)
25
- // pathBounds.height = Math.max(pathBounds.height, 1)
26
- // pathBounds.width = Math.max(pathBounds.width, 1)
27
- const center = {
28
- x: pathBounds.minX + pathBounds.width / 2,
29
- y: pathBounds.minY + pathBounds.height / 2,
30
- }
31
-
32
- return (
33
- <Component.SVGPathComponent
34
- rotation={0}
35
- center={center}
36
- size={pathBounds}
37
- paths={[
38
- {
39
- stroke: "red",
40
- strokeWidth: 0.02,
41
- d: d,
42
- },
43
- ]}
44
- />
45
- )
46
- }
47
-
48
- export default SchematicLine
@@ -1,51 +0,0 @@
1
- import * as Type from "lib/types"
2
- import { directionToVec } from "lib/utils/direction-to-vec"
3
- import * as Component from "."
4
- import Path from "svg-path-generator"
5
- import getSVGPathBounds from "lib/utils/get-svg-path-bounds"
6
-
7
- interface Props {
8
- path: {
9
- schematic: Type.SchematicPath
10
- }
11
- }
12
-
13
- export const SchematicPath = (props: Props) => {
14
- const { points, is_filled, is_closed, fill_color } = props.path.schematic
15
-
16
- if (points.length === 0) return null
17
- const path = Path()
18
- path.moveTo(points[0].x, points[0].y)
19
- for (const point of points.slice(1)) {
20
- path.lineTo(point.x, point.y)
21
- }
22
- if (is_closed) {
23
- path.closePath()
24
- }
25
- const d = path.toString()
26
- const pathBounds = getSVGPathBounds(d)
27
- pathBounds.height = Math.max(pathBounds.height, 1)
28
- pathBounds.width = Math.max(pathBounds.width, 1)
29
- const center = {
30
- x: pathBounds.minX + pathBounds.width / 2,
31
- y: pathBounds.minY + pathBounds.height / 2,
32
- }
33
-
34
- return (
35
- <Component.SVGPathComponent
36
- rotation={0}
37
- center={center}
38
- size={pathBounds}
39
- paths={[
40
- {
41
- stroke: is_filled ? "none" : fill_color ?? "red",
42
- strokeWidth: 0.02,
43
- fill: is_filled ? fill_color ?? "red" : undefined,
44
- d: d,
45
- },
46
- ]}
47
- />
48
- )
49
- }
50
-
51
- export default SchematicPath
@@ -1,63 +0,0 @@
1
- import * as Type from "lib/types"
2
- import { directionToVec } from "lib/utils/direction-to-vec"
3
- import * as Component from "./"
4
- import { useState } from "react"
5
-
6
- interface Props {
7
- port: {
8
- source_port: Type.SourcePort
9
- source_component: Type.SourceComponent
10
- schematic: Type.SchematicPort
11
- }
12
- }
13
-
14
- export const SchematicPort = ({
15
- port: { source_port, source_component, schematic },
16
- }: Props) => {
17
- const hoverName = source_component?.name
18
- ? `.${source_component.name} > .${
19
- source_port?.name ?? source_port?.pin_number
20
- }`
21
- : `.${source_port?.name ?? source_port?.pin_number}`
22
- const vec = directionToVec(schematic.facing_direction)
23
- return (
24
- <Component.SVGPathComponent
25
- rotation={0}
26
- hoverContent={
27
- <div>
28
- {hoverName}
29
- <br />
30
- {source_port?.pin_number && `Pin ${source_port.pin_number}`}
31
- {/* <br />
32
- <div style={{ opacity: 0.5 }}>
33
- {schematic.schematic_port_id}
34
- <br />
35
- {schematic.source_port_id}
36
- </div> */}
37
- </div>
38
- }
39
- center={schematic.center}
40
- size={{
41
- width: 0.2 + Math.abs(vec.x) * 0.04,
42
- height: 0.2 + Math.abs(vec.y) * 0.04,
43
- }}
44
- zIndex={10}
45
- paths={[
46
- {
47
- stroke: "blue",
48
- strokeWidth: 1,
49
- d: "M 0 0 l 10 0 l 0 10 l -10 0 z",
50
- },
51
- schematic.facing_direction
52
- ? {
53
- stroke: "blue",
54
- strokeWidth: 0.5,
55
- d: `M 5 5 l ${vec.x * 7} ${vec.y * 7}`,
56
- }
57
- : null,
58
- ].filter(Boolean)}
59
- />
60
- )
61
- }
62
-
63
- export default SchematicPort
@@ -1,29 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimpleCapacitor
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimpleCapacitor = ({
12
- component: { source, schematic },
13
- }: Props) => {
14
- return (
15
- <SVGPathComponent
16
- rotation={schematic.rotation}
17
- center={schematic.center}
18
- size={schematic.size}
19
- paths={[
20
- { stroke: "red", strokeWidth: 1, d: "M 0 15 l 12 0" },
21
- { stroke: "red", strokeWidth: 1, d: "M 12 0 l 0 30" },
22
- { stroke: "red", strokeWidth: 1, d: "M 18 0 l 0 30" },
23
- { stroke: "red", strokeWidth: 1, d: "M 18 15 l 12 0" },
24
- ]}
25
- />
26
- )
27
- }
28
-
29
- export default SimpleCapacitor
@@ -1,42 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimpleDiode
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimpleDiode = ({ component: { source, schematic } }: Props) => {
12
- return (
13
- <SVGPathComponent
14
- rotation={schematic.rotation}
15
- center={schematic.center}
16
- // size={schematic.size}
17
- size={{
18
- height: 0.5,
19
- width: 1,
20
- }}
21
- paths={[
22
- { stroke: "red", strokeWidth: 2, d: "M 0,0 H 21" },
23
- { stroke: "red", strokeWidth: 2, d: "M 49,0 H 59" },
24
- { stroke: "red", strokeWidth: 2, d: "M 49,0 L 21 14 V -14 Z" },
25
- { stroke: "red", strokeWidth: 2, d: "M 49,-14 V 14" },
26
- // For LEDs
27
- // {
28
- // stroke: "red",
29
- // strokeWidth: 2,
30
- // d: "M 35 -32 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
31
- // },
32
- // {
33
- // stroke: "red",
34
- // strokeWidth: 2,
35
- // d: "M 52 -26 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
36
- // },
37
- ]}
38
- />
39
- )
40
- }
41
-
42
- export default SimpleDiode
@@ -1,30 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimpleGround
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimpleGround = ({ component: { source, schematic } }: Props) => {
12
- return (
13
- <SVGPathComponent
14
- rotation={schematic.rotation}
15
- center={schematic.center}
16
- size={schematic.size}
17
- invertY
18
- shiftToBottom
19
- paths={[
20
- {
21
- stroke: "red",
22
- strokeWidth: 0.7,
23
- d: "M -3 3 L 3 3 M -6 0 L 6 0 M -9 -3 L 9 -3 M 0 -3 L 0 -12",
24
- },
25
- ]}
26
- />
27
- )
28
- }
29
-
30
- export default SimpleGround
@@ -1,29 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimpleInductor
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimpleInductor = ({ component: { source, schematic } }: Props) => {
12
- return (
13
- <SVGPathComponent
14
- rotation={schematic.rotation}
15
- center={schematic.center}
16
- size={schematic.size}
17
- paths={[
18
- {
19
- stroke: "red",
20
- strokeWidth: 1,
21
- // https://commons.wikimedia.org/wiki/File:Electrical_symbols_library.svg
22
- d: "m 371,710.41665 h -14 c -0.0421,-16.39898 -14.02104,-16.39898 -14,0 -0.021,-16.399 -14.04182,-16.34072 -14,0 -2.6e-4,-16.45722 -14.04236,-16.45722 -14,0 2.8e-4,-16.3407 -13.97896,-16.39898 -14,0 -0.0421,-16.39898 -13.91338,-16.39898 -13.91338,0 H 273",
23
- },
24
- ]}
25
- />
26
- )
27
- }
28
-
29
- export default SimpleInductor
@@ -1,43 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimplePowerSource
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimplePowerSource = ({
12
- component: { source, schematic },
13
- }: Props) => {
14
- return (
15
- <SVGPathComponent
16
- rotation={schematic.rotation}
17
- center={schematic.center}
18
- size={schematic.size}
19
- invertY
20
- paths={[
21
- {
22
- stroke: "red",
23
- strokeWidth: 1,
24
- d: "M 0 -17 L 0 -3 M -8 3 L 8 3 M 0 17 L 0 3 M -12 -3 L 12 -3",
25
- },
26
- // positive symbol
27
- {
28
- stroke: "red",
29
- strokeWidth: 0.5,
30
- d: "M 8 -9 L 8 -6 M 9.5 -7.5 L 6.5 -7.5",
31
- },
32
- // negative symbol
33
- {
34
- stroke: "red",
35
- strokeWidth: 0.5,
36
- d: "M 9.5 7.5 L 6.5 7.5",
37
- },
38
- ]}
39
- />
40
- )
41
- }
42
-
43
- export default SimplePowerSource
@@ -1,28 +0,0 @@
1
- import * as Type from "lib/types"
2
- import SVGPathComponent from "./SVGPathComponent"
3
-
4
- interface Props {
5
- component: {
6
- source: Type.SimpleResistor
7
- schematic: Type.SchematicComponent
8
- }
9
- }
10
-
11
- export const SimpleResistor = ({ component: { source, schematic } }: Props) => {
12
- return (
13
- <SVGPathComponent
14
- rotation={schematic.rotation}
15
- center={schematic.center}
16
- size={schematic.size}
17
- paths={[
18
- {
19
- stroke: "red",
20
- strokeWidth: 1,
21
- d: "M 0 15 l 10 0 l 0 -6 l 20 0 l 0 12 l -20 0 l 0 -6 m 20 0 l 10 0",
22
- },
23
- ]}
24
- />
25
- )
26
- }
27
-
28
- export default SimpleResistor
@@ -1,104 +0,0 @@
1
- import { useMaybePromise } from "lib/hooks"
2
- import { Schematic } from "../Schematic"
3
- import { createProjectBuilder } from "@tscircuit/builder"
4
-
5
- const pb = createProjectBuilder()
6
- const $soup = pb
7
- .addGroup((gb) =>
8
- gb
9
- .addResistor((rb) =>
10
- rb
11
- .setSourceProperties({
12
- resistance: "10 ohm",
13
- name: "R1",
14
- })
15
- .setSchematicCenter(2, 1)
16
- )
17
- .addCapacitor((cb) =>
18
- cb
19
- .setSourceProperties({
20
- name: "C1",
21
- capacitance: "10 uF",
22
- })
23
- .setSchematicCenter(4, 2)
24
- .setSchematicRotation("90deg")
25
- )
26
- .addResistor((cb) =>
27
- cb
28
- .setSourceProperties({
29
- resistance: "10 ohm",
30
- name: "R2",
31
- })
32
- .setSchematicCenter(6, 1)
33
- .setSchematicRotation("90deg")
34
- )
35
- .addTrace([".R1 > port.right", ".C1 > port.left", ".R2 > port.left"])
36
- .addPowerSource((cb) =>
37
- cb
38
- .setSourceProperties({
39
- voltage: "5V",
40
- name: "main_power",
41
- })
42
- .setSchematicCenter(1, 2)
43
- )
44
- .addTrace(["power > port.positive", ".R1 > port.left"])
45
- .addTrace([
46
- "power > port.negative",
47
- ".C1 > port.right",
48
- ".R2 > port.right",
49
- ])
50
- .addBug((cb) =>
51
- cb
52
- .setSourceProperties({ name: "B1" })
53
- .setSchematicProperties({
54
- port_arrangement: {
55
- left_size: 3,
56
- right_size: 3,
57
- },
58
- })
59
- .labelPort(1, "PWR")
60
- .labelPort(2, "NC")
61
- .labelPort(3, "RG")
62
- .labelPort(4, "D0")
63
- .labelPort(5, "D1")
64
- .labelPort(6, "GND")
65
- .setSchematicCenter(8, 3)
66
- )
67
- .addTrace([".B1 > port.PWR", ".R2 > port.left"])
68
- .addGround((cb) =>
69
- cb
70
- .setSourceProperties({
71
- name: "GND",
72
- })
73
- .setSchematicCenter(11, 3)
74
- )
75
- .addTrace([".B1 > port.GND", ".gnd"])
76
- .addDiode((db) =>
77
- db
78
- .setSourceProperties({ name: "D1" })
79
- .setSchematicCenter(6, 3.5)
80
- .setSchematicRotation("180deg")
81
- )
82
- .addTrace([".D1 > .left", ".B1 > .RG"])
83
- .addTrace([".D1 > .right", ".C1 > .right"])
84
- .add("net_alias", (nab) =>
85
- nab
86
- .setSourceProperties({
87
- net: "D0BUS",
88
- })
89
- .setSchematicCenter("10mm", "1mm")
90
- )
91
- .addTrace([".D0BUS", ".B1 > .D0"])
92
- )
93
- .build(pb.createBuildContext())
94
-
95
- export const LEDCircuitBuilder = () => {
96
- const soup = useMaybePromise($soup)
97
- if (!soup) return null
98
- return <Schematic style={{ height: 600 }} soup={soup as any} />
99
- }
100
-
101
- export default {
102
- title: "LEDCircuitBuilder",
103
- component: LEDCircuitBuilder,
104
- }