feat: add local custom elements for capacitor and inductor, enhancing SPICE simulation support
This commit is contained in:
parent
a1d3179e1c
commit
7bdbac9f83
|
|
@ -17,9 +17,12 @@ import { useSimulatorStore } from '../store/useSimulatorStore';
|
|||
import { PartSimulationRegistry } from '../simulation/parts';
|
||||
import { isBoardComponent, boardPinToNumber } from '../utils/boardPinMapping';
|
||||
|
||||
// Side-effect import: registers ALL wokwi custom elements (including new ones
|
||||
// like wokwi-capacitor, wokwi-inductor) so document.createElement() works.
|
||||
// Side-effect imports: register every web component we'll create at runtime.
|
||||
// `@wokwi/elements` covers the upstream catalog; `../wokwi-custom` adds the
|
||||
// velxio-local elements (e.g. <wokwi-capacitor>, <wokwi-inductor>) that we
|
||||
// can't push back to the upstream wokwi-elements repo.
|
||||
import '@wokwi/elements';
|
||||
import '../wokwi-custom';
|
||||
|
||||
interface DynamicComponentProps {
|
||||
id: string;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* <wokwi-capacitor> — local replacement for the upstream wokwi-elements
|
||||
* version. Kept inside velxio because we cannot push the original Lit
|
||||
* sources to wokwi/wokwi-elements.
|
||||
*
|
||||
* Plain HTMLElement (no Lit) — the SVG is static and `value` is read by
|
||||
* the SPICE layer from the simulator store, not from this DOM node, so
|
||||
* we don't need reactive rendering.
|
||||
*/
|
||||
|
||||
interface ElementPin {
|
||||
name: string;
|
||||
x: number;
|
||||
y: number;
|
||||
signals: unknown[];
|
||||
}
|
||||
|
||||
const SVG = `
|
||||
<svg width="15.645mm" height="3mm" version="1.1"
|
||||
viewBox="0 0 15.645 3" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="1.175" width="15.558" height="0.638" fill="#aaa" />
|
||||
<ellipse cx="7.82" cy="1.5" rx="3.2" ry="1.5" fill="#165696" />
|
||||
<ellipse cx="6.8" cy="0.9" rx="1.0" ry="0.55" fill="#3a7cc8" opacity="0.5" />
|
||||
</svg>`;
|
||||
|
||||
export class CapacitorElement extends HTMLElement {
|
||||
static observedAttributes = ['value'];
|
||||
|
||||
readonly pinInfo: ElementPin[] = [
|
||||
{ name: '1', x: 0, y: 5.65, signals: [] },
|
||||
{ name: '2', x: 58.8, y: 5.65, signals: [] },
|
||||
];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const root = this.attachShadow({ mode: 'open' });
|
||||
root.innerHTML = `<style>:host{display:flex}</style>${SVG}`;
|
||||
}
|
||||
|
||||
get value(): string {
|
||||
return this.getAttribute('value') ?? '1u';
|
||||
}
|
||||
set value(v: string) {
|
||||
this.setAttribute('value', String(v));
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('wokwi-capacitor')) {
|
||||
customElements.define('wokwi-capacitor', CapacitorElement);
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Velxio-local custom elements.
|
||||
*
|
||||
* These are wokwi-style web components that live IN this project rather
|
||||
* than in the upstream `@wokwi/elements` package — useful when we don't
|
||||
* have push access to wokwi/wokwi-elements but still need to ship new
|
||||
* parts (e.g. `<wokwi-capacitor>`, `<wokwi-inductor>` for SPICE).
|
||||
*
|
||||
* Side-effect import: each module calls `customElements.define(...)` at
|
||||
* load time (guarded against double-registration), so a single
|
||||
* `import './wokwi-custom';` is enough to make the tags resolvable.
|
||||
*/
|
||||
|
||||
import './capacitor-element';
|
||||
import './inductor-element';
|
||||
|
||||
export { CapacitorElement } from './capacitor-element';
|
||||
export { InductorElement } from './inductor-element';
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* <wokwi-inductor> — local replacement for the upstream wokwi-elements
|
||||
* version. Kept inside velxio because we cannot push the original Lit
|
||||
* sources to wokwi/wokwi-elements.
|
||||
*
|
||||
* Plain HTMLElement (no Lit) — the SVG is static and `value` is read by
|
||||
* the SPICE layer from the simulator store, not from this DOM node.
|
||||
*/
|
||||
|
||||
interface ElementPin {
|
||||
name: string;
|
||||
x: number;
|
||||
y: number;
|
||||
signals: unknown[];
|
||||
}
|
||||
|
||||
const SVG = `
|
||||
<svg width="15.645mm" height="3mm" version="1.1"
|
||||
viewBox="0 0 15.645 3" xmlns="http://www.w3.org/2000/svg">
|
||||
<rect y="1.175" width="15.558" height="0.638" fill="#aaa" />
|
||||
<path d="M4.7,1.5 C5.2,0 6.0,0 6.5,1.5 C7.0,3 7.8,3 8.3,1.5 C8.8,0 9.6,0 10.1,1.5 C10.6,3 11.4,3 11.0,1.5"
|
||||
fill="none" stroke="#B23820" stroke-width="0.5" stroke-linecap="round" />
|
||||
<rect x="4.5" y="0.15" width="6.7" height="2.7" rx="0.6" fill="#752119" opacity="0.7" />
|
||||
<path d="M4.7,1.5 C5.2,-0.2 6.0,-0.2 6.5,1.5 C7.0,3.2 7.8,3.2 8.3,1.5 C8.8,-0.2 9.6,-0.2 10.1,1.5 C10.6,3.2 11.4,3.2 11.0,1.5"
|
||||
fill="none" stroke="#B23820" stroke-width="0.45" stroke-linecap="round" />
|
||||
</svg>`;
|
||||
|
||||
export class InductorElement extends HTMLElement {
|
||||
static observedAttributes = ['value'];
|
||||
|
||||
readonly pinInfo: ElementPin[] = [
|
||||
{ name: '1', x: 0, y: 5.65, signals: [] },
|
||||
{ name: '2', x: 58.8, y: 5.65, signals: [] },
|
||||
];
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
const root = this.attachShadow({ mode: 'open' });
|
||||
root.innerHTML = `<style>:host{display:flex}</style>${SVG}`;
|
||||
}
|
||||
|
||||
get value(): string {
|
||||
return this.getAttribute('value') ?? '1m';
|
||||
}
|
||||
set value(v: string) {
|
||||
this.setAttribute('value', String(v));
|
||||
}
|
||||
}
|
||||
|
||||
if (!customElements.get('wokwi-inductor')) {
|
||||
customElements.define('wokwi-inductor', InductorElement);
|
||||
}
|
||||
Loading…
Reference in New Issue