kobaltedev / kobalte

A UI toolkit for building accessible web apps and design systems with SolidJS.
https://kobalte.dev
MIT License
1.2k stars 61 forks source link

Slider onChangeEnd fires twice #322

Closed Exellin closed 7 months ago

Exellin commented 7 months ago

Describe the bug When changing the lower or higher value for a Slider component, onChangeEnd will fire twice

To Reproduce Steps to reproduce the behavior:

  1. Go to https://stackblitz.com/edit/github-b14x5v-d1fpbo?file=src%2FApp.tsx
  2. Open up the console
  3. Move the lower or higher value with your mouse (keyboard movement doesn't fire onChangeEnd)
  4. See that the lower and upper value are logged twice to the console

App.tsx for reference, slightly modified from the multiple thumbs example at https://kobalte.dev/docs/core/components/slider

import { Slider } from '@kobalte/core';
import './style.css';
function App() {
  const onChangeEnd = ([min, max]: number[]) => {
    console.log(min, max);
  };

  return (
    <Slider.Root
      class="SliderRoot"
      defaultValue={[0, 20]}
      onChangeEnd={onChangeEnd}
    >
      <div class="SliderLabel">
        <Slider.Label>Label</Slider.Label>
        <Slider.ValueLabel />
      </div>
      <Slider.Track class="SliderTrack">
        <Slider.Fill class="SliderRange" />
        <Slider.Thumb class="SliderThumb">
          <Slider.Input />
        </Slider.Thumb>
        <Slider.Thumb class="SliderThumb SliderThumb">
          <Slider.Input />
        </Slider.Thumb>
      </Slider.Track>
    </Slider.Root>
  );
}

export default App;

Expected behavior I think that onChangeEnd should only fire once when a value is changed. If an API request is made to save the new value, this request can end up being sent twice for each change of the minimum and maximum values.

Desktop (please complete the following information):

Exellin commented 7 months ago

This doesn't seem to be isolated to double thumbs, was able to reproduce with just a single value: https://stackblitz.com/edit/github-b14x5v-aewck1?file=src%2FApp.tsx%3AL10

import { Slider } from '@kobalte/core';
import './style.css';
function App() {
  const onChangeEnd = ([newValue]: number[]) => {
    console.log(newValue);
  };

  return (
    <Slider.Root class="SliderRoot" onChangeEnd={onChangeEnd}>
      <div class="SliderLabel">
        <Slider.Label>Label</Slider.Label>
        <Slider.ValueLabel />
      </div>
      <Slider.Track class="SliderTrack">
        <Slider.Fill class="SliderRange" />
        <Slider.Thumb class="SliderThumb">
          <Slider.Input />
        </Slider.Thumb>
      </Slider.Track>
    </Slider.Root>
  );
}

export default App;
dev-rb commented 7 months ago

Thanks for reporting! I've made a PR to fix the issue, it was an oversight on my part 😅