index.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. // Utils
  2. import { createNamespace } from '../utils';
  3. import { range } from '../utils/format/number';
  4. import { preventDefault } from '../utils/dom/event'; // Mixins
  5. import { TouchMixin } from '../mixins/touch';
  6. import { ClickOutsideMixin } from '../mixins/click-outside';
  7. var _createNamespace = createNamespace('swipe-cell'),
  8. createComponent = _createNamespace[0],
  9. bem = _createNamespace[1];
  10. var THRESHOLD = 0.15;
  11. export default createComponent({
  12. mixins: [TouchMixin, ClickOutsideMixin({
  13. event: 'touchstart',
  14. method: 'onClick'
  15. })],
  16. props: {
  17. // @deprecated
  18. // should be removed in next major version, use beforeClose instead
  19. onClose: Function,
  20. disabled: Boolean,
  21. leftWidth: [Number, String],
  22. rightWidth: [Number, String],
  23. beforeClose: Function,
  24. stopPropagation: Boolean,
  25. name: {
  26. type: [Number, String],
  27. default: ''
  28. }
  29. },
  30. data: function data() {
  31. return {
  32. offset: 0,
  33. dragging: false
  34. };
  35. },
  36. computed: {
  37. computedLeftWidth: function computedLeftWidth() {
  38. return +this.leftWidth || this.getWidthByRef('left');
  39. },
  40. computedRightWidth: function computedRightWidth() {
  41. return +this.rightWidth || this.getWidthByRef('right');
  42. }
  43. },
  44. mounted: function mounted() {
  45. this.bindTouchEvent(this.$el);
  46. },
  47. methods: {
  48. getWidthByRef: function getWidthByRef(ref) {
  49. if (this.$refs[ref]) {
  50. var rect = this.$refs[ref].getBoundingClientRect();
  51. return rect.width;
  52. }
  53. return 0;
  54. },
  55. // @exposed-api
  56. open: function open(position) {
  57. var offset = position === 'left' ? this.computedLeftWidth : -this.computedRightWidth;
  58. this.opened = true;
  59. this.offset = offset;
  60. this.$emit('open', {
  61. position: position,
  62. name: this.name,
  63. // @deprecated
  64. // should be removed in next major version
  65. detail: this.name
  66. });
  67. },
  68. // @exposed-api
  69. close: function close(position) {
  70. this.offset = 0;
  71. if (this.opened) {
  72. this.opened = false;
  73. this.$emit('close', {
  74. position: position,
  75. name: this.name
  76. });
  77. }
  78. },
  79. onTouchStart: function onTouchStart(event) {
  80. if (this.disabled) {
  81. return;
  82. }
  83. this.startOffset = this.offset;
  84. this.touchStart(event);
  85. },
  86. onTouchMove: function onTouchMove(event) {
  87. if (this.disabled) {
  88. return;
  89. }
  90. this.touchMove(event);
  91. if (this.direction === 'horizontal') {
  92. this.dragging = true;
  93. this.lockClick = true;
  94. var isPrevent = !this.opened || this.deltaX * this.startOffset < 0;
  95. if (isPrevent) {
  96. preventDefault(event, this.stopPropagation);
  97. }
  98. this.offset = range(this.deltaX + this.startOffset, -this.computedRightWidth, this.computedLeftWidth);
  99. }
  100. },
  101. onTouchEnd: function onTouchEnd() {
  102. var _this = this;
  103. if (this.disabled) {
  104. return;
  105. }
  106. if (this.dragging) {
  107. this.toggle(this.offset > 0 ? 'left' : 'right');
  108. this.dragging = false; // compatible with desktop scenario
  109. setTimeout(function () {
  110. _this.lockClick = false;
  111. }, 0);
  112. }
  113. },
  114. toggle: function toggle(direction) {
  115. var offset = Math.abs(this.offset);
  116. var threshold = this.opened ? 1 - THRESHOLD : THRESHOLD;
  117. var computedLeftWidth = this.computedLeftWidth,
  118. computedRightWidth = this.computedRightWidth;
  119. if (computedRightWidth && direction === 'right' && offset > computedRightWidth * threshold) {
  120. this.open('right');
  121. } else if (computedLeftWidth && direction === 'left' && offset > computedLeftWidth * threshold) {
  122. this.open('left');
  123. } else {
  124. this.close();
  125. }
  126. },
  127. onClick: function onClick(position) {
  128. if (position === void 0) {
  129. position = 'outside';
  130. }
  131. this.$emit('click', position);
  132. if (this.opened && !this.lockClick) {
  133. if (this.beforeClose) {
  134. this.beforeClose({
  135. position: position,
  136. name: this.name,
  137. instance: this
  138. });
  139. } else if (this.onClose) {
  140. this.onClose(position, this, {
  141. name: this.name
  142. });
  143. } else {
  144. this.close(position);
  145. }
  146. }
  147. },
  148. getClickHandler: function getClickHandler(position, stop) {
  149. var _this2 = this;
  150. return function (event) {
  151. if (stop) {
  152. event.stopPropagation();
  153. }
  154. _this2.onClick(position);
  155. };
  156. },
  157. genLeftPart: function genLeftPart() {
  158. var h = this.$createElement;
  159. var content = this.slots('left');
  160. if (content) {
  161. return h("div", {
  162. "ref": "left",
  163. "class": bem('left'),
  164. "on": {
  165. "click": this.getClickHandler('left', true)
  166. }
  167. }, [content]);
  168. }
  169. },
  170. genRightPart: function genRightPart() {
  171. var h = this.$createElement;
  172. var content = this.slots('right');
  173. if (content) {
  174. return h("div", {
  175. "ref": "right",
  176. "class": bem('right'),
  177. "on": {
  178. "click": this.getClickHandler('right', true)
  179. }
  180. }, [content]);
  181. }
  182. }
  183. },
  184. render: function render() {
  185. var h = arguments[0];
  186. var wrapperStyle = {
  187. transform: "translate3d(" + this.offset + "px, 0, 0)",
  188. transitionDuration: this.dragging ? '0s' : '.6s'
  189. };
  190. return h("div", {
  191. "class": bem(),
  192. "on": {
  193. "click": this.getClickHandler('cell')
  194. }
  195. }, [h("div", {
  196. "class": bem('wrapper'),
  197. "style": wrapperStyle
  198. }, [this.genLeftPart(), this.slots(), this.genRightPart()])]);
  199. }
  200. });