Skip to content

Commit 2c15489

Browse files
committed
feat: pushbutton element
1 parent 0390789 commit 2c15489

File tree

3 files changed

+186
-0
lines changed

3 files changed

+186
-0
lines changed

.storybook/addons.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1+
import '@storybook/addon-actions/register';
12
import '@storybook/addon-knobs/register';

src/pushbutton-element.stories.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { storiesOf } from '@storybook/polymer';
2+
import { action } from '@storybook/addon-actions';
3+
import { html } from 'lit-html';
4+
import './pushbutton-element';
5+
6+
storiesOf('pushbutton', module)
7+
.add(
8+
'Red',
9+
() =>
10+
html`
11+
<wokwi-pushbutton
12+
color="red"
13+
@button-press=${action('button-press')}
14+
@button-release=${action('button-release')}
15+
></wokwi-pushbutton>
16+
`
17+
)
18+
.add(
19+
'Green',
20+
() =>
21+
html`
22+
<wokwi-pushbutton
23+
color="green"
24+
@button-press=${action('button-press')}
25+
@button-release=${action('button-release')}
26+
></wokwi-pushbutton>
27+
`
28+
);

src/pushbutton-element.ts

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
import { css, customElement, html, LitElement, property } from 'lit-element';
2+
3+
const SPACE_KEY = 32;
4+
5+
@customElement('wokwi-pushbutton')
6+
export class PushbuttonElement extends LitElement {
7+
@property() color = 'red';
8+
@property() pressed = false;
9+
10+
static get styles() {
11+
return css`
12+
:host {
13+
display: inline-block;
14+
}
15+
16+
.pushbutton-container {
17+
display: flex;
18+
flex-direction: column;
19+
border: none;
20+
background: none;
21+
padding: 0;
22+
margin: 0;
23+
text-decoration: none;
24+
-webkit-appearance: none;
25+
-moz-appearance: none;
26+
}
27+
28+
.pushbutton-container:active .button-circle {
29+
fill: url(#grad-down);
30+
}
31+
32+
.clickable-element {
33+
cursor: pointer;
34+
}
35+
`;
36+
}
37+
38+
render() {
39+
const { color } = this;
40+
return html`
41+
<button class="pushbutton-container">
42+
<svg
43+
width="18mm"
44+
height="12mm"
45+
version="1.1"
46+
viewBox="-3 0 18 12"
47+
xmlns="http://www.w3.org/2000/svg"
48+
xmlns:xlink="http://www.w3.org/1999/xlink"
49+
>
50+
<defs>
51+
<linearGradient
52+
id="grad-up"
53+
x1="61.904"
54+
x2="133.7"
55+
y1="70.549"
56+
y2="142.84"
57+
gradientTransform="matrix(.10523 0 0 .10523 -4.3122 -5.2194)"
58+
gradientUnits="userSpaceOnUse"
59+
>
60+
<stop stop-color="#ffffff" offset="0" />
61+
<stop stop-color="${color}" offset="0.3" />
62+
<stop stop-color="${color}" offset="0.5" />
63+
<stop offset="1" />
64+
</linearGradient>
65+
<linearGradient
66+
id="grad-down"
67+
x1="61.904"
68+
x2="133.7"
69+
y1="70.549"
70+
y2="142.84"
71+
gradientTransform="matrix(.10523 0 0 .10523 -4.3122 -5.2194)"
72+
gradientUnits="userSpaceOnUse"
73+
>
74+
<stop offset="0" />
75+
<stop stop-color="${color}" offset="0.5" />
76+
<stop stop-color="${color}" offset="0.7" />
77+
<stop stop-color="#ffffff" offset="1" />
78+
</linearGradient>
79+
</defs>
80+
<rect
81+
x=".0034237"
82+
y=".001709"
83+
width="11.997"
84+
height="11.997"
85+
rx=".42093"
86+
ry=".42093"
87+
fill="#464646"
88+
/>
89+
<rect
90+
x=".69687"
91+
y=".73682"
92+
width="10.523"
93+
height="10.523"
94+
rx=".21047"
95+
ry=".21047"
96+
fill="#eaeaea"
97+
/>
98+
<g fill="#1b1b1">
99+
<circle cx="1.767" cy="1.7916" r=".35301" />
100+
<circle cx="10.161" cy="1.7916" r=".35301" />
101+
<circle cx="10.161" cy="10.197" r=".35301" />
102+
<circle cx="1.767" cy="10.197" r=".35301" />
103+
</g>
104+
<g fill="#eaeaea">
105+
<path
106+
d="m-0.3538 1.4672c-0.058299 0-0.10523 0.0469-0.10523 0.10522v0.38698h-2.1504c-0.1166 0-0.21045 0.0938-0.21045 0.21045v0.50721c0 0.1166 0.093855 0.21045 0.21045 0.21045h2.1504v0.40101c0 0.0583 0.046928 0.10528 0.10523 0.10528h0.35723v-1.9266z"
107+
/>
108+
<path
109+
d="m-0.35376 8.6067c-0.058299 0-0.10523 0.0469-0.10523 0.10523v0.38697h-2.1504c-0.1166 0-0.21045 0.0939-0.21045 0.21045v0.50721c0 0.1166 0.093855 0.21046 0.21045 0.21046h2.1504v0.401c0 0.0583 0.046928 0.10528 0.10523 0.10528h0.35723v-1.9266z"
110+
/>
111+
<path
112+
d="m12.354 1.4672c0.0583 0 0.10522 0.0469 0.10523 0.10522v0.38698h2.1504c0.1166 0 0.21045 0.0938 0.21045 0.21045v0.50721c0 0.1166-0.09385 0.21045-0.21045 0.21045h-2.1504v0.40101c0 0.0583-0.04693 0.10528-0.10523 0.10528h-0.35723v-1.9266z"
113+
/>
114+
<path
115+
d="m12.354 8.6067c0.0583 0 0.10523 0.0469 0.10523 0.10522v0.38698h2.1504c0.1166 0 0.21045 0.0938 0.21045 0.21045v0.50721c0 0.1166-0.09386 0.21045-0.21045 0.21045h-2.1504v0.40101c0 0.0583-0.04693 0.10528-0.10523 0.10528h-0.35723v-1.9266z"
116+
/>
117+
</g>
118+
<g class="clickable-element">
119+
<circle class="button-circle" cx="5.9725" cy="6.0016" r="3.8267" fill="url(#grad-up)" />
120+
<circle
121+
cx="5.9825"
122+
cy="6.0116"
123+
r="2.9019"
124+
fill="${color}"
125+
stroke="#2f2f2f"
126+
stroke-opacity=".47321"
127+
stroke-width=".076779"
128+
/>
129+
</g>
130+
</svg>
131+
</button>
132+
`;
133+
}
134+
135+
firstUpdated() {
136+
this.addEventListener('mousedown', this.down);
137+
this.addEventListener('touchstart', this.down);
138+
this.addEventListener('mouseup', this.up);
139+
this.addEventListener('touchend', this.up);
140+
this.addEventListener('keydown', (e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.down());
141+
this.addEventListener('keyup', (e: KeyboardEvent) => e.keyCode === SPACE_KEY && this.up());
142+
}
143+
144+
private down() {
145+
if (!this.pressed) {
146+
this.pressed = true;
147+
this.dispatchEvent(new Event('button-press'));
148+
}
149+
}
150+
151+
private up() {
152+
if (this.pressed) {
153+
this.pressed = false;
154+
this.dispatchEvent(new Event('button-release'));
155+
}
156+
}
157+
}

0 commit comments

Comments
 (0)