rax-scrollview
Version:
ScrollView component for Rax.
204 lines (203 loc) • 7.62 kB
JavaScript
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); }
import { createElement, forwardRef, useRef, useState, useImperativeHandle } from 'rax';
import View from 'rax-view';
import RefreshControl from 'rax-refreshcontrol';
import getElementById from 'rax-get-element-by-id';
import cx from 'classnames';
import wrapDefaultProperties from '../utils/wrapDefaultProperties';
import indexStyleSheet from '../index.css';
var _styleSheet = indexStyleSheet;
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;
}
/* global __weex_v2__ */
var isWeexV2 = typeof __weex_v2__ === 'object';
var baseCls = 'rax-scrollview';
var ScrollView = forwardRef(function (props, ref) {
var className = props.className,
style = props.style,
horizontal = props.horizontal,
contentContainerStyle = props.contentContainerStyle,
showsHorizontalScrollIndicator = props.showsHorizontalScrollIndicator,
showsVerticalScrollIndicator = props.showsVerticalScrollIndicator,
onEndReached = props.onEndReached,
onEndReachedThreshold = props.onEndReachedThreshold,
onScroll = props.onScroll,
children = props.children;
var _useState = useState(0),
loadmoreretry = _useState[0],
setLoadmoreretry = _useState[1];
var scrollerRef = useRef(null);
var contentContainerRef = useRef(null);
useImperativeHandle(ref, function () {
return {
_nativeNode: scrollerRef.current,
resetScroll: function resetScroll() {
setLoadmoreretry(loadmoreretry + 1);
},
scrollTo: function scrollTo(options) {
if (isWeexV2) {
scrollerRef.current.scrollTo(undefined, options);
} else {
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;
var dom = __weex_require__('@weex-module/dom');
var _contentContainer = contentContainerRef.current;
/**
* Multiple scrollviews on the first screen need to be automatically scrolled to a default selected location,
* but the content may not have been rendered (in the case of contentContainer)
*/
_contentContainer && dom.scrollToElement(_contentContainer, {
offset: x || y || 0,
animated: animated
});
}
},
scrollIntoView: function scrollIntoView(options) {
var _ref2 = options || {},
id = _ref2.id,
_ref2$animated = _ref2.animated,
animated = _ref2$animated === void 0 ? true : _ref2$animated,
duration = _ref2.duration,
offsetX = _ref2.offsetX,
offsetY = _ref2.offsetY;
if (!id) {
throw new Error('Params missing id.');
}
var node = getElementById(id);
if (node) {
if (isWeexV2) {
scrollerRef.current.scrollTo(node, {
animated: animated,
duration: duration,
x: offsetX,
y: offsetY
});
} else {
var dom = __weex_require__('@weex-module/dom');
dom.scrollToElement(node, {
offset: offsetX || offsetY || 0,
animated: animated
});
}
}
}
};
});
// In weex must be int value
onEndReachedThreshold = typeof onEndReachedThreshold === 'string' ? parseInt(onEndReachedThreshold, 10) : onEndReachedThreshold;
if (style) {
var childLayoutProps = ['alignItems', 'justifyContent'].filter(function (prop) {
return style[prop] !== undefined;
});
if (childLayoutProps.length !== 0) {
console.warn('ScrollView child layout (' + JSON.stringify(childLayoutProps) + ') must be applied through the contentContainerStyle prop.');
}
}
var refreshContainer = null;
var contentContainer;
if (isWeexV2) {
contentContainer = children;
} else {
var _cx;
refreshContainer = createElement(View, null);
var contentChild = null;
if (Array.isArray(children)) {
contentChild = children.map(function (child) {
if (typeof child === 'object' && child !== null && 'type' in child && child.type == RefreshControl) {
refreshContainer = child;
return null;
} else {
return child;
}
});
} else {
contentChild = children;
}
contentContainer = createElement(View, {
ref: contentContainerRef,
className: cx((_cx = {}, _cx[baseCls + "-content-container-horizontal"] = horizontal, _cx)),
style: Object.assign({}, _getStyle(cx((_cx = {}, _cx[baseCls + "-content-container-horizontal"] = horizontal, _cx))), contentContainerStyle)
}, contentChild);
}
var scrollerStyle = _extends({}, style);
if (scrollerStyle.height === null) {
scrollerStyle.flex = 1;
}
var cls = cx(baseCls, baseCls + "-" + (horizontal ? 'horizontal' : 'vertical'), className);
var showsScrollIndicator = horizontal ? showsHorizontalScrollIndicator : showsVerticalScrollIndicator;
var weexProps = _extends({}, props);
if (isWeexV2) {
delete weexProps.onEndReachedThreshold;
}
return createElement("scroller", _extends({}, weexProps, {
ref: scrollerRef,
className: cls,
style: Object.assign({}, _getStyle(cls), scrollerStyle),
showScrollbar: showsScrollIndicator,
onLoadmore: onEndReached,
onScroll: onScroll ? function handleScroll(e) {
e.nativeEvent = {
contentOffset: {
// HACK: weex scroll event value is opposite of web
x: -e.contentOffset.x,
y: -e.contentOffset.y
},
contentSize: e.contentSize ? {
width: e.contentSize.width,
height: e.contentSize.height
} : null
};
onScroll(e);
} : null,
loadmoreoffset: onEndReachedThreshold,
loadmoreretry: loadmoreretry,
scrollDirection: horizontal ? 'horizontal' : 'vertical'
}), refreshContainer, contentContainer);
});
export default wrapDefaultProperties(ScrollView);