diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..c3cfc39 --- /dev/null +++ b/biome.json @@ -0,0 +1,52 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json", + "organizeImports": { + "enabled": true + }, + "formatter": { + "enabled": true, + "indentStyle": "space" + }, + "files": { + "ignore": ["cosmos-export", "dist", "package.json"] + }, + "javascript": { + "formatter": { + "jsxQuoteStyle": "double", + "quoteProperties": "asNeeded", + "trailingCommas": "all", + "semicolons": "asNeeded", + "arrowParentheses": "always", + "bracketSpacing": true, + "bracketSameLine": false + } + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "suspicious": { + "noExplicitAny": "off" + }, + "complexity": { + "noForEach": "info" + }, + "correctness": { + "useExhaustiveDependencies": "off" + }, + "style": { + "noUselessElse": "off", + "noNonNullAssertion": "off", + "useNumberNamespace": "off", + "useFilenamingConvention": { + "level": "error", + "options": { + "strictCase": true, + "requireAscii": true, + "filenameCases": ["kebab-case", "export"] + } + } + } + } + } +} diff --git a/bun.lockb b/bun.lockb index 86f0d15..d1a0c44 100755 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/examples/resistor-and-capacitor.fixture.tsx b/examples/resistor-and-capacitor.fixture.tsx new file mode 100644 index 0000000..321ef6b --- /dev/null +++ b/examples/resistor-and-capacitor.fixture.tsx @@ -0,0 +1,16 @@ +import { SchematicViewer } from "lib/components/SchematicViewer" +import { renderToCircuitJson } from "lib/dev/render-to-circuit-json" + +export default () => ( +
+ + + + + , + )} + /> +
+) diff --git a/index.html b/index.html index 6c50af8..06856b5 100644 --- a/index.html +++ b/index.html @@ -7,6 +7,6 @@
- + diff --git a/lib/components/SchematicViewer.tsx b/lib/components/SchematicViewer.tsx new file mode 100644 index 0000000..7f29ab9 --- /dev/null +++ b/lib/components/SchematicViewer.tsx @@ -0,0 +1,78 @@ +import { useMouseMatrixTransform } from "use-mouse-matrix-transform" +import { convertCircuitJsonToSchematicSvg } from "circuit-to-svg" +import { useEffect, useMemo, useRef, useState } from "react" +import { toString as transformToString } from "transformation-matrix" + +interface Props { + circuitJson: Array<{ type: string }> +} + +export const SchematicViewer = ({ circuitJson }: Props) => { + const svgDivRef = useRef(null) + const { ref: containerRef } = useMouseMatrixTransform({ + onSetTransform(transform) { + if (!svgDivRef.current) return + svgDivRef.current.style.transform = transformToString(transform) + }, + }) + const [containerWidth, setContainerWidth] = useState(0) + const [containerHeight, setContainerHeight] = useState(0) + + useEffect(() => { + if (!containerRef.current) return + + const updateDimensions = () => { + const rect = containerRef.current?.getBoundingClientRect() + + setContainerWidth(rect?.width || 0) + setContainerHeight(rect?.height || 0) + } + + // Set initial dimensions + updateDimensions() + + // Add resize listener + const resizeObserver = new ResizeObserver(updateDimensions) + resizeObserver.observe(containerRef.current) + + // Fallback to window resize + window.addEventListener("resize", updateDimensions) + + return () => { + resizeObserver.disconnect() + window.removeEventListener("resize", updateDimensions) + } + }, []) + + const svg = useMemo(() => { + if (!containerWidth || !containerHeight) return "" + + return convertCircuitJsonToSchematicSvg(circuitJson as any, { + width: containerWidth, + height: containerHeight || 720, + }) + }, [circuitJson, containerWidth, containerHeight]) + + return ( +
+
+ dangerouslySetInnerHTML={{ __html: svg }} + /> +
+ ) +} diff --git a/lib/dev/render-to-circuit-json.ts b/lib/dev/render-to-circuit-json.ts new file mode 100644 index 0000000..bea12d9 --- /dev/null +++ b/lib/dev/render-to-circuit-json.ts @@ -0,0 +1,8 @@ +import * as Core from "@tscircuit/core" +console.log(Core) + +export const renderToCircuitJson = (board: React.ReactElement) => { + const circuit = new Core.Circuit() + circuit.add(board) + return circuit.getCircuitJson() +} diff --git a/lib/test.fixture.tsx b/lib/test.fixture.tsx deleted file mode 100644 index 448e529..0000000 --- a/lib/test.fixture.tsx +++ /dev/null @@ -1 +0,0 @@ -export default () =>
Hello world!
\ No newline at end of file diff --git a/package.json b/package.json index ff6abaf..420a9b5 100644 --- a/package.json +++ b/package.json @@ -9,14 +9,17 @@ "build:site": "cosmos-export" }, "devDependencies": { + "@biomejs/biome": "^1.9.4", + "@tscircuit/core": "^0.0.222", "@types/bun": "latest", "@types/react": "^19.0.1", "@types/react-dom": "^19.0.2", "@vitejs/plugin-react": "^4.3.4", - "react": "^19.0.0", + "circuit-json": "^0.0.111", + "react": "18", "react-cosmos": "^6.2.1", "react-cosmos-plugin-vite": "^6.2.0", - "react-dom": "^19.0.0", + "react-dom": "18", "tsup": "^8.3.5", "vite": "^6.0.3" }, @@ -24,6 +27,10 @@ "typescript": "^5.0.0" }, "dependencies": { - "circuit-to-svg": "^0.0.90" + "circuit-to-svg": "^0.0.90", + "debug": "^4.4.0", + "performance-now": "^2.1.0", + "react-reconciler": "^0.31.0", + "use-mouse-matrix-transform": "^1.1.13" } } diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..e3d0752 --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,20 @@ +import React from "react" +import { createRoot } from "react-dom/client" +import { renderToCircuitJson } from "lib/dev/render-to-circuit-json" +import { SchematicViewer } from "lib/components/SchematicViewer" + +const root = createRoot(document.getElementById("root")!) + +root.render( + +
+ + + , + )} + /> +
+
, +) diff --git a/test.ts b/test.ts new file mode 100644 index 0000000..e69de29 diff --git a/tsconfig.json b/tsconfig.json index d84e386..1be19ce 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { // Enable latest features "lib": ["ESNext", "DOM"], - "target": "ESNext", + "target": "ES2020", "module": "ESNext", "moduleDetection": "force", "jsx": "react-jsx", @@ -12,6 +12,7 @@ "paths": { "lib/*": ["lib/*"] }, + "esModuleInterop": true, // Bundler mode "moduleResolution": "bundler", diff --git a/vite.config.js b/vite.config.js index 32a6852..8af75fe 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,12 +1,15 @@ import { defineConfig } from "vite" import react from "@vitejs/plugin-react" -import { resolve } from "path" +import { resolve } from "node:path" export default defineConfig({ plugins: [react()], resolve: { alias: { - lib: resolve(__dirname, "./lib") - } + lib: resolve(__dirname, "./lib"), + }, + }, + define: { + global: {}, }, }) diff --git a/vite/main.tsx b/vite/main.tsx deleted file mode 100644 index 6391bfa..0000000 --- a/vite/main.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import React from "react" -import { createRoot } from "react-dom/client" - -const root = createRoot(document.getElementById("root")!) - -root.render( - -
Hello from @tscircuit/schematic-viewer
-
-)