Skip to content

Commit 216650c

Browse files
committed
Add state components
1 parent f6f5805 commit 216650c

File tree

7 files changed

+356
-22
lines changed

7 files changed

+356
-22
lines changed

README.md

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,14 @@ Web Components library for micro:bit
1919
- [x] Serial Number
2020

2121
## State Class Wrappers
22-
- [ ] Connection State
23-
- [ ] Button State
22+
- [x] Connection State
23+
- [x] Button A State
24+
- [x] Button B State
2425
- [ ] IO Pin State
2526

2627
## Data
2728
- [x] Temperature
28-
- [ ] Compass
29+
- [x] Compass
2930
- [ ] Movement
3031
- [ ] Write IO
3132

src/components.d.ts

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,13 @@ import {
1818

1919
export namespace Components {
2020

21+
interface MicrobitCompass {
22+
'services': Services;
23+
}
24+
interface MicrobitCompassAttributes extends StencilHTMLAttributes {
25+
'services'?: Services;
26+
}
27+
2128
interface MicrobitTemperature {
2229
/**
2330
* The text shown when disconnected
@@ -233,10 +240,96 @@ export namespace Components {
233240
'setDeviceInformation'?: (deviceInformation: DeviceInformation) => void;
234241
'setServices'?: (services: Services) => void;
235242
}
243+
244+
interface MicrobitStateButtonA {
245+
/**
246+
* The css class to use when long-pressed
247+
*/
248+
'longPressClass': string;
249+
/**
250+
* The css class to use when released
251+
*/
252+
'releaseClass': string;
253+
'services': Services;
254+
/**
255+
* The css class to use when short-pressed
256+
*/
257+
'shortPressClass': string;
258+
}
259+
interface MicrobitStateButtonAAttributes extends StencilHTMLAttributes {
260+
/**
261+
* The css class to use when long-pressed
262+
*/
263+
'longPressClass'?: string;
264+
/**
265+
* The css class to use when released
266+
*/
267+
'releaseClass'?: string;
268+
'services'?: Services;
269+
/**
270+
* The css class to use when short-pressed
271+
*/
272+
'shortPressClass'?: string;
273+
}
274+
275+
interface MicrobitStateButtonB {
276+
/**
277+
* The css class to use when long-pressed
278+
*/
279+
'longPressClass': string;
280+
/**
281+
* The css class to use when released
282+
*/
283+
'releaseClass': string;
284+
'services': Services;
285+
/**
286+
* The css class to use when short-pressed
287+
*/
288+
'shortPressClass': string;
289+
}
290+
interface MicrobitStateButtonBAttributes extends StencilHTMLAttributes {
291+
/**
292+
* The css class to use when long-pressed
293+
*/
294+
'longPressClass'?: string;
295+
/**
296+
* The css class to use when released
297+
*/
298+
'releaseClass'?: string;
299+
'services'?: Services;
300+
/**
301+
* The css class to use when short-pressed
302+
*/
303+
'shortPressClass'?: string;
304+
}
305+
306+
interface MicrobitStateConnection {
307+
/**
308+
* The css class to use when connected
309+
*/
310+
'connectedClass': string;
311+
'device': BluetoothDevice;
312+
/**
313+
* The css class to use when disconnected
314+
*/
315+
'disconnectedClass': string;
316+
}
317+
interface MicrobitStateConnectionAttributes extends StencilHTMLAttributes {
318+
/**
319+
* The css class to use when connected
320+
*/
321+
'connectedClass'?: string;
322+
'device'?: BluetoothDevice;
323+
/**
324+
* The css class to use when disconnected
325+
*/
326+
'disconnectedClass'?: string;
327+
}
236328
}
237329

238330
declare global {
239331
interface StencilElementInterfaces {
332+
'MicrobitCompass': Components.MicrobitCompass;
240333
'MicrobitTemperature': Components.MicrobitTemperature;
241334
'MicrobitFirmware': Components.MicrobitFirmware;
242335
'MicrobitHardware': Components.MicrobitHardware;
@@ -247,9 +340,13 @@ declare global {
247340
'MicrobitText': Components.MicrobitText;
248341
'MicrobitApp': Components.MicrobitApp;
249342
'MicrobitConnect': Components.MicrobitConnect;
343+
'MicrobitStateButtonA': Components.MicrobitStateButtonA;
344+
'MicrobitStateButtonB': Components.MicrobitStateButtonB;
345+
'MicrobitStateConnection': Components.MicrobitStateConnection;
250346
}
251347

252348
interface StencilIntrinsicElements {
349+
'microbit-compass': Components.MicrobitCompassAttributes;
253350
'microbit-temperature': Components.MicrobitTemperatureAttributes;
254351
'microbit-firmware': Components.MicrobitFirmwareAttributes;
255352
'microbit-hardware': Components.MicrobitHardwareAttributes;
@@ -260,9 +357,18 @@ declare global {
260357
'microbit-text': Components.MicrobitTextAttributes;
261358
'microbit-app': Components.MicrobitAppAttributes;
262359
'microbit-connect': Components.MicrobitConnectAttributes;
360+
'microbit-state-button-a': Components.MicrobitStateButtonAAttributes;
361+
'microbit-state-button-b': Components.MicrobitStateButtonBAttributes;
362+
'microbit-state-connection': Components.MicrobitStateConnectionAttributes;
263363
}
264364

265365

366+
interface HTMLMicrobitCompassElement extends Components.MicrobitCompass, HTMLStencilElement {}
367+
var HTMLMicrobitCompassElement: {
368+
prototype: HTMLMicrobitCompassElement;
369+
new (): HTMLMicrobitCompassElement;
370+
};
371+
266372
interface HTMLMicrobitTemperatureElement extends Components.MicrobitTemperature, HTMLStencilElement {}
267373
var HTMLMicrobitTemperatureElement: {
268374
prototype: HTMLMicrobitTemperatureElement;
@@ -323,7 +429,26 @@ declare global {
323429
new (): HTMLMicrobitConnectElement;
324430
};
325431

432+
interface HTMLMicrobitStateButtonAElement extends Components.MicrobitStateButtonA, HTMLStencilElement {}
433+
var HTMLMicrobitStateButtonAElement: {
434+
prototype: HTMLMicrobitStateButtonAElement;
435+
new (): HTMLMicrobitStateButtonAElement;
436+
};
437+
438+
interface HTMLMicrobitStateButtonBElement extends Components.MicrobitStateButtonB, HTMLStencilElement {}
439+
var HTMLMicrobitStateButtonBElement: {
440+
prototype: HTMLMicrobitStateButtonBElement;
441+
new (): HTMLMicrobitStateButtonBElement;
442+
};
443+
444+
interface HTMLMicrobitStateConnectionElement extends Components.MicrobitStateConnection, HTMLStencilElement {}
445+
var HTMLMicrobitStateConnectionElement: {
446+
prototype: HTMLMicrobitStateConnectionElement;
447+
new (): HTMLMicrobitStateConnectionElement;
448+
};
449+
326450
interface HTMLElementTagNameMap {
451+
'microbit-compass': HTMLMicrobitCompassElement
327452
'microbit-temperature': HTMLMicrobitTemperatureElement
328453
'microbit-firmware': HTMLMicrobitFirmwareElement
329454
'microbit-hardware': HTMLMicrobitHardwareElement
@@ -334,9 +459,13 @@ declare global {
334459
'microbit-text': HTMLMicrobitTextElement
335460
'microbit-app': HTMLMicrobitAppElement
336461
'microbit-connect': HTMLMicrobitConnectElement
462+
'microbit-state-button-a': HTMLMicrobitStateButtonAElement
463+
'microbit-state-button-b': HTMLMicrobitStateButtonBElement
464+
'microbit-state-connection': HTMLMicrobitStateConnectionElement
337465
}
338466

339467
interface ElementTagNameMap {
468+
'microbit-compass': HTMLMicrobitCompassElement;
340469
'microbit-temperature': HTMLMicrobitTemperatureElement;
341470
'microbit-firmware': HTMLMicrobitFirmwareElement;
342471
'microbit-hardware': HTMLMicrobitHardwareElement;
@@ -347,6 +476,9 @@ declare global {
347476
'microbit-text': HTMLMicrobitTextElement;
348477
'microbit-app': HTMLMicrobitAppElement;
349478
'microbit-connect': HTMLMicrobitConnectElement;
479+
'microbit-state-button-a': HTMLMicrobitStateButtonAElement;
480+
'microbit-state-button-b': HTMLMicrobitStateButtonBElement;
481+
'microbit-state-connection': HTMLMicrobitStateConnectionElement;
350482
}
351483

352484

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { Component, Prop, Element, State, Watch } from "@stencil/core";
2+
import { Services } from "microbit-web-bluetooth";
3+
import DeviceTunnel from '../../device-tunnel';
4+
5+
@Component({
6+
tag: 'microbit-compass'
7+
})
8+
export class MicrobitCompass {
9+
@Element() el;
10+
@Prop() services: Services = undefined;
11+
12+
@State() bearing: number = 0;
13+
14+
@Watch('services')
15+
async watchHandler() {
16+
if (!this.services || !this.services.magnetometerService) {
17+
return;
18+
}
19+
20+
const service = this.services.magnetometerService;
21+
service.addEventListener("magnetometerbearingchanged", event => this.bearing = event.detail);
22+
}
23+
24+
render() {
25+
const style = {
26+
position: "absolute",
27+
transform: `rotate(${this.bearing}deg)`
28+
};
29+
return (
30+
<span style={style}>
31+
<slot />
32+
</span>
33+
);
34+
}
35+
}
36+
37+
DeviceTunnel.injectProps(MicrobitCompass, ['services']);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Component, Prop, Element, Watch, State } from "@stencil/core";
2+
import { Services } from "microbit-web-bluetooth";
3+
import DeviceTunnel from '../../device-tunnel';
4+
5+
@Component({
6+
tag: 'microbit-state-button-a'
7+
})
8+
export class MicrobitStateButtonA {
9+
@Element() el;
10+
@Prop() services: Services = undefined;
11+
12+
/**
13+
* The css class to use when released
14+
*/
15+
@Prop() releaseClass: string = "microbit-release";
16+
17+
/**
18+
* The css class to use when short-pressed
19+
*/
20+
@Prop() shortPressClass: string = "microbit-short-press";
21+
22+
/**
23+
* The css class to use when long-pressed
24+
*/
25+
@Prop() longPressClass: string = "microbit-long-press";
26+
27+
@State() className = this.releaseClass;
28+
29+
@Watch('services')
30+
watchHandler() {
31+
if (!this.services || !this.services.buttonService) {
32+
this.className = this.releaseClass;
33+
return;
34+
}
35+
36+
const service = this.services.buttonService;
37+
service.addEventListener("buttonastatechanged", event => {
38+
this.className = event.detail === 1 ? this.shortPressClass
39+
: event.detail === 2 ? this.longPressClass
40+
: this.releaseClass;
41+
});
42+
}
43+
44+
render() {
45+
return (
46+
<span class={this.className}>
47+
<slot />
48+
</span>
49+
);
50+
}
51+
}
52+
53+
DeviceTunnel.injectProps(MicrobitStateButtonA, ['services']);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { Component, Prop, Element, Watch, State } from "@stencil/core";
2+
import { Services } from "microbit-web-bluetooth";
3+
import DeviceTunnel from '../../device-tunnel';
4+
5+
@Component({
6+
tag: 'microbit-state-button-b'
7+
})
8+
export class MicrobitStateButtonB {
9+
@Element() el;
10+
@Prop() services: Services = undefined;
11+
12+
/**
13+
* The css class to use when released
14+
*/
15+
@Prop() releaseClass: string = "microbit-release";
16+
17+
/**
18+
* The css class to use when short-pressed
19+
*/
20+
@Prop() shortPressClass: string = "microbit-short-press";
21+
22+
/**
23+
* The css class to use when long-pressed
24+
*/
25+
@Prop() longPressClass: string = "microbit-long-press";
26+
27+
@State() className = this.releaseClass;
28+
29+
@Watch('services')
30+
watchHandler() {
31+
if (!this.services || !this.services.buttonService) {
32+
this.className = this.releaseClass;
33+
return;
34+
}
35+
36+
const service = this.services.buttonService;
37+
service.addEventListener("buttonbstatechanged", event => {
38+
this.className = event.detail === 1 ? this.shortPressClass
39+
: event.detail === 2 ? this.longPressClass
40+
: this.releaseClass;
41+
});
42+
}
43+
44+
render() {
45+
return (
46+
<span class={this.className}>
47+
<slot />
48+
</span>
49+
);
50+
}
51+
}
52+
53+
DeviceTunnel.injectProps(MicrobitStateButtonB, ['services']);
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Component, Prop, Element } from "@stencil/core";
2+
import DeviceTunnel from '../../device-tunnel';
3+
4+
@Component({
5+
tag: 'microbit-state-connection'
6+
})
7+
export class MicrobitStateConnection {
8+
@Element() el;
9+
@Prop() device: BluetoothDevice = undefined;
10+
11+
/**
12+
* The css class to use when connected
13+
*/
14+
@Prop() connectedClass: string = "microbit-connected";
15+
16+
/**
17+
* The css class to use when disconnected
18+
*/
19+
@Prop() disconnectedClass: string = "microbit-disconnected";
20+
21+
render() {
22+
const className = this.device ? this.connectedClass : this.disconnectedClass;
23+
return (
24+
<span class={className}>
25+
<slot />
26+
</span>
27+
);
28+
}
29+
}
30+
31+
DeviceTunnel.injectProps(MicrobitStateConnection, ['device']);

0 commit comments

Comments
 (0)