function rangeSlider(options = {}) {
const {min = 0, max = 1, step = 'any', value, color, theme} = options;
const input = rangeInput({min, max, step, value, theme});
if(color) input.style.color = color;
const {precision = 3, format = v => v, display: _display, separator = ' … '} = options;
const round = (p => (p = 10 ** p, v => Math.round(v * p) / p))(precision);
const output = typeof format === 'function' ? format : d3format.format(format);
const display = _display || (v => v.map(output).join(separator));
const {
title, description, submit,
getValue = n => n.value.map(round),
cautious = false
} = options;
const w = widget({
title, description, submit, display, getValue,
form: Object.assign(html`<form>${input}`, {input}),
action:
cautious &&
function(form) {
var oninput = false;
let getRangeValue = form => getValue ? getValue(form.input) : form.input.value;
document.onmouseup = form.onmouseup = form.onkeyup = form.ontouchend = e => {
if (oninput && !submit)
{
form.value = getRangeValue(form);
form.dispatchEvent(new CustomEvent("input"));
oninput = false;
}
};
form.input.oninput = e => {
oninput = true;
e && e.stopPropagation() && e.preventDefault();
const value = getRangeValue(form);
if (form.output) {
const out = display
? display(value)
: format
? format(value)
: value;
if (out instanceof window.Element) {
while (form.output.hasChildNodes()) {
form.output.removeChild(form.output.lastChild);
}
form.output.append(out);
} else {
form.output.value = out;
}
}
};
form.onsubmit = e => {
e && e.preventDefault();
form.value = getRangeValue(form);
form.dispatchEvent(new CustomEvent("input"));
};
form.value = getRangeValue(form);
form.input.dispatchEvent(new CustomEvent("input"));
}
});
w.querySelector('output').style.display = 'inline-block';
return w;
}