@tscircuit/fake-snippets 0.0.4 → 0.0.5

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.
@@ -0,0 +1,498 @@
1
+ export const exampleCircuitJson = [
2
+ {
3
+ type: "source_port",
4
+ source_port_id: "source_port_0",
5
+ name: "pin1",
6
+ pin_number: 1,
7
+ port_hints: ["anode", "pos", "left", "pin1", "1"],
8
+ source_component_id: "source_component_0",
9
+ },
10
+ {
11
+ type: "source_port",
12
+ source_port_id: "source_port_1",
13
+ name: "pin2",
14
+ pin_number: 2,
15
+ port_hints: ["cathode", "neg", "right", "pin2", "2"],
16
+ source_component_id: "source_component_0",
17
+ },
18
+ {
19
+ type: "source_component",
20
+ source_component_id: "source_component_0",
21
+ ftype: "simple_resistor",
22
+ name: "R1",
23
+ supplier_part_numbers: {
24
+ jlcpcb: ["C11702", "C25543", "C226166"],
25
+ },
26
+ resistance: 1000,
27
+ display_resistance: "1kΩ",
28
+ },
29
+ {
30
+ type: "source_port",
31
+ source_port_id: "source_port_2",
32
+ name: "pin1",
33
+ pin_number: 1,
34
+ port_hints: ["anode", "pos", "left", "pin1", "1"],
35
+ source_component_id: "source_component_1",
36
+ },
37
+ {
38
+ type: "source_port",
39
+ source_port_id: "source_port_3",
40
+ name: "pin2",
41
+ pin_number: 2,
42
+ port_hints: ["cathode", "neg", "right", "pin2", "2"],
43
+ source_component_id: "source_component_1",
44
+ },
45
+ {
46
+ type: "source_component",
47
+ source_component_id: "source_component_1",
48
+ ftype: "simple_capacitor",
49
+ name: "C1",
50
+ supplier_part_numbers: {
51
+ jlcpcb: ["C106205", "C1523", "C14442"],
52
+ },
53
+ capacitance: 1e-9,
54
+ display_capacitance: "1nF",
55
+ },
56
+ {
57
+ type: "source_group",
58
+ source_group_id: "source_group_0",
59
+ is_subcircuit: true,
60
+ subcircuit_id: "subcircuit_source_group_0",
61
+ },
62
+ {
63
+ type: "source_trace",
64
+ source_trace_id: "source_trace_0",
65
+ connected_source_port_ids: ["source_port_0", "source_port_2"],
66
+ connected_source_net_ids: [],
67
+ max_length: null,
68
+ display_name: ".R1 > .pin1 to .C1 > .pin1",
69
+ subcircuit_connectivity_map_key: "unnamedsubcircuit27_connectivity_net0",
70
+ },
71
+ {
72
+ type: "schematic_component",
73
+ schematic_component_id: "schematic_component_0",
74
+ center: {
75
+ x: 3,
76
+ y: 0,
77
+ },
78
+ rotation: 0,
79
+ size: {
80
+ width: 1.0583332999999997,
81
+ height: 0.388910699999999,
82
+ },
83
+ source_component_id: "source_component_0",
84
+ symbol_name: "boxresistor_right",
85
+ symbol_display_value: "1kΩ",
86
+ },
87
+ {
88
+ type: "schematic_component",
89
+ schematic_component_id: "schematic_component_1",
90
+ center: {
91
+ x: -3,
92
+ y: 0,
93
+ },
94
+ rotation: 0,
95
+ size: {
96
+ width: 1.0583333000000001,
97
+ height: 0.8400173000000031,
98
+ },
99
+ source_component_id: "source_component_1",
100
+ symbol_name: "capacitor_right",
101
+ symbol_display_value: "1nF",
102
+ },
103
+ {
104
+ type: "schematic_port",
105
+ schematic_port_id: "schematic_port_0",
106
+ schematic_component_id: "schematic_component_0",
107
+ center: {
108
+ x: 2.4662093,
109
+ y: 0.045805199999999324,
110
+ },
111
+ source_port_id: "source_port_0",
112
+ facing_direction: "left",
113
+ distance_from_component_edge: 0.4,
114
+ pin_number: 1,
115
+ display_pin_label: "left",
116
+ },
117
+ {
118
+ type: "schematic_port",
119
+ schematic_port_id: "schematic_port_1",
120
+ schematic_component_id: "schematic_component_0",
121
+ center: {
122
+ x: 3.5337907000000004,
123
+ y: 0.04525870000000065,
124
+ },
125
+ source_port_id: "source_port_1",
126
+ facing_direction: "right",
127
+ distance_from_component_edge: 0.4,
128
+ pin_number: 2,
129
+ display_pin_label: "right",
130
+ },
131
+ {
132
+ type: "schematic_port",
133
+ schematic_port_id: "schematic_port_2",
134
+ schematic_component_id: "schematic_component_1",
135
+ center: {
136
+ x: -3.5512093000000005,
137
+ y: 0.016380250000000984,
138
+ },
139
+ source_port_id: "source_port_2",
140
+ facing_direction: "left",
141
+ distance_from_component_edge: 0.4,
142
+ pin_number: 1,
143
+ display_pin_label: "left",
144
+ },
145
+ {
146
+ type: "schematic_port",
147
+ schematic_port_id: "schematic_port_3",
148
+ schematic_component_id: "schematic_component_1",
149
+ center: {
150
+ x: -2.4487907,
151
+ y: 0.016926950000000218,
152
+ },
153
+ source_port_id: "source_port_3",
154
+ facing_direction: "right",
155
+ distance_from_component_edge: 0.4,
156
+ pin_number: 2,
157
+ display_pin_label: "right",
158
+ },
159
+ {
160
+ type: "schematic_trace",
161
+ schematic_trace_id: "schematic_trace_0",
162
+ source_trace_id: "source_trace_0",
163
+ edges: [
164
+ {
165
+ from: {
166
+ route_type: "wire",
167
+ x: 2.4662093,
168
+ y: 0.045805199999999324,
169
+ width: 0.1,
170
+ layer: "top",
171
+ },
172
+ to: {
173
+ route_type: "wire",
174
+ x: -2.0487906999999996,
175
+ y: 0.045805199999999324,
176
+ width: 0.1,
177
+ layer: "top",
178
+ },
179
+ },
180
+ {
181
+ from: {
182
+ route_type: "wire",
183
+ x: -2.0487906999999996,
184
+ y: 0.045805199999999324,
185
+ width: 0.1,
186
+ layer: "top",
187
+ },
188
+ to: {
189
+ route_type: "wire",
190
+ x: -2.0487906999999996,
191
+ y: 0.7174736499999994,
192
+ width: 0.1,
193
+ layer: "top",
194
+ },
195
+ },
196
+ {
197
+ from: {
198
+ route_type: "wire",
199
+ x: -2.0487906999999996,
200
+ y: 0.7174736499999994,
201
+ width: 0.1,
202
+ layer: "top",
203
+ },
204
+ to: {
205
+ route_type: "wire",
206
+ x: -3.5512093000000005,
207
+ y: 0.7174736499999994,
208
+ width: 0.1,
209
+ layer: "top",
210
+ },
211
+ },
212
+ {
213
+ from: {
214
+ route_type: "wire",
215
+ x: -3.5512093000000005,
216
+ y: 0.7174736499999994,
217
+ width: 0.1,
218
+ layer: "top",
219
+ },
220
+ to: {
221
+ route_type: "wire",
222
+ x: -3.5512093000000005,
223
+ y: 0.016380250000000984,
224
+ width: 0.1,
225
+ layer: "top",
226
+ },
227
+ },
228
+ ],
229
+ junctions: [],
230
+ },
231
+ {
232
+ type: "pcb_component",
233
+ pcb_component_id: "pcb_component_0",
234
+ center: {
235
+ x: 3,
236
+ y: 0,
237
+ },
238
+ width: 1.5999999999999996,
239
+ height: 0.6000000000000001,
240
+ layer: "top",
241
+ rotation: 0,
242
+ source_component_id: "source_component_0",
243
+ subcircuit_id: "subcircuit_source_group_0",
244
+ },
245
+ {
246
+ type: "pcb_component",
247
+ pcb_component_id: "pcb_component_1",
248
+ center: {
249
+ x: -3,
250
+ y: 0,
251
+ },
252
+ width: 1.5999999999999996,
253
+ height: 0.6000000000000001,
254
+ layer: "top",
255
+ rotation: 0,
256
+ source_component_id: "source_component_1",
257
+ subcircuit_id: "subcircuit_source_group_0",
258
+ },
259
+ {
260
+ type: "pcb_board",
261
+ pcb_board_id: "pcb_board_0",
262
+ center: {
263
+ x: 0,
264
+ y: 0,
265
+ },
266
+ thickness: 1.4,
267
+ num_layers: 4,
268
+ width: 10,
269
+ height: 10,
270
+ },
271
+ {
272
+ type: "pcb_smtpad",
273
+ pcb_smtpad_id: "pcb_smtpad_0",
274
+ pcb_component_id: "pcb_component_0",
275
+ pcb_port_id: "pcb_port_0",
276
+ layer: "top",
277
+ shape: "rect",
278
+ width: 0.6000000000000001,
279
+ height: 0.6000000000000001,
280
+ port_hints: ["1", "left"],
281
+ x: 2.5,
282
+ y: 0,
283
+ subcircuit_id: "subcircuit_source_group_0",
284
+ },
285
+ {
286
+ type: "pcb_solder_paste",
287
+ pcb_solder_paste_id: "pcb_solder_paste_0",
288
+ layer: "top",
289
+ shape: "rect",
290
+ width: 0.42000000000000004,
291
+ height: 0.42000000000000004,
292
+ x: 2.5,
293
+ y: 0,
294
+ pcb_component_id: "pcb_component_0",
295
+ pcb_smtpad_id: "pcb_smtpad_0",
296
+ subcircuit_id: "subcircuit_source_group_0",
297
+ },
298
+ {
299
+ type: "pcb_smtpad",
300
+ pcb_smtpad_id: "pcb_smtpad_1",
301
+ pcb_component_id: "pcb_component_0",
302
+ pcb_port_id: "pcb_port_1",
303
+ layer: "top",
304
+ shape: "rect",
305
+ width: 0.6000000000000001,
306
+ height: 0.6000000000000001,
307
+ port_hints: ["2", "right"],
308
+ x: 3.5,
309
+ y: 0,
310
+ subcircuit_id: "subcircuit_source_group_0",
311
+ },
312
+ {
313
+ type: "pcb_solder_paste",
314
+ pcb_solder_paste_id: "pcb_solder_paste_1",
315
+ layer: "top",
316
+ shape: "rect",
317
+ width: 0.42000000000000004,
318
+ height: 0.42000000000000004,
319
+ x: 3.5,
320
+ y: 0,
321
+ pcb_component_id: "pcb_component_0",
322
+ pcb_smtpad_id: "pcb_smtpad_1",
323
+ subcircuit_id: "subcircuit_source_group_0",
324
+ },
325
+ {
326
+ type: "pcb_smtpad",
327
+ pcb_smtpad_id: "pcb_smtpad_2",
328
+ pcb_component_id: "pcb_component_1",
329
+ pcb_port_id: "pcb_port_2",
330
+ layer: "top",
331
+ shape: "rect",
332
+ width: 0.6000000000000001,
333
+ height: 0.6000000000000001,
334
+ port_hints: ["1", "left"],
335
+ x: -3.5,
336
+ y: 0,
337
+ subcircuit_id: "subcircuit_source_group_0",
338
+ },
339
+ {
340
+ type: "pcb_solder_paste",
341
+ pcb_solder_paste_id: "pcb_solder_paste_2",
342
+ layer: "top",
343
+ shape: "rect",
344
+ width: 0.42000000000000004,
345
+ height: 0.42000000000000004,
346
+ x: -3.5,
347
+ y: 0,
348
+ pcb_component_id: "pcb_component_1",
349
+ pcb_smtpad_id: "pcb_smtpad_2",
350
+ subcircuit_id: "subcircuit_source_group_0",
351
+ },
352
+ {
353
+ type: "pcb_smtpad",
354
+ pcb_smtpad_id: "pcb_smtpad_3",
355
+ pcb_component_id: "pcb_component_1",
356
+ pcb_port_id: "pcb_port_3",
357
+ layer: "top",
358
+ shape: "rect",
359
+ width: 0.6000000000000001,
360
+ height: 0.6000000000000001,
361
+ port_hints: ["2", "right"],
362
+ x: -2.5,
363
+ y: 0,
364
+ subcircuit_id: "subcircuit_source_group_0",
365
+ },
366
+ {
367
+ type: "pcb_solder_paste",
368
+ pcb_solder_paste_id: "pcb_solder_paste_3",
369
+ layer: "top",
370
+ shape: "rect",
371
+ width: 0.42000000000000004,
372
+ height: 0.42000000000000004,
373
+ x: -2.5,
374
+ y: 0,
375
+ pcb_component_id: "pcb_component_1",
376
+ pcb_smtpad_id: "pcb_smtpad_3",
377
+ subcircuit_id: "subcircuit_source_group_0",
378
+ },
379
+ {
380
+ type: "pcb_port",
381
+ pcb_port_id: "pcb_port_0",
382
+ pcb_component_id: "pcb_component_0",
383
+ layers: ["top"],
384
+ subcircuit_id: "subcircuit_source_group_0",
385
+ x: 2.5,
386
+ y: 0,
387
+ source_port_id: "source_port_0",
388
+ },
389
+ {
390
+ type: "pcb_port",
391
+ pcb_port_id: "pcb_port_1",
392
+ pcb_component_id: "pcb_component_0",
393
+ layers: ["top"],
394
+ subcircuit_id: "subcircuit_source_group_0",
395
+ x: 3.5,
396
+ y: 0,
397
+ source_port_id: "source_port_1",
398
+ },
399
+ {
400
+ type: "pcb_port",
401
+ pcb_port_id: "pcb_port_2",
402
+ pcb_component_id: "pcb_component_1",
403
+ layers: ["top"],
404
+ subcircuit_id: "subcircuit_source_group_0",
405
+ x: -3.5,
406
+ y: 0,
407
+ source_port_id: "source_port_2",
408
+ },
409
+ {
410
+ type: "pcb_port",
411
+ pcb_port_id: "pcb_port_3",
412
+ pcb_component_id: "pcb_component_1",
413
+ layers: ["top"],
414
+ subcircuit_id: "subcircuit_source_group_0",
415
+ x: -2.5,
416
+ y: 0,
417
+ source_port_id: "source_port_3",
418
+ },
419
+ {
420
+ type: "pcb_trace",
421
+ pcb_trace_id: "pcb_trace_0",
422
+ route: [
423
+ {
424
+ route_type: "wire",
425
+ x: 2.5,
426
+ y: 0,
427
+ width: 0.16,
428
+ layer: "top",
429
+ start_pcb_port_id: "pcb_port_0",
430
+ },
431
+ {
432
+ route_type: "wire",
433
+ x: -1.2000000000000002,
434
+ y: 0,
435
+ width: 0.16,
436
+ layer: "top",
437
+ },
438
+ {
439
+ route_type: "wire",
440
+ x: -1.2000000000000002,
441
+ y: 1.3,
442
+ width: 0.16,
443
+ layer: "top",
444
+ },
445
+ {
446
+ route_type: "wire",
447
+ x: -3.5,
448
+ y: 1.3,
449
+ width: 0.16,
450
+ layer: "top",
451
+ },
452
+ {
453
+ route_type: "wire",
454
+ x: -3.5,
455
+ y: 0,
456
+ width: 0.16,
457
+ layer: "top",
458
+ end_pcb_port_id: "pcb_port_2",
459
+ },
460
+ ],
461
+ source_trace_id: "source_trace_0",
462
+ trace_length: 8.6,
463
+ },
464
+ {
465
+ type: "cad_component",
466
+ cad_component_id: "cad_component_0",
467
+ position: {
468
+ x: 3,
469
+ y: 0,
470
+ z: 0.7,
471
+ },
472
+ rotation: {
473
+ x: 0,
474
+ y: 0,
475
+ z: 0,
476
+ },
477
+ pcb_component_id: "pcb_component_0",
478
+ source_component_id: "source_component_0",
479
+ footprinter_string: "0402",
480
+ },
481
+ {
482
+ type: "cad_component",
483
+ cad_component_id: "cad_component_1",
484
+ position: {
485
+ x: -3,
486
+ y: 0,
487
+ z: 0.7,
488
+ },
489
+ rotation: {
490
+ x: 0,
491
+ y: 0,
492
+ z: 0,
493
+ },
494
+ pcb_component_id: "pcb_component_1",
495
+ source_component_id: "source_component_1",
496
+ footprinter_string: "0402",
497
+ },
498
+ ]
@@ -0,0 +1,186 @@
1
+ import React, { useState } from "react"
2
+ import {
3
+ Dialog,
4
+ DialogContent,
5
+ DialogHeader,
6
+ DialogTitle,
7
+ DialogFooter,
8
+ } from "@/components/ui/dialog"
9
+ import { Button } from "@/components/ui/button"
10
+ import { Textarea } from "@/components/ui/textarea"
11
+ import { useAxios } from "@/hooks/use-axios"
12
+ import { useToast } from "@/hooks/use-toast"
13
+ import { useLocation } from "wouter"
14
+ import { useGlobalStore } from "@/hooks/use-global-store"
15
+ import { convertCircuitJsonToTscircuit } from "circuit-json-to-tscircuit"
16
+
17
+ interface CircuitJsonImportDialogProps {
18
+ open: boolean
19
+ onOpenChange: (open: boolean) => void
20
+ }
21
+
22
+ const isValidJSON = (code: string) => {
23
+ try {
24
+ JSON.parse(code)
25
+ return true
26
+ } catch {
27
+ return false
28
+ }
29
+ }
30
+
31
+ export function CircuitJsonImportDialog({
32
+ open,
33
+ onOpenChange,
34
+ }: CircuitJsonImportDialogProps) {
35
+ const [circuitJson, setcircuitJson] = useState("")
36
+ const [file, setFile] = useState<File | null>(null)
37
+ const [isLoading, setIsLoading] = useState(false)
38
+ const [error, setError] = useState<string | null>(null)
39
+ const axios = useAxios()
40
+ const { toast } = useToast()
41
+ const [, navigate] = useLocation()
42
+ const isLoggedIn = useGlobalStore((s) => Boolean(s.session))
43
+ const session = useGlobalStore((s) => s.session)
44
+
45
+ const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
46
+ const selectedFile = e.target.files?.[0]
47
+ if (selectedFile && selectedFile.type === "application/json") {
48
+ setFile(selectedFile)
49
+ } else {
50
+ setError("Please select a valid JSON file.")
51
+ }
52
+ }
53
+
54
+ const handleImport = async () => {
55
+ let importedCircuitJson
56
+
57
+ if (file) {
58
+ try {
59
+ const fileText = await file.text()
60
+ importedCircuitJson = JSON.parse(fileText)
61
+ } catch (err) {
62
+ setError("Error reading JSON file. Please ensure it is valid.")
63
+ return
64
+ }
65
+ } else if (isValidJSON(circuitJson)) {
66
+ setIsLoading(true)
67
+ setError(null)
68
+ importedCircuitJson = JSON.parse(circuitJson)
69
+ } else {
70
+ toast({
71
+ title: "Invalid Input",
72
+ description: "Please provide a valid JSON content or file.",
73
+ variant: "destructive",
74
+ })
75
+ return
76
+ }
77
+ let tscircuit
78
+ try {
79
+ tscircuit = convertCircuitJsonToTscircuit(importedCircuitJson as any, {
80
+ componentName: "circuit",
81
+ })
82
+ console.info(tscircuit)
83
+ } catch {
84
+ toast({
85
+ title: "Import Failed",
86
+ description: "Invalid Circuit JSON was provided.",
87
+ variant: "destructive",
88
+ })
89
+ setIsLoading(false)
90
+ return
91
+ }
92
+
93
+ try {
94
+ const newSnippetData = {
95
+ snippet_type: importedCircuitJson.type ?? "board",
96
+ circuit_json: importedCircuitJson,
97
+ code: tscircuit,
98
+ }
99
+ const response = await axios
100
+ .post("/snippets/create", newSnippetData)
101
+ .catch((e) => e)
102
+ const { snippet, message } = response.data
103
+ if (message) {
104
+ setError(message)
105
+ setIsLoading(false)
106
+ return
107
+ }
108
+ toast({
109
+ title: "Import Successful",
110
+ description: "Circuit Json has been imported successfully.",
111
+ })
112
+ onOpenChange(false)
113
+ navigate(`/editor?snippet_id=${snippet.snippet_id}`)
114
+ } catch (error) {
115
+ console.error("Error importing Circuit Json:", error)
116
+ toast({
117
+ title: "Import Failed",
118
+ description: "Failed to import the Circuit Json. Please try again.",
119
+ variant: "destructive",
120
+ })
121
+ } finally {
122
+ setIsLoading(false)
123
+ }
124
+ }
125
+
126
+ return (
127
+ <Dialog open={open} onOpenChange={onOpenChange}>
128
+ <DialogContent>
129
+ <DialogHeader>
130
+ <DialogTitle>Import Circuit JSON</DialogTitle>
131
+ </DialogHeader>
132
+ <div className="pb-4">
133
+ <Textarea
134
+ className="mt-3"
135
+ placeholder="Paste the Circuit JSON."
136
+ value={circuitJson}
137
+ onChange={(e) => setcircuitJson(e.target.value)}
138
+ disabled={!!file}
139
+ />
140
+ <div className="mt-4 flex flex-col gap-2">
141
+ <label
142
+ htmlFor="file-input"
143
+ className="block text-sm font-medium text-gray-700"
144
+ >
145
+ Upload JSON File
146
+ </label>
147
+ <div className="flex items-center gap-4">
148
+ <input
149
+ id="file-input"
150
+ type="file"
151
+ accept="application/json"
152
+ onChange={handleFileChange}
153
+ className="hidden" // Hide the default file input
154
+ />
155
+ <label
156
+ htmlFor="file-input"
157
+ className="px-4 py-2 bg-slate-900 text-slate-50 rounded-lg shadow cursor-pointer hover:bg-slate-900/90 dark:bg-slate-50 dark:text-slate-900 dark:hover:bg-slate-50/90 transition-all duration-200"
158
+ >
159
+ Choose File
160
+ </label>
161
+ </div>
162
+ {file && (
163
+ <p className="text-sm text-gray-600">
164
+ <span className="font-medium text-gray-900">
165
+ Selected file:
166
+ </span>{" "}
167
+ {file.name}
168
+ </p>
169
+ )}
170
+ </div>
171
+
172
+ {error && <p className="bg-red-100 p-2 mt-2 pre-wrap">{error}</p>}
173
+ </div>
174
+ <DialogFooter>
175
+ <Button onClick={handleImport} disabled={isLoading || !isLoggedIn}>
176
+ {!isLoggedIn
177
+ ? "Must be logged in for JSON import"
178
+ : isLoading
179
+ ? "Importing..."
180
+ : "Import"}
181
+ </Button>
182
+ </DialogFooter>
183
+ </DialogContent>
184
+ </Dialog>
185
+ )
186
+ }