index-eef3af38.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. import { r as ref, V as onDeactivated, M as onBeforeUnmount, w as watch, d as defineComponent, c as createVNode, L as Transition, T as Teleport, h as withDirectives, v as vShow, a as computed, z as nextTick, o as onMounted, p as onActivated, U as provide, F as Fragment, m as mergeProps } from "./index-5e4623ce.js";
  2. import { n as numericProp, t as truthProp, G as unknownProp, a3 as TAP_OFFSET, a4 as onMountedOrActivated, a0 as getScrollParent, p as preventDefault, c as createNamespace, D as useEventListener, e as extend, g as getZIndexStyle, k as isDef, w as withInstall, z as makeStringProp, H as HAPTICS_FEEDBACK, I as Icon } from "./index-487cde8c.js";
  3. import { u as useExpose, a as useScopeId } from "./use-scope-id-0b5b8615.js";
  4. import { P as POPUP_TOGGLE_KEY, c as callInterceptor } from "./on-popup-reopen-c5ca1603.js";
  5. let globalZIndex = 2e3;
  6. const useGlobalZIndex = () => ++globalZIndex;
  7. const popupSharedProps = {
  8. // whether to show popup
  9. show: Boolean,
  10. // z-index
  11. zIndex: numericProp,
  12. // whether to show overlay
  13. overlay: truthProp,
  14. // transition duration
  15. duration: numericProp,
  16. // teleport
  17. teleport: [String, Object],
  18. // prevent body scroll
  19. lockScroll: truthProp,
  20. // whether to lazy render
  21. lazyRender: truthProp,
  22. // callback function before close
  23. beforeClose: Function,
  24. // overlay custom style
  25. overlayStyle: Object,
  26. // overlay custom class name
  27. overlayClass: unknownProp,
  28. // Initial rendering animation
  29. transitionAppear: Boolean,
  30. // whether to close popup when overlay is clicked
  31. closeOnClickOverlay: truthProp
  32. };
  33. const popupSharedPropKeys = Object.keys(
  34. popupSharedProps
  35. );
  36. function getDirection(x, y) {
  37. if (x > y) {
  38. return "horizontal";
  39. }
  40. if (y > x) {
  41. return "vertical";
  42. }
  43. return "";
  44. }
  45. function useTouch() {
  46. const startX = ref(0);
  47. const startY = ref(0);
  48. const deltaX = ref(0);
  49. const deltaY = ref(0);
  50. const offsetX = ref(0);
  51. const offsetY = ref(0);
  52. const direction = ref("");
  53. const isTap = ref(true);
  54. const isVertical = () => direction.value === "vertical";
  55. const isHorizontal = () => direction.value === "horizontal";
  56. const reset = () => {
  57. deltaX.value = 0;
  58. deltaY.value = 0;
  59. offsetX.value = 0;
  60. offsetY.value = 0;
  61. direction.value = "";
  62. isTap.value = true;
  63. };
  64. const start = (event) => {
  65. reset();
  66. startX.value = event.touches[0].clientX;
  67. startY.value = event.touches[0].clientY;
  68. };
  69. const move = (event) => {
  70. const touch = event.touches[0];
  71. deltaX.value = (touch.clientX < 0 ? 0 : touch.clientX) - startX.value;
  72. deltaY.value = touch.clientY - startY.value;
  73. offsetX.value = Math.abs(deltaX.value);
  74. offsetY.value = Math.abs(deltaY.value);
  75. const LOCK_DIRECTION_DISTANCE = 10;
  76. if (!direction.value || offsetX.value < LOCK_DIRECTION_DISTANCE && offsetY.value < LOCK_DIRECTION_DISTANCE) {
  77. direction.value = getDirection(offsetX.value, offsetY.value);
  78. }
  79. if (isTap.value && (offsetX.value > TAP_OFFSET || offsetY.value > TAP_OFFSET)) {
  80. isTap.value = false;
  81. }
  82. };
  83. return {
  84. move,
  85. start,
  86. reset,
  87. startX,
  88. startY,
  89. deltaX,
  90. deltaY,
  91. offsetX,
  92. offsetY,
  93. direction,
  94. isVertical,
  95. isHorizontal,
  96. isTap
  97. };
  98. }
  99. let totalLockCount = 0;
  100. const BODY_LOCK_CLASS = "van-overflow-hidden";
  101. function useLockScroll(rootRef, shouldLock) {
  102. const touch = useTouch();
  103. const DIRECTION_UP = "01";
  104. const DIRECTION_DOWN = "10";
  105. const onTouchMove = (event) => {
  106. touch.move(event);
  107. const direction = touch.deltaY.value > 0 ? DIRECTION_DOWN : DIRECTION_UP;
  108. const el = getScrollParent(
  109. event.target,
  110. rootRef.value
  111. );
  112. const { scrollHeight, offsetHeight, scrollTop } = el;
  113. let status = "11";
  114. if (scrollTop === 0) {
  115. status = offsetHeight >= scrollHeight ? "00" : "01";
  116. } else if (scrollTop + offsetHeight >= scrollHeight) {
  117. status = "10";
  118. }
  119. if (status !== "11" && touch.isVertical() && !(parseInt(status, 2) & parseInt(direction, 2))) {
  120. preventDefault(event, true);
  121. }
  122. };
  123. const lock = () => {
  124. document.addEventListener("touchstart", touch.start);
  125. document.addEventListener("touchmove", onTouchMove, { passive: false });
  126. if (!totalLockCount) {
  127. document.body.classList.add(BODY_LOCK_CLASS);
  128. }
  129. totalLockCount++;
  130. };
  131. const unlock = () => {
  132. if (totalLockCount) {
  133. document.removeEventListener("touchstart", touch.start);
  134. document.removeEventListener("touchmove", onTouchMove);
  135. totalLockCount--;
  136. if (!totalLockCount) {
  137. document.body.classList.remove(BODY_LOCK_CLASS);
  138. }
  139. }
  140. };
  141. const init = () => shouldLock() && lock();
  142. const destroy = () => shouldLock() && unlock();
  143. onMountedOrActivated(init);
  144. onDeactivated(destroy);
  145. onBeforeUnmount(destroy);
  146. watch(shouldLock, (value) => {
  147. value ? lock() : unlock();
  148. });
  149. }
  150. function useLazyRender(show) {
  151. const inited = ref(false);
  152. watch(
  153. show,
  154. (value) => {
  155. if (value) {
  156. inited.value = value;
  157. }
  158. },
  159. { immediate: true }
  160. );
  161. return (render) => () => inited.value ? render() : null;
  162. }
  163. const [name$1, bem$1] = createNamespace("overlay");
  164. const overlayProps = {
  165. show: Boolean,
  166. zIndex: numericProp,
  167. duration: numericProp,
  168. className: unknownProp,
  169. lockScroll: truthProp,
  170. lazyRender: truthProp,
  171. customStyle: Object,
  172. teleport: [String, Object]
  173. };
  174. var stdin_default$1 = defineComponent({
  175. name: name$1,
  176. props: overlayProps,
  177. setup(props, {
  178. slots
  179. }) {
  180. const root = ref();
  181. const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
  182. const onTouchMove = (event) => {
  183. if (props.lockScroll) {
  184. preventDefault(event, true);
  185. }
  186. };
  187. const renderOverlay = lazyRender(() => {
  188. var _a;
  189. const style = extend(getZIndexStyle(props.zIndex), props.customStyle);
  190. if (isDef(props.duration)) {
  191. style.animationDuration = `${props.duration}s`;
  192. }
  193. return withDirectives(createVNode("div", {
  194. "ref": root,
  195. "style": style,
  196. "class": [bem$1(), props.className]
  197. }, [(_a = slots.default) == null ? void 0 : _a.call(slots)]), [[vShow, props.show]]);
  198. });
  199. useEventListener("touchmove", onTouchMove, {
  200. target: root
  201. });
  202. return () => {
  203. const Content = createVNode(Transition, {
  204. "name": "van-fade",
  205. "appear": true
  206. }, {
  207. default: renderOverlay
  208. });
  209. if (props.teleport) {
  210. return createVNode(Teleport, {
  211. "to": props.teleport
  212. }, {
  213. default: () => [Content]
  214. });
  215. }
  216. return Content;
  217. };
  218. }
  219. });
  220. const Overlay = withInstall(stdin_default$1);
  221. const popupProps = extend({}, popupSharedProps, {
  222. round: Boolean,
  223. position: makeStringProp("center"),
  224. closeIcon: makeStringProp("cross"),
  225. closeable: Boolean,
  226. transition: String,
  227. iconPrefix: String,
  228. closeOnPopstate: Boolean,
  229. closeIconPosition: makeStringProp("top-right"),
  230. safeAreaInsetTop: Boolean,
  231. safeAreaInsetBottom: Boolean
  232. });
  233. const [name, bem] = createNamespace("popup");
  234. var stdin_default = defineComponent({
  235. name,
  236. inheritAttrs: false,
  237. props: popupProps,
  238. emits: ["open", "close", "opened", "closed", "keydown", "update:show", "clickOverlay", "clickCloseIcon"],
  239. setup(props, {
  240. emit,
  241. attrs,
  242. slots
  243. }) {
  244. let opened;
  245. let shouldReopen;
  246. const zIndex = ref();
  247. const popupRef = ref();
  248. const lazyRender = useLazyRender(() => props.show || !props.lazyRender);
  249. const style = computed(() => {
  250. const style2 = {
  251. zIndex: zIndex.value
  252. };
  253. if (isDef(props.duration)) {
  254. const key = props.position === "center" ? "animationDuration" : "transitionDuration";
  255. style2[key] = `${props.duration}s`;
  256. }
  257. return style2;
  258. });
  259. const open = () => {
  260. if (!opened) {
  261. opened = true;
  262. zIndex.value = props.zIndex !== void 0 ? +props.zIndex : useGlobalZIndex();
  263. emit("open");
  264. }
  265. };
  266. const close = () => {
  267. if (opened) {
  268. callInterceptor(props.beforeClose, {
  269. done() {
  270. opened = false;
  271. emit("close");
  272. emit("update:show", false);
  273. }
  274. });
  275. }
  276. };
  277. const onClickOverlay = (event) => {
  278. emit("clickOverlay", event);
  279. if (props.closeOnClickOverlay) {
  280. close();
  281. }
  282. };
  283. const renderOverlay = () => {
  284. if (props.overlay) {
  285. return createVNode(Overlay, mergeProps({
  286. "show": props.show,
  287. "class": props.overlayClass,
  288. "zIndex": zIndex.value,
  289. "duration": props.duration,
  290. "customStyle": props.overlayStyle,
  291. "role": props.closeOnClickOverlay ? "button" : void 0,
  292. "tabindex": props.closeOnClickOverlay ? 0 : void 0
  293. }, useScopeId(), {
  294. "onClick": onClickOverlay
  295. }), {
  296. default: slots["overlay-content"]
  297. });
  298. }
  299. };
  300. const onClickCloseIcon = (event) => {
  301. emit("clickCloseIcon", event);
  302. close();
  303. };
  304. const renderCloseIcon = () => {
  305. if (props.closeable) {
  306. return createVNode(Icon, {
  307. "role": "button",
  308. "tabindex": 0,
  309. "name": props.closeIcon,
  310. "class": [bem("close-icon", props.closeIconPosition), HAPTICS_FEEDBACK],
  311. "classPrefix": props.iconPrefix,
  312. "onClick": onClickCloseIcon
  313. }, null);
  314. }
  315. };
  316. let timer;
  317. const onOpened = () => {
  318. if (timer)
  319. clearTimeout(timer);
  320. timer = setTimeout(() => {
  321. emit("opened");
  322. });
  323. };
  324. const onClosed = () => emit("closed");
  325. const onKeydown = (event) => emit("keydown", event);
  326. const renderPopup = lazyRender(() => {
  327. var _a;
  328. const {
  329. round,
  330. position,
  331. safeAreaInsetTop,
  332. safeAreaInsetBottom
  333. } = props;
  334. return withDirectives(createVNode("div", mergeProps({
  335. "ref": popupRef,
  336. "style": style.value,
  337. "role": "dialog",
  338. "tabindex": 0,
  339. "class": [bem({
  340. round,
  341. [position]: position
  342. }), {
  343. "van-safe-area-top": safeAreaInsetTop,
  344. "van-safe-area-bottom": safeAreaInsetBottom
  345. }],
  346. "onKeydown": onKeydown
  347. }, attrs, useScopeId()), [(_a = slots.default) == null ? void 0 : _a.call(slots), renderCloseIcon()]), [[vShow, props.show]]);
  348. });
  349. const renderTransition = () => {
  350. const {
  351. position,
  352. transition,
  353. transitionAppear
  354. } = props;
  355. const name2 = position === "center" ? "van-fade" : `van-popup-slide-${position}`;
  356. return createVNode(Transition, {
  357. "name": transition || name2,
  358. "appear": transitionAppear,
  359. "onAfterEnter": onOpened,
  360. "onAfterLeave": onClosed
  361. }, {
  362. default: renderPopup
  363. });
  364. };
  365. watch(() => props.show, (show) => {
  366. if (show && !opened) {
  367. open();
  368. if (attrs.tabindex === 0) {
  369. nextTick(() => {
  370. var _a;
  371. (_a = popupRef.value) == null ? void 0 : _a.focus();
  372. });
  373. }
  374. }
  375. if (!show && opened) {
  376. opened = false;
  377. emit("close");
  378. }
  379. });
  380. useExpose({
  381. popupRef
  382. });
  383. useLockScroll(popupRef, () => props.show && props.lockScroll);
  384. useEventListener("popstate", () => {
  385. if (props.closeOnPopstate) {
  386. close();
  387. shouldReopen = false;
  388. }
  389. });
  390. onMounted(() => {
  391. if (props.show) {
  392. open();
  393. }
  394. });
  395. onActivated(() => {
  396. if (shouldReopen) {
  397. emit("update:show", true);
  398. shouldReopen = false;
  399. }
  400. });
  401. onDeactivated(() => {
  402. if (props.show && props.teleport) {
  403. close();
  404. shouldReopen = true;
  405. }
  406. });
  407. provide(POPUP_TOGGLE_KEY, () => props.show);
  408. return () => {
  409. if (props.teleport) {
  410. return createVNode(Teleport, {
  411. "to": props.teleport
  412. }, {
  413. default: () => [renderOverlay(), renderTransition()]
  414. });
  415. }
  416. return createVNode(Fragment, null, [renderOverlay(), renderTransition()]);
  417. };
  418. }
  419. });
  420. const Popup = withInstall(stdin_default);
  421. export {
  422. Overlay as O,
  423. Popup as P,
  424. popupSharedPropKeys as a,
  425. popupSharedProps as p,
  426. useTouch as u
  427. };