Skip to content

feat(range): report which knob moved in knob move events - #31754

Open
ShaneK wants to merge 1 commit into
feature-9.1from
FW-7492
Open

ShaneK wants to merge 1 commit into
feature-9.1from
FW-7492

Conversation

@ShaneK

@ShaneK ShaneK commented Nov 13, 2026 •

Copy link
Copy Markdown
Member

Issue number: resolves #25216


What is the current behavior?

Currently, ionKnobMoveStart and ionKnobMoveEnd only include value, so a range with dualKnobs has no way to tell you which knob the user moved.

What is the new behavior?

Both events now include knob and position in their detail. The knob field is 'A' or 'B' and stays the same if the knobs cross. The position field is 'lower' or 'upper', based on the value that knob holds before the move on start and after it on end, so dragging knob A past knob B reports lower and then upper. A single knob range always reports 'A' and 'lower'.

To report the knob on ionKnobMoveStart, we now pick it in onStart. Before this, it was picked on the first onMove, after the start event had already fired.

Does this introduce a breaking change?

  • Yes
  • No

Other information

The field names match range's existing shadow parts, where knob-a and knob-b stick with a knob and knob-lower and knob-upper swap when the knobs cross. We expose both because the issue asks for different behavior per knob, and some apps will care about the knob while others care about which value it changed.

The new types use the Range prefix like the other range types (RangeValue, RangeCustomEvent). There's a RangeKnobName and RangeKnobPosition for the field values, plus a RangeKnobMoveStartCustomEvent and RangeKnobMoveEndCustomEvent per event, the same way we added ReorderMoveCustomEvent and RefresherPullEndCustomEvent. The custom event types are exported from core and from the Angular, React and Vue packages.

We export them because otherwise RangeCustomEvent is the only typed option, and its detail is a union that includes RangeChangeEventDetail, so reading knob needs a cast:

// Without the new types
const onKnobMoveEnd = (ev: RangeCustomEvent) => {
  const { knob } = ev.detail as RangeKnobMoveEndEventDetail;
};
const handlers: Record<RangeKnobMoveEndEventDetail['knob'], () => void> = { A: moveA, B: moveB };

// With them
const onKnobMoveEnd = (ev: RangeKnobMoveEndCustomEvent) => {
  const { knob } = ev.detail;
};
const handlers: Record<RangeKnobName, () => void> = { A: moveA, B: moveB };

Tapping a range inside an ion-content with scroll-y="false" also no longer turns scrolling back on, since the tap now saves the scroll state before restoring it. This was sort of an unexpected bug fix that came along for the ride (resolves #30952)

Docs PR

ionic-team/ionic-docs#4849

@ShaneK
ShaneK requested a review from a team as a code owner November 13, 2026 21:45
@ShaneK
ShaneK requested a review from thetaPC November 13, 2026 21:45
@vercel

vercel Bot commented Nov 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
ionic-framework Ready Ready Preview Nov 13, 2026 9:45pm UTC

Request Review

This branch was successfully deployed

1 active deployment
Preview — 5984d147 Deployed Nov 13, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

package: angular @ionic/angular package package: core @ionic/core package package: react @ionic/react package package: vue @ionic/vue package

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant