Skip to content

Commit 6c3da08

Browse files
committed
feat: add pushbutton-6mm
wokwi/wokwi-features#728
1 parent 4cc76b9 commit 6c3da08

File tree

4 files changed

+314
-0
lines changed

4 files changed

+314
-0
lines changed

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export { fontA02 } from './lcd1602-font-a02';
88
export { LEDElement } from './led-element';
99
export { NeoPixelElement } from './neopixel-element';
1010
export { PushbuttonElement } from './pushbutton-element';
11+
export { Pushbutton6mmElement } from './pushbutton-6mm-element';
1112
export { ResistorElement } from './resistor-element';
1213
export { MembraneKeypadElement } from './membrane-keypad-element';
1314
export { PotentiometerElement } from './potentiometer-element';

src/pushbutton-6mm-element.stories.ts

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import { action } from '@storybook/addon-actions';
2+
import { html } from 'lit';
3+
import './pushbutton-6mm-element';
4+
5+
export default {
6+
title: 'Pushbutton 6mm',
7+
component: 'wokwi-pushbutton-6mm',
8+
};
9+
10+
export const Red = () =>
11+
html`
12+
<wokwi-pushbutton-6mm
13+
color="red"
14+
@button-press=${action('button-press')}
15+
@button-release=${action('button-release')}
16+
></wokwi-pushbutton-6mm>
17+
`;
18+
19+
export const Green = () =>
20+
html`
21+
<wokwi-pushbutton-6mm
22+
color="green"
23+
@button-press=${action('button-press')}
24+
@button-release=${action('button-release')}
25+
></wokwi-pushbutton-6mm>
26+
`;
27+
28+
export const RedWithLabel = () =>
29+
html`
30+
<wokwi-pushbutton-6mm
31+
color="red"
32+
label="Press me!"
33+
@button-press=${action('button-press')}
34+
@button-release=${action('button-release')}
35+
></wokwi-pushbutton-6mm>
36+
`;
37+
38+
export const RedWithLongLabel = () =>
39+
html`
40+
<wokwi-pushbutton-6mm
41+
color="red"
42+
label="I have a really long label..."
43+
@button-press=${action('button-press')}
44+
@button-release=${action('button-release')}
45+
></wokwi-pushbutton-6mm>
46+
`;
47+
48+
export const FourButtons = () =>
49+
html`
50+
<wokwi-pushbutton-6mm
51+
color="red"
52+
@button-press=${action('red button-press')}
53+
@button-release=${action('red button-release')}
54+
></wokwi-pushbutton-6mm>
55+
<wokwi-pushbutton-6mm
56+
color="green"
57+
@button-press=${action('green button-press')}
58+
@button-release=${action('green button-release')}
59+
></wokwi-pushbutton-6mm>
60+
<wokwi-pushbutton-6mm
61+
color="blue"
62+
@button-press=${action('blue button-press')}
63+
@button-release=${action('blue button-release')}
64+
></wokwi-pushbutton-6mm>
65+
<wokwi-pushbutton-6mm
66+
color="white"
67+
@button-press=${action('white button-press')}
68+
@button-release=${action('white button-release')}
69+
></wokwi-pushbutton-6mm>
70+
`;

src/pushbutton-6mm-element.ts

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
import { css, html, LitElement } from 'lit';
2+
import { customElement, property } from 'lit/decorators.js';
3+
import { ElementPin } from './pin';
4+
import { ctrlCmdPressed, SPACE_KEYS } from './utils/keys';
5+
6+
@customElement('wokwi-pushbutton-6mm')
7+
export class Pushbutton6mmElement extends LitElement {
8+
@property() color = 'red';
9+
@property() pressed = false;
10+
@property() label = '';
11+
12+
private static pushbuttonCounter = 0;
13+
private uniqueId;
14+
15+
readonly pinInfo: ElementPin[] = [
16+
{ name: '1.l', x: 0, y: 2.2, signals: [] },
17+
{ name: '2.l', x: 0, y: 21, signals: [] },
18+
{ name: '1.r', x: 28, y: 2.2, signals: [] },
19+
{ name: '2.r', x: 28, y: 21, signals: [] },
20+
];
21+
22+
constructor() {
23+
super();
24+
this.uniqueId = 'pushbutton' + Pushbutton6mmElement.pushbuttonCounter++;
25+
}
26+
27+
static get styles() {
28+
return css`
29+
:host {
30+
display: inline-flex;
31+
flex-direction: column;
32+
}
33+
34+
button {
35+
border: none;
36+
background: none;
37+
padding: 0;
38+
margin: 0;
39+
text-decoration: none;
40+
-webkit-appearance: none;
41+
-moz-appearance: none;
42+
}
43+
44+
.button-active-circle {
45+
opacity: 0;
46+
}
47+
48+
button:active .button-active-circle {
49+
opacity: 1;
50+
}
51+
52+
.clickable-element {
53+
cursor: pointer;
54+
}
55+
56+
.label {
57+
width: 0;
58+
min-width: 100%;
59+
font-size: 12px;
60+
text-align: center;
61+
color: gray;
62+
position: relative;
63+
line-height: 1;
64+
top: -2px;
65+
}
66+
`;
67+
}
68+
69+
render() {
70+
const { color, label, uniqueId } = this;
71+
const buttonFill = this.pressed ? `url(#grad-down-${uniqueId})` : `url(#grad-up-${uniqueId})`;
72+
73+
return html`
74+
<button
75+
aria-label="${label} ${color} pushbutton 6mm"
76+
@mousedown=${this.down}
77+
@mouseup=${this.up}
78+
@touchstart=${this.down}
79+
@touchend=${this.up}
80+
@pointerleave=${this.up}
81+
@keydown=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.down()}
82+
@keyup=${(e: KeyboardEvent) => SPACE_KEYS.includes(e.key) && this.up(e)}
83+
>
84+
<svg
85+
width="7.4129977mm"
86+
height="6mm"
87+
version="1.1"
88+
viewBox="-3 0 7.4954476 6"
89+
id="svg17"
90+
sodipodi:docname="pushbutton.svg"
91+
inkscape:version="1.3 (0e150ed, 2023-07-21)"
92+
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
93+
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
94+
xmlns="http://www.w3.org/2000/svg"
95+
xmlns:svg="http://www.w3.org/2000/svg"
96+
>
97+
<sodipodi:namedview
98+
id="namedview17"
99+
pagecolor="#ffffff"
100+
bordercolor="#666666"
101+
borderopacity="1.0"
102+
inkscape:showpageshadow="2"
103+
inkscape:pageopacity="0.0"
104+
inkscape:pagecheckerboard="0"
105+
inkscape:deskcolor="#d1d1d1"
106+
inkscape:document-units="mm"
107+
inkscape:zoom="16.962656"
108+
inkscape:cx="4.5983365"
109+
inkscape:cy="10.582069"
110+
inkscape:window-width="1920"
111+
inkscape:window-height="1200"
112+
inkscape:window-x="0"
113+
inkscape:window-y="0"
114+
inkscape:window-maximized="0"
115+
inkscape:current-layer="svg17"
116+
/>
117+
<defs id="defs8">
118+
<linearGradient id="grad-up-${uniqueId}" x1="0" x2="1" y1="0" y2="1">
119+
<stop stop-color="#ffffff" offset="0" id="stop1" />
120+
<stop stop-color="${color}" offset="0.3" id="stop2" />
121+
<stop stop-color="${color}" offset="0.5" id="stop3" />
122+
<stop offset="1" id="stop4" />
123+
</linearGradient>
124+
<linearGradient
125+
id="grad-down-${uniqueId}"
126+
x1="9.8219995"
127+
x2="2.178"
128+
y1="9.8219995"
129+
y2="2.178"
130+
gradientUnits="userSpaceOnUse"
131+
>
132+
<stop stop-color="#ffffff" offset="0" id="stop5" />
133+
<stop stop-color="${color}" offset="0.3" id="stop6" />
134+
<stop stop-color="${color}" offset="0.5" id="stop7" />
135+
<stop offset="1" id="stop8" />
136+
</linearGradient>
137+
</defs>
138+
<rect
139+
x="-2.2698734"
140+
y="-0.033367086"
141+
width="6.0667338"
142+
height="6.0667338"
143+
rx="0.22244692"
144+
ry="0.22244692"
145+
fill="#464646"
146+
id="rect8"
147+
style="stroke-width:0.505561"
148+
/>
149+
<rect
150+
x="-1.8907025"
151+
y="0.3458038"
152+
width="5.3083925"
153+
height="5.3083925"
154+
rx="0.1066734"
155+
ry="0.1066734"
156+
fill="#eaeaea"
157+
id="rect9"
158+
style="stroke-width:0.505561"
159+
/>
160+
<g
161+
class="clickable-element"
162+
id="g17"
163+
transform="matrix(0.50556117,0,0,0.50556117,-2.2698734,-0.03336708)"
164+
>
165+
<circle cx="6" cy="6" r="3.822" fill="${buttonFill}" id="circle15" />
166+
<circle
167+
class="button-active-circle"
168+
cx="6"
169+
cy="6"
170+
r="3.822"
171+
fill="url(#grad-down-${uniqueId})"
172+
id="circle16"
173+
style="fill:url(#grad-down-$%7BuniqueId%7D)"
174+
/>
175+
<circle
176+
cx="6"
177+
cy="6"
178+
r="2.9000001"
179+
fill="${color}"
180+
stroke="#2f2f2f"
181+
stroke-opacity="0.47"
182+
stroke-width="0.08"
183+
id="circle17"
184+
/>
185+
<rect
186+
style="fill:#b3b3b3;stroke-width:1.72987;paint-order:stroke markers fill"
187+
id="rect18"
188+
width="1.455145"
189+
height="0.85429525"
190+
x="-1.4441905"
191+
y="0.59993488"
192+
rx="0.014974313"
193+
/>
194+
<rect
195+
style="fill:#b3b3b3;stroke-width:1.69238;paint-order:stroke markers fill"
196+
id="rect18-5"
197+
width="1.3927531"
198+
height="0.85429525"
199+
x="-1.3971666"
200+
y="10.694777"
201+
rx="0.014332262"
202+
/>
203+
<rect
204+
style="fill:#b3b3b3;stroke-width:1.69238;paint-order:stroke markers fill"
205+
id="rect18-0"
206+
width="1.3927531"
207+
height="0.85429525"
208+
x="11.989052"
209+
y="0.59516686"
210+
rx="0.014332262"
211+
/>
212+
<rect
213+
style="fill:#b3b3b3;stroke-width:1.69238;paint-order:stroke markers fill"
214+
id="rect18-0-4"
215+
width="1.3927531"
216+
height="0.85429525"
217+
x="11.985411"
218+
y="10.744086"
219+
rx="0.014332262"
220+
/>
221+
</g>
222+
</svg>
223+
</button>
224+
<span class="label">${this.label}</span>
225+
`;
226+
}
227+
228+
private down() {
229+
if (!this.pressed) {
230+
this.pressed = true;
231+
this.dispatchEvent(new Event('button-press'));
232+
}
233+
}
234+
235+
private up(e: KeyboardEvent | MouseEvent) {
236+
if (this.pressed && !ctrlCmdPressed(e)) {
237+
this.pressed = false;
238+
this.dispatchEvent(new Event('button-release'));
239+
}
240+
}
241+
}

src/react-types.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import { NeoPixelElement } from './neopixel-element';
1111
import { NeopixelMatrixElement } from './neopixel-matrix-element';
1212
import { PotentiometerElement } from './potentiometer-element';
1313
import { PushbuttonElement } from './pushbutton-element';
14+
import { Pushbutton6mmElement } from './pushbutton-6mm-element';
1415
import { ResistorElement } from './resistor-element';
1516
import { RotaryDialerElement } from './rotary-dialer-element';
1617
import { SSD1306Element } from './ssd1306-element';
@@ -63,6 +64,7 @@ declare global {
6364
'wokwi-led': WokwiElement<LEDElement>;
6465
'wokwi-neopixel': WokwiElement<NeoPixelElement>;
6566
'wokwi-pushbutton': WokwiElement<PushbuttonElement>;
67+
'wokwi-pushbutton-6mm': WokwiElement<Pushbutton6mmElement>;
6668
'wokwi-resistor': WokwiElement<ResistorElement>;
6769
'wokwi-membrane-keypad': WokwiElement<MembraneKeypadElement>;
6870
'wokwi-potentiometer': WokwiElement<PotentiometerElement>;

0 commit comments

Comments
 (0)