(function (global) { function ConfidenceMentalDemandSlider(opts) { this.opts = Object.assign({ min: 0, max: 100, step: 1, initialValue: null, widthPercent: 80, leftLabel: "0", rightLabel: "100", hiddenInputId: null, showLiveValue: false, onChange: function () {} }, opts || {}); this.wrapper = null; this.input = null; this.live = null; this.hiddenInput = null; this.touched = false; this._boundResize = this.updateLivePosition.bind(this); } ConfidenceMentalDemandSlider.prototype.resolveHiddenInput = function () { if (!this.opts.hiddenInputId) { throw new Error("ConfidenceMentalDemandSlider: hiddenInputId is required."); } this.hiddenInput = document.getElementById(this.opts.hiddenInputId); if (!this.hiddenInput) { throw new Error("ConfidenceMentalDemandSlider: hidden input not found: " + this.opts.hiddenInputId); } // Keep validation semantics consistent: untouched slider leaves hidden input empty. this.hiddenInput.value = ""; }; ConfidenceMentalDemandSlider.prototype.getInitialValue = function () { if (this.opts.initialValue !== null && this.opts.initialValue !== undefined) { return Number(this.opts.initialValue); } return (Number(this.opts.min) + Number(this.opts.max)) / 2; }; ConfidenceMentalDemandSlider.prototype.updateLivePosition = function () { if (!this.opts.showLiveValue || !this.input || !this.live) { return; } var min = Number(this.opts.min); var max = Number(this.opts.max); var value = Number(this.input.value); var pct = (value - min) / (max - min); pct = Math.max(0, Math.min(1, pct)); var thumb = 40; var usable = Math.max(0, this.input.clientWidth - thumb); var x = thumb / 2 + usable * pct; this.live.textContent = String(value); this.live.style.left = x + "px"; }; ConfidenceMentalDemandSlider.prototype.handleInput = function () { this.markTouched(); this.hiddenInput.value = this.input.value; if (this.opts.showLiveValue) { this.live.style.visibility = "visible"; this.updateLivePosition(); } this.opts.onChange(Number(this.input.value), this); }; ConfidenceMentalDemandSlider.prototype.markTouched = function () { if (!this.touched) { this.touched = true; this.wrapper.classList.remove("cmds-pristine"); } }; ConfidenceMentalDemandSlider.prototype.handlePointerSelection = function () { // A click on the track is an intentional selection, even if value stays unchanged. this.markTouched(); this.hiddenInput.value = this.input.value; if (this.opts.showLiveValue) { this.live.style.visibility = "visible"; this.updateLivePosition(); } this.opts.onChange(Number(this.input.value), this); }; ConfidenceMentalDemandSlider.prototype.mount = function (container) { if (!container) { throw new Error("ConfidenceMentalDemandSlider: container is required."); } this.resolveHiddenInput(); var wrapper = document.createElement("div"); wrapper.className = "cmds-wrapper cmds-pristine"; wrapper.style.width = String(this.opts.widthPercent) + "%"; var live = document.createElement("div"); live.className = "cmds-live"; if (!this.opts.showLiveValue) { live.style.display = "none"; } wrapper.appendChild(live); var input = document.createElement("input"); input.type = "range"; input.className = "cmds-input"; input.min = String(this.opts.min); input.max = String(this.opts.max); input.step = String(this.opts.step); input.value = String(this.getInitialValue()); wrapper.appendChild(input); var labels = document.createElement("div"); labels.className = "cmds-labels"; labels.innerHTML = ""; labels.querySelector(".cmds-left").textContent = this.opts.leftLabel; labels.querySelector(".cmds-right").textContent = this.opts.rightLabel; wrapper.appendChild(labels); container.innerHTML = ""; container.appendChild(wrapper); this.wrapper = wrapper; this.input = input; this.live = live; this.input.addEventListener("input", this.handleInput.bind(this)); this.input.addEventListener("change", this.handleInput.bind(this)); this.input.addEventListener("pointerdown", this.handlePointerSelection.bind(this)); this.input.addEventListener("mousedown", this.handlePointerSelection.bind(this)); this.input.addEventListener("click", this.handlePointerSelection.bind(this)); this.input.addEventListener("touchstart", this.handlePointerSelection.bind(this), { passive: true }); window.addEventListener("resize", this._boundResize); this.updateLivePosition(); if (this.opts.showLiveValue) { this.live.style.visibility = "hidden"; } }; global.ConfidenceMentalDemandSlider = ConfidenceMentalDemandSlider; })(window);