Connect the range slider

This commit is contained in:
Andy Smith
2025-06-04 12:49:32 -05:00
parent 68ac1f80ec
commit 80b1ac8cc9
4 changed files with 43 additions and 30 deletions
+8
View File
@@ -20,6 +20,8 @@
}
.knob__slider {
--hover-size: 0;
appearance: none;
background-color: transparent;
block-size: var(--knob-size);
@@ -37,6 +39,8 @@
&::-webkit-slider-thumb {
appearance: none;
background-color: transparent;
height: 1px;
width: 1px;
}
}
@@ -60,6 +64,10 @@
color: var(--knob-color-accent);
}
&:has(:focus-visible) {
box-shadow: 0 0 0 2px var(--knob-color);
}
/* Tick marks */
&:before {
background-color: var(--knob-color);
+19 -17
View File
@@ -1,27 +1,29 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "wrapper" ]
static targets = [ "field", "option", "slider" ]
optionChanged(e) {
const input = e.target
const value = input.value
const index = (input.getAttribute("data-index"))
this.wrapperTarget.style.setProperty("--knob-index", `${index}`);
this.#setIndex(e.target.getAttribute("data-index"))
}
sliderChanged(e) {
const sliderIndex = e.target.value
const index = e.target.value
this.#setIndex(index)
this.#setValue(index)
console.log(index)
}
#setIndex(index) {
this.fieldTarget.style.setProperty("--knob-index", `${index}`);
this.sliderTarget.value = index;
}
#setValue(index) {
const option = this.optionTargets.find(option => {
return option.dataset.index === index;
});
option.checked = true;
}
}
// The slider has a range of 0-4. We can't add day values statically.
// These 0-4 values are used to set the angle via css.
// but, that if the range was simply used to set the value of the radio input.
// OK, what if we get the knob and radio inputs working as expected, then…
// When radio input changes, update the slider
// when the slider changes, update the radio input
// knob need an index, options have the index.
// when option is changed, set i on main component
@@ -5,4 +5,4 @@
<%= form.select :auto_close_period, collection_auto_close_options, {}, { class: "input input--select full-width margin-block-end", data: { action: "change->form#submit" } } %>
<% end %>
<%= render "collections/edit/knob", day_options: [3, 7, 30, 90, 365], default_index: 0, label: "Days until auto-close" %>
<%= render "collections/edit/knob", knob_options: [3, 7, 30, 90, 365], default_index: 0, label: "Days until auto-close" %>
+15 -12
View File
@@ -1,11 +1,12 @@
<fieldset class="knob" data-controller="knob" data-knob-target="wrapper" style="--knob-options: <%= day_options.length %>; --knob-index: <%= default_index %>;">
<fieldset class="knob" data-controller="knob" data-knob-target="field" style="--knob-options: <%= knob_options.length %>; --knob-index: <%= default_index %>;">
<div class="knob__options">
<% day_options.each_with_index do |value, i| %>
<% knob_options.each_with_index do |value, i| %>
<label class="knob__option" style="--i: <%= i %>">
<input
<%= "checked" if value == knob_options[default_index] %>
data-action="change->knob#optionChanged"
data-index="<%= i %>"
<%= "checked" if value == day_options[default_index] %>
data-knob-target="option"
name="<%= label.dasherize %>"
type="radio"
value="<%= value %>"
@@ -17,14 +18,16 @@
<legend class="knob__label"><%= label %></legend>
<input
aria-hidden
class="knob__slider"
data-action="input->knob#sliderChanged"
data-knob-target="slider"
max="<%= knob_options.length - 1 %>"
min="0"
type="range"
value="<%= default_index %>"
/>
<div class="knob__knob" aria-hidden></div>
</fieldset>
<%#
OK, the indicator needs to know what index position to point to
We have --knob-index on the wrapper, set to the default.
As the input changes, update that index.
%>