function snapRange(input, values, options = {}) {
const {
invalidation: invalidated = invalidation,
margin = 0,
transform = snap(values, margin),
} = options;
const isRange = n => n.localName === 'input' && n.type === 'range';
let pointer = false, target, disabled = false;
const handlers = {
input: e => {
if(!e.isTrusted || !pointer || disabled) return;
target = transform(input.value);
if(target !== undefined && target !== input.value) input.value = target;
},
pointerdown: e => {
pointer = isRange(e.target);
},
keydown: e => {
disabled = true;
},
keyup: e => {
disabled = false;
},
change: e => {
pointer = false;
},
};
for(const [name, fn] of Object.entries(handlers)) {
input.addEventListener(name, fn);
invalidated.then(() => input.removeEventListener(name, fn));
}
return input;
}