rax-scrollview
Version:
ScrollView component for Rax.
197 lines (195 loc) • 7.13 kB
JavaScript
exports.__esModule = true;
exports.default = void 0;
var _rax = require("rax");
var _classnames = _interopRequireDefault(require("classnames"));
var _wrapDefaultProperties = _interopRequireDefault(require("../utils/wrapDefaultProperties"));
var _systemInfo = require("@uni/system-info");
var _index = _interopRequireDefault(require("../index.css"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _extends() { _extends = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }
var _styleSheet = _index.default;
function _getClassName() {
var className = [];
var args = arguments[0];
var type = Object.prototype.toString.call(args).slice(8, -1).toLowerCase();
if (type === 'string') {
args = args.trim();
args && className.push(args);
} else if (type === 'array') {
args.forEach(function (cls) {
cls = _getClassName(cls).trim();
cls && className.push(cls);
});
} else if (type === 'object') {
for (var k in args) {
k = k.trim();
if (k && args.hasOwnProperty(k) && args[k]) {
className.push(k);
}
}
}
return className.join(' ').trim();
}
function _getStyle(classNameExpression) {
var cache = _styleSheet.__cache || (_styleSheet.__cache = {});
var className = _getClassName(classNameExpression);
var classNameArr = className.split(/\s+/);
var style = cache[className];
if (!style) {
style = {};
if (classNameArr.length === 1) {
style = _styleSheet[classNameArr[0].trim()];
} else {
classNameArr.forEach(function (cls) {
var value = _styleSheet[cls.trim()];
if (typeof value === 'object') {
style = Object.assign(style, _styleSheet[cls.trim()]);
}
});
}
cache[className] = style;
}
return style;
}
var FULL_WIDTH = 750;
var ANIMATION_DURATION = 400;
var baseCls = 'rax-scrollview';
var pixelRatio;
function getPixelRatio() {
if (pixelRatio) {
return pixelRatio;
}
pixelRatio = (0, _systemInfo.getInfoSync)().windowWidth / FULL_WIDTH;
return pixelRatio;
}
function translateToPx(origin) {
if (typeof origin === 'number') {
return origin;
}
var matched = /^([\d\.]+)(r?px)?$/.exec(origin);
if (matched) {
if (!matched[2]) {
return parseFloat(matched[1]);
}
if (matched[2] === 'rpx') {
var _pixelRatio = getPixelRatio();
return parseFloat(matched[1]) * _pixelRatio;
}
if (matched[2] === 'px') {
return parseFloat(matched[1]);
}
}
return 0;
}
var ScrollView = (0, _rax.forwardRef)(function (props, ref) {
var className = props.className,
style = props.style,
horizontal = props.horizontal,
onEndReached = props.onEndReached,
onScroll = props.onScroll,
children = props.children,
_props$disableScroll = props.disableScroll,
disableScroll = _props$disableScroll === void 0 ? false : _props$disableScroll,
onEndReachedThreshold = props.onEndReachedThreshold;
var _useState = (0, _rax.useState)(0),
scrollTop = _useState[0];
var _useState2 = (0, _rax.useState)(0),
scrollLeft = _useState2[0];
var _useState3 = (0, _rax.useState)(false),
scrollWithAnimation = _useState3[0],
setScrollWithAnimation = _useState3[1];
var _useState4 = (0, _rax.useState)(ANIMATION_DURATION),
scrollAnimationDuration = _useState4[0],
setScrollAnimationDuration = _useState4[1];
var _useState5 = (0, _rax.useState)(null),
scrollIntoViewId = _useState5[0];
var scrollerRef = (0, _rax.useRef)(null);
(0, _rax.useImperativeHandle)(ref, function () {
return {
_nativeNode: scrollerRef.current,
resetScroll: function resetScroll() {
if (horizontal) {
scrollerRef.current.setAttribute('scroll-left', '0');
} else {
scrollerRef.current.setAttribute('scroll-top', '0');
}
},
scrollTo: function scrollTo(options) {
var _ref = options || {},
_ref$x = _ref.x,
x = _ref$x === void 0 ? 0 : _ref$x,
_ref$y = _ref.y,
y = _ref$y === void 0 ? 0 : _ref$y,
_ref$animated = _ref.animated,
animated = _ref$animated === void 0 ? true : _ref$animated,
_ref$duration = _ref.duration,
duration = _ref$duration === void 0 ? ANIMATION_DURATION : _ref$duration;
// Scroll event caused by users can not change scroll-top or scroll-left, so here we add some slight random element to force update
if (horizontal) {
scrollerRef.current.setAttribute('scroll-left', String(translateToPx(x)));
} else {
scrollerRef.current.setAttribute('scroll-top', String(translateToPx(y)));
}
setScrollWithAnimation(animated);
setScrollAnimationDuration(duration);
},
scrollIntoView: function scrollIntoView(options) {
var _ref2 = options || {},
id = _ref2.id,
_ref2$animated = _ref2.animated,
animated = _ref2$animated === void 0 ? true : _ref2$animated,
_ref2$duration = _ref2.duration,
duration = _ref2$duration === void 0 ? ANIMATION_DURATION : _ref2$duration;
if (!id) {
throw new Error('Params missing id.');
}
scrollerRef.current.setAttribute('scroll-into-view', id);
setScrollWithAnimation(animated);
setScrollAnimationDuration(duration);
}
};
});
var scrollerStyle = _extends({}, style);
if (scrollerStyle.height === null) {
scrollerStyle.flex = 1;
}
var cls = (0, _classnames.default)(baseCls, baseCls + "-" + (horizontal ? 'horizontal' : 'vertical'), className);
var endReachedThreshold = translateToPx(onEndReachedThreshold);
return (0, _rax.createElement)("scroll-view", _extends({}, props, {
ref: scrollerRef,
className: cls,
style: Object.assign({}, _getStyle(cls), scrollerStyle),
"scroll-top": scrollTop,
"scroll-left": scrollLeft,
onScroll: onScroll ? function handleScroll(e) {
if (onScroll) {
e.nativeEvent = {
get contentOffset() {
return {
x: e.detail.scrollLeft,
y: e.detail.scrollTop
};
},
get contentSize() {
return {
width: e.detail.scrollWidth,
height: e.detail.scrollHeight
};
}
};
onScroll(e);
}
} : null,
onScrollToLower: onEndReached,
"lower-threshold": endReachedThreshold,
"scroll-with-animation": scrollWithAnimation,
"scroll-animation-duration": scrollAnimationDuration,
"scroll-x": !disableScroll && horizontal,
"scroll-y": !disableScroll && !horizontal,
"scroll-into-view": scrollIntoViewId,
"enable-flex": true
}), children);
});
var _default = (0, _wrapDefaultProperties.default)(ScrollView);
exports.default = _default;
;