Skip to content

Commit

Permalink
feat(ui5-slider): focus and keyboard handling implementation (#2614)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndeshev authored Jan 11, 2021
1 parent a12358a commit 7b78c16
Show file tree
Hide file tree
Showing 10 changed files with 458 additions and 19 deletions.
18 changes: 18 additions & 0 deletions packages/base/src/Keys.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ const isUp = event => (event.key ? (event.key === "ArrowUp" || event.key === "Up

const isDown = event => (event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && !hasModifierKeys(event);

const isLeftCtrl = event => (event.key ? (event.key === "ArrowLeft" || event.key === "Left") : event.keyCode === KeyCodes.ARROW_LEFT) && checkModifierKeys(event, true, false, false);

const isRightCtrl = event => (event.key ? (event.key === "ArrowRight" || event.key === "Right") : event.keyCode === KeyCodes.ARROW_RIGHT) && checkModifierKeys(event, true, false, false);

const isUpCtrl = event => (event.key ? (event.key === "ArrowUp" || event.key === "Up") : event.keyCode === KeyCodes.ARROW_UP) && checkModifierKeys(event, true, false, false);

const isDownCtrl = event => (event.key ? (event.key === "ArrowDown" || event.key === "Down") : event.keyCode === KeyCodes.ARROW_DOWN) && checkModifierKeys(event, true, false, false);

const isHome = event => (event.key ? event.key === "Home" : event.keyCode === KeyCodes.HOME) && !hasModifierKeys(event);

const isEnd = event => (event.key ? event.key === "End" : event.keyCode === KeyCodes.END) && !hasModifierKeys(event);
Expand Down Expand Up @@ -149,6 +157,10 @@ const isPageUpShiftCtrl = event => (event.key ? event.key === "PageUp" : event.k

const isPageDownShiftCtrl = event => (event.key ? event.key === "PageDown" : event.keyCode === KeyCodes.PAGE_DOWN) && checkModifierKeys(event, true, false, true);

const isPlus = event => (event.key ? event.key === "+" : event.keyCode === KeyCodes.PLUS) || (event.keyCode === KeyCodes.NUMPAD_PLUS && !hasModifierKeys(event));

const isMinus = event => (event.key ? event.key === "-" : event.keyCode === KeyCodes.MINUS) || (event.keyCode === KeyCodes.NUMPAD_MINUS && !hasModifierKeys(event));

const isShow = event => {
if (event.key) {
return isF4(event) || isShowByArrows(event);
Expand Down Expand Up @@ -182,8 +194,14 @@ export {
isRight,
isUp,
isDown,
isLeftCtrl,
isRightCtrl,
isUpCtrl,
isDownCtrl,
isHome,
isEnd,
isPlus,
isMinus,
isHomeCtrl,
isEndCtrl,
isEscape,
Expand Down
7 changes: 5 additions & 2 deletions packages/main/src/RangeSlider.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import Float from "@ui5/webcomponents-base/dist/types/Float.js";
import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import ResizeHandler from "@ui5/webcomponents-base/dist/delegate/ResizeHandler.js";
import SliderBase from "./SliderBase.js";

// Template
import RangeSliderTemplate from "./generated/templates/RangeSliderTemplate.lit.js";

/**
Expand Down Expand Up @@ -99,6 +98,10 @@ class RangeSlider extends SliderBase {
this.i18nBundle = getI18nBundle("@ui5/webcomponents");
}

onEnterDOM() {
ResizeHandler.register(this, this._resizeHandler);
}

get tooltipStartValue() {
const stepPrecision = this.constructor._getDecimalPrecisionOfNumber(this._effectiveStep);
return this.startValue.toFixed(stepPrecision);
Expand Down
8 changes: 7 additions & 1 deletion packages/main/src/Slider.hbs
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
{{>include "./SliderBase.hbs"}}

{{#*inline "handles"}}
<div class="ui5-slider-handle" style="{{styles.handle}}">
<div class="ui5-slider-handle"
style="{{styles.handle}}"
tabindex="{{tabIndex}}"
@focusout="{{_onfocusout}}"
@focusin="{{_onfocusin}}"
data-sap-focus-ref
>
{{#if showTooltip}}
<div class="ui5-slider-tooltip" style="{{styles.tooltip}}">
<span class="ui5-slider-tooltip-value">{{tooltipValue}}</span>
Expand Down
54 changes: 51 additions & 3 deletions packages/main/src/Slider.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import Float from "@ui5/webcomponents-base/dist/types/Float.js";
import { fetchI18nBundle, getI18nBundle } from "@ui5/webcomponents-base/dist/i18nBundle.js";
import { isEscape } from "@ui5/webcomponents-base/dist/Keys.js";
import SliderBase from "./SliderBase.js";

// Template
Expand Down Expand Up @@ -82,6 +83,7 @@ class Slider extends SliderBase {
constructor() {
super();
this._stateStorage.value = null;
this._setInitialValue("value", null);
this.i18nBundle = getI18nBundle("@ui5/webcomponents");
}

Expand Down Expand Up @@ -121,13 +123,41 @@ class Slider extends SliderBase {
const newValue = this.handleDownBase(event);
this._valueOnInteractionStart = this.value;

// Set initial value if one is not set previously on focus in.
// It will be restored if ESC key is pressed.
if (this._getInitialValue("value") === null) {
this._setInitialValue("value", this.value);
}

// Do not yet update the Slider if press is over a handle. It will be updated if the user drags the mouse.
if (!this._isHandlePressed(this.constructor.getPageXValueFromEvent(event))) {
this._updateHandleAndProgress(newValue);
this.updateValue("value", newValue);
}
}

_onfocusin(event) {
// Set initial value if one is not set previously on focus in.
// It will be restored if ESC key is pressed.
if (this._getInitialValue("value") === null) {
this._setInitialValue("value", this.value);
}
}

_onfocusout(event) {
// Prevent focusout when the focus is getting set within the slider internal
// element (on the handle), before the Slider' customElement itself is finished focusing
if (this._isFocusing()) {
this._preventFocusOut();
return;
}

// Reset focus state and the stored Slider's initial
// value that was saved when it was first focused in
this._setInitialValue("value", null);
}


/**
* Called when the user moves the slider
*
Expand Down Expand Up @@ -166,9 +196,7 @@ class Slider extends SliderBase {
* @private
*/
_isHandlePressed(clientX) {
const sliderHandle = this.shadowRoot.querySelector(".ui5-slider-handle");
const sliderHandleDomRect = sliderHandle.getBoundingClientRect();

const sliderHandleDomRect = this._sliderHandle.getBoundingClientRect();
return clientX >= sliderHandleDomRect.left && clientX <= sliderHandleDomRect.right;
}

Expand All @@ -187,6 +215,18 @@ class Slider extends SliderBase {
this._handlePositionFromStart = this._progressPercentage * 100;
}

_handleActionKeyPress(event) {
const min = this._effectiveMin;
const max = this._effectiveMax;
const currentValue = this.value;
const newValue = isEscape(event) ? this._getInitialValue("value") : this.constructor.clipValue(this._handleActionKeyPressBase(event, "value") + currentValue, min, max);

if (newValue !== currentValue) {
this._updateHandleAndProgress(newValue);
this.updateValue("value", newValue);
}
}

get styles() {
return {
progress: {
Expand All @@ -212,6 +252,10 @@ class Slider extends SliderBase {
};
}

get _sliderHandle() {
return this.shadowRoot.querySelector(".ui5-slider-handle");
}

get labelItems() {
return this._labelItems;
}
Expand All @@ -221,6 +265,10 @@ class Slider extends SliderBase {
return this.value.toFixed(stepPrecision);
}

get tabIndexProgress() {
return "-1";
}

static async onDefine() {
await fetchI18nBundle("@ui5/webcomponents");
}
Expand Down
4 changes: 3 additions & 1 deletion packages/main/src/SliderBase.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
@touchstart="{{_ontouchstart}}"
@mouseover="{{_onmouseover}}"
@mouseout="{{_onmouseout}}"
@keydown="{{_onkeydown}}"
@keyup="{{_onkeyup}}"
dir="{{effectiveDir}}"
>
<div class="ui5-slider-inner">
Expand All @@ -21,7 +23,7 @@
{{/if}}

<div class="ui5-slider-progress-container">
<div class="ui5-slider-progress" style="{{styles.progress}}"></div>
<div class="ui5-slider-progress" style="{{styles.progress}}" @focusout="{{_onfocusout}}" @focusin="{{_onfocusin}}" tabindex="{{tabIndexProgress}}"></div>
</div>
{{> handles}}
</div>
Expand Down
Loading

0 comments on commit 7b78c16

Please sign in to comment.