UNPKG

@vnmfify/core

Version:

```shell npm i @vnmfify/core -S ```

317 lines (277 loc) 12.4 kB
import _clamp from "lodash/clamp"; var _excluded = ["className", "defaultOpen", "open", "disabled", "stopPropagation", "beforeClose", "onOpen", "onClose", "onClick", "onTouchStart", "onTouchMove", "onTouchEnd", "onTouchCancel", "children"]; function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; } function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; } function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } import { useUncontrolled } from "@vnmfify/hooks"; import { View } from "@vnxjs/components"; import classNames from "classnames"; import * as React from "react"; import { Children, cloneElement, isValidElement, useCallback, useMemo, useRef, useState } from "react"; import { useFunctionInterceptor, useRenderedEffect } from "../hooks"; import { prefixClassname } from "../styles"; import { inBrowser } from "../utils/base"; import { preventDefault } from "../utils/dom/event"; import { getRect } from "../utils/dom/rect"; import { addUnitPx } from "../utils/format/unit"; import { fulfillPromise } from "../utils/promisify"; import { useTouch } from "../utils/touch"; import SwipeCellActions from "./swipe-cell-actions"; function useSwipeCellChildren(children, leftRef, rightRef, createClickHandler) { return useMemo(() => { var __children__ = { left: undefined, content: [], right: undefined }; Children.forEach(children, child => { if ( /*#__PURE__*/isValidElement(child)) { var element = child; var elementType = element.type; if (elementType === SwipeCellActions) { var { props } = element; var { side, onClick: _onClick } = props; if (side === "left") { __children__.left = /*#__PURE__*/cloneElement(element, _objectSpread(_objectSpread({}, props), {}, { ref: leftRef, onClick: event => { _onClick === null || _onClick === void 0 ? void 0 : _onClick(event); createClickHandler === null || createClickHandler === void 0 ? void 0 : createClickHandler("left", true)(event); } })); } else if (side === "right") { __children__.right = /*#__PURE__*/cloneElement(element, _objectSpread(_objectSpread({}, props), {}, { ref: rightRef, onClick: event => { _onClick === null || _onClick === void 0 ? void 0 : _onClick(event); createClickHandler === null || createClickHandler === void 0 ? void 0 : createClickHandler("right", true)(event); } })); } } else { var _children__$content; (_children__$content = __children__.content) === null || _children__$content === void 0 ? void 0 : _children__$content.push(element); } } else { var _children__$content2; (_children__$content2 = __children__.content) === null || _children__$content2 === void 0 ? void 0 : _children__$content2.push(child); } }); return __children__; }, [children, createClickHandler, leftRef, rightRef]); } function SwipeCell(props) { var { className, defaultOpen, open: openProp, disabled, stopPropagation, beforeClose: beforeCloseProp, onOpen, onClose, onClick: onClickProp, onTouchStart: _onTouchStart, onTouchMove: _onTouchMove, onTouchEnd: _onTouchEnd, onTouchCancel: _onTouchCancel, children: childrenProp } = props, restProps = _objectWithoutProperties(props, _excluded); var beforeClose = useFunctionInterceptor(beforeCloseProp); var { value } = useUncontrolled({ defaultValue: defaultOpen, value: openProp }); var openedRef = useRef(false); var lockClickRef = useRef(false); var startOffsetRef = useRef(0); var rootRef = useRef(); var leftRef = useRef(); var rightRef = useRef(); var leftWidthRef = useRef(0); var rightWidthRef = useRef(0); var positionRef = useRef("outside"); var draggingRef = useRef(false); var [offset, setOffset] = useState(0); var touch = useTouch(); var updateLeftWidth = () => getRect(leftRef).then(_ref => { var { width } = _ref; return width !== null && width !== void 0 ? width : 0; }).then(leftWidth => leftWidthRef.current = leftWidth); var updateRightWidth = () => getRect(rightRef).then(_ref2 => { var { width } = _ref2; return width !== null && width !== void 0 ? width : 0; }).then(rightWidth => rightWidthRef.current = rightWidth); var open = useCallback(function (side) { var emitOpen = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; openedRef.current = true; setOffset(side === "left" ? leftWidthRef.current : -rightWidthRef.current); if (emitOpen) { onOpen === null || onOpen === void 0 ? void 0 : onOpen(side); } }, [onOpen]); var close = useCallback(function (position) { var emitClose = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true; openedRef.current = false; setOffset(0); if (emitClose) { onClose === null || onClose === void 0 ? void 0 : onClose(position); } }, [onClose]); var toggle = useCallback(side => { var THRESHOLD = 0.15; var threshold = openedRef.current ? 1 - THRESHOLD : THRESHOLD; var width = side === "left" ? leftWidthRef.current : rightWidthRef.current; var offsetAbs = Math.abs(offset); if (width && offsetAbs > width * threshold) { open(side); } else { close(side); } }, [close, offset, open]); var handleTouchStart = event => { if (disabled) { return; } fulfillPromise(Promise.all([updateLeftWidth(), updateRightWidth()])); startOffsetRef.current = offset; touch.start(event); }; var handleTouchMove = useCallback( /*#__PURE__*/function () { var _ref3 = _asyncToGenerator(function* (event) { if (disabled) { return; } var { deltaX } = touch; touch.move(event); if (touch.isHorizontal()) { var _offset = _clamp(deltaX + startOffsetRef.current, -rightWidthRef.current, leftWidthRef.current); if (!draggingRef.current) { draggingRef.current = true; } lockClickRef.current = true; var isEdge = !openedRef.current || deltaX * startOffsetRef.current < 0; if (isEdge) { preventDefault(event, stopPropagation); } positionRef.current = _offset > 0 ? "left" : "right"; setOffset(_offset); } }); return function (_x) { return _ref3.apply(this, arguments); }; }(), [disabled, stopPropagation, touch]); var handleTouchEnd = () => { if (disabled) { return; } draggingRef.current = false; toggle(positionRef.current); setTimeout(() => { lockClickRef.current = false; }, 0); }; var onClick = useCallback(function () { var position = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : "outside"; if (openedRef.current && !lockClickRef.current) { beforeClose(position).then(() => close(position)); } }, [beforeClose, close]); var createClickHandler = useCallback((position, stop) => event => { if (stop) { event.stopPropagation(); } onClick(position); }, [onClick]); var { left, content, right } = useSwipeCellChildren(childrenProp, leftRef, rightRef, createClickHandler); var valueChange = side => { if (side === "left" || side === "right") { new Promise(resolve => { if (inBrowser) { setTimeout(() => { if (side === "left") { updateLeftWidth().then(resolve); } else { updateRightWidth().then(resolve); } }, 150); } else { resolve(true); } }).then(() => { draggingRef.current = false; open(side, false); }); } else { close("outside", false); } }; useRenderedEffect(() => { if (!inBrowser) { fulfillPromise(updateLeftWidth()); } }, [left]); useRenderedEffect(() => { if (!inBrowser) { fulfillPromise(updateRightWidth()); } }, [right]); useRenderedEffect(() => valueChange(value), [value]); return /*#__PURE__*/React.createElement(View, _objectSpread({ catchMove: true, ref: rootRef, className: classNames(prefixClassname("swipe-cell"), className), onTouchStart: event => { _onTouchStart === null || _onTouchStart === void 0 ? void 0 : _onTouchStart(event); handleTouchStart(event); }, onTouchMove: event => { _onTouchMove === null || _onTouchMove === void 0 ? void 0 : _onTouchMove(event); handleTouchMove === null || handleTouchMove === void 0 ? void 0 : handleTouchMove(event); }, onTouchEnd: event => { _onTouchEnd === null || _onTouchEnd === void 0 ? void 0 : _onTouchEnd(event); handleTouchEnd(); }, onTouchCancel: event => { _onTouchCancel === null || _onTouchCancel === void 0 ? void 0 : _onTouchCancel(event); handleTouchEnd(); }, onClick: event => { onClickProp === null || onClickProp === void 0 ? void 0 : onClickProp(event); createClickHandler("cell")(event); } }, restProps), /*#__PURE__*/React.createElement(View, { className: prefixClassname("swipe-cell__wrapper"), style: _objectSpread({ transform: "translate3d(".concat(addUnitPx(offset), ", 0, 0)") }, inBrowser ? { transitionDuration: draggingRef.current ? "0s" : ".3s" } : {}) }, left, content, right)); } export default SwipeCell; //# sourceMappingURL=swipe-cell.js.map