tangled
alpha
login
or
join now
vielle.dev
/
dnd-astral-powers
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
add point counter
vielle.dev
1 month ago
bddffbc0
63693774
verified
This commit was signed with the committer's
known signature
.
vielle.dev
SSH Key Fingerprint:
SHA256:/4bvxqoEh9iMdjAPgcgAgXKZZQTROL3ULiPt6nH9RSs=
+178
2 changed files
expand all
collapse all
unified
split
src
components
astral
Points.astro
pages
astral
index.astro
+171
src/components/astral/Points.astro
···
1
1
+
---
2
2
+
3
3
+
---
4
4
+
5
5
+
<script>
6
6
+
import Powers, { type powerObj } from "../../lib/powers";
7
7
+
8
8
+
class HTMLPointsMeterElement extends HTMLElement {
9
9
+
dec: HTMLButtonElement;
10
10
+
inc: HTMLButtonElement;
11
11
+
meter: HTMLMeterElement;
12
12
+
count: HTMLElement;
13
13
+
max: HTMLElement;
14
14
+
15
15
+
constructor() {
16
16
+
super();
17
17
+
const dec = this.querySelector("button[data-dec]");
18
18
+
const inc = this.querySelector("button[data-inc]");
19
19
+
const meter = this.querySelector("meter");
20
20
+
const count = this.querySelector("span.count");
21
21
+
const max = this.querySelector("span.max");
22
22
+
23
23
+
if (
24
24
+
!(
25
25
+
dec instanceof HTMLButtonElement &&
26
26
+
inc instanceof HTMLButtonElement &&
27
27
+
meter instanceof HTMLMeterElement &&
28
28
+
count instanceof HTMLElement &&
29
29
+
max instanceof HTMLElement
30
30
+
)
31
31
+
) {
32
32
+
throw "Elements not set correctly";
33
33
+
}
34
34
+
35
35
+
this.dec = dec;
36
36
+
this.inc = inc;
37
37
+
this.meter = meter;
38
38
+
this.count = count;
39
39
+
this.max = max;
40
40
+
41
41
+
Powers.subscribe(this.handleState.bind(this));
42
42
+
43
43
+
this.dec.addEventListener("click", async () => {
44
44
+
this.max.innerText = "...";
45
45
+
this.dec.disabled = true;
46
46
+
47
47
+
await Powers.setKey("points", Powers.get().points - 1).catch((e) =>
48
48
+
console.warn(e),
49
49
+
);
50
50
+
51
51
+
this.dec.disabled = !(
52
52
+
Powers.get().points - 1 >= 0 &&
53
53
+
Powers.get().points - 1 >= Powers.get().powers.length
54
54
+
);
55
55
+
});
56
56
+
57
57
+
this.inc.addEventListener("click", async () => {
58
58
+
this.max.innerText = "...";
59
59
+
this.inc.disabled = true;
60
60
+
await Powers.setKey("points", Powers.get().points + 1).catch((e) =>
61
61
+
console.warn(e),
62
62
+
);
63
63
+
64
64
+
this.inc.disabled = false;
65
65
+
});
66
66
+
}
67
67
+
68
68
+
handleState(_val: Readonly<powerObj> | null) {
69
69
+
const val = _val ? _val : { powers: [""], points: 1 };
70
70
+
this.meter.value = val.powers.length;
71
71
+
this.meter.max = val.points;
72
72
+
this.count.innerText = val.powers.length + "";
73
73
+
this.max.innerText = val.points + "";
74
74
+
75
75
+
this.dec.disabled = !(
76
76
+
val.points - 1 >= 0 && val.points - 1 >= val.powers.length
77
77
+
);
78
78
+
}
79
79
+
}
80
80
+
81
81
+
customElements.define("points-meter", HTMLPointsMeterElement);
82
82
+
</script>
83
83
+
84
84
+
<points-meter>
85
85
+
<button aria-label="decrement" data-dec>-</button>
86
86
+
<meter></meter>
87
87
+
<span class="total"
88
88
+
><span class="count"></span>/<span class="max"></span></span
89
89
+
>
90
90
+
<button aria-label="increment" data-inc>+</button>
91
91
+
</points-meter>
92
92
+
93
93
+
<style>
94
94
+
points-meter {
95
95
+
background-color: color-mix(
96
96
+
in oklch,
97
97
+
100% var(--background),
98
98
+
10% var(--text)
99
99
+
);
100
100
+
border: 5px solid var(--text);
101
101
+
border-radius: 10px;
102
102
+
padding: 1em;
103
103
+
z-index: 99;
104
104
+
105
105
+
display: grid;
106
106
+
gap: 1em;
107
107
+
grid-template: "dec meter inc" 1fr / 1fr 3fr 1fr;
108
108
+
max-width: 100%;
109
109
+
width: 400px;
110
110
+
111
111
+
button {
112
112
+
background-color: inherit;
113
113
+
border: 3px solid;
114
114
+
border-color: inherit;
115
115
+
border-radius: inherit;
116
116
+
117
117
+
&[disabled],
118
118
+
&:active {
119
119
+
opacity: 0.7;
120
120
+
}
121
121
+
}
122
122
+
123
123
+
.total {
124
124
+
width: min-content;
125
125
+
padding: 0.2em 1em;
126
126
+
margin: auto;
127
127
+
z-index: 99;
128
128
+
129
129
+
background: var(--background);
130
130
+
border: 1px solid;
131
131
+
border-color: inherit;
132
132
+
border-radius: 0.5em;
133
133
+
}
134
134
+
135
135
+
meter {
136
136
+
appearance: none;
137
137
+
width: 100%;
138
138
+
height: 3rem;
139
139
+
background: var(--background);
140
140
+
border-radius: 10px;
141
141
+
overflow: clip;
142
142
+
143
143
+
&::-webkit-meter-bar {
144
144
+
background: inherit;
145
145
+
height: 3rem;
146
146
+
}
147
147
+
148
148
+
&::-moz-meter-bar {
149
149
+
background: var(--green);
150
150
+
}
151
151
+
152
152
+
&::-webkit-meter-optimum-value {
153
153
+
background: var(--green);
154
154
+
height: 100%;
155
155
+
}
156
156
+
}
157
157
+
158
158
+
button[data-dec] {
159
159
+
grid-area: dec;
160
160
+
}
161
161
+
162
162
+
button[data-inc] {
163
163
+
grid-area: inc;
164
164
+
}
165
165
+
166
166
+
meter,
167
167
+
.total {
168
168
+
grid-area: meter;
169
169
+
}
170
170
+
}
171
171
+
</style>
+7
src/pages/astral/index.astro
···
1
1
---
2
2
import Base from "../../Base.astro";
3
3
+
import Points from "../../components/astral/Points.astro";
3
4
import Powers from "../../components/astral/Powers.astro";
4
5
import { powerData, powers, powerTree } from "../../consts/astral";
5
6
---
···
37
38
38
39
body {
39
40
margin: 2em 0 2em 10em;
41
41
+
display: flex;
42
42
+
flex-direction: column;
43
43
+
align-items: center;
44
44
+
gap: 5em;
40
45
}
41
46
</style>
47
47
+
48
48
+
<Points />
42
49
43
50
<Powers {...powerTree} i={0} siblings={1} />
44
51
</Base>