Skip to content

Commit

Permalink
feat(ui5-wheelslider): swipe feature implementation (#1470)
Browse files Browse the repository at this point in the history
  • Loading branch information
tsanislavgatev committed Apr 14, 2020
1 parent 348bde9 commit 3665193
Show file tree
Hide file tree
Showing 4 changed files with 143 additions and 73 deletions.
8 changes: 5 additions & 3 deletions packages/main/src/TimePicker.js
Original file line number Diff line number Diff line change
Expand Up @@ -581,7 +581,7 @@ class TimePicker extends UI5Element {
}
}

_oncontainerkeydown(e) {
async _oncontainerkeydown(e) {
if (isLeft(e)) {
let expandedSliderIndex = 0;
for (let i = 0; i < this._slidersDomRefs.length; i++) {
Expand Down Expand Up @@ -610,11 +610,13 @@ class TimePicker extends UI5Element {
}

if (isTabNext(e) && e.target === this._slidersDomRefs[this._slidersDomRefs.length - 1]) {
const responsivePopover = await this._getPopover();
e.preventDefault();
this.getStaticAreaItemDomRef().querySelector(".ui5-timepicker-footer").firstElementChild.focus();
responsivePopover.querySelector(".ui5-timepicker-footer").firstElementChild.focus();
} else if (isTabPrevious(e) && e.target === this._slidersDomRefs[0]) {
const responsivePopover = await this._getPopover();
e.preventDefault();
this.getStaticAreaItemDomRef().querySelector(`.ui5-timepicker-footer`).lastElementChild.focus();
responsivePopover.querySelector(`.ui5-timepicker-footer`).lastElementChild.focus();
}
}

Expand Down
196 changes: 128 additions & 68 deletions packages/main/src/WheelSlider.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
} from "@ui5/webcomponents-base/src/Keys.js";
import "@ui5/webcomponents-icons/dist/icons/navigation-up-arrow.js";
import "@ui5/webcomponents-icons/dist/icons/navigation-down-arrow.js";
import ScrollEnablement from "@ui5/webcomponents-base/dist/delegate/ScrollEnablement.js";
import WheelSliderTemplate from "./generated/templates/WheelSliderTemplate.lit.js";
import Button from "./Button.js";

Expand Down Expand Up @@ -153,6 +154,10 @@ class WheelSlider extends UI5Element {
this._currentElementIndex = 0;
this._itemCellHeight = 0;
this._itemsToShow = [];
this._scroller = new ScrollEnablement(this);
this._scroller.attachEvent("scroll", this._updateScrolling.bind(this));
this._scroller.attachEvent("mouseup", this._handleScrollTouchEnd.bind(this));
this._scroller.attachEvent("touchend", this._handleScrollTouchEnd.bind(this));
}

onBeforeRendering() {
Expand All @@ -169,15 +174,19 @@ class WheelSlider extends UI5Element {
this._updateItemCellHeight();
}

_updateItemCellHeight() {
this._itemCellHeight = this.shadowRoot.querySelectorAll(".ui5-wheelslider-item").length && Number(getComputedStyle(this.shadowRoot.querySelector(".ui5-wheelslider-item")).getPropertyValue("--_ui5_wheelslider_item_height").replace("rem", ""));
}

static async onDefine() {
await Button.define();
}

onAfterRendering() {
if (!this._scroller.scrollContainer) {
this._scroller.scrollContainer = this.shadowRoot.querySelector(`#${this._id}--wrapper`);
}

if (!this._expanded) {
this._scroller.scrollTo(0, 0);
}

if (this._expanded) {
const elements = this.shadowRoot.querySelectorAll(".ui5-wheelslider-item");
for (let i = 0; i < elements.length; i++) {
Expand All @@ -191,25 +200,6 @@ class WheelSlider extends UI5Element {
}
}

_timesMultipliedOnCyclic() {
const minElementsInCyclicWheelSlider = 70;
const repetitionCount = Math.round(minElementsInCyclicWheelSlider / this._items.length);
const minRepetitionCount = 3;

return Math.max(minRepetitionCount, repetitionCount);
}

_buildItemsToShow() {
this._itemsToShow = this._items;
if (this.cyclic) {
if (this._itemsToShow.length < this._items.length * this._timesMultipliedOnCyclic()) {
for (let i = 0; i < this._timesMultipliedOnCyclic(); i++) {
this._itemsToShow = this._itemsToShow.concat(this._items);
}
}
}
}

get classes() {
return {
root: {
Expand All @@ -219,49 +209,56 @@ class WheelSlider extends UI5Element {
};
}

_handleWheel(e) {
if (!e) {
return;
}
expandSlider() {
this._expanded = true;
this.fireEvent("expand", {});
}

e.stopPropagation();
e.preventDefault();
collapseSlider() {
this._expanded = false;
this.fireEvent("collapse", {});
}

if (e.timeStamp === this._prevWheelTimestamp || !this._expanded) {
return;
_updateItemCellHeight() {
if (this.shadowRoot.querySelectorAll(".ui5-wheelslider-item").length) {
const itemComputedStyle = getComputedStyle(this.shadowRoot.querySelector(".ui5-wheelslider-item"));
const itemHeightValue = itemComputedStyle.getPropertyValue("--_ui5_wheelslider_item_height");
const onlyDigitsValue = itemHeightValue.replace("rem", "");

this._itemCellHeight = Number(onlyDigitsValue);
}
}

if (e.deltaY > 0) {
this._onArrowUp(e);
} else if (e.deltaY < 0) {
this._onArrowDown(e);
_updateScrolling() {
const sizeOfOneElementInPixels = this._itemCellHeight * 16,
scrollWhere = this._scroller.scrollContainer.scrollTop;
let offsetIndex;

if (!scrollWhere) {
return;
}

this._prevWheelTimestamp = e.timeStamp;
}
offsetIndex = Math.round(scrollWhere / sizeOfOneElementInPixels);

_onclick(e) {
if (!e.target.classList.contains("ui5-wheelslider-item")) {
if (this.value === this._itemsToShow[offsetIndex]) {
return;
}

if (this._expanded) {
this.value = e.target.textContent;
this._selectElement(e.target);
this.fireEvent("valueSelect", { value: this.value });
} else {
this._expanded = true;
if (this.cyclic) {
const newIndex = this._handleArrayBorderReached(offsetIndex);
if (offsetIndex !== newIndex) {
offsetIndex = newIndex;
}
}
}

expandSlider() {
this._expanded = true;
this.fireEvent("expand", {});
this.value = this._itemsToShow[offsetIndex];
this._currentElementIndex = offsetIndex;
}

collapseSlider() {
this._expanded = false;
this.fireEvent("collapse", {});
_handleScrollTouchEnd() {
if (this._expanded) {
this._selectElementByIndex(this._currentElementIndex);
}
}

_selectElement(element) {
Expand All @@ -280,28 +277,48 @@ class WheelSlider extends UI5Element {
}

_selectElementByIndex(currentIndex) {
const sliderElement = this.shadowRoot.getElementById(`${this._id}--items-list`);
const itemsCount = this._itemsToShow.length;
const itemCellHeight = this._itemCellHeight ? this._itemCellHeight : 2.875;
const offsetStep = isPhone() ? 4 : 2;
let index = currentIndex;
const itemsCount = this._itemsToShow.length;
const sizeOfCellInCompactInRem = 2;
const sizeOfCellInCozyInRem = 2.875;
const sizeOfCellInCompactInPixels = sizeOfCellInCompactInRem * 16;
const sizeOfCellInCozyInPixels = sizeOfCellInCozyInRem * 16;
const scrollBy = this.isCompact ? sizeOfCellInCompactInPixels * index : sizeOfCellInCozyInPixels * index;

if (this.cyclic) {
index = this.handleArrayBorderReached(index);
index = this._handleArrayBorderReached(index);
}

if (index < itemsCount && index > -1) {
const offsetSelectedElement = offsetStep * itemCellHeight - (index * itemCellHeight);
sliderElement.setAttribute("style", `top:${offsetSelectedElement}rem`);
this._scroller.scrollTo(0, scrollBy);
this._currentElementIndex = index;
this.value = this._items[index - (this._getCurrentRepetition() * this._items.length)];
this.fireEvent("valueSelect", { value: this.value });
}
}

handleArrayBorderReached(currentIndex) {
_timesMultipliedOnCyclic() {
const minElementsInCyclicWheelSlider = 70;
const repetitionCount = Math.round(minElementsInCyclicWheelSlider / this._items.length);
const minRepetitionCount = 3;

return Math.max(minRepetitionCount, repetitionCount);
}

_buildItemsToShow() {
this._itemsToShow = this._items;
if (this.cyclic) {
if (this._itemsToShow.length < this._items.length * this._timesMultipliedOnCyclic()) {
for (let i = 0; i < this._timesMultipliedOnCyclic(); i++) {
this._itemsToShow = this._itemsToShow.concat(this._items);
}
}
}
}

_handleArrayBorderReached(currentIndex) {
const arrayLength = this._itemsToShow.length;
const maxVisibleElementsOnOneSide = 5;
const maxVisibleElementsOnOneSide = 7;
let index = currentIndex;

if (maxVisibleElementsOnOneSide > index) {
Expand All @@ -313,29 +330,72 @@ class WheelSlider extends UI5Element {
return index;
}

_handleWheel(e) {
if (!e) {
return;
}

e.stopPropagation();
e.preventDefault();

if (e.timeStamp === this._prevWheelTimestamp || !this._expanded) {
return;
}

if (e.deltaY > 0) {
this._itemUp();
} else if (e.deltaY < 0) {
this._itemDown();
}

this._prevWheelTimestamp = e.timeStamp;
}

_onclick(e) {
if (!e.target.classList.contains("ui5-wheelslider-item")) {
return;
}

if (this._expanded) {
this.value = e.target.textContent;
this._selectElement(e.target);
this.fireEvent("valueSelect", { value: this.value });
} else {
this._expanded = true;
}
}

_onArrowDown(e) {
e.preventDefault();
const nextElementIndex = this._currentElementIndex + 1;
this._selectElementByIndex(nextElementIndex);
this._itemDown();
}

_onArrowUp(e) {
e.preventDefault();
this._itemUp();
}

_itemDown() {
const nextElementIndex = this._currentElementIndex + 1;
this._selectElementByIndex(nextElementIndex);
}

_itemUp() {
const nextElementIndex = this._currentElementIndex - 1;
this._selectElementByIndex(nextElementIndex);
}

_onkeydown(event) {
_onkeydown(е) {
if (!this._expanded) {
return;
}

if (isUp(event)) {
this._onArrowUp(event);
if (isUp(е)) {
this._onArrowUp(е);
}

if (isDown(event)) {
this._onArrowDown(event);
if (isDown(е)) {
this._onArrowDown(е);
}
}

Expand Down
8 changes: 8 additions & 0 deletions packages/main/src/themes/WheelSlider.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
padding: 0;
position: absolute;
top: var(--_ui5_wheelslider_selection_frame_margin_top);
height: 3000px;
cursor: pointer;
list-style-type: none;
}
Expand All @@ -108,6 +109,13 @@
.ui5-wheelslider-root[expanded] .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul {
list-style-type: none;
top: 0;
padding-top: calc(var(--_ui5_wheelslider_item_height) * 2);
}

.ui5-wheelslider-root.ui5-phone[expanded] .ui5-wheelslider-inner .ui5-wheelslider-wrapper > ul {
list-style-type: none;
top: 0;
padding-top: calc(var(--_ui5_wheelslider_item_height) * 4);
}

.ui5-wheelslider-root .ui5-wheelslider-inner .ui5-wheelslider-wrapper {
Expand Down
4 changes: 2 additions & 2 deletions packages/main/test/specs/WheelSlider.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ describe("Wheel Slider general interaction", () => {
const slider = browser.$("#wheelslider");
const sliderElements = slider.shadow$$(".ui5-wheelslider-item");

sliderElements[5].click();
sliderElements[3].click();

assert.strictEqual(slider.getValue(), "6", "Wheel Slider pick elements with click works");
assert.strictEqual(slider.getValue(), "4", "Wheel Slider pick elements with click works");
});
});

0 comments on commit 3665193

Please sign in to comment.