@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
JavaScript
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
};