image-compare icon indicating copy to clipboard operation
image-compare copied to clipboard

Allow to define the range input step

Open mably opened this issue 1 year ago • 4 comments

We are currently adding it as a custom step attribute to the image-compare element:

<image-compare step="5" ...

And then activate it after page load using some code similar to this:

once('image_compare', 'image-compare', context).forEach(function (element) {
  var range_input = element.shadowRoot.querySelector('input');
  if (range_input && parseInt(element.getAttribute('step')) > 1) {
    range_input.step = element.getAttribute('step');
  }
});

Could improve keyboard use in some cases.

mably avatar May 07 '24 17:05 mably

This is a good idea!

I'm not sure when I'll have a chance to look into this. Feel free to make a PR if you'd like. Otherwise I'll try to tackle this when I have some free time.

Paul-Hebert avatar May 07 '24 17:05 Paul-Hebert

I think we can improve things a bit when using a high step value for keyboard use by simply disabling our custom step when using the mouse, so we can keep it as fluid as possible on screen.

The solution is to simply set step to 1 on mousedown event and bring it back to its user defined value on mouseup event:

if (parseInt(element.getAttribute('step')) > 1) {
  range_input.step = element.getAttribute('step');
  range_input.addEventListener('mousedown', function() {
    range_input.step = 1;
  });
  range_input.addEventListener('mouseup', function() {
    range_input.step = element.getAttribute('step');
  });
}

I guess we could even increase the max value to 1000 for example with a step of 20+ when using the keyboard.

mably avatar May 07 '24 18:05 mably

Forget about it, this doesn't work in fact, or not perfectly.

When you release the mouse, the slider handle moves to the closest "step".

May be we should do it differently and enable stepping on keydown events only.

Will give it a try.

mably avatar May 07 '24 18:05 mably

Ok, doing it the other way seems to work.

You just need to avoid setting the "keyboard step" when you leave the range input using the keyboard, using the tab key for example.

var keyboardStep = 1;
if (parseInt(element.getAttribute('step')) > 1) {
  keyboardStep = parseInt(element.getAttribute('step'));
}
if (keyboardStep > 1) {
  range_input.addEventListener('keydown', function(evt) {
    // Only set the step on arrow key events.
    switch (evt.key) {
      case 'ArrowDown':
      case 'ArrowLeft':
      case 'ArrowRight':
      case 'ArrowUp':
        range_input.step = keyboardStep;
    }
  });
  range_input.addEventListener('keyup', function() {
    range_input.step = 1;
  });
}

Can be tested here: https://standardbm.e-bordeaux.org/image-compare-slider (first slider on page has a step of 5).

mably avatar May 07 '24 18:05 mably