@varlet/ui
Version:
A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.
241 lines (240 loc) • 7.95 kB
JavaScript
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {
for (var prop in b || (b = {}))
if (__hasOwnProp.call(b, prop))
__defNormalProp(a, prop, b[prop]);
if (__getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(b)) {
if (__propIsEnum.call(b, prop))
__defNormalProp(a, prop, b[prop]);
}
return a;
};
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
import { defineComponent, reactive, ref, watch } from "vue";
import { call, clamp, getRect, preventDefault } from "@varlet/shared";
import { onSmartMounted, onWindowResize, useTouch } from "@varlet/use";
import { createNamespace, useTeleport } from "../utils/components.mjs";
import { toPxNum } from "../utils/elements.mjs";
import { props } from "./props.mjs";
const { name, n, classes } = createNamespace("drag");
import { renderSlot as _renderSlot, mergeProps as _mergeProps, createElementVNode as _createElementVNode, Teleport as _Teleport, openBlock as _openBlock, createBlock as _createBlock } from "vue";
function __render__(_ctx, _cache) {
return _openBlock(), _createBlock(_Teleport, {
to: _ctx.teleport === false ? void 0 : _ctx.teleport,
disabled: _ctx.teleportDisabled || _ctx.teleport === false
}, [
_createElementVNode(
"div",
_mergeProps({
ref: "drag",
class: _ctx.classes(_ctx.n(), _ctx.n("$--box"), [_ctx.enableTransition, _ctx.n("--transition")]),
style: {
"z-index": _ctx.zIndex
}
}, _ctx.getAttrs(), {
onTouchstart: _cache[0] || (_cache[0] = (...args) => _ctx.handleTouchstart && _ctx.handleTouchstart(...args)),
onTouchmove: _cache[1] || (_cache[1] = (...args) => _ctx.handleTouchmove && _ctx.handleTouchmove(...args)),
onTouchend: _cache[2] || (_cache[2] = (...args) => _ctx.handleTouchend && _ctx.handleTouchend(...args)),
onTouchcancel: _cache[3] || (_cache[3] = (...args) => _ctx.handleTouchend && _ctx.handleTouchend(...args)),
onClick: _cache[4] || (_cache[4] = (...args) => _ctx.handleClick && _ctx.handleClick(...args))
}),
[
_renderSlot(_ctx.$slots, "default")
],
16
/* FULL_PROPS */
)
], 8, ["to", "disabled"]);
}
const __sfc__ = defineComponent({
name,
inheritAttrs: false,
props,
setup(props2, { attrs }) {
const drag = ref(null);
const x = ref(0);
const y = ref(0);
const dragged = ref(false);
const enableTransition = ref(false);
const { touching, dragging, moveX, moveY, startTouch, moveTouch, endTouch, resetTouch } = useTouch();
const { disabled: teleportDisabled } = useTeleport();
const boundary = reactive({
top: 0,
bottom: 0,
left: 0,
right: 0
});
watch(() => props2.boundary, toPxBoundary);
onWindowResize(resize);
onSmartMounted(() => {
toPxBoundary();
resize();
});
function handleTouchstart(event) {
if (props2.disabled) {
return;
}
startTouch(event);
saveXY();
}
function handleTouchmove(event) {
if (!touching.value || props2.disabled) {
return;
}
moveTouch(event);
preventDefault(event);
enableTransition.value = false;
dragged.value = true;
if (props2.direction.includes("x")) {
x.value += moveX.value;
}
if (props2.direction.includes("y")) {
y.value += moveY.value;
}
clampToBoundary();
}
function handleTouchend() {
if (props2.disabled) {
return;
}
endTouch();
enableTransition.value = true;
attract();
}
function handleClick(event) {
if (dragging.value) {
return;
}
call(props2.onClick, event);
}
function saveXY() {
const { left, top } = getOffset();
x.value = left;
y.value = top;
}
function getOffset() {
const dragRect = getRect(drag.value);
const windowRect = getRect(window);
const top = dragRect.top - windowRect.top;
const bottom = windowRect.bottom - dragRect.bottom;
const left = dragRect.left - windowRect.left;
const right = windowRect.right - dragRect.right;
const { width, height } = dragRect;
const { width: windowWidth, height: windowHeight } = windowRect;
return {
top,
bottom,
left,
right,
width,
height,
halfWidth: width / 2,
halfHeight: height / 2,
windowWidth,
windowHeight
};
}
function getRange() {
const offset = getOffset();
const x1 = boundary.left;
const x2 = offset.windowWidth - boundary.right - offset.width;
const y1 = boundary.top;
const y2 = offset.windowHeight - boundary.bottom - offset.height;
return {
minX: x1,
minY: y1,
// fallback the drag element overflows boundary
maxX: x1 < x2 ? x2 : x1,
maxY: y1 < y2 ? y2 : y1
};
}
function attract() {
if (props2.attraction == null) {
return;
}
const { halfWidth, halfHeight, top, bottom, left, right } = getOffset();
const { minX, minY, maxX, maxY } = getRange();
const leftDistance = left + halfWidth - boundary.left;
const rightDistance = right + halfWidth - boundary.right;
const topDistance = top + halfHeight - boundary.top;
const bottomDistance = bottom + halfHeight - boundary.bottom;
const nearLeft = leftDistance <= rightDistance;
const nearTop = topDistance <= bottomDistance;
if (props2.attraction.includes("x")) {
x.value = nearLeft ? minX : maxX;
}
if (props2.attraction.includes("y")) {
y.value = nearTop ? minY : maxY;
}
}
function clampToBoundary() {
const { minX, minY, maxX, maxY } = getRange();
x.value = clamp(x.value, minX, maxX);
y.value = clamp(y.value, minY, maxY);
}
function toPxBoundary() {
const { top = 0, bottom = 0, left = 0, right = 0 } = props2.boundary;
boundary.top = toPxNum(top);
boundary.bottom = toPxNum(bottom);
boundary.left = toPxNum(left);
boundary.right = toPxNum(right);
}
function getAttrs() {
var _a;
const style = (_a = attrs.style) != null ? _a : {};
return __spreadProps(__spreadValues({}, attrs), {
style: __spreadProps(__spreadValues({}, style), {
// when the drag element is dragged for the first time, the inset should be cleared to avoid affecting translateX and translateY.
top: dragged.value ? 0 : style.top,
left: dragged.value ? 0 : style.left,
right: dragged.value ? "auto" : style.right,
bottom: dragged.value ? "auto" : style.bottom,
transform: dragged.value ? `translate(${x.value}px, ${y.value}px)` : style.transform
})
});
}
function resize() {
if (!dragged.value) {
return;
}
saveXY();
clampToBoundary();
}
function reset() {
resetTouch();
enableTransition.value = false;
dragged.value = false;
x.value = 0;
y.value = 0;
}
return {
drag,
x,
y,
enableTransition,
dragging,
teleportDisabled,
n,
classes,
getAttrs,
handleTouchstart,
handleTouchmove,
handleTouchend,
handleClick,
resize,
reset
};
}
});
__sfc__.render = __render__;
var stdin_default = __sfc__;
export {
stdin_default as default
};