@@ -65,3 +65,191 @@ export type LibraryItem = z.infer<typeof LibraryItem>;
6565 */
6666export const Library = z . array ( LibraryItem ) ;
6767export type Library = z . infer < typeof Library > ;
68+
69+ /**
70+ * Component shape discriminator for default components
71+ */
72+ export type ComponentShape = 'rect' | 'circle' ;
73+
74+ /**
75+ * Default component specification for pre-defined library items
76+ *
77+ * This format is used to define common THT components with standardized dimensions.
78+ * The fields map to LibraryItem properties as follows:
79+ *
80+ * **For rectangles (shape = "rect"):**
81+ * - `width` → LibraryItem.width (X dimension in mm)
82+ * - `depth` → LibraryItem.height (Y dimension along board in mm)
83+ * - `height` → LibraryItem.depth (component height above PCB → hole depth in mm)
84+ *
85+ * **For circles (shape = "circle"):**
86+ * - `width` → LibraryItem.radius (diameter in mm, converted to radius by dividing by 2)
87+ * - `depth` → Not used (kept equal to width for consistency)
88+ * - `height` → LibraryItem.depth (component height above PCB → hole depth in mm)
89+ *
90+ * @see convertDefaultComponentToLibraryItem for conversion logic
91+ */
92+ export interface DefaultComponent {
93+ /** User-friendly component name */
94+ name : string ;
95+ /** Shape type: "rect" for rectangular, "circle" for round components */
96+ shape : ComponentShape ;
97+ /** For rect: X dimension (width). For circle: diameter */
98+ width : number ;
99+ /** For rect: Y dimension (along board). For circle: not used (set = width) */
100+ depth : number ;
101+ /** Component height above PCB (maps to hole depth in LibraryItem) */
102+ height : number ;
103+ }
104+
105+ /**
106+ * Pre-defined common THT components for quick library initialization
107+ *
108+ * Includes standard footprints with dimensions sourced from datasheets:
109+ * - DIP IC sockets (narrow and wide)
110+ * - Radial electrolytic capacitors (various sizes)
111+ * - PCB-mount buzzers (small and large)
112+ * - Screw terminal blocks (5.08mm pitch)
113+ * - Generic relays (small and large)
114+ *
115+ * Users can load these defaults into their library via the "Load defaults"
116+ * button in the Library modal. Duplicates (by name) are automatically skipped.
117+ */
118+ export const DEFAULT_COMPONENTS : DefaultComponent [ ] = [
119+ // DIP IC sockets
120+ {
121+ name : 'DIP-8 socket (narrow)' ,
122+ shape : 'rect' ,
123+ width : 7.6 , // body width ~7.6 mm
124+ depth : 10 , // body length ~10 mm
125+ height : 5 // profile height ~3.5–5 mm
126+ } ,
127+ {
128+ name : 'DIP-14/16 socket (narrow)' ,
129+ shape : 'rect' ,
130+ width : 7.6 ,
131+ depth : 20 , // ~19–20 mm body length
132+ height : 5
133+ } ,
134+ {
135+ name : 'DIP-28 socket (wide)' ,
136+ shape : 'rect' ,
137+ width : 15.2 , // wide row spacing ~15.24 mm
138+ depth : 37 , // ~37 mm body length
139+ height : 5
140+ } ,
141+ {
142+ name : 'DIP-40 socket (wide)' ,
143+ shape : 'rect' ,
144+ width : 15.2 ,
145+ depth : 52 , // ~52 mm body length
146+ height : 5
147+ } ,
148+
149+ // Radial electrolytic capacitors (DxL families)
150+ {
151+ name : 'Electrolytic Ø5×11' ,
152+ shape : 'circle' ,
153+ width : 5 , // diameter 5 mm
154+ depth : 5 , // not used for circle, keep = diameter
155+ height : 11 // can-height ~11 mm
156+ } ,
157+ {
158+ name : 'Electrolytic Ø8×12' ,
159+ shape : 'circle' ,
160+ width : 8 , // diameter 8 mm
161+ depth : 8 ,
162+ height : 12 // height 12 mm
163+ } ,
164+ {
165+ name : 'Electrolytic Ø10×16' ,
166+ shape : 'circle' ,
167+ width : 10 , // diameter 10 mm
168+ depth : 10 ,
169+ height : 16 // height 16 mm
170+ } ,
171+
172+ // Buzzers
173+ {
174+ name : 'Buzzer small Ø14×8' ,
175+ shape : 'circle' ,
176+ width : 14 , // small PCB buzzer ~13–14 mm Ø
177+ depth : 14 ,
178+ height : 8 // ~7–8 mm height above PCB
179+ } ,
180+ {
181+ name : 'Buzzer large Ø31×14' ,
182+ shape : 'circle' ,
183+ width : 31 , // typical large buzzer ~30–32 mm Ø
184+ depth : 31 ,
185+ height : 14 // ~14–15 mm height
186+ } ,
187+
188+ // Terminal blocks (5.08 mm pitch family)
189+ {
190+ name : 'Terminal block 2×5.08' ,
191+ shape : 'rect' ,
192+ width : 10.5 , // ≈2×5.08 + housing margins
193+ depth : 8 , // body depth ~7–9 mm
194+ height : 11 // ~10–12 mm above PCB
195+ } ,
196+ {
197+ name : 'Terminal block 3×5.08' ,
198+ shape : 'rect' ,
199+ width : 15.5 , // ≈3×5.08 + housing margins
200+ depth : 8 ,
201+ height : 11
202+ } ,
203+
204+ // Generic board parts
205+ {
206+ name : 'Small relay' ,
207+ shape : 'rect' ,
208+ width : 10 ,
209+ depth : 19 ,
210+ height : 15
211+ } ,
212+ {
213+ name : 'Large relay' ,
214+ shape : 'rect' ,
215+ width : 15 ,
216+ depth : 28 ,
217+ height : 20
218+ }
219+ ] ;
220+
221+ /**
222+ * Converts a DefaultComponent to a LibraryItem for storage
223+ *
224+ * Applies dimension mappings according to shape type:
225+ *
226+ * **Rectangle conversion:**
227+ * - width → width (X dimension preserved)
228+ * - depth → height (Y dimension - confusingly named in LibraryItem)
229+ * - height → depth (component height above PCB becomes hole depth)
230+ * - rotation defaults to 0
231+ *
232+ * **Circle conversion:**
233+ * - width (diameter) → radius (divided by 2)
234+ * - height → depth (component height above PCB becomes hole depth)
235+ * - depth field in DefaultComponent is unused for circles
236+ *
237+ * @param component - Default component specification
238+ * @returns LibraryItem ready for storage in library
239+ */
240+ export const convertDefaultComponentToLibraryItem = ( component : DefaultComponent ) : LibraryItem =>
241+ component . shape === 'circle'
242+ ? {
243+ type : 'circle' ,
244+ name : component . name ,
245+ radius : component . width / 2 , // Convert diameter to radius
246+ depth : component . height // Component height → hole depth
247+ }
248+ : {
249+ type : 'rectangle' ,
250+ name : component . name ,
251+ width : component . width , // X dimension
252+ height : component . depth , // Y dimension (confusingly named in LibraryItem)
253+ depth : component . height , // Component height → hole depth
254+ rotation : 0 // Default rotation
255+ } ;
0 commit comments