Skip to content

Commit b0570bc

Browse files
augustjkRajdeepc
andauthored
fix(slider): ensure input fires on track interaction (#5554)
* test(sp-slider): regression test for input emit from track * fix(sp-slider): ensure input is fired with track interaction * chore(sp-slider): add changeset --------- Co-authored-by: Rajdeep Chandra <[email protected]>
1 parent 158b8ec commit b0570bc

File tree

3 files changed

+107
-26
lines changed

3 files changed

+107
-26
lines changed

.changeset/quiet-cars-taste.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@spectrum-web-components/slider': patch
3+
---
4+
5+
Editable sliders will now reliably emit `input` events when interaction starts with the track.

packages/slider/src/HandleController.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,15 +121,15 @@ export class HandleController {
121121
if (!elements) return;
122122

123123
const { input } = elements;
124-
if (input.valueAsNumber === handle.value) {
125-
if (handle.dragging) {
126-
handle.dispatchInputEvent();
127-
}
128-
} else {
129-
input.valueAsNumber = handle.value;
130-
this.requestUpdate();
131-
}
124+
125+
input.valueAsNumber = handle.value;
126+
this.requestUpdate();
127+
// reset to potentially clamped value
132128
handle.value = input.valueAsNumber;
129+
130+
if (handle.dragging) {
131+
handle.dispatchInputEvent();
132+
}
133133
}
134134

135135
public handleHasChanged(handle: SliderHandle): void {

packages/slider/test/index.ts

Lines changed: 94 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -110,24 +110,22 @@ export const testEditableSlider = (type: string): void => {
110110
it('dispatches `input` of the animation frame', async () => {
111111
const inputSpy = spy();
112112
const changeSpy = spy();
113-
const el = await fixture<Slider>(
114-
html`
115-
<sp-slider
116-
editable
117-
hide-stepper
118-
min="1"
119-
max="100"
120-
step="1"
121-
label="Slider label"
122-
@input=${(event: Event & { target: Slider }) => {
123-
inputSpy(event.target.value);
124-
}}
125-
@change=${(event: Event & { target: Slider }) => {
126-
changeSpy(event.target.value);
127-
}}
128-
></sp-slider>
129-
`
130-
);
113+
const el = await fixture<Slider>(html`
114+
<sp-slider
115+
editable
116+
hide-stepper
117+
min="1"
118+
max="100"
119+
step="1"
120+
label="Slider label"
121+
@input=${(event: Event & { target: Slider }) => {
122+
inputSpy(event.target.value);
123+
}}
124+
@change=${(event: Event & { target: Slider }) => {
125+
changeSpy(event.target.value);
126+
}}
127+
></sp-slider>
128+
`);
131129
await elementUpdated(el);
132130
expect(el.value).to.equal(50.5);
133131

@@ -364,5 +362,83 @@ export const testEditableSlider = (type: string): void => {
364362
el.handleController.inputForHandle(el)
365363
);
366364
});
365+
366+
// regression test for https://github.com/adobe/spectrum-web-components/issues/5522
367+
it('dispatches `input` on track interaction after handle interaction', async () => {
368+
const inputSpy = spy();
369+
const changeSpy = spy();
370+
371+
const el = await fixture<Slider>(html`
372+
<sp-slider
373+
editable
374+
hide-stepper
375+
min="1"
376+
max="100"
377+
step="1"
378+
label="Slider label"
379+
@input=${(event: Event & { target: Slider }) => {
380+
inputSpy(event.target.value);
381+
}}
382+
@change=${(event: Event & { target: Slider }) => {
383+
changeSpy(event.target.value);
384+
}}
385+
></sp-slider>
386+
`);
387+
await elementUpdated(el);
388+
expect(el.value).to.equal(50.5);
389+
390+
expect(inputSpy.callCount, 'start clean').to.equal(0);
391+
expect(changeSpy.callCount, 'start clean').to.equal(0);
392+
393+
const handle = el.shadowRoot.querySelector(
394+
'.handle'
395+
) as HTMLDivElement;
396+
397+
const rect = handle.getBoundingClientRect();
398+
399+
// click handle once
400+
await sendMouse({
401+
steps: [
402+
{
403+
type: 'move',
404+
position: [
405+
rect.left + rect.width / 2,
406+
rect.top + rect.height / 2,
407+
],
408+
},
409+
{
410+
type: 'down',
411+
},
412+
{ type: 'up' },
413+
],
414+
});
415+
416+
await elementUpdated(el);
417+
418+
expect(changeSpy.callCount, 'one change').to.equal(1);
419+
expect(inputSpy.callCount, 'no input').to.equal(0);
420+
421+
// move to and click track once
422+
await sendMouse({
423+
steps: [
424+
{
425+
type: 'move',
426+
position: [
427+
rect.left - rect.width,
428+
rect.top + rect.height / 2,
429+
],
430+
},
431+
{
432+
type: 'down',
433+
},
434+
{ type: 'up' },
435+
],
436+
});
437+
438+
await elementUpdated(el);
439+
440+
expect(changeSpy.callCount, 'one additional change').to.equal(2);
441+
expect(inputSpy.callCount, 'one input').to.equal(1);
442+
});
367443
});
368444
};

0 commit comments

Comments
 (0)