Repository: bevyengine/bevy
File: crates/bevy_core_widgets/src/core_slider.rs (Rust)

Code before:
    q_children: Query<&Children>,
    mut commands: Commands,
    ui_scale: Res<UiScale>,
) {
    if let Ok((node, slider, range, precision, transform, drag, disabled)) =
        q_slider.get_mut(trigger.target())
    {
        trigger.propagate(false);
        if drag.dragging && !disabled {
            let mut distance = trigger.event().distance / ui_scale.0;
            distance.y *= -1.;
            let distance = transform.transform_vector2(distance);
            // Find thumb size by searching descendants for the first entity with CoreSliderThumb
            let thumb_size = q_children
                .iter_descendants(trigger.target())
                .find_map(|child_id| q_thumb.get(child_id).ok().map(|thumb| thumb.size().x))
                .unwrap_or(0.0);
            let slider_width = ((node.size().x - thumb_size) * node.inverse_scale_factor).max(1.0);
            let span = range.span();
            let new_value = if span > 0. {
                range.clamp(drag.offset + (distance.x * span) / slider_width)
            } else {
                range.start() + span * 0.5
            };
            let rounded_value = precision
                .map(|prec| prec.round(new_value))
                .unwrap_or(new_value);

            if matches!(slider.on_change, Callback::Ignore) {
                commands
                    .entity(trigger.target())
                    .insert(SliderValue(rounded_value));
            } else {
                commands.notify_with(&slider.on_change, rounded_value);
            }
        }
    }
}

pub(crate) fn slider_on_drag_end(
    mut trigger: On<Pointer<DragEnd>>,
    mut q_slider: Query<(&CoreSlider, &mut CoreSliderDragState)>,
) {
    if let Ok((_slider, mut drag)) = q_slider.get_mut(trigger.target()) {
        trigger.propagate(false);
        if drag.dragging {
            drag.dragging = false;
        }
    }
}


Review comment (suggestion):
Need to clamp here, otherwise it can round the value to outside of the slider range

```suggestion
                .map(|prec| range.clamp(prec.round(new_value)))
```

Code after:
    q_children: Query<&Children>,
    mut commands: Commands,
    ui_scale: Res<UiScale>,
) {
    if let Ok((node, slider, range, precision, transform, drag, disabled)) =
        q_slider.get_mut(trigger.target())
    {
        trigger.propagate(false);
        if drag.dragging && !disabled {
            let mut distance = trigger.event().distance / ui_scale.0;
            distance.y *= -1.;
            let distance = transform.transform_vector2(distance);
            // Find thumb size by searching descendants for the first entity with CoreSliderThumb
            let thumb_size = q_children
                .iter_descendants(trigger.target())
                .find_map(|child_id| q_thumb.get(child_id).ok().map(|thumb| thumb.size().x))
                .unwrap_or(0.0);
            let slider_width = ((node.size().x - thumb_size) * node.inverse_scale_factor).max(1.0);
            let span = range.span();
            let new_value = if span > 0. {
                drag.offset + (distance.x * span) / slider_width
            } else {
                range.start() + span * 0.5
            };
            let rounded_value = range.clamp(
                precision
                    .map(|prec| prec.round(new_value))
                    .unwrap_or(new_value),
            );

            if matches!(slider.on_change, Callback::Ignore) {
                commands
                    .entity(trigger.target())
                    .insert(SliderValue(rounded_value));
            } else {
                commands.notify_with(&slider.on_change, rounded_value);
            }
        }
    }
}

pub(crate) fn slider_on_drag_end(
    mut trigger: On<Pointer<DragEnd>>,
    mut q_slider: Query<(&CoreSlider, &mut CoreSliderDragState)>,
) {
    if let Ok((_slider, mut drag)) = q_slider.get_mut(trigger.target()) {
        trigger.propagate(false);
        if drag.dragging {
            drag.dragging = false;
        }
    }