Skip to content

Commit 22cf489

Browse files
keithamuskoddsson
andcommitted
initial implementation
Co-authored-by: Kristján Oddsson <[email protected]>
1 parent 8c8abd0 commit 22cf489

File tree

3 files changed

+106
-32
lines changed

3 files changed

+106
-32
lines changed

examples/index.html

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@
22
<html lang="en">
33
<head>
44
<meta charset="utf-8" />
5-
<title>custom-element demo</title>
5+
<title>tomato-timer demo</title>
66
</head>
77
<body>
8-
<custom-element></custom-element>
8+
<tomato-timer>25:00</tomato-timer>
99

1010
<script type="module">
11-
// import 'https://unpkg.com/@github/custom-element-boilerplate@latest/dist/custom-element.js'
12-
import '../src/custom-element.ts'
11+
// import 'https://unpkg.com/@github/tomato-timer-boilerplate@latest/dist/tomato-timer.js'
12+
import '../src/tomato-timer-element.ts'
1313
</script>
1414
</body>
1515
</html>

src/custom-element.ts

Lines changed: 0 additions & 28 deletions
This file was deleted.

src/tomato-timer-element.ts

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
const stylesheet = new CSSStyleSheet()
2+
stylesheet.replaceSync(`
3+
4+
`)
5+
6+
/**
7+
* An example Custom Element. This documentation ends up in the
8+
* README so describe how this elements works here.
9+
*
10+
* You can event add examples on the element is used with Markdown.
11+
*
12+
* ```
13+
* <tomato-timer></tomato-timer>
14+
* ```
15+
*/
16+
class TomatoTimerElement extends HTMLElement {
17+
#timer = 0
18+
#renderRoot!: ShadowRoot
19+
#notification: Notification | null
20+
#timeoutId = 0
21+
22+
#mode = 'tick'
23+
get mode() {
24+
return this.#mode
25+
}
26+
27+
set mode(value: 'tick' | 'tock') {
28+
this.#mode = value
29+
}
30+
31+
get tickSeconds() {
32+
return 60
33+
}
34+
35+
get tockSeconds() {
36+
return 30
37+
}
38+
39+
get #display() {
40+
return this.#renderRoot.querySelector('div')!
41+
}
42+
43+
connectedCallback(): void {
44+
this.#renderRoot = this.attachShadow({mode:'open'})
45+
this.#renderRoot.adoptedStyleSheets = [stylesheet]
46+
this.#renderRoot.innerHTML = `<div></div><button>
47+
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-pause"><rect x="6" y="4" width="4" height="16"></rect><rect x="14" y="4" width="4" height="16"></rect></svg>
48+
</button>`
49+
this.start(this.tickSeconds)
50+
this.addEventListener('click', this)
51+
}
52+
53+
handleEvent(event: Event) {
54+
clearTimeout(this.#timeoutId)
55+
}
56+
57+
start(time: number) {
58+
this.#timer = Date.now() + time * 1000
59+
this.#update()
60+
Notification.requestPermission()
61+
}
62+
63+
#update() {
64+
const remaining = this.#timer - Date.now()
65+
const seconds = Math.round(remaining / 1000)
66+
if (seconds < 0) {
67+
return this.end()
68+
}
69+
this.#timeoutId = setTimeout(() => this.#update(), 1000)
70+
const minutes = Math.floor(seconds / 60)
71+
const minutesDisplay = String(minutes % 60).padStart(2, '0')
72+
const secondDisplay = String(seconds % 60).padStart(2, '0')
73+
this.#display.textContent = `${minutesDisplay}:${secondDisplay}`
74+
}
75+
76+
end() {
77+
if (this.mode === 'tick') {
78+
const notification = new Notification('Time for break!')
79+
setTimeout(() => notification.close(), 4000)
80+
this.mode = 'tock'
81+
this.start(this.tockSeconds)
82+
} else if (this.mode === 'tock') {
83+
const notification = new Notification('Back to work!')
84+
setTimeout(() => notification.close(), 4000)
85+
this.mode = 'tick'
86+
this.start(this.tickSeconds)
87+
}
88+
}
89+
}
90+
91+
declare global {
92+
interface Window {
93+
TomatoTimerElement: typeof TomatoTimerElement
94+
}
95+
}
96+
97+
export default TomatoTimerElement
98+
99+
if (!window.customElements.get('tomato-timer')) {
100+
window.TomatoTimerElement = TomatoTimerElement
101+
window.customElements.define('tomato-timer', TomatoTimerElement)
102+
}

0 commit comments

Comments
 (0)