SwipeCell.js 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. var __defProp = Object.defineProperty;
  2. var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
  3. var __getOwnPropNames = Object.getOwnPropertyNames;
  4. var __hasOwnProp = Object.prototype.hasOwnProperty;
  5. var __export = (target, all) => {
  6. for (var name2 in all)
  7. __defProp(target, name2, { get: all[name2], enumerable: true });
  8. };
  9. var __copyProps = (to, from, except, desc) => {
  10. if (from && typeof from === "object" || typeof from === "function") {
  11. for (let key of __getOwnPropNames(from))
  12. if (!__hasOwnProp.call(to, key) && key !== except)
  13. __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
  14. }
  15. return to;
  16. };
  17. var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
  18. var stdin_exports = {};
  19. __export(stdin_exports, {
  20. default: () => stdin_default,
  21. swipeCellProps: () => swipeCellProps
  22. });
  23. module.exports = __toCommonJS(stdin_exports);
  24. var import_vue = require("vue");
  25. var import_utils = require("../utils");
  26. var import_use = require("@vant/use");
  27. var import_use_touch = require("../composables/use-touch");
  28. var import_use_expose = require("../composables/use-expose");
  29. const [name, bem] = (0, import_utils.createNamespace)("swipe-cell");
  30. const swipeCellProps = {
  31. name: (0, import_utils.makeNumericProp)(""),
  32. disabled: Boolean,
  33. leftWidth: import_utils.numericProp,
  34. rightWidth: import_utils.numericProp,
  35. beforeClose: Function,
  36. stopPropagation: Boolean
  37. };
  38. var stdin_default = (0, import_vue.defineComponent)({
  39. name,
  40. props: swipeCellProps,
  41. emits: ["open", "close", "click"],
  42. setup(props, {
  43. emit,
  44. slots
  45. }) {
  46. let opened;
  47. let lockClick;
  48. let startOffset;
  49. let isInBeforeClosing;
  50. const root = (0, import_vue.ref)();
  51. const leftRef = (0, import_vue.ref)();
  52. const rightRef = (0, import_vue.ref)();
  53. const state = (0, import_vue.reactive)({
  54. offset: 0,
  55. dragging: false
  56. });
  57. const touch = (0, import_use_touch.useTouch)();
  58. const getWidthByRef = (ref2) => ref2.value ? (0, import_use.useRect)(ref2).width : 0;
  59. const leftWidth = (0, import_vue.computed)(() => (0, import_utils.isDef)(props.leftWidth) ? +props.leftWidth : getWidthByRef(leftRef));
  60. const rightWidth = (0, import_vue.computed)(() => (0, import_utils.isDef)(props.rightWidth) ? +props.rightWidth : getWidthByRef(rightRef));
  61. const open = (side) => {
  62. state.offset = side === "left" ? leftWidth.value : -rightWidth.value;
  63. if (!opened) {
  64. opened = true;
  65. emit("open", {
  66. name: props.name,
  67. position: side
  68. });
  69. }
  70. };
  71. const close = (position) => {
  72. state.offset = 0;
  73. if (opened) {
  74. opened = false;
  75. emit("close", {
  76. name: props.name,
  77. position
  78. });
  79. }
  80. };
  81. const toggle = (side) => {
  82. const offset = Math.abs(state.offset);
  83. const THRESHOLD = 0.15;
  84. const threshold = opened ? 1 - THRESHOLD : THRESHOLD;
  85. const width = side === "left" ? leftWidth.value : rightWidth.value;
  86. if (width && offset > width * threshold) {
  87. open(side);
  88. } else {
  89. close(side);
  90. }
  91. };
  92. const onTouchStart = (event) => {
  93. if (!props.disabled) {
  94. startOffset = state.offset;
  95. touch.start(event);
  96. }
  97. };
  98. const onTouchMove = (event) => {
  99. if (props.disabled) {
  100. return;
  101. }
  102. const {
  103. deltaX
  104. } = touch;
  105. touch.move(event);
  106. if (touch.isHorizontal()) {
  107. lockClick = true;
  108. state.dragging = true;
  109. const isEdge = !opened || deltaX.value * startOffset < 0;
  110. if (isEdge) {
  111. (0, import_utils.preventDefault)(event, props.stopPropagation);
  112. }
  113. state.offset = (0, import_utils.clamp)(deltaX.value + startOffset, -rightWidth.value, leftWidth.value);
  114. }
  115. };
  116. const onTouchEnd = () => {
  117. if (state.dragging) {
  118. state.dragging = false;
  119. toggle(state.offset > 0 ? "left" : "right");
  120. setTimeout(() => {
  121. lockClick = false;
  122. }, 0);
  123. }
  124. };
  125. const onClick = (position = "outside", event) => {
  126. if (isInBeforeClosing) return;
  127. emit("click", position);
  128. if (opened && !lockClick) {
  129. isInBeforeClosing = true;
  130. (0, import_utils.callInterceptor)(props.beforeClose, {
  131. args: [{
  132. event,
  133. name: props.name,
  134. position
  135. }],
  136. done: () => {
  137. isInBeforeClosing = false;
  138. close(position);
  139. },
  140. canceled: () => isInBeforeClosing = false,
  141. error: () => isInBeforeClosing = false
  142. });
  143. }
  144. };
  145. const getClickHandler = (position, stop) => (event) => {
  146. if (stop) {
  147. event.stopPropagation();
  148. }
  149. if (lockClick) {
  150. return;
  151. }
  152. onClick(position, event);
  153. };
  154. const renderSideContent = (side, ref2) => {
  155. const contentSlot = slots[side];
  156. if (contentSlot) {
  157. return (0, import_vue.createVNode)("div", {
  158. "ref": ref2,
  159. "class": bem(side),
  160. "onClick": getClickHandler(side, true)
  161. }, [contentSlot()]);
  162. }
  163. };
  164. (0, import_use_expose.useExpose)({
  165. open,
  166. close
  167. });
  168. (0, import_use.useClickAway)(root, (event) => onClick("outside", event), {
  169. eventName: "touchstart"
  170. });
  171. (0, import_use.useEventListener)("touchmove", onTouchMove, {
  172. target: root
  173. });
  174. return () => {
  175. var _a;
  176. const wrapperStyle = {
  177. transform: `translate3d(${state.offset}px, 0, 0)`,
  178. transitionDuration: state.dragging ? "0s" : ".6s"
  179. };
  180. return (0, import_vue.createVNode)("div", {
  181. "ref": root,
  182. "class": bem(),
  183. "onClick": getClickHandler("cell", lockClick),
  184. "onTouchstartPassive": onTouchStart,
  185. "onTouchend": onTouchEnd,
  186. "onTouchcancel": onTouchEnd
  187. }, [(0, import_vue.createVNode)("div", {
  188. "class": bem("wrapper"),
  189. "style": wrapperStyle
  190. }, [renderSideContent("left", leftRef), (_a = slots.default) == null ? void 0 : _a.call(slots), renderSideContent("right", rightRef)])]);
  191. };
  192. }
  193. });