microsoft / microsoft/fluentui

[Bug]: prevent programmatic value changes from emitting change events in fluent-slider

Open
#36,714 0 comments 0 reactions 2 assignees View on GitHub

@chrisdholt is already working on this.

Since Sep 15, 2026.

Component: Slider Fluent UI WC (v3) Type: Bug :bug: web-components
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-components 3.1.2

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.