Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@better-scroll/wheel

Package Overview
Dependencies
Maintainers
3
Versions
44
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@better-scroll/wheel - npm Package Compare versions

Comparing version 2.0.7 to 2.1.0

8

dist/types/index.d.ts

@@ -23,2 +23,3 @@ import BScroll from '@better-scroll/core';

getSelectedIndex(): number;
restorePosition(): void;
}

@@ -33,2 +34,3 @@ export default class Wheel implements PluginAPI {

selectedIndex: number;
isAdjustingPosition: boolean;
target: EventTarget | null;

@@ -41,6 +43,6 @@ constructor(scroll: BScroll);

private refreshBoundary;
private handleSelectedIndex;
setSelectedIndex(index: number, contentChanged?: boolean): void;
getSelectedIndex(): number;
wheelTo(index?: number, time?: number, ease?: EaseItem): boolean;
private wheelToAfterClick;
wheelTo(index?: number, time?: number, ease?: EaseItem): void;
restorePosition(): void;
private transitionDuration;

@@ -47,0 +49,0 @@ private timeFunction;

/*!
* better-scroll / wheel
* (c) 2016-2020 ustbhuangyi
* (c) 2016-2021 ustbhuangyi
* Released under the MIT License.

@@ -22,3 +22,3 @@ */

// ios version >= 13.4 issue 982
return !!(parts[0] >= 13 && parts[1] >= 4);
return !!(parts[0] === 13 && parts[1] >= 4);
}

@@ -104,2 +104,5 @@ return false;

}
function HTMLCollectionToArray(el) {
return Array.prototype.slice.call(el, 0);
}

@@ -134,8 +137,12 @@ var ease = {

key: 'wheelTo',
name: 'wheelTo'
name: 'wheelTo',
},
{
key: 'getSelectedIndex',
name: 'getSelectedIndex'
}
name: 'getSelectedIndex',
},
{
key: 'restorePosition',
name: 'restorePosition',
},
];

@@ -145,6 +152,7 @@ var propertiesConfig = propertiesMap.map(function (item) {

key: item.key,
sourceKey: sourcePrefix + "." + item.name
sourceKey: sourcePrefix + "." + item.name,
};
});
var WHEEL_INDEX_CHANGED_EVENT_NAME = 'wheelIndexChanged';
var CONSTANTS = {

@@ -164,6 +172,7 @@ rate: 4,

this.refreshBoundary();
this.handleSelectedIndex();
this.setSelectedIndex(this.options.selectedIndex);
};
Wheel.prototype.handleBScroll = function () {
this.scroll.proxy(propertiesConfig);
this.scroll.registerType([WHEEL_INDEX_CHANGED_EVENT_NAME]);
};

@@ -186,2 +195,3 @@ Wheel.prototype.handleOptions = function () {

var _this = this;
var scroll = this.scroll;
var scroller = this.scroll.scroller;

@@ -191,12 +201,31 @@ var actionsHandler = scroller.actionsHandler, scrollBehaviorX = scroller.scrollBehaviorX, scrollBehaviorY = scroller.scrollBehaviorY, animater = scroller.animater;

// BScroll
scroll.on(scroll.eventTypes.scrollEnd, function (position) {
var index = _this.findNearestValidWheel(position.y).index;
if (scroller.animater.forceStopped && !_this.isAdjustingPosition) {
_this.target = _this.items[index];
// since stopped from an animation.
// prevent user's scrollEnd callback triggered twice
return true;
}
else {
_this.setSelectedIndex(index);
if (_this.isAdjustingPosition) {
_this.isAdjustingPosition = false;
}
}
});
// BScroll.hooks
this.scroll.hooks.on(this.scroll.hooks.eventTypes.refresh, function (content) {
if (content !== prevContent) {
prevContent = content;
_this.handleSelectedIndex();
_this.setSelectedIndex(_this.options.selectedIndex, true);
}
// check we are stop at a disable item
// rotate all wheel-items
// because position may not change
_this.rotateX(_this.scroll.y);
// check we are stop at a disable item or not
_this.wheelTo(_this.selectedIndex, 0);
});
this.scroll.hooks.on(this.scroll.hooks.eventTypes.beforeInitialScrollTo, function (position) {
// selectedIndex has a better priority than bs.options.startY
// selectedIndex has higher priority than bs.options.startY
position.x = 0;

@@ -207,8 +236,6 @@ position.y = -(_this.selectedIndex * _this.itemHeight);

scroller.hooks.on(scroller.hooks.eventTypes.checkClick, function () {
var index = Array.prototype.slice
.call(_this.items, 0)
.indexOf(_this.target);
var index = HTMLCollectionToArray(_this.items).indexOf(_this.target);
if (index === -1)
return true;
_this.wheelToAfterClick(index, _this.options.adjustTime, ease.swipe);
_this.wheelTo(index, _this.options.adjustTime, ease.swipe);
return true;

@@ -219,2 +246,11 @@ });

});
// when content is scrolling
// click wheel-item DOM repeatedly and crazily will cause scrollEnd not triggered
// so reset forceStopped
scroller.hooks.on(scroller.hooks.eventTypes.minDistanceScroll, function () {
var animater = scroller.animater;
if (animater.forceStopped === true) {
animater.forceStopped = false;
}
});
scroller.hooks.on(scroller.hooks.eventTypes.scrollToElement, function (el, pos) {

@@ -263,3 +299,2 @@ if (!hasClass(el, _this.options.wheelItemClass)) {

momentumInfo.duration = _this.options.adjustTime;
_this.selectedIndex = validWheel.index;
});

@@ -273,17 +308,7 @@ // Animater

});
animater.hooks.on(animater.hooks.eventTypes.beforeForceStop, function (_a) {
var y = _a.y;
_this.target = _this.items[_this.findNearestValidWheel(y).index];
// don't dispatch scrollEnd when forceStop from transition or animation
return true;
});
// bs.stop() to make wheel stop at a correct position
// bs.stop() to make wheel stop at a correct position when pending
animater.hooks.on(animater.hooks.eventTypes.callStop, function () {
var index = Array.prototype.slice
.call(_this.items, 0)
.indexOf(_this.target);
if (index > 0) {
var y = -(index * _this.itemHeight);
animater.translate({ x: 0, y: y });
}
var index = _this.findNearestValidWheel(_this.scroll.y).index;
_this.isAdjustingPosition = true;
_this.wheelTo(index, 0);
});

@@ -293,3 +318,2 @@ // Translater

_this.rotateX(endPoint.y);
_this.selectedIndex = _this.findNearestValidWheel(endPoint.y).index;
});

@@ -302,4 +326,10 @@ };

};
Wheel.prototype.handleSelectedIndex = function () {
this.selectedIndex = this.options.selectedIndex;
Wheel.prototype.setSelectedIndex = function (index, contentChanged) {
if (contentChanged === void 0) { contentChanged = false; }
var prevSelectedIndex = this.selectedIndex;
this.selectedIndex = index;
// if content DOM changed, should not trigger event
if (prevSelectedIndex !== index && !contentChanged) {
this.scroll.trigger(WHEEL_INDEX_CHANGED_EVENT_NAME, index);
}
};

@@ -313,15 +343,11 @@ Wheel.prototype.getSelectedIndex = function () {

var y = -index * this.itemHeight;
var currentY = Math.round(this.scroll.y);
this.scroll.scrollTo(0, y, time, ease);
return y === currentY;
};
Wheel.prototype.wheelToAfterClick = function (index, time, ease) {
if (index === void 0) { index = 0; }
if (time === void 0) { time = 0; }
var needDispatchScrollEnd = this.wheelTo(index, time, ease);
// startpoint === endpoint
// manually trigger scrollEnd
if (needDispatchScrollEnd) {
var hooks = this.scroll.scroller.hooks;
hooks.trigger(hooks.eventTypes.scrollEnd);
Wheel.prototype.restorePosition = function () {
// bs is scrolling
var isPending = this.scroll.pending;
if (isPending) {
var selectedIndex = this.getSelectedIndex();
this.scroll.scroller.animater.clearTimer();
this.wheelTo(selectedIndex, 0);
}

@@ -356,3 +382,3 @@ };

.wheelDisabledItemClass;
// Impersonation web native select
// implement web native select element
// first, check whether there is a enable item whose index is smaller than currentIndex

@@ -380,3 +406,3 @@ // then, check whether there is a enable item whose index is bigger than currentIndex

}
// when all the items are disabled, this.selectedIndex should always be -1
// when all the items are disabled, selectedIndex should always be -1
return {

@@ -383,0 +409,0 @@ index: this.wheelItemsAllDisabled ? -1 : currentIndex,

/*!
* better-scroll / wheel
* (c) 2016-2020 ustbhuangyi
* (c) 2016-2021 ustbhuangyi
* Released under the MIT License.

@@ -28,3 +28,3 @@ */

// ios version >= 13.4 issue 982
return !!(parts[0] >= 13 && parts[1] >= 4);
return !!(parts[0] === 13 && parts[1] >= 4);
}

@@ -110,2 +110,5 @@ return false;

}
function HTMLCollectionToArray(el) {
return Array.prototype.slice.call(el, 0);
}

@@ -140,8 +143,12 @@ var ease = {

key: 'wheelTo',
name: 'wheelTo'
name: 'wheelTo',
},
{
key: 'getSelectedIndex',
name: 'getSelectedIndex'
}
name: 'getSelectedIndex',
},
{
key: 'restorePosition',
name: 'restorePosition',
},
];

@@ -151,6 +158,7 @@ var propertiesConfig = propertiesMap.map(function (item) {

key: item.key,
sourceKey: sourcePrefix + "." + item.name
sourceKey: sourcePrefix + "." + item.name,
};
});
var WHEEL_INDEX_CHANGED_EVENT_NAME = 'wheelIndexChanged';
var CONSTANTS = {

@@ -170,6 +178,7 @@ rate: 4,

this.refreshBoundary();
this.handleSelectedIndex();
this.setSelectedIndex(this.options.selectedIndex);
};
Wheel.prototype.handleBScroll = function () {
this.scroll.proxy(propertiesConfig);
this.scroll.registerType([WHEEL_INDEX_CHANGED_EVENT_NAME]);
};

@@ -192,2 +201,3 @@ Wheel.prototype.handleOptions = function () {

var _this = this;
var scroll = this.scroll;
var scroller = this.scroll.scroller;

@@ -197,12 +207,31 @@ var actionsHandler = scroller.actionsHandler, scrollBehaviorX = scroller.scrollBehaviorX, scrollBehaviorY = scroller.scrollBehaviorY, animater = scroller.animater;

// BScroll
scroll.on(scroll.eventTypes.scrollEnd, function (position) {
var index = _this.findNearestValidWheel(position.y).index;
if (scroller.animater.forceStopped && !_this.isAdjustingPosition) {
_this.target = _this.items[index];
// since stopped from an animation.
// prevent user's scrollEnd callback triggered twice
return true;
}
else {
_this.setSelectedIndex(index);
if (_this.isAdjustingPosition) {
_this.isAdjustingPosition = false;
}
}
});
// BScroll.hooks
this.scroll.hooks.on(this.scroll.hooks.eventTypes.refresh, function (content) {
if (content !== prevContent) {
prevContent = content;
_this.handleSelectedIndex();
_this.setSelectedIndex(_this.options.selectedIndex, true);
}
// check we are stop at a disable item
// rotate all wheel-items
// because position may not change
_this.rotateX(_this.scroll.y);
// check we are stop at a disable item or not
_this.wheelTo(_this.selectedIndex, 0);
});
this.scroll.hooks.on(this.scroll.hooks.eventTypes.beforeInitialScrollTo, function (position) {
// selectedIndex has a better priority than bs.options.startY
// selectedIndex has higher priority than bs.options.startY
position.x = 0;

@@ -213,8 +242,6 @@ position.y = -(_this.selectedIndex * _this.itemHeight);

scroller.hooks.on(scroller.hooks.eventTypes.checkClick, function () {
var index = Array.prototype.slice
.call(_this.items, 0)
.indexOf(_this.target);
var index = HTMLCollectionToArray(_this.items).indexOf(_this.target);
if (index === -1)
return true;
_this.wheelToAfterClick(index, _this.options.adjustTime, ease.swipe);
_this.wheelTo(index, _this.options.adjustTime, ease.swipe);
return true;

@@ -225,2 +252,11 @@ });

});
// when content is scrolling
// click wheel-item DOM repeatedly and crazily will cause scrollEnd not triggered
// so reset forceStopped
scroller.hooks.on(scroller.hooks.eventTypes.minDistanceScroll, function () {
var animater = scroller.animater;
if (animater.forceStopped === true) {
animater.forceStopped = false;
}
});
scroller.hooks.on(scroller.hooks.eventTypes.scrollToElement, function (el, pos) {

@@ -269,3 +305,2 @@ if (!hasClass(el, _this.options.wheelItemClass)) {

momentumInfo.duration = _this.options.adjustTime;
_this.selectedIndex = validWheel.index;
});

@@ -279,17 +314,7 @@ // Animater

});
animater.hooks.on(animater.hooks.eventTypes.beforeForceStop, function (_a) {
var y = _a.y;
_this.target = _this.items[_this.findNearestValidWheel(y).index];
// don't dispatch scrollEnd when forceStop from transition or animation
return true;
});
// bs.stop() to make wheel stop at a correct position
// bs.stop() to make wheel stop at a correct position when pending
animater.hooks.on(animater.hooks.eventTypes.callStop, function () {
var index = Array.prototype.slice
.call(_this.items, 0)
.indexOf(_this.target);
if (index > 0) {
var y = -(index * _this.itemHeight);
animater.translate({ x: 0, y: y });
}
var index = _this.findNearestValidWheel(_this.scroll.y).index;
_this.isAdjustingPosition = true;
_this.wheelTo(index, 0);
});

@@ -299,3 +324,2 @@ // Translater

_this.rotateX(endPoint.y);
_this.selectedIndex = _this.findNearestValidWheel(endPoint.y).index;
});

@@ -308,4 +332,10 @@ };

};
Wheel.prototype.handleSelectedIndex = function () {
this.selectedIndex = this.options.selectedIndex;
Wheel.prototype.setSelectedIndex = function (index, contentChanged) {
if (contentChanged === void 0) { contentChanged = false; }
var prevSelectedIndex = this.selectedIndex;
this.selectedIndex = index;
// if content DOM changed, should not trigger event
if (prevSelectedIndex !== index && !contentChanged) {
this.scroll.trigger(WHEEL_INDEX_CHANGED_EVENT_NAME, index);
}
};

@@ -319,15 +349,11 @@ Wheel.prototype.getSelectedIndex = function () {

var y = -index * this.itemHeight;
var currentY = Math.round(this.scroll.y);
this.scroll.scrollTo(0, y, time, ease);
return y === currentY;
};
Wheel.prototype.wheelToAfterClick = function (index, time, ease) {
if (index === void 0) { index = 0; }
if (time === void 0) { time = 0; }
var needDispatchScrollEnd = this.wheelTo(index, time, ease);
// startpoint === endpoint
// manually trigger scrollEnd
if (needDispatchScrollEnd) {
var hooks = this.scroll.scroller.hooks;
hooks.trigger(hooks.eventTypes.scrollEnd);
Wheel.prototype.restorePosition = function () {
// bs is scrolling
var isPending = this.scroll.pending;
if (isPending) {
var selectedIndex = this.getSelectedIndex();
this.scroll.scroller.animater.clearTimer();
this.wheelTo(selectedIndex, 0);
}

@@ -362,3 +388,3 @@ };

.wheelDisabledItemClass;
// Impersonation web native select
// implement web native select element
// first, check whether there is a enable item whose index is smaller than currentIndex

@@ -386,3 +412,3 @@ // then, check whether there is a enable item whose index is bigger than currentIndex

}
// when all the items are disabled, this.selectedIndex should always be -1
// when all the items are disabled, selectedIndex should always be -1
return {

@@ -389,0 +415,0 @@ index: this.wheelItemsAllDisabled ? -1 : currentIndex,

@@ -1,1 +0,1 @@

!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Wheel=t()}(this,function(){"use strict";var n="undefined"!=typeof window,o=n&&navigator.userAgent.toLowerCase(),s=(o&&/wechatdevtools/.test(o),o&&o.indexOf("android"),function(){if("string"!=typeof o)return;var e=/os (\d\d?_\d(_\d)?)/.exec(o);if(!e)return;var t=e[1].split("_").map(function(e){return parseInt(e,10)});13<=t[0]&&t[1]}(),n&&document.createElement("div").style),t=function(){if(!n)return!1;for(var e=0,t=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];e<t.length;e++){var o=t[e];if(void 0!==s[o.value])return o.key}return!1}();function e(e){return!1===t?e:"standard"===t?"transitionEnd"===e?"transitionend":e:t+e.charAt(0).toUpperCase()+e.substr(1)}t&&"standard"!==t&&t.toLowerCase();var i=e("transform"),r=(e("transition"),n&&e("perspective")in s,i),l=e("transitionTimingFunction"),a=e("transitionDuration");e("transitionDelay"),e("transformOrigin"),e("transitionEnd"),e("transitionProperty");function h(e,t){return new RegExp("(^|\\s)"+t+"(\\s|$)").test(e.className)}var c={style:"cubic-bezier(0.23, 1, 0.32, 1)",fn:function(e){return 1+--e*e*e*e*e}},d=[{key:"wheelTo",name:"wheelTo"},{key:"getSelectedIndex",name:"getSelectedIndex"}].map(function(e){return{key:e.key,sourceKey:"plugins.wheel."+e.name}}),u=4;function f(e){this.scroll=e,this.init()}return f.prototype.init=function(){this.handleBScroll(),this.handleOptions(),this.handleHooks(),this.refreshBoundary(),this.handleSelectedIndex()},f.prototype.handleBScroll=function(){this.scroll.proxy(d)},f.prototype.handleOptions=function(){var e=!0===this.scroll.options.wheel?{}:this.scroll.options.wheel;this.options=function(e,t){for(var o in t)e[o]=t[o];return e}({wheelWrapperClass:"wheel-scroll",wheelItemClass:"wheel-item",rotate:25,adjustTime:400,selectedIndex:0,wheelDisabledItemClass:"wheel-disabled-item"},e)},f.prototype.handleHooks=function(){var o=this,e=this.scroll.scroller,t=e.actionsHandler,n=e.scrollBehaviorX,s=e.scrollBehaviorY,i=e.animater,r=e.content;this.scroll.hooks.on(this.scroll.hooks.eventTypes.refresh,function(e){e!==r&&(r=e,o.handleSelectedIndex()),o.wheelTo(o.selectedIndex,0)}),this.scroll.hooks.on(this.scroll.hooks.eventTypes.beforeInitialScrollTo,function(e){e.x=0,e.y=-(o.selectedIndex*o.itemHeight)}),e.hooks.on(e.hooks.eventTypes.checkClick,function(){var e=Array.prototype.slice.call(o.items,0).indexOf(o.target);return-1===e||o.wheelToAfterClick(e,o.options.adjustTime,c),!0}),e.hooks.on(e.hooks.eventTypes.scrollTo,function(e){e.y=o.findNearestValidWheel(e.y).y}),e.hooks.on(e.hooks.eventTypes.scrollToElement,function(e,t){return!h(e,o.options.wheelItemClass)||void(t.top=o.findNearestValidWheel(t.top).y)}),t.hooks.on(t.hooks.eventTypes.beforeStart,function(e){o.target=e.target}),n.hooks.on(n.hooks.eventTypes.computeBoundary,function(e){e.maxScrollPos=0,e.minScrollPos=0}),s.hooks.on(s.hooks.eventTypes.computeBoundary,function(e){o.items=o.scroll.scroller.content.children,o.checkWheelAllDisabled(),o.itemHeight=0<o.items.length?s.contentSize/o.items.length:0,e.maxScrollPos=-o.itemHeight*(o.items.length-1),e.minScrollPos=0}),s.hooks.on(s.hooks.eventTypes.momentum,function(e,t){e.rate=u,e.destination=o.findNearestValidWheel(e.destination).y;t<1e3&&(e.duration=Math.max(800,t/1e3*o.scroll.options.swipeTime))}),s.hooks.on(s.hooks.eventTypes.end,function(e){var t=o.findNearestValidWheel(s.currentPos);e.destination=t.y,e.duration=o.options.adjustTime,o.selectedIndex=t.index}),i.hooks.on(i.hooks.eventTypes.time,function(e){o.transitionDuration(e)}),i.hooks.on(i.hooks.eventTypes.timeFunction,function(e){o.timeFunction(e)}),i.hooks.on(i.hooks.eventTypes.beforeForceStop,function(e){var t=e.y;return o.target=o.items[o.findNearestValidWheel(t).index],!0}),i.hooks.on(i.hooks.eventTypes.callStop,function(){var e,t=Array.prototype.slice.call(o.items,0).indexOf(o.target);0<t&&(e=-(t*o.itemHeight),i.translate({x:0,y:e}))}),i.translater.hooks.on(i.translater.hooks.eventTypes.translate,function(e){o.rotateX(e.y),o.selectedIndex=o.findNearestValidWheel(e.y).index})},f.prototype.refreshBoundary=function(){var e=this.scroll.scroller,t=e.scrollBehaviorX,o=e.scrollBehaviorY,n=e.content;t.refresh(n),o.refresh(n)},f.prototype.handleSelectedIndex=function(){this.selectedIndex=this.options.selectedIndex},f.prototype.getSelectedIndex=function(){return this.selectedIndex},f.prototype.wheelTo=function(e,t,o){void 0===e&&(e=0),void 0===t&&(t=0);var n=-e*this.itemHeight,s=Math.round(this.scroll.y);return this.scroll.scrollTo(0,n,t,o),n===s},f.prototype.wheelToAfterClick=function(e,t,o){var n;void 0===e&&(e=0),void 0===t&&(t=0),this.wheelTo(e,t,o)&&(n=this.scroll.scroller.hooks).trigger(n.eventTypes.scrollEnd)},f.prototype.transitionDuration=function(e){for(var t=0;t<this.items.length;t++)this.items[t].style[a]=e+"ms"},f.prototype.timeFunction=function(e){for(var t=0;t<this.items.length;t++)this.items[t].style[l]=e},f.prototype.rotateX=function(e){for(var t=this.options.rotate,o=void 0===t?25:t,n=0;n<this.items.length;n++){var s=(o*(e/this.itemHeight+n)).toFixed(3);this.items[n].style[r]="rotateX("+s+"deg)"}},f.prototype.findNearestValidWheel=function(e){e=0<e?0:e<this.scroll.maxScrollY?this.scroll.maxScrollY:e;for(var t=Math.abs(Math.round(-e/this.itemHeight)),o=t,n=this.items,s=this.options.wheelDisabledItemClass;0<=t&&h(n[t],s);)t--;if(t<0)for(t=o;t<=n.length-1&&h(n[t],s);)t++;return t===n.length&&(t=o),{index:this.wheelItemsAllDisabled?-1:t,y:-t*this.itemHeight}},f.prototype.checkWheelAllDisabled=function(){var e=this.options.wheelDisabledItemClass,t=this.items;this.wheelItemsAllDisabled=!0;for(var o=0;o<t.length;o++)if(!h(t[o],e)){this.wheelItemsAllDisabled=!1;break}},f.pluginName="wheel",f});
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e="undefined"!=typeof globalThis?globalThis:e||self).Wheel=t()}(this,function(){"use strict";var n="undefined"!=typeof window,o=n&&navigator.userAgent.toLowerCase(),s=(o&&/wechatdevtools/.test(o),o&&o.indexOf("android"),function(){if("string"!=typeof o)return;var e=/os (\d\d?_\d(_\d)?)/.exec(o);if(!e)return;var t=e[1].split("_").map(function(e){return parseInt(e,10)});13===t[0]&&t[1]}(),n&&document.createElement("div").style),t=function(){if(!n)return!1;for(var e=0,t=[{key:"standard",value:"transform"},{key:"webkit",value:"webkitTransform"},{key:"Moz",value:"MozTransform"},{key:"O",value:"OTransform"},{key:"ms",value:"msTransform"}];e<t.length;e++){var o=t[e];if(void 0!==s[o.value])return o.key}return!1}();function e(e){return!1===t?e:"standard"===t?"transitionEnd"===e?"transitionend":e:t+e.charAt(0).toUpperCase()+e.substr(1)}t&&"standard"!==t&&t.toLowerCase();var i=e("transform"),r=(e("transition"),n&&e("perspective")in s,i),l=e("transitionTimingFunction"),a=e("transitionDuration");e("transitionDelay"),e("transformOrigin"),e("transitionEnd"),e("transitionProperty");function h(e,t){return new RegExp("(^|\\s)"+t+"(\\s|$)").test(e.className)}var c={style:"cubic-bezier(0.23, 1, 0.32, 1)",fn:function(e){return 1+--e*e*e*e*e}},d=[{key:"wheelTo",name:"wheelTo"},{key:"getSelectedIndex",name:"getSelectedIndex"},{key:"restorePosition",name:"restorePosition"}].map(function(e){return{key:e.key,sourceKey:"plugins.wheel."+e.name}}),u="wheelIndexChanged",f=4;function p(e){this.scroll=e,this.init()}return p.prototype.init=function(){this.handleBScroll(),this.handleOptions(),this.handleHooks(),this.refreshBoundary(),this.setSelectedIndex(this.options.selectedIndex)},p.prototype.handleBScroll=function(){this.scroll.proxy(d),this.scroll.registerType([u])},p.prototype.handleOptions=function(){var e=!0===this.scroll.options.wheel?{}:this.scroll.options.wheel;this.options=function(e,t){for(var o in t)e[o]=t[o];return e}({wheelWrapperClass:"wheel-scroll",wheelItemClass:"wheel-item",rotate:25,adjustTime:400,selectedIndex:0,wheelDisabledItemClass:"wheel-disabled-item"},e)},p.prototype.handleHooks=function(){var o=this,e=this.scroll,n=this.scroll.scroller,t=n.actionsHandler,s=n.scrollBehaviorX,i=n.scrollBehaviorY,r=n.animater,l=n.content;e.on(e.eventTypes.scrollEnd,function(e){var t=o.findNearestValidWheel(e.y).index;if(n.animater.forceStopped&&!o.isAdjustingPosition)return o.target=o.items[t],!0;o.setSelectedIndex(t),o.isAdjustingPosition&&(o.isAdjustingPosition=!1)}),this.scroll.hooks.on(this.scroll.hooks.eventTypes.refresh,function(e){e!==l&&(l=e,o.setSelectedIndex(o.options.selectedIndex,!0)),o.rotateX(o.scroll.y),o.wheelTo(o.selectedIndex,0)}),this.scroll.hooks.on(this.scroll.hooks.eventTypes.beforeInitialScrollTo,function(e){e.x=0,e.y=-(o.selectedIndex*o.itemHeight)}),n.hooks.on(n.hooks.eventTypes.checkClick,function(){var e,t=(e=o.items,Array.prototype.slice.call(e,0).indexOf(o.target));return-1===t||o.wheelTo(t,o.options.adjustTime,c),!0}),n.hooks.on(n.hooks.eventTypes.scrollTo,function(e){e.y=o.findNearestValidWheel(e.y).y}),n.hooks.on(n.hooks.eventTypes.minDistanceScroll,function(){var e=n.animater;!0===e.forceStopped&&(e.forceStopped=!1)}),n.hooks.on(n.hooks.eventTypes.scrollToElement,function(e,t){return!h(e,o.options.wheelItemClass)||void(t.top=o.findNearestValidWheel(t.top).y)}),t.hooks.on(t.hooks.eventTypes.beforeStart,function(e){o.target=e.target}),s.hooks.on(s.hooks.eventTypes.computeBoundary,function(e){e.maxScrollPos=0,e.minScrollPos=0}),i.hooks.on(i.hooks.eventTypes.computeBoundary,function(e){o.items=o.scroll.scroller.content.children,o.checkWheelAllDisabled(),o.itemHeight=0<o.items.length?i.contentSize/o.items.length:0,e.maxScrollPos=-o.itemHeight*(o.items.length-1),e.minScrollPos=0}),i.hooks.on(i.hooks.eventTypes.momentum,function(e,t){e.rate=f,e.destination=o.findNearestValidWheel(e.destination).y;t<1e3&&(e.duration=Math.max(800,t/1e3*o.scroll.options.swipeTime))}),i.hooks.on(i.hooks.eventTypes.end,function(e){var t=o.findNearestValidWheel(i.currentPos);e.destination=t.y,e.duration=o.options.adjustTime}),r.hooks.on(r.hooks.eventTypes.time,function(e){o.transitionDuration(e)}),r.hooks.on(r.hooks.eventTypes.timeFunction,function(e){o.timeFunction(e)}),r.hooks.on(r.hooks.eventTypes.callStop,function(){var e=o.findNearestValidWheel(o.scroll.y).index;o.isAdjustingPosition=!0,o.wheelTo(e,0)}),r.translater.hooks.on(r.translater.hooks.eventTypes.translate,function(e){o.rotateX(e.y)})},p.prototype.refreshBoundary=function(){var e=this.scroll.scroller,t=e.scrollBehaviorX,o=e.scrollBehaviorY,n=e.content;t.refresh(n),o.refresh(n)},p.prototype.setSelectedIndex=function(e,t){void 0===t&&(t=!1),this.selectedIndex===(this.selectedIndex=e)||t||this.scroll.trigger(u,e)},p.prototype.getSelectedIndex=function(){return this.selectedIndex},p.prototype.wheelTo=function(e,t,o){void 0===e&&(e=0),void 0===t&&(t=0);var n=-e*this.itemHeight;this.scroll.scrollTo(0,n,t,o)},p.prototype.restorePosition=function(){var e;this.scroll.pending&&(e=this.getSelectedIndex(),this.scroll.scroller.animater.clearTimer(),this.wheelTo(e,0))},p.prototype.transitionDuration=function(e){for(var t=0;t<this.items.length;t++)this.items[t].style[a]=e+"ms"},p.prototype.timeFunction=function(e){for(var t=0;t<this.items.length;t++)this.items[t].style[l]=e},p.prototype.rotateX=function(e){for(var t=this.options.rotate,o=void 0===t?25:t,n=0;n<this.items.length;n++){var s=(o*(e/this.itemHeight+n)).toFixed(3);this.items[n].style[r]="rotateX("+s+"deg)"}},p.prototype.findNearestValidWheel=function(e){e=0<e?0:e<this.scroll.maxScrollY?this.scroll.maxScrollY:e;for(var t=Math.abs(Math.round(-e/this.itemHeight)),o=t,n=this.items,s=this.options.wheelDisabledItemClass;0<=t&&h(n[t],s);)t--;if(t<0)for(t=o;t<=n.length-1&&h(n[t],s);)t++;return t===n.length&&(t=o),{index:this.wheelItemsAllDisabled?-1:t,y:-t*this.itemHeight}},p.prototype.checkWheelAllDisabled=function(){var e=this.options.wheelDisabledItemClass,t=this.items;this.wheelItemsAllDisabled=!0;for(var o=0;o<t.length;o++)if(!h(t[o],e)){this.wheelItemsAllDisabled=!1;break}},p.pluginName="wheel",p});
{
"name": "@better-scroll/wheel",
"version": "2.0.7",
"version": "2.1.0",
"description": "a BetterScroll plugin to imitate IOS Picker",

@@ -32,5 +32,5 @@ "author": {

"dependencies": {
"@better-scroll/core": "^2.0.7"
"@better-scroll/core": "^2.1.0"
},
"gitHead": "6f3a78b8563219def89c836421a6bb55229a4794"
"gitHead": "29312b14a1762be5656419c9d7e9b498ec8cb34d"
}

@@ -47,2 +47,6 @@ import BScroll, { Boundary } from '@better-scroll/core'

},
{
key: 'restorePosition',
sourceKey: 'plugins.wheel.restorePosition',
},
])

@@ -122,2 +126,11 @@ })

expect(wheel.wheelTo).toHaveBeenCalledWith(0, 400, expect.anything())
// if target element is not found
addPropertiesToWheel(wheel, {
items: [div],
target: null,
wheelTo: jest.fn(),
})
let ret = scroll.scroller.hooks.trigger('checkClick')
expect(ret).toBe(true)
})

@@ -157,2 +170,20 @@

})
// mismatch target element
let div1 = document.createElement('div')
let pos1 = {
top: -40,
left: 0,
}
addPropertiesToWheel(wheel, {
items: [div1],
target: div1,
itemHeight: 40,
})
let ret = scroll.scroller.hooks.trigger('scrollToElement', div1, pos1)
expect(ret).toBe(true)
expect(pos1).toMatchObject({
top: -40,
left: 0,
})
})

@@ -229,16 +260,51 @@

})
scroll.scroller.scrollBehaviorY.hooks.trigger('momentum', momentumInfo, 800)
expect(momentumInfo).toEqual({
destination: -0,
rate: 4,
duration: 2000,
})
})
it('should change target when scroll.scroller.animater trigger beforeForceStop hook', () => {
it('scroll.hooks.refresh ', () => {
let newContent = document.createElement('p')
let div = document.createElement('div')
addPropertiesToWheel(wheel, {
items: [div],
target: div,
itemHeight: 40,
wheelItemsAllDisabled: false,
})
scroll.scroller.animater.hooks.trigger('beforeForceStop', { x: 0, y: -20 })
expect(wheel.target).toEqual(div)
wheel.options.selectedIndex = 1
scroll.hooks.trigger(scroll.hooks.eventTypes.refresh, newContent)
expect(scroll.scrollTo).toBeCalledWith(0, -40, 0, undefined)
})
it('should stop at correct position when callStop hook is trigger', () => {
it('scroll.scroller.animater.hooks.time ', () => {
let div = document.createElement('div')
addPropertiesToWheel(wheel, {
items: [div],
})
const animater = scroll.scroller.animater
animater.hooks.trigger(animater.hooks.eventTypes.time, 100)
expect(div.style.transitionDuration).toBe('100ms')
})
it('scroll.scroller.animater.hooks.timeFunction ', () => {
let div = document.createElement('div')
addPropertiesToWheel(wheel, {
items: [div],
})
const animater = scroll.scroller.animater
animater.hooks.trigger(
animater.hooks.eventTypes.timeFunction,
'cubic-bezier(0.23, 1, 0.32, 1)'
)
expect(div.style.transitionTimingFunction).toBe(
'cubic-bezier(0.23, 1, 0.32, 1)'
)
})
it('scroll.scroller.animater.hooks.callStop', () => {
let div1 = document.createElement('div')

@@ -248,15 +314,12 @@ let div2 = document.createElement('div')

items: [div1, div2],
target: div2,
itemHeight: 40,
wheelItemsAllDisabled: false,
})
scroll.y = -41
scroll.maxScrollY = -80
scroll.scroller.animater.hooks.trigger('callStop')
expect(wheel.target).toEqual(div2)
expect(scroll.scroller.animater.translate).toBeCalledWith({
x: 0,
y: -40,
})
expect(scroll.scrollTo).toBeCalledWith(0, -40, 0, undefined)
})
it('should change selectedIndex when scroll.scroller.animater.translater trigger translate hook', () => {
it('scroll.scroller.animater.translater.hooks.translate', () => {
let div = document.createElement('div')

@@ -268,4 +331,4 @@ addPropertiesToWheel(wheel, {

})
scroll.scroller.animater.translater.hooks.trigger('translate', {
const translater = scroll.scroller.animater.translater
translater.hooks.trigger(translater.hooks.eventTypes.translate, {
x: 0,

@@ -276,2 +339,80 @@ y: -20,

})
it('scroll.scroller.hooks.minDistanceScroll ', () => {
let div = document.createElement('div')
addPropertiesToWheel(wheel, {
items: [div],
})
const scroller = scroll.scroller
scroller.animater.forceStopped = true
scroller.hooks.trigger(scroller.hooks.eventTypes.minDistanceScroll)
expect(scroller.animater.forceStopped).toBe(false)
})
it('scrollEnd event', () => {
let div1 = document.createElement('div')
let div2 = document.createElement('div')
addPropertiesToWheel(wheel, {
itemHeight: 40,
items: [div1, div2],
})
scroll.maxScrollY = -80
scroll.scroller.animater.forceStopped = true
// stopped from an animation,
// prevent user's scrollEnd callback triggered twice
const ret = scroll.trigger(scroll.eventTypes.scrollEnd, { y: 0 })
expect(ret).toBe(true)
wheel.isAdjustingPosition = true
// update selectedIndex
scroll.trigger(scroll.eventTypes.scrollEnd, { y: -41 })
expect(wheel.getSelectedIndex()).toBe(1)
expect(wheel.isAdjustingPosition).toBe(false)
})
it('wheel.restorePosition()', () => {
addPropertiesToWheel(wheel, {
itemHeight: 40,
})
// simulate bs is scrolling
scroll.pending = true
wheel.restorePosition()
expect(scroll.scroller.animater.clearTimer).toBeCalled()
expect(scroll.scrollTo).toBeCalledWith(0, -0, 0, undefined)
})
it('should support disable wheel items', () => {
let div1 = document.createElement('div')
let div2 = document.createElement('div')
const scroller = scroll.scroller
const position = { y: -41 }
addPropertiesToWheel(wheel, {
items: [div1, div2],
itemHeight: 40,
wheelItemsAllDisabled: false,
})
scroll.y = -41
scroll.maxScrollY = -80
div2.className = 'wheel-disabled-item'
scroller.hooks.trigger(scroller.hooks.eventTypes.scrollTo, position)
expect(position.y).toBe(-0)
div1.className = 'wheel-disabled-item'
wheel.wheelItemsAllDisabled = true
scroller.hooks.trigger(scroller.hooks.eventTypes.scrollTo, position)
expect(position.y).toBe(-0)
let div3 = document.createElement('div')
let position3 = {
y: -39,
}
addPropertiesToWheel(wheel, {
items: [div1, div2, div3],
itemHeight: 40,
wheelItemsAllDisabled: false,
})
scroller.hooks.trigger(scroller.hooks.eventTypes.scrollTo, position3)
expect(position3.y).toBe(-80)
})
})

@@ -8,2 +8,4 @@ import BScroll, { Boundary } from '@better-scroll/core'

extend,
Position,
HTMLCollectionToArray,
} from '@better-scroll/shared-utils'

@@ -14,2 +16,4 @@ import propertiesConfig from './propertiesConfig'

const WHEEL_INDEX_CHANGED_EVENT_NAME = 'wheelIndexChanged'
export interface WheelConfig {

@@ -36,2 +40,3 @@ selectedIndex: number

getSelectedIndex(): number
restorePosition(): void
}

@@ -49,2 +54,3 @@

selectedIndex: number
isAdjustingPosition: boolean
target: EventTarget | null

@@ -61,3 +67,3 @@ constructor(public scroll: BScroll) {

this.refreshBoundary()
this.handleSelectedIndex()
this.setSelectedIndex(this.options.selectedIndex)
}

@@ -67,2 +73,3 @@

this.scroll.proxy(propertiesConfig)
this.scroll.registerType([WHEEL_INDEX_CHANGED_EVENT_NAME])
}

@@ -87,2 +94,3 @@

private handleHooks() {
const scroll = this.scroll
const scroller = this.scroll.scroller

@@ -97,2 +105,17 @@ const {

// BScroll
scroll.on(scroll.eventTypes.scrollEnd, (position: Position) => {
const index = this.findNearestValidWheel(position.y).index
if (scroller.animater.forceStopped && !this.isAdjustingPosition) {
this.target = this.items[index]
// since stopped from an animation.
// prevent user's scrollEnd callback triggered twice
return true
} else {
this.setSelectedIndex(index)
if (this.isAdjustingPosition) {
this.isAdjustingPosition = false
}
}
})
// BScroll.hooks
this.scroll.hooks.on(

@@ -103,5 +126,8 @@ this.scroll.hooks.eventTypes.refresh,

prevContent = content
this.handleSelectedIndex()
this.setSelectedIndex(this.options.selectedIndex, true)
}
// check we are stop at a disable item
// rotate all wheel-items
// because position may not change
this.rotateX(this.scroll.y)
// check we are stop at a disable item or not
this.wheelTo(this.selectedIndex, 0)

@@ -113,4 +139,4 @@ }

this.scroll.hooks.eventTypes.beforeInitialScrollTo,
(position: { x: number; y: number }) => {
// selectedIndex has a better priority than bs.options.startY
(position: Position) => {
// selectedIndex has higher priority than bs.options.startY
position.x = 0

@@ -122,8 +148,6 @@ position.y = -(this.selectedIndex * this.itemHeight)

scroller.hooks.on(scroller.hooks.eventTypes.checkClick, () => {
const index = Array.prototype.slice
.call(this.items, 0)
.indexOf(this.target as Element)
const index = HTMLCollectionToArray(this.items).indexOf(this.target)
if (index === -1) return true
this.wheelToAfterClick(index, this.options.adjustTime, ease.swipe)
this.wheelTo(index, this.options.adjustTime, ease.swipe)
return true

@@ -133,6 +157,15 @@ })

scroller.hooks.eventTypes.scrollTo,
(endPoint: { x: number; y: number }) => {
(endPoint: Position) => {
endPoint.y = this.findNearestValidWheel(endPoint.y).y
}
)
// when content is scrolling
// click wheel-item DOM repeatedly and crazily will cause scrollEnd not triggered
// so reset forceStopped
scroller.hooks.on(scroller.hooks.eventTypes.minDistanceScroll, () => {
const animater = scroller.animater
if (animater.forceStopped === true) {
animater.forceStopped = false
}
})
scroller.hooks.on(

@@ -214,3 +247,2 @@ scroller.hooks.eventTypes.scrollToElement,

momentumInfo.duration = this.options.adjustTime
this.selectedIndex = validWheel.index
}

@@ -229,20 +261,7 @@ )

)
animater.hooks.on(
animater.hooks.eventTypes.beforeForceStop,
({ y }: { x: number; y: number }) => {
this.target = this.items[this.findNearestValidWheel(y).index]
// don't dispatch scrollEnd when forceStop from transition or animation
return true
}
)
// bs.stop() to make wheel stop at a correct position
// bs.stop() to make wheel stop at a correct position when pending
animater.hooks.on(animater.hooks.eventTypes.callStop, () => {
const index = Array.prototype.slice
.call(this.items, 0)
.indexOf(this.target as Element)
if (index > 0) {
const y = -(index * this.itemHeight)
animater.translate({ x: 0, y })
}
const { index } = this.findNearestValidWheel(this.scroll.y)
this.isAdjustingPosition = true
this.wheelTo(index, 0)
})

@@ -253,5 +272,4 @@

animater.translater.hooks.eventTypes.translate,
(endPoint: { x: number; y: number }) => {
(endPoint: Position) => {
this.rotateX(endPoint.y)
this.selectedIndex = this.findNearestValidWheel(endPoint.y).index
}

@@ -267,4 +285,10 @@ )

private handleSelectedIndex() {
this.selectedIndex = this.options.selectedIndex
setSelectedIndex(index: number, contentChanged: boolean = false) {
const prevSelectedIndex = this.selectedIndex
this.selectedIndex = index
// if content DOM changed, should not trigger event
if (prevSelectedIndex !== index && !contentChanged) {
this.scroll.trigger(WHEEL_INDEX_CHANGED_EVENT_NAME, index)
}
}

@@ -276,17 +300,14 @@

wheelTo(index = 0, time = 0, ease?: EaseItem): boolean {
wheelTo(index = 0, time = 0, ease?: EaseItem) {
const y = -index * this.itemHeight
const currentY = Math.round(this.scroll.y)
this.scroll.scrollTo(0, y, time, ease)
return y === currentY
}
private wheelToAfterClick(index = 0, time = 0, ease: EaseItem) {
const needDispatchScrollEnd = this.wheelTo(index, time, ease)
// startpoint === endpoint
// manually trigger scrollEnd
if (needDispatchScrollEnd) {
const hooks = this.scroll.scroller.hooks
hooks.trigger(hooks.eventTypes.scrollEnd)
restorePosition() {
// bs is scrolling
const isPending = this.scroll.pending
if (isPending) {
const selectedIndex = this.getSelectedIndex()
this.scroll.scroller.animater.clearTimer()
this.wheelTo(selectedIndex, 0)
}

@@ -329,3 +350,3 @@ }

.wheelDisabledItemClass as string
// Impersonation web native select
// implement web native select element
// first, check whether there is a enable item whose index is smaller than currentIndex

@@ -365,3 +386,3 @@ // then, check whether there is a enable item whose index is bigger than currentIndex

}
// when all the items are disabled, this.selectedIndex should always be -1
// when all the items are disabled, selectedIndex should always be -1
return {

@@ -368,0 +389,0 @@ index: this.wheelItemsAllDisabled ? -1 : currentIndex,

@@ -5,14 +5,18 @@ const sourcePrefix = 'plugins.wheel'

key: 'wheelTo',
name: 'wheelTo'
name: 'wheelTo',
},
{
key: 'getSelectedIndex',
name: 'getSelectedIndex'
}
name: 'getSelectedIndex',
},
{
key: 'restorePosition',
name: 'restorePosition',
},
]
export default propertiesMap.map(item => {
export default propertiesMap.map((item) => {
return {
key: item.key,
sourceKey: `${sourcePrefix}.${item.name}`
sourceKey: `${sourcePrefix}.${item.name}`,
}
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc