diff --git a/data/index.html b/data/index.html
index 1afab11..bea2808 100644
--- a/data/index.html
+++ b/data/index.html
@@ -11,6 +11,7 @@
+
@@ -249,6 +250,23 @@
/>
+
diff --git a/data/range-input.js b/data/range-input.js
new file mode 100644
index 0000000..4b31c04
--- /dev/null
+++ b/data/range-input.js
@@ -0,0 +1,14 @@
+document.querySelector("form").addEventListener("input", (event) => {
+ if (event.target.classList.contains("range")) {
+ updateValue(event.target);
+ }
+});
+
+function updateValue(slider) {
+ const percentage = Math.round((slider.value / slider.max) * 100);
+ slider.nextElementSibling.innerText = `${percentage}%`;
+}
+
+document.querySelectorAll("input[type='range'].range").forEach((element) => {
+ updateValue(element);
+});
diff --git a/data/style.css b/data/style.css
index a664028..d663279 100644
--- a/data/style.css
+++ b/data/style.css
@@ -4,7 +4,7 @@
--color-background: #222;
--color-surface: #333;
--color-danger: #fa2b58;
- --icon-button-size: 2.5rem;
+ --appended-item-size: 2.5rem;
}
body {
@@ -51,8 +51,13 @@ label span {
}
input,
-select {
+select,
+label div {
width: clamp(200px, 100%, 400px);
+}
+
+input,
+select {
background-color: var(--color-background);
color: white;
border: 1px solid white;
@@ -67,8 +72,13 @@ select:focus {
border-color: var(--color-primary);
}
-select:has(+ .icon-button) {
- width: calc(clamp(200px, 100%, 400px) - var(--icon-button-size) - 8px);
+select:has(+ .icon-button),
+label div input[type="range"] {
+ width: calc(clamp(200px, 100%, 400px) - var(--appended-item-size) - 8px);
+}
+
+input[type="range"] {
+ accent-color: var(--color-primary);
}
button {
@@ -245,8 +255,8 @@ button.reload {
.icon-button {
padding: 8px;
font-size: 0;
- width: var(--icon-button-size);
- height: var(--icon-button-size);
+ width: var(--appended-item-size);
+ height: var(--appended-item-size);
}
.spinning {
@@ -256,6 +266,19 @@ button.reload {
animation-timing-function: linear;
}
+div:has(.range-value) {
+ display: flex;
+ flex-direction: row;
+ gap: 8px;
+}
+
+.range-value {
+ width: var(--appended-item-size);
+ height: var(--appended-item-size);
+ text-align: center;
+ line-height: var(--appended-item-size);
+}
+
.status {
background-color: var(--color-surface);
padding: 8px;
diff --git a/data/submit.js b/data/submit.js
index cc1404b..bb6165e 100644
--- a/data/submit.js
+++ b/data/submit.js
@@ -18,7 +18,7 @@ function parseValue(input) {
return null;
}
- if (input.type === "number") {
+ if (input.type === "number" || input.type === "range") {
const number = Number(input.value);
return Number.isNaN(number) ? null : number;
}
diff --git a/src/routes/config.cpp b/src/routes/config.cpp
index 5ca6107..7450e5e 100644
--- a/src/routes/config.cpp
+++ b/src/routes/config.cpp
@@ -96,6 +96,7 @@ void onGetConfig(AsyncWebServerRequest *request)
doc["direction-1"] = config.getUInt("direction-1", Output);
doc["universe-2"] = config.getUInt("universe-2", 1);
doc["direction-2"] = config.getUInt("direction-2", Input);
+ doc["led-brightness"] = config.getUInt("led-brightness", 25);
config.end();
@@ -152,6 +153,8 @@ void onPutConfig(AsyncWebServerRequest *request, uint8_t *data, size_t len, size
config.putUInt("universe-1", doc["universe-1"]);
config.putUInt("universe-2", doc["universe-2"]);
+ config.putUInt("led-brightness", doc["led-brightness"]);
+
config.end();
request->send(200);