microsoft / microsoft/fluentui
[Bug]: prevent programmatic value changes from emitting change events in fluent-slider
@chrisdholt is already working on this.
Since Sep 15, 2026.
- Dominant language
- TypeScript
- Stars
- 20.3k
- Forks
- 2.9k
- Avg merge
- 2d 9h
- Merged PRs (30d)
- 46
Description
🐛 Bug Report
<fluent-slider> emits a change event whenever its value changes, including changes made programmatically through the value attribute or property. Consumers cannot initialize or synchronize the slider value without triggering handlers intended for user interaction.
💻 Repro or Code Sample
<fluent-slider></fluent-slider>
<script type="module">
import "@fluentui/web-components/slider/define.js";
await customElements.whenDefined("fluent-slider");
const slider = document.querySelector("fluent-slider");
await new Promise(resolve => requestAnimationFrame(resolve));
let changeCount = 0;
slider.addEventListener("change", () => {
changeCount++;
});
slider.setAttribute("value", "25");
console.log(changeCount); // Actual: 1; expected: 0
slider.value = "50";
console.log(changeCount); // Actual: 2; expected: 0
</script>
🤔 Expected Behavior
Programmatically changing the value attribute or property should update the slider position, form value, and ARIA state without emitting a change event.
A change event should be emitted only in response to user interaction. The value attribute should update the current value only while the control is in a clean state.
😯 Current Behavior
The connected slider's initialValueChanged() callback assigns the new initial value through the value setter. That setter unconditionally calls $emit("change").
Direct property assignments, attribute updates, form resets, and internal value normalization therefore emit the same event as pointer or keyboard interaction.
💁 Possible Solution
Track an internal dirty-value state, following the patterns used by components such as text input, checkbox, and radio group.
Move change event dispatching out of the generic value setter and into user-interaction paths. Use the dirty state to control whether initialValueChanged() synchronizes the current value, and clear it during form reset.
🔦 Context
Applications commonly use change to distinguish user edits from programmatic initialization or controlled-state synchronization. The current behavior can cause duplicate updates, feedback loops, and initialization being treated as user input.
🌍 Your Environment
- OS & Device: macOS 26.6.2 on Mac
- Browser: Google Chrome 152.0.7977.83
- Version:
@fluentui/web-components3.1.2
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.