diff --git a/.storybook/preview.js b/.storybook/preview.js index 024d3cc..6a9360b 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -5,7 +5,5 @@ export const parameters = { import { setCustomElements } from '@storybook/web-components'; import customElements from '../custom-elements.json'; -import '../src/utils/show-pins-element'; - // Configure Storybook Docs Addon for Web Components setCustomElements(customElements); diff --git a/package.json b/package.json index 57d1578..811014b 100644 --- a/package.json +++ b/package.json @@ -1,11 +1,11 @@ { - "name": "@wokwi/elements", - "version": "1.4.10", + "name": "@b.borisov/cu-elements", + "version": "1.4.22", "main": "dist/cjs/index.js", "module": "./dist/esm/index.js", "types": "./dist/esm/index.d.ts", - "repository": "https://github.com/wokwi/wokwi-elements", - "author": "Uri Shaked ", + "repository": "https://github.com/Pupe6/wokwi-elements", + "author": "Borislav Borisov ", "license": "MIT", "files": [ "dist" diff --git a/src/arduino-mega-element.stories.ts b/src/arduino-mega-element.stories.ts index 4a24ecf..a581b85 100644 --- a/src/arduino-mega-element.stories.ts +++ b/src/arduino-mega-element.stories.ts @@ -5,7 +5,7 @@ import './arduino-mega-element'; import { action } from '@storybook/addon-actions'; storiesOf('Arduino Mega', module) - .addParameters({ component: 'wokwi-arduino-mega' }) + .addParameters({ component: 'ArduinoMegaElement' }) .addDecorator(withKnobs) .add( 'Mega', diff --git a/src/arduino-mega-element.ts b/src/arduino-mega-element.ts index 9a8d2af..7fdc86a 100644 --- a/src/arduino-mega-element.ts +++ b/src/arduino-mega-element.ts @@ -11,9 +11,10 @@ export class ArduinoMegaElement extends LitElement { @property() ledTX = false; @property() ledPower = false; @property() resetPressed = false; + // i need to watch for element pin changes @query('#reset-button') resetButton!: SVGCircleElement; - readonly pinInfo: ElementPin[] = [ + pinInfo: ElementPin[] = [ { name: 'SCL', x: 90, y: 9, signals: [i2c('SCL')] }, { name: 'SDA', x: 100, y: 9, signals: [i2c('SDA')] }, { name: 'AREF', x: 109, y: 9, signals: [] }, @@ -120,268 +121,274 @@ export class ArduinoMegaElement extends LitElement { render() { const { ledPower, led13, ledRX, ledTX } = this; return html` - - - - - - - - - - - - - ${pinsFemalePattern} - - - - - - + + + + + + + + - - + + + - - - - - - - - - - this.down()} - @touchstart=${() => this.down()} - @mouseup=${() => this.up()} - @mouseleave=${() => this.leave()} - @touchend=${() => this.leave()} - @keydown=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.down()} - @keyup=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.up()} - /> + ${pinsFemalePattern} - - - - - - - - - - - + + + + + - - - - + - - - - + - - + + + + + + + this.down()} + @touchstart=${() => this.down()} + @mouseup=${() => this.up()} + @mouseleave=${() => this.leave()} + @touchend=${() => this.leave()} + @keydown=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.down()} + @keyup=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.up()} /> - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + - - - - + + + + - - - - ${ledPower && - svg``} - + + + + ${ledPower && + svg``} + - - PWR - + + PWR + - - - ${led13 && - svg``} - + + + ${led13 && + svg``} + - - - ${ledTX && - svg``} - + + + ${ledTX && + svg``} + - - - ${ledRX && - svg``} - + + + ${ledRX && + svg``} + - - L - TX - RX -   - + + L + TX + RX +   + - - - - PWM - + + + + PWM + - - - COMMUNICATION - + + + COMMUNICATION + - - AREF - GND - 13 - 12 - 11 - 10 - 9 - 8 - 7 - 6 - 5 - 4 - 3 - 2 - TX→ 1 - RX← 0 - TX3 14 - RX3 15 - TX2 16 - RX2 17 - TX1 18 - RX1 19 - SDA 20 - SCL 21 -   - + + AREF + GND + 13 + 12 + 11 + 10 + 9 + 8 + 7 + 6 + 5 + 4 + 3 + 2 + TX→ 1 + RX← 0 + TX3 14 + RX3 15 + TX2 16 + RX2 17 + TX1 18 + RX1 19 + SDA 20 + SCL 21 +   + - - - - POWER - ANALOG IN - - - IOREF - RESET - 3.3V - 5V - GND - GND - Vin - A0 - A1 - A2 - A3 - A4 - A5 - A6 - A7 - A8 - A9 - A10 - A11 - A12 - A13 - A14 - A15 -   - + + + + POWER + ANALOG IN + + + IOREF + RESET + 3.3V + 5V + GND + GND + Vin + A0 + A1 + A2 + A3 + A4 + A5 + A6 + A7 + A8 + A9 + A10 + A11 + A12 + A13 + A14 + A15 +   + - - - Arduino MEGA - - + + + Arduino MEGA + + + `; } private down() { diff --git a/src/arduino-nano-element.stories.ts b/src/arduino-nano-element.stories.ts index cc4595a..6bac051 100644 --- a/src/arduino-nano-element.stories.ts +++ b/src/arduino-nano-element.stories.ts @@ -5,7 +5,7 @@ import { action } from '@storybook/addon-actions'; import './arduino-nano-element'; storiesOf('Arduino Nano', module) - .addParameters({ component: 'wokwi-arduino-nano' }) + .addParameters({ component: 'ArduinoNanoElement' }) .addDecorator(withKnobs) .add( 'Nano', diff --git a/src/arduino-uno-element.stories.ts b/src/arduino-uno-element.stories.ts index 675a2ae..70145c9 100644 --- a/src/arduino-uno-element.stories.ts +++ b/src/arduino-uno-element.stories.ts @@ -5,7 +5,7 @@ import { html } from 'lit'; import './arduino-uno-element'; storiesOf('Arduino Uno', module) - .addParameters({ component: 'wokwi-arduino-uno' }) + .addParameters({ component: 'ArduinoUnoElement' }) .addDecorator(withKnobs) .add( 'Uno R3', diff --git a/src/assets/SmallBreadboard.svg b/src/assets/SmallBreadboard.svg new file mode 100644 index 0000000..ac5af8d --- /dev/null +++ b/src/assets/SmallBreadboard.svg @@ -0,0 +1 @@ +
a
a
b
b
c
c
d
d
e
e
f
f
h
h
g
g
0
0
1
1
2
2
3
3
Text is not SVG - cannot display
\ No newline at end of file diff --git a/src/attiny85-element.stories.ts b/src/attiny85-element.stories.ts new file mode 100644 index 0000000..9dd2a6a --- /dev/null +++ b/src/attiny85-element.stories.ts @@ -0,0 +1,21 @@ +import { html } from 'lit'; +import './attiny85-element'; + +export default { + title: 'Attiny85', + component: 'wokwi-attiny85', + argTypes: { + value: { control: { type: 'number', min: 1, max: 10, step: 1 } }, + }, + args: { + value: 5, + }, +}; + +const Template = ({ value }) => html``; + +export const Default = Template.bind({}); +Default.args = { value: 5 }; + +export const Large = Template.bind({}); +Large.args = { value: 10 }; diff --git a/src/attiny85-element.ts b/src/attiny85-element.ts new file mode 100644 index 0000000..c73f81a --- /dev/null +++ b/src/attiny85-element.ts @@ -0,0 +1,4070 @@ +import { html, LitElement, svg } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { ElementPin } from './pin'; + +@customElement('wokwi-attiny85') +export class Attiny85Element extends LitElement { + pinInfo: ElementPin[] = []; + + constructPins() { + for (let i = 1; i < 4; i++) { + this.pinInfo.push({ + name: `PB${i}`, + x: 20 + i * 19.4, + y: 10, + } as ElementPin); + } + + for (let i = 0; i < 4; i++) { + this.pinInfo.push({ + name: `PB${i}`, + x: 10 + i * 10, + y: 200, + } as ElementPin); + } + } + + firstUpdated() { + this.constructPins(); + } + + render() { + return html` + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + `; + } +} diff --git a/src/breadboard-element.stories.ts b/src/breadboard-element.stories.ts new file mode 100644 index 0000000..caca0ad --- /dev/null +++ b/src/breadboard-element.stories.ts @@ -0,0 +1,30 @@ +import { html } from 'lit'; +import './breadboard-element'; + +export default { + title: 'Breadboard', + component: 'BreaboardElement', + argTypes: { + type: { + control: { + type: 'select', + options: ['small', 'normal'], + }, + }, + }, + args: { + type: 'normal', + }, +}; + +const Template = ({ type }) => html` + + + +`; + +export const Small = Template.bind({}); +Small.args = { type: 'small' }; + +export const Normal = Template.bind({}); +Normal.args = { type: 'normal' }; diff --git a/src/breadboard-element.ts b/src/breadboard-element.ts new file mode 100644 index 0000000..9e4e162 --- /dev/null +++ b/src/breadboard-element.ts @@ -0,0 +1,1681 @@ +import { html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { ElementPin } from './pin'; + +@customElement('wokwi-breadboard') +export class BreadboardElement extends LitElement { + @property() type: 'small' | 'normal' = 'small'; + + // colums A-I and rows 0-19 + pinInfo: ElementPin[] = []; + + constructSmallPins() { + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 4; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(65 + col)}${row}`, + x: 10.3 + col * 17, + y: 26 + row * 17, + } as ElementPin); + } + } + + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 4; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(69 + col)}${row}`, + x: 112.7 + col * 17, + y: 26 + row * 17, + } as ElementPin); + } + } + } + + constructNormalPins() { + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 12; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(65 + col)}${row}`, + x: 10.3 + col * 17.15, + y: 26 + row * 17.15, + } as ElementPin); + } + } + + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 12; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(69 + col)}${row}`, + x: 113 + col * 17.15, + y: 26 + row * 17.15, + } as ElementPin); + } + } + } + + firstUpdated() { + const { type } = this; + + if (type === 'small') { + this.constructSmallPins(); + } else { + this.constructNormalPins(); + } + } + + render() { + const { type } = this; + + // svg is coming from assets folder + return type === 'normal' + ? html` + + + + + + + + + + + + + + +
+
+
+ a +
+
+
+ + a + +
+
+ + + +
+
+
+ b +
+
+
+ + b + +
+
+ + + +
+
+
+ c +
+
+
+ + c + +
+
+ + + +
+
+
+ d +
+
+
+ + d + +
+
+ + + +
+
+
+ e +
+
+
+ + e + +
+
+ + + +
+
+
+ f +
+
+
+ + f + +
+
+ + + +
+
+
+ h +
+
+
+ + h + +
+
+ + + +
+
+
+ g +
+
+
+ + g + +
+
+ + + +
+
+
+ 0 +
+
+
+ + 0 + +
+
+ + + +
+
+
+ 1 +
+
+
+ + 1 + +
+
+ + + +
+
+
+ 2 +
+
+
+ + 2 + +
+
+ + + +
+
+
+ 3 +
+
+
+ + 3 + +
+
+ + + + +
+
+
+ 4 +
+
+
+ + 4 + +
+
+ + + +
+
+
+ 5 +
+
+
+ + 5 + +
+
+ + + +
+
+
+ 6 +
+
+
+ + 6 + +
+
+ + + +
+
+
+ 7 +
+
+
+ + 7 + +
+
+ + + +
+
+
+ 8 +
+
+
+ + 8 + +
+
+ + + +
+
+
+ 9 +
+
+
+ + 9 + +
+
+ + + +
+
+
+ 10 +
+
+
+ + 10 + +
+
+ + + +
+
+
+ 11 +
+
+
+ + 11 + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
+ ` + : html` + + + + + + + + + + + + + + +
+
+
+ a +
+
+
+ + a + +
+
+ + + +
+
+
+ b +
+
+
+ + b + +
+
+ + + +
+
+
+ c +
+
+
+ + c + +
+
+ + + +
+
+
+ d +
+
+
+ + d + +
+
+ + + +
+
+
+ e +
+
+
+ + e + +
+
+ + + +
+
+
+ f +
+
+
+ + f + +
+
+ + + +
+
+
+ h +
+
+
+ + h + +
+
+ + + +
+
+
+ g +
+
+
+ + g + +
+
+ + + +
+
+
+ 0 +
+
+
+ + 0 + +
+
+ + + +
+
+
+ 1 +
+
+
+ + 1 + +
+
+ + + +
+
+
+ 2 +
+
+
+ + 2 + +
+
+ + + +
+
+
+ 3 +
+
+
+ + 3 + +
+
+ +
+ + + + + Text is not SVG - cannot display + + + +
+ + `; + } +} diff --git a/src/index.ts b/src/index.ts index 386fcbe..347f97b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -51,3 +51,8 @@ export { StepperMotorElement } from './stepper-motor-element'; export { HX711Element } from './hx711-element'; export { KS2EMDC5Element } from './ks2e-m-dc5-element'; export { BiaxialStepperElement } from './biaxial-stepper-element'; +export { BreadboardElement } from './breadboard-element'; +export { ShowPinsElement } from './show-pins-element'; +export { MainBreadboardElement } from './main-breadboard-element'; +export { McuBreadboardElement } from './mcu-breadboard-element'; +export { Attiny85Element } from './attiny85-element'; diff --git a/src/main-breadboard-element.stories.ts b/src/main-breadboard-element.stories.ts new file mode 100644 index 0000000..1a78362 --- /dev/null +++ b/src/main-breadboard-element.stories.ts @@ -0,0 +1,13 @@ +import { html } from 'lit'; +import './main-breadboard-element'; + +export default { + title: 'Main Breadboard', + component: 'wokwi-main-breadboard', + argTypes: {}, + args: {}, +}; + +const Template = () => html``; + +export const Default = Template.bind({}); diff --git a/src/main-breadboard-element.ts b/src/main-breadboard-element.ts new file mode 100644 index 0000000..704d581 --- /dev/null +++ b/src/main-breadboard-element.ts @@ -0,0 +1,1013 @@ +import { html, LitElement, svg } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { ElementPin } from './pin'; + +@customElement('wokwi-main-breadboard') +export class MainBreadboardElement extends LitElement { + pinInfo: ElementPin[] = []; + + constructNormalPins() { + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 12; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(65 + col)}${row}`, + x: 10.3 + col * 17.15, + y: 26 + row * 17.15, + } as ElementPin); + } + } + + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 12; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(69 + col)}${row}`, + x: 113 + col * 17.15, + y: 26 + row * 17.15, + } as ElementPin); + } + } + } + + firstUpdated() { + this.constructNormalPins(); + } + + render() { + return html` + + + + + + + + + + + + + + +
+
+
+ a +
+
+
+ + a + +
+
+ + + +
+
+
+ b +
+
+
+ + b + +
+
+ + + +
+
+
+ c +
+
+
+ + c + +
+
+ + + +
+
+
+ d +
+
+
+ + d + +
+
+ + + +
+
+
+ e +
+
+
+ + e + +
+
+ + + +
+
+
+ f +
+
+
+ + f + +
+
+ + + +
+
+
+ h +
+
+
+ + h + +
+
+ + + +
+
+
+ g +
+
+
+ + g + +
+
+ + + +
+
+
+ 0 +
+
+
+ + 0 + +
+
+ + + +
+
+
+ 1 +
+
+
+ + 1 + +
+
+ + + +
+
+
+ 2 +
+
+
+ + 2 + +
+
+ + + +
+
+
+ 3 +
+
+
+ + 3 + +
+
+ + + + +
+
+
+ 4 +
+
+
+ + 4 + +
+
+ + + +
+
+
+ 5 +
+
+
+ + 5 + +
+
+ + + +
+
+
+ 6 +
+
+
+ + 6 + +
+
+ + + +
+
+
+ 7 +
+
+
+ + 7 + +
+
+ + + +
+
+
+ 8 +
+
+
+ + 8 + +
+
+ + + +
+
+
+ 9 +
+
+
+ + 9 + +
+
+ + + +
+
+
+ 10 +
+
+
+ + 10 + +
+
+ + + +
+
+
+ 11 +
+
+
+ + 11 + +
+
+
+ + + + + Text is not SVG - cannot display + + + +
+ `; + } +} diff --git a/src/mcu-breadboard-element.stories.ts b/src/mcu-breadboard-element.stories.ts new file mode 100644 index 0000000..3543664 --- /dev/null +++ b/src/mcu-breadboard-element.stories.ts @@ -0,0 +1,13 @@ +import { html } from 'lit'; +import './mcu-breadboard-element'; + +export default { + title: 'Mcu Breadboard', + component: 'wokwi-mcu-breadboard', + argTypes: {}, + args: {}, +}; + +const Template = () => html``; + +export const Default = Template.bind({}); diff --git a/src/mcu-breadboard-element.ts b/src/mcu-breadboard-element.ts new file mode 100644 index 0000000..5d6ab88 --- /dev/null +++ b/src/mcu-breadboard-element.ts @@ -0,0 +1,650 @@ +import { html, LitElement, svg } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { ElementPin } from './pin'; + +@customElement('wokwi-mcu-breadboard') +export class McuBreadboardElement extends LitElement { + pinInfo: ElementPin[] = []; + + constructSmallPins() { + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 4; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(65 + col)}${row}`, + x: 10.3 + col * 17, + y: 26 + row * 17, + } as ElementPin); + } + } + + for (let col = 0; col < 4; col++) { + for (let row = 0; row < 4; row++) { + this.pinInfo.push({ + name: `${String.fromCharCode(69 + col)}${row}`, + x: 112.7 + col * 17, + y: 26 + row * 17, + } as ElementPin); + } + } + } + + firstUpdated() { + this.constructSmallPins(); + } + + render() { + return html` + + + + + + + + + + + + + + +
+
+
+ a +
+
+
+ + a + +
+
+ + + +
+
+
+ b +
+
+
+ + b + +
+
+ + + +
+
+
+ c +
+
+
+ + c + +
+
+ + + +
+
+
+ d +
+
+
+ + d + +
+
+ + + +
+
+
+ e +
+
+
+ + e + +
+
+ + + +
+
+
+ f +
+
+
+ + f + +
+
+ + + +
+
+
+ h +
+
+
+ + h + +
+
+ + + +
+
+
+ g +
+
+
+ + g + +
+
+ + + +
+
+
+ 0 +
+
+
+ + 0 + +
+
+ + + +
+
+
+ 1 +
+
+
+ + 1 + +
+
+ + + +
+
+
+ 2 +
+
+
+ + 2 + +
+
+ + + +
+
+
+ 3 +
+
+
+ + 3 + +
+
+ +
+ + + + + Text is not SVG - cannot display + + + +
+ `; + } +} diff --git a/src/react-types.ts b/src/react-types.ts index 0316ea9..5180b38 100644 --- a/src/react-types.ts +++ b/src/react-types.ts @@ -50,62 +50,73 @@ import { StepperMotorElement } from './stepper-motor-element'; import { HX711Element } from './hx711-element'; import { KS2EMDC5Element } from './ks2e-m-dc5-element'; import { BiaxialStepperElement } from './biaxial-stepper-element'; +import { BreadboardElement } from './breadboard-element'; +import { ShowPinsElement } from './show-pins-element'; +import { MainBreadboardElement } from './main-breadboard-element'; +import { McuBreadboardElement } from './mcu-breadboard-element'; + import type React from 'react'; +import { Attiny85Element } from './attiny85-element'; type WokwiElement = Partial & React.ClassAttributes; declare global { namespace JSX { interface IntrinsicElements { - 'wokwi-7segment': WokwiElement; - 'wokwi-arduino-uno': WokwiElement; - 'wokwi-lcd1602': WokwiElement; - 'wokwi-led': WokwiElement; - 'wokwi-neopixel': WokwiElement; - 'wokwi-pushbutton': WokwiElement; - 'wokwi-resistor': WokwiElement; - 'wokwi-membrane-keypad': WokwiElement; - 'wokwi-potentiometer': WokwiElement; - 'wokwi-neopixel-matrix': WokwiElement; - 'wokwi-ssd1306': WokwiElement; - 'wokwi-buzzer': WokwiElement; - 'wokwi-rotary-dialer': WokwiElement; - 'wokwi-servo': WokwiElement; - 'wokwi-dht22': WokwiElement; - 'wokwi-arduino-mega': WokwiElement; - 'wokwi-arduino-nano': WokwiElement; - 'wokwi-ds1307': WokwiElement; - 'wokwi-neopixel-ring': WokwiElement; - 'wokwi-slide-switch': WokwiElement; - 'wokwi-hc-sr04': WokwiElement; - 'wokwi-lcd2004': WokwiElement; - 'wokwi-analog-joystick': WokwiElement; - 'wokwi-slide-potentiometer': WokwiElement; - 'wokwi-ir-receiver': WokwiElement; - 'wokwi-ir-remote': WokwiElement; - 'wokwi-pir-motion-sensor': WokwiElement; - 'wokwi-ntc-temperature-sensor': WokwiElement; - 'wokwi-heart-beat-sensor': WokwiElement; - 'wokwi-tilt-switch': WokwiElement; - 'wokwi-flame-sensor': WokwiElement; - 'wokwi-gas-sensor': WokwiElement; - 'wokwi-franzininho': WokwiElement; - 'wokwi-nano-rp2040-connect': WokwiElement; - 'wokwi-small-sound-sensor': WokwiElement; - 'wokwi-big-sound-sensor': WokwiElement; - 'wokwi-mpu6050': WokwiElement; - 'wokwi-esp32-devkit-v1': WokwiElement; - 'wokwi-ky-040': WokwiElement; - 'wokwi-photoresistor-sensor': WokwiElement; - 'wokwi-rgb-led': WokwiElement; - 'wokwi-ili9341': WokwiElement; - 'wokwi-led-bar-graph': WokwiElement; - 'wokwi-microsd-card': WokwiElement; - 'wokwi-dip-switch-8': WokwiElement; - 'wokwi-stepper-motor': WokwiElement; - 'wokwi-hx711': WokwiElement; - 'wokwi-ks2e-m-dc5': WokwiElement; - 'wokwi-biaxial-stepper': WokwiElement; + SevenSegment: WokwiElement; + ArduinoUno: WokwiElement; + LCD1602: WokwiElement; + LED: WokwiElement; + NeoPixel: WokwiElement; + Pushbutton: WokwiElement; + Resistor: WokwiElement; + MembraneKeypad: WokwiElement; + Potentiometer: WokwiElement; + NeopixelMatrix: WokwiElement; + SSD1306: WokwiElement; + Buzzer: WokwiElement; + RotaryDialer: WokwiElement; + Servo: WokwiElement; + DHT22: WokwiElement; + ArduinoMega: WokwiElement; + ArduinoNano: WokwiElement; + DS1307: WokwiElement; + LEDRing: WokwiElement; + SlideSwitch: WokwiElement; + HCSR04: WokwiElement; + LCD2004: WokwiElement; + AnalogJoystick: WokwiElement; + SlidePotentiometer: WokwiElement; + IRReceiver: WokwiElement; + IRRemote: WokwiElement; + PIRMotionSensor: WokwiElement; + NTCTemperatureSensor: WokwiElement; + HeartBeatSensor: WokwiElement; + TiltSwitch: WokwiElement; + FlameSensor: WokwiElement; + GasSensor: WokwiElement; + Franzininho: WokwiElement; + NanoRP2040Connect: WokwiElement; + SmallSoundSensor: WokwiElement; + BigSoundSensor: WokwiElement; + MPU6050: WokwiElement; + ESP32DevkitV1: WokwiElement; + KY040: WokwiElement; + PhotoresistorSensor: WokwiElement; + RGBLed: WokwiElement; + ILI9341: WokwiElement; + LedBarGraph: WokwiElement; + MicrosdCard: WokwiElement; + DipSwitch8: WokwiElement; + StepperMotor: WokwiElement; + HX711: WokwiElement; + KS2EMDC5: WokwiElement; + BiaxialStepper: WokwiElement; + Breadboard: WokwiElement; + ShowPins: WokwiElement; + MainBreadboard: WokwiElement; + MCUBreadboard: WokwiElement; + Attiny85: WokwiElement; } } } diff --git a/src/show-pins-element.stories.ts b/src/show-pins-element.stories.ts new file mode 100644 index 0000000..8625ef8 --- /dev/null +++ b/src/show-pins-element.stories.ts @@ -0,0 +1,33 @@ +import { html } from 'lit'; +import './show-pins-element'; + +export default { + title: 'Show Pin', + component: 'wokwi-show-pins', + argTypes: { + pinColor: { control: 'color' }, + pinType: { control: { type: 'select', options: ['circle', 'rect'] } }, + pinWidth: { control: 'number' }, + pinHeight: { control: 'number' }, + pinRadius: { control: 'number' }, + }, + args: { + pinColor: 'transparent', + pinType: 'circle', + pinWidth: 10, + pinHeight: 10, + pinRadius: 10, + }, +}; + +const Template = ({ pinColor, pinType, pinWidth, pinHeight, pinRadius }) => html` +`; + +export const Default = Template.bind({}); +Default.args = { pinColor: 'transparent' }; diff --git a/src/show-pins-element.ts b/src/show-pins-element.ts new file mode 100644 index 0000000..7067cd1 --- /dev/null +++ b/src/show-pins-element.ts @@ -0,0 +1,164 @@ +import { html, LitElement, PropertyPart, svg } from 'lit'; +import { customElement, property, query } from 'lit/decorators.js'; +import { ElementPin } from './pin'; + +export interface ElementWithPinInfo extends Element { + pinInfo?: ElementPin[]; +} + +/** + * Utility element to debug the pinInfo property. Pin locations are displayed using red dots. + * Moving your mouse over one of the red dots shows a tooltip with the pin's name. + * + * + * Usage: + * 1. Import this file in your element's story file, e.g. + * ``` + * import './utils/show-pins-element'; + * ``` + * 2. Wrap your element with the element, e.g. + * ``` + * export const HCSR04 = () => html` + * + * + * + * `; + * ``` + */ + +enum PinType { + Circle = 'circle', + Rect = 'rect', +} + +@customElement('wokwi-show-pins') +export class ShowPinsElement extends LitElement { + @property() pinColor = 'black'; + @property() pinType: PinType = PinType.Circle; + @property() pinWidth = 5; + @property() pinHeight = 5; + @property() pinRadius = 2.5; + + // need to add properties that are functions that do something with the pins (like a callback), mouseover, click, etc. + // the plan is to use this in another project where im going to write a function that sets to the state that the pin is clicked + + @query('#content') elementSlot!: HTMLSlotElement; + + activePinIndex = -1; + previousSlotChild?: ElementWithPinInfo; + + get slotChild() { + return this.elementSlot?.assignedElements()[0] as ElementWithPinInfo | undefined; + } + + private pinInfoChangeCallback = () => { + this.requestUpdate(); + }; + + handleSlotChange() { + const slotChild = this.slotChild; + if (slotChild !== this.previousSlotChild) { + this.previousSlotChild?.removeEventListener('pininfo-change', this.pinInfoChangeCallback); + slotChild?.addEventListener('pininfo-change', this.pinInfoChangeCallback); + this.previousSlotChild = slotChild; + } + this.requestUpdate(); + } + + handleMouseOver({ pin, idx }: { pin: ElementPin; idx: number }) { + if (idx !== this.activePinIndex) { + document.dispatchEvent(new CustomEvent('pin-mouseover', { detail: { pin, idx } })); + this.activePinIndex = idx; + this.requestUpdate(); + } + } + handleMouseOut({ pin, idx }: { pin: ElementPin; idx: number }) { + this.activePinIndex = -1; + document.dispatchEvent(new CustomEvent('pin-mouseout', { detail: { pin, index: idx } })); + this.requestUpdate(); + } + handlePinClick({ + pin, + idx, + }: { + pin: { + elementName: string; + pinName: string; + x: number; + y: number; + }; + idx: number; + }) { + console.log('pin clicked', pin, idx); + document.dispatchEvent( + new CustomEvent('pin-click', { + detail: { + // if clicked on main breadboard, this will be the pin name --> MAINA11 + pin: { + pinName: pin.elementName, + elementName: pin.pinName, + x: pin.x, + y: pin.y, + }, + index: idx, + }, + }) + ); + } + + render() { + const pinInfo = this.slotChild?.pinInfo ?? []; + const elementName = this.slotChild?.localName; + const { pinColor, pinType, pinWidth, pinHeight, pinRadius } = this; + return html`
+ this.handleSlotChange()}> + + ${pinInfo.map((pin, idx) => + pinType === PinType.Rect + ? svg`${pin.name} + ` + : svg` + ${pin.name} + ` + )} + +
`; + } +} diff --git a/src/utils/show-pins-element.ts b/src/utils/show-pins-element.ts deleted file mode 100644 index b444fa7..0000000 --- a/src/utils/show-pins-element.ts +++ /dev/null @@ -1,66 +0,0 @@ -import { html, LitElement, svg } from 'lit'; -import { customElement, property, query } from 'lit/decorators.js'; -import { ElementPin } from '../pin'; - -export interface ElementWithPinInfo extends Element { - pinInfo?: ElementPin[]; -} - -/** - * Utility element to debug the pinInfo property. Pin locations are displayed using red dots. - * Moving your mouse over one of the red dots shows a tooltip with the pin's name. - * - * - * Usage: - * 1. Import this file in your element's story file, e.g. - * ``` - * import './utils/show-pins-element'; - * ``` - * 2. Wrap your element with the element, e.g. - * ``` - * export const HCSR04 = () => html` - * - * - * - * `; - * ``` - */ -@customElement('wokwi-show-pins') -export class ShowPinsElement extends LitElement { - @property() pinColor = 'red'; - @query('#content') elementSlot!: HTMLSlotElement; - - previousSlotChild?: ElementWithPinInfo; - - get slotChild() { - return this.elementSlot?.assignedElements()[0] as ElementWithPinInfo | undefined; - } - - private pinInfoChangeCallback = () => { - this.requestUpdate(); - }; - - handleSlotChange() { - const slotChild = this.slotChild; - if (slotChild !== this.previousSlotChild) { - this.previousSlotChild?.removeEventListener('pininfo-change', this.pinInfoChangeCallback); - slotChild?.addEventListener('pininfo-change', this.pinInfoChangeCallback); - this.previousSlotChild = slotChild; - } - this.requestUpdate(); - } - - render() { - const pinInfo = this.slotChild?.pinInfo ?? []; - const { pinColor } = this; - return html`
- this.handleSlotChange()}> - - - ${pinInfo.map( - (pin) => svg`${pin.name}` - )} - -
`; - } -}