index-e8b8fc91.js 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import { c as createNamespace, m as makeNumericProp, n as numericProp, A as useScrollParent, D as useEventListener, P as getScrollTop, p as preventDefault, w as withInstall } from "./index-487cde8c.js";
  2. import { u as useTouch } from "./index-eef3af38.js";
  3. import { L as Loading } from "./index-217c49a0.js";
  4. import { d as defineComponent, r as ref, n as reactive, w as watch, c as createVNode, z as nextTick } from "./index-5e4623ce.js";
  5. const [name, bem, t] = createNamespace("pull-refresh");
  6. const DEFAULT_HEAD_HEIGHT = 50;
  7. const TEXT_STATUS = ["pulling", "loosing", "success"];
  8. const pullRefreshProps = {
  9. disabled: Boolean,
  10. modelValue: Boolean,
  11. headHeight: makeNumericProp(DEFAULT_HEAD_HEIGHT),
  12. successText: String,
  13. pullingText: String,
  14. loosingText: String,
  15. loadingText: String,
  16. pullDistance: numericProp,
  17. successDuration: makeNumericProp(500),
  18. animationDuration: makeNumericProp(300)
  19. };
  20. var stdin_default = defineComponent({
  21. name,
  22. props: pullRefreshProps,
  23. emits: ["change", "refresh", "update:modelValue"],
  24. setup(props, {
  25. emit,
  26. slots
  27. }) {
  28. let reachTop;
  29. const root = ref();
  30. const track = ref();
  31. const scrollParent = useScrollParent(root);
  32. const state = reactive({
  33. status: "normal",
  34. distance: 0,
  35. duration: 0
  36. });
  37. const touch = useTouch();
  38. const getHeadStyle = () => {
  39. if (props.headHeight !== DEFAULT_HEAD_HEIGHT) {
  40. return {
  41. height: `${props.headHeight}px`
  42. };
  43. }
  44. };
  45. const isTouchable = () => state.status !== "loading" && state.status !== "success" && !props.disabled;
  46. const ease = (distance) => {
  47. const pullDistance = +(props.pullDistance || props.headHeight);
  48. if (distance > pullDistance) {
  49. if (distance < pullDistance * 2) {
  50. distance = pullDistance + (distance - pullDistance) / 2;
  51. } else {
  52. distance = pullDistance * 1.5 + (distance - pullDistance * 2) / 4;
  53. }
  54. }
  55. return Math.round(distance);
  56. };
  57. const setStatus = (distance, isLoading) => {
  58. const pullDistance = +(props.pullDistance || props.headHeight);
  59. state.distance = distance;
  60. if (isLoading) {
  61. state.status = "loading";
  62. } else if (distance === 0) {
  63. state.status = "normal";
  64. } else if (distance < pullDistance) {
  65. state.status = "pulling";
  66. } else {
  67. state.status = "loosing";
  68. }
  69. emit("change", {
  70. status: state.status,
  71. distance
  72. });
  73. };
  74. const getStatusText = () => {
  75. const {
  76. status
  77. } = state;
  78. if (status === "normal") {
  79. return "";
  80. }
  81. return props[`${status}Text`] || t(status);
  82. };
  83. const renderStatus = () => {
  84. const {
  85. status,
  86. distance
  87. } = state;
  88. if (slots[status]) {
  89. return slots[status]({
  90. distance
  91. });
  92. }
  93. const nodes = [];
  94. if (TEXT_STATUS.includes(status)) {
  95. nodes.push(createVNode("div", {
  96. "class": bem("text")
  97. }, [getStatusText()]));
  98. }
  99. if (status === "loading") {
  100. nodes.push(createVNode(Loading, {
  101. "class": bem("loading")
  102. }, {
  103. default: getStatusText
  104. }));
  105. }
  106. return nodes;
  107. };
  108. const showSuccessTip = () => {
  109. state.status = "success";
  110. setTimeout(() => {
  111. setStatus(0);
  112. }, +props.successDuration);
  113. };
  114. const checkPosition = (event) => {
  115. reachTop = getScrollTop(scrollParent.value) === 0;
  116. if (reachTop) {
  117. state.duration = 0;
  118. touch.start(event);
  119. }
  120. };
  121. const onTouchStart = (event) => {
  122. if (isTouchable()) {
  123. checkPosition(event);
  124. }
  125. };
  126. const onTouchMove = (event) => {
  127. if (isTouchable()) {
  128. if (!reachTop) {
  129. checkPosition(event);
  130. }
  131. const {
  132. deltaY
  133. } = touch;
  134. touch.move(event);
  135. if (reachTop && deltaY.value >= 0 && touch.isVertical()) {
  136. preventDefault(event);
  137. setStatus(ease(deltaY.value));
  138. }
  139. }
  140. };
  141. const onTouchEnd = () => {
  142. if (reachTop && touch.deltaY.value && isTouchable()) {
  143. state.duration = +props.animationDuration;
  144. if (state.status === "loosing") {
  145. setStatus(+props.headHeight, true);
  146. emit("update:modelValue", true);
  147. nextTick(() => emit("refresh"));
  148. } else {
  149. setStatus(0);
  150. }
  151. }
  152. };
  153. watch(() => props.modelValue, (value) => {
  154. state.duration = +props.animationDuration;
  155. if (value) {
  156. setStatus(+props.headHeight, true);
  157. } else if (slots.success || props.successText) {
  158. showSuccessTip();
  159. } else {
  160. setStatus(0, false);
  161. }
  162. });
  163. useEventListener("touchmove", onTouchMove, {
  164. target: track
  165. });
  166. return () => {
  167. var _a;
  168. const trackStyle = {
  169. transitionDuration: `${state.duration}ms`,
  170. transform: state.distance ? `translate3d(0,${state.distance}px, 0)` : ""
  171. };
  172. return createVNode("div", {
  173. "ref": root,
  174. "class": bem()
  175. }, [createVNode("div", {
  176. "ref": track,
  177. "class": bem("track"),
  178. "style": trackStyle,
  179. "onTouchstartPassive": onTouchStart,
  180. "onTouchend": onTouchEnd,
  181. "onTouchcancel": onTouchEnd
  182. }, [createVNode("div", {
  183. "class": bem("head"),
  184. "style": getHeadStyle()
  185. }, [renderStatus()]), (_a = slots.default) == null ? void 0 : _a.call(slots)])]);
  186. };
  187. }
  188. });
  189. const PullRefresh = withInstall(stdin_default);
  190. const index = "";
  191. export {
  192. PullRefresh as P
  193. };