index.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. import { __assign } from "tslib";
  2. import { SwipeActionDefaultProps } from './props';
  3. import fmtEvent from '../_util/fmtEvent';
  4. import { compareVersion } from '../_util/compareVersion';
  5. import '../_util/assert-component2';
  6. import { platform } from '../_util/platform';
  7. import { getInstanceBoundingClientRect } from '../_util/jsapi/get-instance-bounding-client-rect';
  8. import { transformOptions } from './wechat';
  9. var setStyleObj1 = function (buttons, inertiaWidth) {
  10. var _a, _b, _c;
  11. var widthPos = buttons.length === 2 ? 0.5 : 0.3333;
  12. return [
  13. { marginLeft: 0 },
  14. {
  15. marginLeft: "".concat(-(((_a = buttons[0]) === null || _a === void 0 ? void 0 : _a.width) + 1 + (inertiaWidth || 0) * widthPos) / 2, "px"),
  16. },
  17. {
  18. marginLeft: "".concat(-(((_b = buttons[0]) === null || _b === void 0 ? void 0 : _b.width) +
  19. ((_c = buttons[1]) === null || _c === void 0 ? void 0 : _c.width) +
  20. 1 +
  21. (inertiaWidth || 0) * 0.6666) / 2, "px"),
  22. },
  23. ];
  24. };
  25. var setStyleObj2 = function (buttons, inertiaWidth) {
  26. var _a, _b, _c, _d;
  27. var length = buttons.length;
  28. if (length === 2) {
  29. return [
  30. { marginRight: 0 },
  31. {
  32. marginRight: "-".concat((((_a = buttons[0]) === null || _a === void 0 ? void 0 : _a.width) + (inertiaWidth || 0) * 0.5) / 2, "px"),
  33. },
  34. ];
  35. }
  36. if (length === 3) {
  37. return [
  38. { marginRight: 0 },
  39. {
  40. marginRight: "-".concat((((_b = buttons[0]) === null || _b === void 0 ? void 0 : _b.width) + (inertiaWidth || 0) * 0.3333) / 2, "px"),
  41. },
  42. {
  43. marginRight: "-".concat((((_c = buttons[0]) === null || _c === void 0 ? void 0 : _c.width) +
  44. ((_d = buttons[1]) === null || _d === void 0 ? void 0 : _d.width) +
  45. (inertiaWidth || 0) * 0.6666) /
  46. 2, "px"),
  47. },
  48. ];
  49. }
  50. return [{ marginRight: 0 }];
  51. };
  52. var myTimeOut = null;
  53. var getDirectionLeft = function (arr) {
  54. if (arr.length < 2) {
  55. arr = [0, arr[0]];
  56. }
  57. return arr[0] + arr[1] <= 0;
  58. };
  59. var isOldVersion = getIsOldVersion();
  60. function getIsOldVersion() {
  61. if (typeof my === 'undefined') {
  62. return false;
  63. }
  64. var SDKVersion = my.SDKVersion;
  65. return compareVersion(SDKVersion, '2.0.0') < 0;
  66. }
  67. function getInitReady() {
  68. if (platform() === 'wechat') {
  69. return false;
  70. }
  71. if (isOldVersion) {
  72. return false;
  73. }
  74. return true;
  75. }
  76. Component(transformOptions({
  77. props: SwipeActionDefaultProps,
  78. didMount: function () {
  79. var _this = this;
  80. var _a = this.getProps(), defaultSwiped = _a.defaultSwiped, elasticity = _a.elasticity;
  81. this.setButtonItemWidth();
  82. this.setData({ inertiaWidth: !isOldVersion && elasticity ? 20 : 0 });
  83. if (defaultSwiped) {
  84. this.initWidth(function (maxSwipe) {
  85. maxSwipe &&
  86. _this.setData({
  87. swipeX: (maxSwipe + 0.01) * (defaultSwiped === 'right' ? -1 : 1),
  88. swipedR: defaultSwiped === 'right',
  89. swipedL: defaultSwiped === 'left',
  90. });
  91. });
  92. }
  93. },
  94. didUpdate: function (prevProp) {
  95. var _a = this.getProps(), swiped = _a.swiped, damping = _a.damping, elasticity = _a.elasticity;
  96. // 设置不同的滑动位置时需要重置
  97. var rs = prevProp.swiped !== swiped && !swiped;
  98. var is = prevProp.elasticity !== elasticity;
  99. var ds = prevProp.damping !== damping;
  100. if (rs || is || ds) {
  101. this.setData({
  102. swipeX: 0,
  103. swipedR: false,
  104. swipedL: false,
  105. tapTypeL: '',
  106. tapTypeR: '',
  107. });
  108. }
  109. if (is) {
  110. this.setData({ inertiaWidth: elasticity ? 20 : 0 });
  111. }
  112. },
  113. data: {
  114. // 在微信小程序与支付宝小程序基础库 1.0
  115. // 组件初始化时的 margin-left 决定了后续可移动的距离,所以需要等组件初始化以后再加载
  116. ready: getInitReady(),
  117. swipeLeft: true,
  118. swipeX: 0,
  119. moveX: 0,
  120. tapTypeL: '',
  121. tapTypeR: '',
  122. leftWidth: 20,
  123. rightWidth: 20,
  124. maxSwipeL: 0,
  125. maxSwipeR: 0,
  126. inTouch: false,
  127. swipedR: false,
  128. swipedL: false,
  129. changeArr: [0, 0],
  130. myStyle: {},
  131. inertiaWidth: 20,
  132. animation: !isOldVersion,
  133. _leftButtons: [],
  134. _rightButtons: [],
  135. },
  136. methods: {
  137. setWidth: function () {
  138. var _a = this.data, _leftButtons = _a._leftButtons, _rightButtons = _a._rightButtons;
  139. var _rightArr = _rightButtons || [];
  140. var _leftArr = _leftButtons || [];
  141. this.setData({
  142. ready: true,
  143. rightWidth: _rightArr.reduce(function (tolal, cur) {
  144. return tolal + cur.width;
  145. }, 0),
  146. leftWidth: _leftArr.length
  147. ? _leftArr.reduce(function (tolal, cur) {
  148. return tolal + cur.width;
  149. }, 0)
  150. : 0,
  151. });
  152. },
  153. setButtonItemWidth: function () {
  154. var _this = this;
  155. var _a = this.getProps(), leftButtons = _a.leftButtons, rightButtons = _a.rightButtons;
  156. leftButtons.forEach(function (i) {
  157. i.width = i.width || 150;
  158. });
  159. rightButtons.forEach(function (i) {
  160. i.width = i.width || 150;
  161. });
  162. this.setData({ _leftButtons: leftButtons, _rightButtons: rightButtons }, function () {
  163. _this.setWidth();
  164. });
  165. },
  166. getProps: function () {
  167. var _this = this;
  168. if (platform() === 'wechat') {
  169. return __assign(__assign({}, this.data), { onSwipeStart: function (v) {
  170. _this.triggerEvent('swipestart', v);
  171. }, onSwipeEnd: function (v) {
  172. _this.triggerEvent('swipeend', v);
  173. }, onButtonTap: function (v) {
  174. _this.triggerEvent('buttontap', v);
  175. } });
  176. }
  177. return this.props;
  178. },
  179. initWidth: function (func) {
  180. var _this = this;
  181. var _a = this.getProps(), leftButtons = _a.leftButtons, rightButtons = _a.rightButtons;
  182. // 获取宽度信息,设置滑轨的宽度、初始化滑动位置
  183. // 如果没有获取到该信息则把左滑禁用掉
  184. rightButtons.length > 0 &&
  185. this.boundingClientRect(".ant-swipe-action-movable-right".concat(this.$id ? '-' + this.$id : '')).then(function (ret) {
  186. if (ret && ret.width) {
  187. _this.setData({ maxSwipeR: ret.width });
  188. func && func(ret.width);
  189. }
  190. });
  191. leftButtons.length > 0 &&
  192. this.boundingClientRect(".ant-swipe-action-movable-left".concat(this.$id ? '-' + this.$id : '')).then(function (ret) {
  193. if (ret && ret.width) {
  194. _this.setData({ maxSwipeL: ret.width });
  195. func && func(ret.width);
  196. }
  197. });
  198. },
  199. boundingClientRect: function (id) {
  200. if (typeof my === 'undefined') {
  201. return getInstanceBoundingClientRect(this, id);
  202. }
  203. return getInstanceBoundingClientRect(my, id);
  204. },
  205. // 向外透出事件
  206. onTouchStart: function () {
  207. var onSwipeStart = this.getProps().onSwipeStart;
  208. var _a = this.data, swipedR = _a.swipedR, swipedL = _a.swipedL;
  209. this.initWidth();
  210. this.setData({ tapTypeL: '', tapTypeR: '', inTouch: true }); // 清空confirmType = auto 的表现
  211. onSwipeStart({
  212. swiped: !!(swipedR || swipedL),
  213. direction: swipedL ? 'left' : swipedR ? 'right' : '',
  214. }, fmtEvent(this.getProps()));
  215. },
  216. onTouchEnd: function (e) {
  217. // 因为微信小程序没有 onChangeEnd 事件
  218. // 所以用 onTouchEnd 模拟 onChangeEnd
  219. if (platform() === 'wechat') {
  220. this.onChangeEnd(e);
  221. }
  222. this.setData({ inTouch: false });
  223. },
  224. // 滑动过程中的事件,是内部事件不向外透出,用于控制右侧按钮的位置信息
  225. onChange: function (e) {
  226. var _this = this;
  227. var _a = this.data, changeArr = _a.changeArr, maxSwipeR = _a.maxSwipeR, maxSwipeL = _a.maxSwipeL, inTouch = _a.inTouch, swipedR = _a.swipedR, swipedL = _a.swipedL, inertiaWidth = _a.inertiaWidth;
  228. var x = e.detail.x;
  229. var L = x;
  230. // changeArr用于精准的控制滑动的方向
  231. var newArr = changeArr[1] === L ? [changeArr] : [changeArr[1], L];
  232. this.setData({ moveX: L, changeArr: newArr });
  233. var ridx = this.getProps().rightButtons.findIndex(function (u) { return u.confirmType === 'move'; });
  234. var lidx = this.getProps().leftButtons.findIndex(function (u) { return u.confirmType === 'move'; });
  235. if (ridx === -1 && lidx === -1)
  236. return;
  237. var isRight = getDirectionLeft(changeArr);
  238. // 左滑时的滑动确认、收起处理
  239. if (isRight) {
  240. if (L < 0 && Math.abs(L) >= maxSwipeR && inTouch && !swipedR) {
  241. clearTimeout(myTimeOut);
  242. myTimeOut = setTimeout(function () {
  243. var _a = _this.data, changeArr = _a.changeArr, maxSwipeR = _a.maxSwipeR, inTouch = _a.inTouch, swipedR = _a.swipedR, moveX = _a.moveX;
  244. var _left = getDirectionLeft(changeArr) && changeArr[0] >= changeArr[1];
  245. if (inTouch &&
  246. maxSwipeR + inertiaWidth + 2 >= Math.abs(moveX) &&
  247. _left &&
  248. !swipedR) {
  249. _this.onSetCheck(true);
  250. }
  251. }, 100);
  252. }
  253. if (changeArr[0] < changeArr[1] && maxSwipeR > L + 4 && inTouch) {
  254. this.setData({ tapTypeR: '', myStyle: {} });
  255. }
  256. }
  257. else {
  258. if (L > 0 && L + 1 >= maxSwipeL && inTouch && !swipedL) {
  259. clearTimeout(myTimeOut);
  260. myTimeOut = setTimeout(function () {
  261. var _a = _this.data, changeArr = _a.changeArr, maxSwipeL = _a.maxSwipeL, inTouch = _a.inTouch, swipedL = _a.swipedL, moveX = _a.moveX;
  262. var _right = !getDirectionLeft(changeArr) && changeArr[1] >= changeArr[0];
  263. if (inTouch && maxSwipeL <= moveX + 1 && _right && !swipedL) {
  264. _this.onSetCheck(false);
  265. }
  266. }, 100);
  267. }
  268. if (changeArr[0] > changeArr[1] && maxSwipeL > L + 2 && inTouch) {
  269. this.setData({ tapTypeL: '', myStyle: {} });
  270. }
  271. }
  272. },
  273. onSetCheck: function (isRight) {
  274. var _a = this.getProps(), rightButtons = _a.rightButtons, leftButtons = _a.leftButtons;
  275. var _b = this.data, inertiaWidth = _b.inertiaWidth, _leftButtons = _b._leftButtons, _rightButtons = _b._rightButtons;
  276. var arr = isRight ? rightButtons : leftButtons;
  277. var idx = arr.findIndex(function (u) { return u.confirmType === 'move'; });
  278. if (idx === -1)
  279. return;
  280. typeof my !== 'undefined' && my.vibrateShort({ success: function () { } });
  281. var styArr = isRight
  282. ? setStyleObj1(_rightButtons, inertiaWidth)
  283. : setStyleObj2(_leftButtons, inertiaWidth);
  284. var sty = styArr[idx];
  285. this.setData({ myStyle: sty });
  286. isRight
  287. ? this.setData({ tapTypeR: 'R-' + idx })
  288. : this.setData({ tapTypeL: 'L-' + idx });
  289. },
  290. // 意外中断了滑动,则立即开始结算滑动动作
  291. onTouchCancel: function (e) {
  292. this.onChangeEnd(e);
  293. },
  294. onChangeEnd: function (e) {
  295. var x = e.detail.x;
  296. var changeArr = this.data.changeArr;
  297. // 如果是停留在初始态返回
  298. if (x === 0)
  299. return;
  300. // 判断是否是左滑
  301. var isRight = getDirectionLeft(changeArr);
  302. this.setData({ swipeLeft: isRight });
  303. isRight ? this.onSetSwipeRight(x) : this.onSetSwipeLeft(x);
  304. },
  305. onSetSwipeRight: function (x, needBack) {
  306. var _a = this.data, swipedR = _a.swipedR, inTouch = _a.inTouch, tapTypeR = _a.tapTypeR, changeArr = _a.changeArr;
  307. var onButtonTap = this.getProps().onButtonTap;
  308. var isRight = Math.abs(changeArr[1]) > Math.abs(changeArr[0]);
  309. if (!swipedR && Math.abs(x) < 10) {
  310. isRight = false;
  311. }
  312. needBack && (isRight = false);
  313. !isRight && this.setData({ tapTypeR: '', myStyle: {} });
  314. if (inTouch && !!tapTypeR) {
  315. this.setData({ tapTypeR: '', myStyle: {} });
  316. onButtonTap({
  317. direction: 'right',
  318. btnIdx: parseInt(tapTypeR.replace('R-', '')),
  319. }, fmtEvent(this.getProps()));
  320. this.onSwipeRight(false);
  321. return;
  322. }
  323. this.setData({ changeArr: [0, 0] });
  324. this.onSwipeRight(isRight);
  325. },
  326. onSetSwipeLeft: function (x, needBack) {
  327. var _a = this.data, swipedL = _a.swipedL, inTouch = _a.inTouch, tapTypeL = _a.tapTypeL, changeArr = _a.changeArr;
  328. var onButtonTap = this.getProps().onButtonTap;
  329. // true:初始是往右滑,false: 右滑收起
  330. var isRight = changeArr[1] >= changeArr[0];
  331. if (!swipedL && Math.abs(x) < 10) {
  332. isRight = false;
  333. }
  334. needBack && (isRight = false);
  335. // 清空二次确认的状态
  336. !isRight && this.setData({ tapTypeL: '', myStyle: {} });
  337. // 处理滑动-触发事件
  338. if (inTouch && !!tapTypeL) {
  339. this.setData({ tapTypeL: '', myStyle: {} });
  340. onButtonTap({ direction: 'left', btnIdx: parseInt(tapTypeL.replace('L-', '')) }, fmtEvent(this.getProps()));
  341. this.onSwipeLeft(false);
  342. return;
  343. }
  344. // 清空滑动方向
  345. this.setData({ changeArr: [0, 0] });
  346. this.onSwipeLeft(isRight);
  347. },
  348. // 结算
  349. onSwipeLeft: function (isRight) {
  350. var _this = this;
  351. var onSwipeEnd = this.getProps().onSwipeEnd;
  352. var _a = this.data, maxSwipeL = _a.maxSwipeL, inertiaWidth = _a.inertiaWidth;
  353. // 为了处理到重置状态的效果
  354. var maxX = maxSwipeL + 0.01 + inertiaWidth;
  355. this.setData({
  356. swipeX: isRight ? maxX : -0.01,
  357. }, function () {
  358. var flag = _this.data.swipeX === -0.01;
  359. setTimeout(function () {
  360. _this.setData({
  361. swipeX: flag ? 0 : maxSwipeL + 0.01,
  362. swipedL: !flag,
  363. }, function () {
  364. onSwipeEnd({ direction: 'left', swiped: !!isRight }, fmtEvent(_this.getProps()));
  365. });
  366. }, inertiaWidth > 0 ? 180 : 0);
  367. });
  368. },
  369. onSwipeRight: function (isRight) {
  370. var _this = this;
  371. var _a = this.data, maxSwipeR = _a.maxSwipeR, inertiaWidth = _a.inertiaWidth;
  372. var onSwipeEnd = this.getProps().onSwipeEnd;
  373. // 处理x的位置,两次setData X是因为x如果相同位置不会变,刚好也把弹性在这里处理了
  374. // 为了处理到重置状态的效果
  375. var maxX = -(maxSwipeR + 0.01 + inertiaWidth);
  376. this.setData({
  377. swipeX: isRight ? maxX : -0.01,
  378. }, function () {
  379. var flag = _this.data.swipeX === -0.01;
  380. setTimeout(function () {
  381. _this.setData({
  382. swipeX: flag ? 0 : -(maxSwipeR + 0.01),
  383. swipedR: !flag,
  384. }, function () {
  385. onSwipeEnd({ direction: 'right', swiped: !!isRight }, fmtEvent(_this.getProps()));
  386. });
  387. }, inertiaWidth > 0 ? 180 : 0);
  388. });
  389. },
  390. // 处理右侧点击事件
  391. onItemTap: function (e) {
  392. var _a = this.data, swipeLeft = _a.swipeLeft, tapTypeL = _a.tapTypeL, tapTypeR = _a.tapTypeR, _leftButtons = _a._leftButtons, _rightButtons = _a._rightButtons;
  393. var onButtonTap = this.getProps().onButtonTap;
  394. if (!onButtonTap)
  395. return;
  396. var _b = e.currentTarget.dataset.item, itemL = _b.itemL, idx = _b.idx, item = _b.item;
  397. var confirmType = (swipeLeft ? item : itemL).confirmType;
  398. if (tapTypeL === 'L-' + idx) {
  399. this.onSetSwipeLeft(0, true);
  400. this.setData({ tapTypeL: '', myStyle: {} });
  401. onButtonTap({ direction: 'left', btnIdx: idx }, fmtEvent(this.getProps()));
  402. return;
  403. }
  404. if (tapTypeR === 'R-' + idx) {
  405. this.onSetSwipeRight(0, true);
  406. this.setData({ tapTypeR: '', myStyle: {} });
  407. onButtonTap({ direction: 'right', btnIdx: idx }, fmtEvent(this.getProps()));
  408. return;
  409. }
  410. // auto 是展开按钮二次确认的效果
  411. if (confirmType === 'tap' || confirmType === 'move') {
  412. var styArr = swipeLeft
  413. ? setStyleObj1(_rightButtons)
  414. : setStyleObj2(_leftButtons);
  415. var sty = styArr[idx];
  416. this.setData({ myStyle: sty });
  417. !swipeLeft
  418. ? this.setData({ tapTypeL: 'L-' + idx })
  419. : this.setData({ tapTypeR: 'R-' + idx });
  420. }
  421. else {
  422. !swipeLeft
  423. ? this.onSetSwipeLeft(0, true)
  424. : this.onSetSwipeRight(0, true);
  425. onButtonTap({ direction: !swipeLeft ? 'left' : 'right', btnIdx: idx }, fmtEvent(this.getProps()));
  426. }
  427. },
  428. },
  429. }));