@jdcfe/yep-react
Version:
一套移动端的React组件库
417 lines (362 loc) • 14.7 kB
JavaScript
import _extends from "@babel/runtime/helpers/extends";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _assertThisInitialized from "@babel/runtime/helpers/assertThisInitialized";
import _inherits from "@babel/runtime/helpers/inherits";
import _possibleConstructorReturn from "@babel/runtime/helpers/possibleConstructorReturn";
import _getPrototypeOf from "@babel/runtime/helpers/getPrototypeOf";
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
var __rest = this && this.__rest || function (s, e) {
var t = {};
for (var p in s) {
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
}
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import classNames from 'classnames';
import ListView from './ListView';
import { _event, getOffsetTop } from './util';
import List from '../list';
import noop from '../_utils/noop';
var Item = List.Item;
function setDocumentScrollTop(val) {
window.document.body.scrollTop = val; // chrome61 is invalid
window.document.documentElement.scrollTop = val;
}
var draggingIndexBar = false;
document.addEventListener('touchmove', function (e) {
draggingIndexBar && e.preventDefault();
}, {
passive: false
});
var IndexedList = /*#__PURE__*/function (_React$PureComponent) {
_inherits(IndexedList, _React$PureComponent);
var _super = _createSuper(IndexedList);
function IndexedList(props) {
var _this;
_classCallCheck(this, IndexedList);
_this = _super.call(this, props);
_this.sectionComponents = {};
_this.onQuickSearch = function (sectionID) {
var lv = ReactDOM.findDOMNode(_this.indexedListView.listViewRef);
var sec = ReactDOM.findDOMNode(_this.sectionComponents[sectionID]);
var devicePixelRatio = window.devicePixelRatio || 2;
if (_this.props.useBodyScroll) {
//保证上一个吸顶的字母不再影响当前字母
setDocumentScrollTop(sec.getBoundingClientRect().top - lv.getBoundingClientRect().top + getOffsetTop(lv) + devicePixelRatio);
} else {
lv.scrollTop += sec.getBoundingClientRect().top - lv.getBoundingClientRect().top + devicePixelRatio;
}
_this.props.onQuickSearch(sectionID);
};
_this.renderIndexedBar = _this.renderIndexedBar.bind(_assertThisInitialized(_this));
_this.renderIndicator = _this.renderIndicator.bind(_assertThisInitialized(_this));
_this.createIndicatorRef = _this.createIndicatorRef.bind(_assertThisInitialized(_this));
_this.createIndexedBarRef = _this.createIndexedBarRef.bind(_assertThisInitialized(_this));
_this.onTouchStart = _this.onTouchStart.bind(_assertThisInitialized(_this));
_this.onTouchMove = _this.onTouchMove.bind(_assertThisInitialized(_this));
_this.onTouchEnd = _this.onTouchEnd.bind(_assertThisInitialized(_this));
_this.getQsInfo = _this.getQsInfo.bind(_assertThisInitialized(_this));
_this._disableParent = _this._disableParent.bind(_assertThisInitialized(_this));
_this.updateIndicator = _this.updateIndicator.bind(_assertThisInitialized(_this));
_this.state = {
showIndicator: false
};
return _this;
}
_createClass(IndexedList, [{
key: "createIndicatorRef",
value: function createIndicatorRef(el) {
this.indicator = el;
}
}, {
key: "createIndexedBarRef",
value: function createIndexedBarRef(el) {
this.indexedBar = el;
}
}, {
key: "_disableParent",
value: function _disableParent(e) {
e.preventDefault();
e.stopPropagation();
}
}, {
key: "onQuickSearchTop",
value: function onQuickSearchTop(sectionID, topId) {
if (this.props.useBodyScroll) {
setDocumentScrollTop(0);
} else {
// @ts-ignore
ReactDOM.findDOMNode(this.indexedListView.listViewRef).scrollTop = 0;
}
this.props.onQuickSearch(sectionID, topId);
}
}, {
key: "updateIndicator",
value: function updateIndicator(ele) {
var _this2 = this;
var end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
var el = ele;
if (!el.getAttribute('data-index-target')) {
el = el.parentNode;
}
if (this.props.showIndicator) {
this.indicator.innerText = el.innerText.trim();
this.setState({
showIndicator: true
});
if (this._indicatorTimer) {
clearTimeout(this._indicatorTimer);
} // @ts-ignore
this._indicatorTimer = setTimeout(function () {
_this2.setState({
showIndicator: false
});
}, 1000);
}
var cls = "".concat(this.props.prefixCls, "-indexed-bar-over");
var activeCls = "".concat(this.props.prefixCls, "-indexed-bar-active"); // can not use setState to change className, it has a big performance issue!
this._hCache.forEach(function (d) {
d[0].className = d[0].className.replace(cls, '').replace(activeCls, ''); //add active class
d[0].className = "".concat(d[0].className, " ").concat(d[0].getAttribute('data-index-target') === el.innerText.trim() ? activeCls : '').trim();
});
if (!end) {
el.className = "".concat(el.className, " ").concat(cls).trim();
}
}
}, {
key: "onTouchStart",
value: function onTouchStart(e) {
this._target = e.target;
this._basePos = this.indexedBar.getBoundingClientRect();
draggingIndexBar = true;
this.updateIndicator(this._target);
}
}, {
key: "onTouchMove",
value: function onTouchMove(e) {
e.preventDefault();
if (this._target) {
var ex = _event(e);
var basePos = this._basePos;
var _pos;
if (ex.clientY >= basePos.top && ex.clientY <= basePos.top + this._qsHeight) {
_pos = Math.floor((ex.clientY - basePos.top) / this._avgH);
var target;
if (_pos in this._hCache) {
target = this._hCache[_pos][0];
}
if (target) {
var overValue = target.getAttribute('data-index-target');
if (this._target !== target) {
if (this.props.quickIndexedBarTop.value === overValue) {
this.onQuickSearchTop(undefined, overValue);
} else {
this.onQuickSearch(overValue);
}
this.updateIndicator(target);
}
this._target = target;
}
}
}
}
}, {
key: "onTouchEnd",
value: function onTouchEnd() {
if (!this._target) {
return;
}
draggingIndexBar = false;
this.updateIndicator(this._target, true);
this._target = null;
}
}, {
key: "componentDidMount",
value: function componentDidMount() {
this.getQsInfo();
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate() {
this.getQsInfo();
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
if (this._indicatorTimer) {
clearTimeout(this._indicatorTimer);
}
this._hCache = null;
}
}, {
key: "getQsInfo",
value: function getQsInfo() {
var quickSearchBar = this.indexedBar;
var height = quickSearchBar.offsetHeight;
var hCache = [];
[].slice.call(quickSearchBar.querySelectorAll('[data-index-target]')).forEach(function (d) {
hCache.push([d]);
});
var _avgH = height / hCache.length;
var _top = 0;
for (var i = 0, len = hCache.length; i < len; i++) {
_top = i * _avgH;
hCache[i][1] = [_top, _top + _avgH];
}
this._qsHeight = height;
this._avgH = _avgH;
this._hCache = hCache;
}
}, {
key: "componentWillReceiveProps",
value: function componentWillReceiveProps(nextProps) {
if (nextProps.activeBar !== this.props.activeBar) {
var activeCls = "".concat(this.props.prefixCls, "-indexed-bar-active");
this._hCache.forEach(function (d) {
d[0].className = d[0].className.replace(activeCls, ''); //add active class
d[0].className = "".concat(d[0].className, " ").concat(d[0].getAttribute('data-index-target') === nextProps.activeBar ? activeCls : '');
});
}
}
}, {
key: "renderIndexedBar",
value: function renderIndexedBar() {
var _this3 = this;
var _this$props = this.props,
prefixCls = _this$props.prefixCls,
indexedBarStyle = _this$props.indexedBarStyle,
data = _this$props.data,
quickIndexedBarTop = _this$props.quickIndexedBarTop,
enableQuickIndexedBarTop = _this$props.enableQuickIndexedBarTop;
var sectionKvs = Object.keys(data).map(function (item) {
return {
label: item,
value: item
};
});
return /*#__PURE__*/React.createElement("ul", {
ref: this.createIndexedBarRef,
className: "".concat(prefixCls, "-indexed-bar"),
style: indexedBarStyle,
onTouchStart: this.onTouchStart,
onTouchMove: this.onTouchMove,
onTouchEnd: this.onTouchEnd,
onTouchCancel: this.onTouchEnd
}, enableQuickIndexedBarTop && /*#__PURE__*/React.createElement("li", {
"data-index-target": quickIndexedBarTop.value,
onClick: function onClick() {
return _this3.onQuickSearchTop(undefined, quickIndexedBarTop.value);
}
}, quickIndexedBarTop.label), sectionKvs.map(function (kv) {
return /*#__PURE__*/React.createElement("li", {
key: kv.value,
"data-index-target": kv.value,
onClick: function onClick() {
return _this3.onQuickSearch(kv.value);
}
}, kv.label);
}));
}
}, {
key: "renderIndicator",
value: function renderIndicator() {
var _this$props2 = this.props,
prefixCls = _this$props2.prefixCls,
showIndicator = _this$props2.showIndicator,
indicatorStyle = _this$props2.indicatorStyle;
var cls = classNames("".concat(prefixCls, "-indicator"), _defineProperty({}, "".concat(prefixCls, "-indicator-hide"), !showIndicator || !this.state.showIndicator));
return showIndicator && /*#__PURE__*/React.createElement("div", {
className: cls,
style: indicatorStyle,
ref: this.createIndicatorRef
});
}
}, {
key: "render",
value: function render() {
var _this4 = this;
var _a = this.props,
prefixCls = _a.prefixCls,
listPrefixCls = _a.listPrefixCls,
className = _a.className,
_renderSectionHeader = _a.renderSectionHeader,
renderHeader = _a.renderHeader,
renderFooter = _a.renderFooter,
renderBodyComponent = _a.renderBodyComponent,
restProps = __rest(_a, ["prefixCls", "listPrefixCls", "className", "renderSectionHeader", "renderHeader", "renderFooter", "renderBodyComponent"]);
var cls = classNames(prefixCls, listPrefixCls, className);
var sectionHeaderClassName = classNames(["".concat(prefixCls, "-section-header")], ["".concat(listPrefixCls, "-body")]);
var otherProps = {};
if (renderHeader) {
otherProps.renderHeader = function () {
return /*#__PURE__*/React.createElement("div", {
className: "".concat(listPrefixCls, "-header")
}, renderHeader());
};
}
if (renderFooter) {
otherProps.renderFooter = function () {
return /*#__PURE__*/React.createElement("div", {
className: "".concat(listPrefixCls, "-footer")
}, renderFooter());
};
}
return /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-container")
}, /*#__PURE__*/React.createElement(ListView, _extends({
className: cls,
ref: function ref(el) {
return _this4.indexedListView = el;
},
sectionBodyClassName: "".concat(prefixCls, "-section-body ").concat(listPrefixCls, "-body"),
renderBodyComponent: renderBodyComponent || function () {
return /*#__PURE__*/React.createElement("div", {
className: "".concat(listPrefixCls, "-body")
});
},
renderSectionHeader: function renderSectionHeader(sectionData, sectionId) {
return /*#__PURE__*/React.cloneElement( /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(Item, {
prefixCls: listPrefixCls
}, _renderSectionHeader(sectionData, sectionId))), {
ref: function ref(el) {
return _this4.sectionComponents[sectionId] = el;
},
className: sectionHeaderClassName
});
}
}, restProps, otherProps)), this.renderIndexedBar(), this.renderIndicator());
}
}]);
return IndexedList;
}(React.PureComponent);
export { IndexedList as default };
IndexedList.defaultProps = {
prefixCls: 'Yep-indexed-list',
listPrefixCls: 'Yep-list',
style: {},
indexedBarStyle: {},
indicatorStyle: {},
showIndicator: false,
renderSectionHeader: function renderSectionHeader(sectionData) {
return /*#__PURE__*/React.createElement("div", null, sectionData);
},
quickIndexedBarTop: {
label: '#',
value: '#'
},
useBodyScroll: true,
onQuickSearch: noop,
enableQuickIndexedBarTop: true,
keyLabel: 'value',
renderBodyComponent: function renderBodyComponent() {
return /*#__PURE__*/React.createElement("div", null);
}
};