Skip to content

Commit 7924d58

Browse files
committed
fix(range): add focus back to the range for keyboard movements
1 parent e617be3 commit 7924d58

1 file changed

Lines changed: 16 additions & 31 deletions

File tree

core/src/components/range/range.tsx

Lines changed: 16 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export class Range implements ComponentInterface {
7373
private contentEl: HTMLElement | null = null;
7474
private initialContentScrollY = true;
7575
private originalIonInput?: EventEmitter<RangeChangeEventDetail>;
76+
private focusFromPointer = false;
7677

7778
@Element() el!: HTMLIonRangeElement;
7879

@@ -533,12 +534,6 @@ export class Range implements ComponentInterface {
533534
// update the active knob's position
534535
this.update(currentX);
535536

536-
/**
537-
* Blur the knob so focus styles are cleared.
538-
*/
539-
const knobEl = this.getKnobElement(this.pressedKnob);
540-
knobEl?.blur();
541-
542537
/**
543538
* Reset the pressed knob to undefined since the user
544539
* may start dragging a different knob in the next gesture event.
@@ -583,17 +578,6 @@ export class Range implements ComponentInterface {
583578
ratio = 1 - ratio;
584579
}
585580
this.pressedKnob = !this.dualKnobs || Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio) ? 'A' : 'B';
586-
587-
this.setFocus(this.pressedKnob);
588-
}
589-
590-
/**
591-
* Returns the DOM element for the given knob.
592-
*/
593-
private getKnobElement(knob: KnobName): HTMLElement | null {
594-
return this.el.shadowRoot?.querySelector(
595-
knob === 'A' ? '.range-knob-handle-a' : '.range-knob-handle-b'
596-
) as HTMLElement | null;
597581
}
598582

599583
private get valA() {
@@ -664,13 +648,6 @@ export class Range implements ComponentInterface {
664648
this.noUpdate = false;
665649
}
666650

667-
private setFocus(knob: KnobName) {
668-
if (this.el.shadowRoot) {
669-
const knobEl = this.getKnobElement(knob);
670-
knobEl?.focus();
671-
}
672-
}
673-
674651
private onBlur = () => {
675652
if (this.hasFocus) {
676653
this.hasFocus = false;
@@ -687,7 +664,16 @@ export class Range implements ComponentInterface {
687664
};
688665

689666
private onKnobFocus = (knob: KnobName) => {
690-
this.focusedKnob = knob;
667+
// Clicking focuses the range which is needed for the keyboard,
668+
// but we only want to add the ion-focused class when focused via Tab.
669+
if (!this.focusFromPointer) {
670+
this.focusedKnob = knob;
671+
} else {
672+
this.focusFromPointer = false;
673+
this.focusedKnob = undefined;
674+
}
675+
676+
// If the knob was not already focused, emit the focus event
691677
if (!this.hasFocus) {
692678
this.hasFocus = true;
693679
this.ionFocus.emit();
@@ -818,6 +804,9 @@ export class Range implements ComponentInterface {
818804
<div
819805
class="range-slider"
820806
ref={(rangeEl) => (this.rangeSlider = rangeEl)}
807+
onPointerDown={() => {
808+
this.focusFromPointer = true;
809+
}}
821810
/**
822811
* Since the gesture has a threshold, the value
823812
* won't change until the user has dragged past
@@ -830,6 +819,8 @@ export class Range implements ComponentInterface {
830819
* we need to listen for the "pointerUp" event.
831820
*/
832821
onPointerUp={(ev: PointerEvent) => {
822+
this.focusFromPointer = false;
823+
833824
/**
834825
* If the user drags the knob on the web
835826
* version (does not occur on mobile),
@@ -1044,12 +1035,6 @@ const renderKnob = (
10441035

10451036
return (
10461037
<div
1047-
onMouseDown={(ev) => {
1048-
/**
1049-
* Prevent the knob from being focused when the user clicks on it.
1050-
*/
1051-
ev.preventDefault();
1052-
}}
10531038
onKeyDown={(ev: KeyboardEvent) => {
10541039
const key = ev.key;
10551040
if (key === 'ArrowLeft' || key === 'ArrowDown') {

0 commit comments

Comments
 (0)