zmp-ui
Version:
Zalo Mini App framework
187 lines • 8.05 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React, { useEffect, useRef, useState } from "react";
import classNames from "clsx";
import { DEFAULT_PICKER_ITEM_HEIGHT } from "./common/constant";
var columnHeight = DEFAULT_PICKER_ITEM_HEIGHT * 5;
var itemHeight = DEFAULT_PICKER_ITEM_HEIGHT;
var PickerColumn = function PickerColumn(props) {
var options = props.options,
className = props.className,
prefixCls = props.prefixCls,
value = props.value,
defaultValue = props.defaultValue,
name = props.name,
onChange = props.onChange,
_props$datePickerColu = props.datePickerColumn,
datePickerColumn = _props$datePickerColu === void 0 ? false : _props$datePickerColu;
var prevSelected = useRef();
var animationRef = useRef();
var scrollerTranslateRef = useRef(0);
var _useState = useState(function () {
var initVal = value || defaultValue;
var selectedIndex = initVal ? options.map(function (opt) {
return opt.value;
}).indexOf(initVal.value) : 0;
var translate = columnHeight / 2 - itemHeight / 2 - selectedIndex * itemHeight;
scrollerTranslateRef.current = translate;
prevSelected.current = options[selectedIndex].value;
return {
isMoving: false,
startTouchY: 0,
startScrollerTranslate: translate,
scrollerTranslate: translate,
minTranslate: columnHeight / 2 - itemHeight * options.length + itemHeight / 2,
maxTranslate: columnHeight / 2 - itemHeight / 2
};
}),
state = _useState[0],
setState = _useState[1];
var updateScrollerTranslate = function updateScrollerTranslate(data) {
scrollerTranslateRef.current = data;
setState(function (prev) {
return _objectSpread(_objectSpread({}, prev), {}, {
scrollerTranslate: data
});
});
};
var onValueSelected = function onValueSelected(opt, colName) {
onChange == null || onChange(opt, colName);
};
var computeTranslate = function computeTranslate() {
var initVal = value || defaultValue;
var selectedIndex = initVal ? options.map(function (opt) {
return opt.value;
}).indexOf(initVal.value) : 0;
if (datePickerColumn && (value == null ? void 0 : value.value) === prevSelected.current && selectedIndex <= 0 && prevSelected.current) {
var latestValue = parseInt(prevSelected.current.toString(), 10);
var lastValue = parseInt(options[options.length - 1].value.toString(), 10);
if (latestValue > lastValue) {
selectedIndex = options.length - 1;
}
}
selectedIndex = Math.max(selectedIndex, 0);
onValueSelected(options[selectedIndex], name);
prevSelected.current = options[selectedIndex].value;
var translate = columnHeight / 2 - itemHeight / 2 - selectedIndex * itemHeight;
scrollerTranslateRef.current = translate;
return {
scrollerTranslate: translate,
minTranslate: columnHeight / 2 - itemHeight * options.length + itemHeight / 2,
maxTranslate: columnHeight / 2 - itemHeight / 2
};
};
useEffect(function () {
if (state.isMoving) return;
var newState = computeTranslate();
setState(function (prev) {
return _objectSpread(_objectSpread({}, prev), newState);
});
}, [value, options]);
var handleTouchStart = function handleTouchStart(event) {
var startY = event.targetTouches[0].pageY;
setState(function (prev) {
return _objectSpread(_objectSpread({}, prev), {}, {
isMoving: true,
startTouchY: startY,
startScrollerTranslate: scrollerTranslateRef.current
});
});
};
var handleTouchMove = function handleTouchMove(event) {
var touchY = event.targetTouches[0].pageY;
var delta = touchY - state.startTouchY;
var nextTranslate = state.startScrollerTranslate + delta;
if (nextTranslate < state.minTranslate) {
nextTranslate = state.minTranslate - Math.pow(state.minTranslate - nextTranslate, 0.8);
} else if (nextTranslate > state.maxTranslate) {
nextTranslate = state.maxTranslate + Math.pow(nextTranslate - state.maxTranslate, 0.8);
}
cancelAnimationFrame(animationRef.current);
animationRef.current = requestAnimationFrame(function () {
updateScrollerTranslate(nextTranslate);
});
};
var handleTouchEnd = function handleTouchEnd() {
setState(function (prev) {
return _objectSpread(_objectSpread({}, prev), {}, {
isMoving: false
});
});
var minTranslate = state.minTranslate,
maxTranslate = state.maxTranslate;
var current = scrollerTranslateRef.current;
var activeIndex = 0;
if (current > maxTranslate) {
activeIndex = 0;
} else if (current < minTranslate) {
activeIndex = options.length - 1;
} else {
activeIndex = Math.round((maxTranslate - current) / itemHeight);
}
onValueSelected(options[activeIndex], name);
prevSelected.current = options[activeIndex].value;
var newTranslate = columnHeight / 2 - itemHeight / 2 - activeIndex * itemHeight;
updateScrollerTranslate(newTranslate);
};
var handleTouchCancel = function handleTouchCancel() {
updateScrollerTranslate(state.startScrollerTranslate);
setState(function (prev) {
return _objectSpread(_objectSpread({}, prev), {}, {
isMoving: false
});
});
};
var renderItems = function renderItems() {
var selectedIndex = options.findIndex(function (opt) {
return opt.value === (value == null ? void 0 : value.value);
});
return options.map(function (option, index) {
var _classNames;
var style = {
height: itemHeight + "px",
lineHeight: itemHeight + "px"
};
var itemPrefixCls = prefixCls + "-item";
var itemCls = classNames(itemPrefixCls, (_classNames = {}, _classNames[itemPrefixCls + "-selected"] = !state.isMoving && index === selectedIndex, _classNames[itemPrefixCls + "-2nd"] = !state.isMoving && selectedIndex > -1 && (index === selectedIndex - 1 || index === selectedIndex + 1), _classNames));
return /*#__PURE__*/React.createElement("div", {
key: name + "-" + (option.key || option.value),
className: itemCls,
style: style,
onClick: function onClick() {
return onValueSelected(option, name);
},
role: "presentation"
}, option.displayName);
});
};
var translateString = "translate3d(0, " + state.scrollerTranslate + "px, 0)";
var style = {
willChange: "transform",
MsTransform: translateString,
MozTransform: translateString,
OTransform: translateString,
WebkitTransform: translateString,
transform: translateString,
transitionDuration: state.isMoving ? "0ms" : "150ms"
};
var cls = classNames(prefixCls + "-column", className);
var scrollerPrefixCls = prefixCls + "-scroller";
return /*#__PURE__*/React.createElement("div", {
className: cls
}, /*#__PURE__*/React.createElement("div", {
className: scrollerPrefixCls,
onTouchStart: handleTouchStart,
onTouchMove: handleTouchMove,
onTouchEnd: handleTouchEnd,
onTouchCancel: handleTouchCancel,
style: _objectSpread({
height: columnHeight + "px"
}, style)
}, renderItems()));
};
PickerColumn.defaultProps = {
datePickerColumn: false
};
export default /*#__PURE__*/React.memo(PickerColumn);