UNPKG

@varlet/ui

Version:

A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.

216 lines (215 loc) • 7.79 kB
var __async = (__this, __arguments, generator) => { return new Promise((resolve, reject) => { var fulfilled = (value) => { try { step(generator.next(value)); } catch (e) { reject(e); } }; var rejected = (value) => { try { step(generator.throw(value)); } catch (e) { reject(e); } }; var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected); step((generator = generator.apply(__this, __arguments)).next()); }); }; import { computed, defineComponent, nextTick, ref, watch } from "vue"; import { call, getRect, getScrollTop, isNumber, isString, preventDefault, toNumber } from "@varlet/shared"; import { onSmartMounted, useEventListener, useTouch } from "@varlet/use"; import VarIcon from "../icon/index.mjs"; import { createNamespace } from "../utils/components.mjs"; import { getParentScroller, getTarget } from "../utils/elements.mjs"; import { props } from "./props.mjs"; const { name, n, classes } = createNamespace("pull-refresh"); const ICON_TRANSITION = 150; import { resolveComponent as _resolveComponent, normalizeClass as _normalizeClass, createVNode as _createVNode, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, renderSlot as _renderSlot, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue"; function __render__(_ctx, _cache) { const _component_var_icon = _resolveComponent("var-icon"); return _openBlock(), _createElementBlock( "div", { ref: "freshNode", class: _normalizeClass(_ctx.n()), onTouchstart: _cache[0] || (_cache[0] = (...args) => _ctx.handleTouchstart && _ctx.handleTouchstart(...args)), onTouchend: _cache[1] || (_cache[1] = (...args) => _ctx.handleTouchend && _ctx.handleTouchend(...args)), onTouchcancel: _cache[2] || (_cache[2] = (...args) => _ctx.handleTouchend && _ctx.handleTouchend(...args)) }, [ _createElementVNode( "div", { ref: "controlNode", class: _normalizeClass(_ctx.classes(_ctx.n("control"), _ctx.n("$-elevation--2"), [_ctx.isSuccess, _ctx.n("control-success")])), style: _normalizeStyle(_ctx.controlStyle) }, [ _createVNode(_component_var_icon, { name: _ctx.iconName, transition: _ctx.ICON_TRANSITION, class: _normalizeClass(_ctx.classes(_ctx.n("icon"), [_ctx.refreshStatus === "loading", _ctx.n("animation")])), "var-pull-refresh-cover": "" }, null, 8, ["name", "transition", "class"]) ], 6 /* CLASS, STYLE */ ), _renderSlot(_ctx.$slots, "default") ], 34 /* CLASS, NEED_HYDRATION */ ); } const __sfc__ = defineComponent({ name, components: { VarIcon }, props, setup(props2) { const controlPosition = ref(0); const freshNode = ref(null); const controlNode = ref(null); const startPosition = ref(0); const distance = ref("-125%"); const iconName = ref("arrow-down"); const refreshStatus = ref("default"); const isEnd = ref(false); const maxDistance = computed(() => Math.abs(2 * controlPosition.value)); const isSuccess = computed(() => refreshStatus.value === "success"); const isTouchable = computed( () => refreshStatus.value !== "loading" && refreshStatus.value !== "success" && !props2.disabled ); const controlStyle = computed(() => ({ transform: `translate3d(0px, ${isString(distance.value) ? distance.value : `${distance.value}px`}, 0px) translate(-50%, 0)`, transition: isEnd.value ? `transform ${props2.animationDuration}ms` : void 0, background: isSuccess.value ? props2.successBgColor : props2.bgColor, color: isSuccess.value ? props2.successColor : props2.color })); const { startTouch, moveTouch, endTouch, isReachTop } = useTouch(); let scroller; let eventTargetScroller; watch( () => props2.modelValue, (newValue) => { if (newValue === false) { isEnd.value = true; refreshStatus.value = "success"; iconName.value = "checkbox-marked-circle"; setTimeout(() => { distance.value = controlPosition.value; reset(); }, toNumber(props2.successDuration)); } } ); onSmartMounted(setScroller); useEventListener(freshNode, "touchmove", handleTouchmove); function startIconTransition(name2) { if (iconName.value === name2) { return; } iconName.value = name2; return new Promise((resolve) => { window.setTimeout(resolve, ICON_TRANSITION); }); } function lockEvent(action) { const el = "classList" in scroller ? scroller : document.body; el.classList[action](`${n()}--lock`); } function handleTouchstart(event) { startTouch(event); if (controlPosition.value === 0) { const { width } = getRect(controlNode.value); controlPosition.value = -(width + width * 0.25); } eventTargetScroller = getParentScroller(event.target); } function handleTouchmove(event) { moveTouch(event); if (!isTouchable.value || !eventTargetScroller) { return; } if (eventTargetScroller !== scroller && getScrollTop(eventTargetScroller) > 0) { return; } const scrollTop = getScrollTop(scroller); if (scrollTop > 0) { return; } if (isReachTop(scroller)) { preventDefault(event); } if (refreshStatus.value !== "pulling") { refreshStatus.value = "pulling"; startPosition.value = event.touches[0].clientY; } if (isReachTop(scroller) && isNumber(distance.value) && distance.value > controlPosition.value) { lockEvent("add"); } const moveDistance = (event.touches[0].clientY - startPosition.value) / 2 + controlPosition.value; distance.value = moveDistance >= maxDistance.value ? maxDistance.value : moveDistance; startIconTransition(distance.value >= maxDistance.value * 0.2 ? "refresh" : "arrow-down"); } function handleTouchend() { return __async(this, null, function* () { endTouch(); if (!isTouchable.value) { return; } isEnd.value = true; if (toNumber(distance.value) >= maxDistance.value * 0.2) { yield startIconTransition("refresh"); refreshStatus.value = "loading"; distance.value = maxDistance.value * 0.3; call(props2["onUpdate:modelValue"], true); nextTick(() => { call(props2.onRefresh); }); lockEvent("remove"); } else { refreshStatus.value = "loosing"; iconName.value = "arrow-down"; distance.value = controlPosition.value; setTimeout(() => { isEnd.value = false; lockEvent("remove"); }, toNumber(props2.animationDuration)); } eventTargetScroller = null; }); } function setScroller() { scroller = props2.target ? getTarget(props2.target, "PullRefresh") : getParentScroller(freshNode.value); } function reset() { setTimeout(() => { refreshStatus.value = "default"; iconName.value = "arrow-down"; isEnd.value = false; }, toNumber(props2.animationDuration)); } return { ICON_TRANSITION, refreshStatus, freshNode, controlNode, iconName, controlStyle, isSuccess, n, classes, handleTouchstart, handleTouchmove, handleTouchend }; } }); __sfc__.render = __render__; var stdin_default = __sfc__; export { stdin_default as default };