Skip to content

Commit 23f699f

Browse files
committed
initial implementation
1 parent b82f21b commit 23f699f

File tree

4 files changed

+140
-33
lines changed

4 files changed

+140
-33
lines changed

examples/index.html

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,21 @@
22
<html lang="en">
33
<head>
44
<meta charset="utf-8" />
5-
<title>custom-element demo</title>
5+
<title>spark-line demo</title>
66
</head>
77
<body>
8-
<custom-element></custom-element>
8+
<spark-line>
9+
<spark-line-point datetime="2022-12-12T17:07:00Z" value="20"></spark-line-point>
10+
<spark-line-point datetime="2022-12-12T17:06:00Z" value="50"></spark-line-point>
11+
<spark-line-point datetime="2022-12-12T17:06:50Z" value="80"></spark-line-point>
12+
<div>
13+
<p>Hello World</p>
14+
</div>
15+
</spark-line>
916

1017
<script type="module">
11-
// import 'https://unpkg.com/@github/custom-element-boilerplate@latest/dist/custom-element.js'
12-
import '../src/custom-element.ts'
18+
// import 'https://unpkg.com/@github/spark-line-boilerplate@latest/dist/spark-line.js'
19+
import '../src/spark-line-element.ts'
1320
</script>
1421
</body>
1522
</html>

src/custom-element.ts

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

src/spark-line-element.ts

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
const html = String.raw
2+
const css = String.raw
3+
const sparkLineStyles = new CSSStyleSheet()
4+
sparkLineStyles.replaceSync(css`
5+
:host {
6+
display: block;
7+
border: 1px solid black;
8+
}
9+
div {
10+
position: relative;
11+
height: 100px;
12+
}
13+
`)
14+
15+
/**
16+
* An example Custom Element. This documentation ends up in the
17+
* README so describe how this elements works here.
18+
*
19+
* You can event add examples on the element is used with Markdown.
20+
*
21+
* ```
22+
* <spark-line></spark-line>
23+
* ```
24+
*/
25+
class SparkLineElement extends HTMLElement {
26+
#renderRoot!: ShadowRoot
27+
28+
get #pointsSlot() {
29+
return this.#renderRoot.querySelector<HTMLSlotElement>('slot[name=points]')
30+
}
31+
32+
get startTime(): Date {
33+
let lowest: Date | number = Infinity
34+
for (const point of this.querySelectorAll<SparkLinePointElement>('spark-line-point')) {
35+
if (+point.datetime < lowest) {
36+
lowest = point.datetime
37+
}
38+
}
39+
return new Date(lowest as Date)
40+
}
41+
42+
get endTime(): Date {
43+
let highest: Date | number = -Infinity
44+
for (const point of this.querySelectorAll<SparkLinePointElement>('spark-line-point')) {
45+
if (+point.datetime > highest) {
46+
highest = point.datetime
47+
}
48+
}
49+
return new Date(highest as Date)
50+
}
51+
52+
connectedCallback(): void {
53+
this.#renderRoot = this.attachShadow({mode: 'open', slotAssignment: 'manual'})
54+
this.#renderRoot.adoptedStyleSheets = [sparkLineStyles]
55+
this.#renderRoot.innerHTML = html`
56+
<div>
57+
<slot name="points"></slot>
58+
<caption>
59+
<slot></slot>
60+
</caption>
61+
</div>
62+
`
63+
64+
this.#pointsSlot?.assign(...this.querySelectorAll('spark-line-point'))
65+
}
66+
}
67+
68+
const sparkLinePointStyles = new CSSStyleSheet()
69+
sparkLinePointStyles.replaceSync(css`
70+
div {
71+
border: 1px solid red;
72+
margin: 4px;
73+
display: inline-block;
74+
position: absolute;
75+
bottom: var(--point-value);
76+
left: var(--left-value);
77+
}
78+
`)
79+
// eslint-disable-next-line custom-elements/one-element-per-file, custom-elements/file-name-matches-element
80+
class SparkLinePointElement extends HTMLElement {
81+
#renderRoot!: ShadowRoot
82+
static observedAttributes = ['value', 'datetime']
83+
84+
#pointStyles = new CSSStyleSheet()
85+
86+
get value() {
87+
return Number(this.getAttribute('value')) || 0
88+
}
89+
90+
get datetime(): Date {
91+
return new Date(this.getAttribute('datetime') || 0)
92+
}
93+
94+
connectedCallback() {
95+
this.#renderRoot = this.attachShadow({mode: 'open', slotAssignment: 'manual'})
96+
this.#renderRoot.adoptedStyleSheets = [sparkLinePointStyles, this.#pointStyles]
97+
this.#renderRoot.innerHTML = html`<div></div>`
98+
}
99+
100+
attributeChangedCallback(name: 'value' | 'datetime', oldValue: string | null, newValue: string | null) {
101+
this.#pointStyles.replaceSync(
102+
css`
103+
div {
104+
--left-value: ${+this.datetime}px;
105+
--point-value: ${this.value}px;
106+
}
107+
`
108+
)
109+
}
110+
}
111+
112+
declare global {
113+
interface Window {
114+
SparkLineElement: typeof SparkLineElement
115+
}
116+
}
117+
118+
export default SparkLineElement
119+
120+
if (!window.customElements.get('spark-line')) {
121+
window.SparkLineElement = SparkLineElement
122+
window.customElements.define('spark-line', SparkLineElement)
123+
}
124+
125+
if (!window.customElements.get('spark-line-point')) {
126+
window.SparkLinePointElement = SparkLinePointElement
127+
window.customElements.define('spark-line-point', SparkLinePointElement)
128+
}

tsconfig.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"compilerOptions": {
33
"module": "esnext",
44
"target": "es2017",
5-
"lib": ["es2018", "dom"],
5+
"lib": ["es2018", "dom", "dom.iterable"],
66
"strict": true,
77
"declaration": true,
88
"outDir": "dist",

0 commit comments

Comments
 (0)