SwipeCell.js 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  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. });
  22. module.exports = __toCommonJS(stdin_exports);
  23. var import_vue = require("vue");
  24. var import_vue2 = 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_vue2.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. const root = (0, import_vue2.ref)();
  50. const leftRef = (0, import_vue2.ref)();
  51. const rightRef = (0, import_vue2.ref)();
  52. const state = (0, import_vue2.reactive)({
  53. offset: 0,
  54. dragging: false
  55. });
  56. const touch = (0, import_use_touch.useTouch)();
  57. const getWidthByRef = (ref2) => ref2.value ? (0, import_use.useRect)(ref2).width : 0;
  58. const leftWidth = (0, import_vue2.computed)(() => (0, import_utils.isDef)(props.leftWidth) ? +props.leftWidth : getWidthByRef(leftRef));
  59. const rightWidth = (0, import_vue2.computed)(() => (0, import_utils.isDef)(props.rightWidth) ? +props.rightWidth : getWidthByRef(rightRef));
  60. const open = (side) => {
  61. state.offset = side === "left" ? leftWidth.value : -rightWidth.value;
  62. if (!opened) {
  63. opened = true;
  64. emit("open", {
  65. name: props.name,
  66. position: side
  67. });
  68. }
  69. };
  70. const close = (position) => {
  71. state.offset = 0;
  72. if (opened) {
  73. opened = false;
  74. emit("close", {
  75. name: props.name,
  76. position
  77. });
  78. }
  79. };
  80. const toggle = (side) => {
  81. const offset = Math.abs(state.offset);
  82. const THRESHOLD = 0.15;
  83. const threshold = opened ? 1 - THRESHOLD : THRESHOLD;
  84. const width = side === "left" ? leftWidth.value : rightWidth.value;
  85. if (width && offset > width * threshold) {
  86. open(side);
  87. } else {
  88. close(side);
  89. }
  90. };
  91. const onTouchStart = (event) => {
  92. if (!props.disabled) {
  93. startOffset = state.offset;
  94. touch.start(event);
  95. }
  96. };
  97. const onTouchMove = (event) => {
  98. if (props.disabled) {
  99. return;
  100. }
  101. const {
  102. deltaX
  103. } = touch;
  104. touch.move(event);
  105. if (touch.isHorizontal()) {
  106. lockClick = true;
  107. state.dragging = true;
  108. const isEdge = !opened || deltaX.value * startOffset < 0;
  109. if (isEdge) {
  110. (0, import_utils.preventDefault)(event, props.stopPropagation);
  111. }
  112. state.offset = (0, import_utils.clamp)(deltaX.value + startOffset, -rightWidth.value, leftWidth.value);
  113. }
  114. };
  115. const onTouchEnd = () => {
  116. if (state.dragging) {
  117. state.dragging = false;
  118. toggle(state.offset > 0 ? "left" : "right");
  119. setTimeout(() => {
  120. lockClick = false;
  121. }, 0);
  122. }
  123. };
  124. const onClick = (position = "outside") => {
  125. emit("click", position);
  126. if (opened && !lockClick) {
  127. (0, import_utils.callInterceptor)(props.beforeClose, {
  128. args: [{
  129. name: props.name,
  130. position
  131. }],
  132. done: () => close(position)
  133. });
  134. }
  135. };
  136. const getClickHandler = (position, stop) => (event) => {
  137. if (stop) {
  138. event.stopPropagation();
  139. }
  140. onClick(position);
  141. };
  142. const renderSideContent = (side, ref2) => {
  143. const contentSlot = slots[side];
  144. if (contentSlot) {
  145. return (0, import_vue.createVNode)("div", {
  146. "ref": ref2,
  147. "class": bem(side),
  148. "onClick": getClickHandler(side, true)
  149. }, [contentSlot()]);
  150. }
  151. };
  152. (0, import_use_expose.useExpose)({
  153. open,
  154. close
  155. });
  156. (0, import_use.useClickAway)(root, () => onClick("outside"), {
  157. eventName: "touchstart"
  158. });
  159. (0, import_use.useEventListener)("touchmove", onTouchMove, {
  160. target: root
  161. });
  162. return () => {
  163. var _a;
  164. const wrapperStyle = {
  165. transform: `translate3d(${state.offset}px, 0, 0)`,
  166. transitionDuration: state.dragging ? "0s" : ".6s"
  167. };
  168. return (0, import_vue.createVNode)("div", {
  169. "ref": root,
  170. "class": bem(),
  171. "onClick": getClickHandler("cell", lockClick),
  172. "onTouchstartPassive": onTouchStart,
  173. "onTouchend": onTouchEnd,
  174. "onTouchcancel": onTouchEnd
  175. }, [(0, import_vue.createVNode)("div", {
  176. "class": bem("wrapper"),
  177. "style": wrapperStyle
  178. }, [renderSideContent("left", leftRef), (_a = slots.default) == null ? void 0 : _a.call(slots), renderSideContent("right", rightRef)])]);
  179. };
  180. }
  181. });