From 3e9bcb5f32e45232f178e62d56e651fb86e4e758 Mon Sep 17 00:00:00 2001 From: Arnav K Date: Mon, 10 Feb 2025 21:41:48 +0530 Subject: [PATCH] feat: Allow creating footprints on footprinter website (#177) * feat: Allow creating footprints on footprinter website * chore * remove 'data' var use * ui revamp * Update index.html --- .github/workflows/deploy-gallery.yml | 6 +- .gitignore | 1 + bun.lockb | Bin 126240 -> 127307 bytes gallery/generate-grid-content.ts | 75 ++++++++++++ gallery/index.html | 21 ++++ gallery/index.tsx | 173 +++++++++++++++++++++++++++ package.json | 4 +- tsconfig.json | 3 +- 8 files changed, 278 insertions(+), 5 deletions(-) mode change 100644 => 100755 bun.lockb create mode 100644 gallery/generate-grid-content.ts create mode 100644 gallery/index.html create mode 100644 gallery/index.tsx diff --git a/.github/workflows/deploy-gallery.yml b/.github/workflows/deploy-gallery.yml index cad69dbf..de307de8 100644 --- a/.github/workflows/deploy-gallery.yml +++ b/.github/workflows/deploy-gallery.yml @@ -10,10 +10,10 @@ jobs: build-and-deploy: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Bun - uses: oven-sh/setup-bun@v1 + uses: oven-sh/setup-bun@v2 with: bun-version: latest @@ -24,7 +24,7 @@ jobs: run: bun run generate-gallery - name: Rename gallery.html to index.html - run: mv public/gallery.html public/index.html + run: cp gallery/index.html public/index.html - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 diff --git a/.gitignore b/.gitignore index ff267abc..b849adbe 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ dist *.diff.png package-lock.json public +gallery/content.ts diff --git a/bun.lockb b/bun.lockb old mode 100644 new mode 100755 index 6acc438a5b01d0e5ce2d33c386c04f67029e06a5..f61006ee276d32ba3a545def20b48fb79caa8dff GIT binary patch delta 19858 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 JF1DxT{{TD%p5p)j delta 19295 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 TW1npGS file.endsWith(".snap.svg")) + } catch (error) { + console.warn( + `Directory not found: ${dir}. Proceeding with empty file list.`, + ) + return [] + } +} + +function readAndFormatSvg(filePath) { + try { + const svgContent = fs + .readFileSync(filePath, "utf-8") + .replace(/width="\d+"/, 'width="300"') + .replace(/height="\d+"/, 'height="225" viewBox="0 0 800 600"') + return svgContent + } catch (error) { + console.warn(`Failed to read file: ${filePath}. Skipping.`) + return null + } +} + +function generateFootprintsData(svgFiles) { + return svgFiles.reduce((data, file) => { + const filePath = path.join(snapshotsDir, file) + const svgContent = readAndFormatSvg(filePath) + + if (svgContent) { + data.push({ + svgContent, + title: path.basename(file, ".snap.svg"), + }) + } + return data + }, []) +} + +// Ensure output directory exists +ensureDirectoryExists(path.dirname(outputFile)) + +// Process SVG files +const svgFiles = getSvgFiles(snapshotsDir) +const data = generateFootprintsData(svgFiles) + +// Write to output file +try { + fs.writeFileSync( + outputFile, + `export default ${JSON.stringify(data, null, 2)};`, + ) + console.log(`Data successfully written to ${outputFile}`) +} catch (error) { + console.error(`Failed to write to ${outputFile}:`, error) +} + +// Build site +const buildOutput = await Bun.build({ + outdir: "public", + entrypoints: ["./gallery/index.tsx"], +}) +console.log("\n", buildOutput) diff --git a/gallery/index.html b/gallery/index.html new file mode 100644 index 00000000..3e10097c --- /dev/null +++ b/gallery/index.html @@ -0,0 +1,21 @@ + + + + + + tscircuit/footprinter gallery + + + + + + diff --git a/gallery/index.tsx b/gallery/index.tsx new file mode 100644 index 00000000..b5f316a6 --- /dev/null +++ b/gallery/index.tsx @@ -0,0 +1,173 @@ +import { convertCircuitJsonToPcbSvg } from "circuit-to-svg" +import React, { useState, useCallback } from "react" +import ReactDOM from "react-dom/client" +import { fp } from "src/footprinter" +// @ts-ignore data is built during CI +import data from "./content" + +interface Footprint { + svgContent: string + title: string +} + +const FootprintCreator: React.FC = () => { + const [definition, setDefinition] = useState("") + const [generatedSvg, setGeneratedSvg] = useState(null) + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") + + // Generate the SVG based on the provided footprint definition. + const generateFootprint = useCallback(async (input: string) => { + setError("") + setGeneratedSvg(null) + + if (!input.trim()) { + setError("Please enter a footprint definition.") + return + } + + setLoading(true) + try { + const circuitJson = fp.string(input).circuitJson() + const svgContent = convertCircuitJsonToPcbSvg(circuitJson) + setGeneratedSvg(svgContent) + } catch (err: any) { + setError(err.message) + } finally { + setLoading(false) + } + }, []) + + // Form submission triggers generation. + const handleGenerate = (e: React.FormEvent) => { + e.preventDefault() + generateFootprint(definition) + } + + // When a grid item is clicked, update the definition and generate its SVG. + const handleFootprintClick = (footprint: Footprint) => { + setDefinition(footprint.title) + generateFootprint(footprint.title) + window.scrollTo({ top: 0, behavior: "smooth" }) + } + + // Allow generation on pressing Enter (without Shift). + const handleKeyDown = (e: React.KeyboardEvent) => { + if (e.key === "Enter" && !e.shiftKey) { + e.preventDefault() + generateFootprint(definition) + } + } + + return ( +
+ {/* Header */} +
+ +
+ + {/* Main Content */} +
+
+ {/* Responsive Left/Right Layout */} +
+ {/* Left: Form */} +
+
+