@vnmfify/core
Version:
```shell npm i @vnmfify/core -S ```
317 lines (277 loc) • 12.4 kB
JavaScript
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