hrithik18k/smartknob-screen
A mixed SMT component library containing 3.3V regulators, resistors/capacitors, MOSFETs/transistors, USB-UART and sensor ICs, LEDs, connectors, an inductor, and related PCB footprints/CAD models.
- Version
- 1.0.3
- License
- Apache-2.0
- Stars
- 0
smartknob-board.tsx
import { importedParts } from './imported-parts'
/** Preserve the released KiCad land patterns. Supplier models supply MPN/BOM/3D data;
* geometry and physical-pad aliases are deliberately overridden for exact placement.
*/
function ReferenceFootprint({ component: c }: { component: any }) {
return <footprint insertionDirection={c.value.includes("USB") ? "from_y_neg" : "from_above"}>{c.pads.flatMap((p: any, i: number) => {
const common = { pcbX: p.x, pcbY: p.y, portHints: [p.pin] }
if (p.type === 'thru_hole') {
if (p.drill[0] === 'oval') return <platedhole {...common} shape="pill" outerWidth={p.width} outerHeight={p.height} holeWidth={Number(p.drill[1])} holeHeight={Number(p.drill[2])} pcbRotation={p.rotation} />
return <platedhole {...common} shape="circle" outerDiameter={p.width} holeDiameter={Number(p.drill[0])} />
}
if (p.shape === 'circle') return <smtpad {...common} layer={p.layer} shape="circle" radius={p.width / 2} coveredWithSolderMask={p.mask} />
if (p.shape === 'oval') {
return <smtpad {...common} layer={p.layer} shape="rotated_pill" width={p.width} height={p.height} radius={Math.min(p.width,p.height)/2} ccwRotation={p.rotation} coveredWithSolderMask={p.mask} />
}
if (p.shape === 'custom') return <smtpad {...common} layer={p.layer} shape="polygon" points={p.polygon} coveredWithSolderMask={p.mask} />
return <smtpad {...common} layer={p.layer} shape="rotated_rect" width={p.width} height={p.height} ccwRotation={p.rotation} cornerRadius={p.radius ?? 0} coveredWithSolderMask={p.mask} />
})}</footprint>
}
function Part({ component: c }: { component: any }) {
const Component = c.importKey ? importedParts[c.importKey] : c.name === 'J2' && c.value.includes('USB') ? 'connector' : 'chip'
const props: any = {
name: c.name, ...(!c.importKey ? {manufacturerPartNumber: c.value} : {}),
pcbX: c.x, pcbY: c.y, ...(c.layer === 'bottom' ? {layer: 'bottom'} : {}),
schX: c.schX, schY: c.schY, schSectionName: c.section,
schPinArrangement: {leftSide: {pins: Object.keys(c.pinLabels), direction: "top-to-bottom"}},
pinLabels: c.pinLabels, pinAttributes: c.pinAttributes,
shouldBeOnEdgeOfBoard: c.value.includes("USB"),
allowOffBoard: c.value.includes("USB"),
noConnect: c.noConnect, doNotPlace: c.doNotPlace,
symbol: undefined, symbolName: undefined,
footprint: <ReferenceFootprint component={c} />,
pcbStyle: { silkscreenTextVisibility: 'hidden' },
...(c.lcsc ? {supplierPartNumbers: {jlcpcb: [c.lcsc]}} : {}),
...(c.name === 'NT1' ? {internallyConnectedPins: [['pin1', 'pin2']]} : {}),
}
return <Component {...props} />
}
/** Both boards have independent net scopes and should be built as separate entrypoints. */
export function SmartKnobBoard({ data }: { data: any }) {
return <board width={Math.max(...data.outline.map((p: any) => p.x))-Math.min(...data.outline.map((p: any) => p.x))} height={Math.max(...data.outline.map((p: any) => p.y))-Math.min(...data.outline.map((p: any) => p.y))} title={data.title} outline={data.outline} thickness={data.thickness} layers={2} isViaInPadAllowed
solderMaskColor="white" silkscreenColor="black" routingDisabled routeRemaining={false}
// The checker boxes angled LED footprints axis-aligned and flags clear
// flexure slots. Exact pad/body-to-cutout geometry is audited separately.
placementDrcChecksDisabled={data.title.includes('Base')}
pcbStyle={{silkscreenTextVisibility:'hidden'}}>
{data.sections.map((name: string) => <schematicsection name={name} />)}
{data.cutouts.map((points: any, i: number) => <cutout shape="polygon" points={points} />)}
{data.holes.map((h: any, i: number) => <hole pcbX={h.x} pcbY={h.y} diameter={h.diameter} />)}
{data.components.map((c: any) => <Part component={c} />)}
{/* One source trace per net, in stable data.nets order. validate.py asserts
that each explicit copper segment resolves to the expected source net. */}
{data.nets.map((n: any) => <trace path={[...n.pins, `net.${n.name}`]} />)}
{/* Core accepts the circuit-json source link; current JSX declarations omit it. */}
{data.traces.map((t: any) => <pcbtrace {...({source_trace_id: `source_trace_${t.sourceIndex}`, route: t.route} as any)} />)}
{data.vias.map((v: any, i: number) => <via pcbX={v.x} pcbY={v.y} holeDiameter={v.drill} outerDiameter={v.diameter} fromLayer="top" toLayer="bottom" connectsTo={`net.${v.net}`} />)}
{data.pours.map((p: any, i: number) => <copperpour name={`POUR_${i}`} layer={p.layer} connectsTo={`net.${p.net}`} outline={p.outline} clearance={0} padMargin={0} traceMargin={0} boardEdgeMargin={0.22} cutoutMargin={0} />)}
</board>
}