@varlet/use
Version:
composable utils of varlet
568 lines (551 loc) • 15.8 kB
JavaScript
;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
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 __objRest = (source, exclude) => {
var target = {};
for (var prop in source)
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
target[prop] = source[prop];
if (source != null && __getOwnPropSymbols)
for (var prop of __getOwnPropSymbols(source)) {
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
target[prop] = source[prop];
}
return target;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
keyInProvides: () => keyInProvides,
onSmartMounted: () => onSmartMounted,
onSmartUnmounted: () => onSmartUnmounted,
onWindowResize: () => onWindowResize,
useChildren: () => useChildren,
useClickOutside: () => useClickOutside,
useClientId: () => useClientId,
useEventListener: () => useEventListener,
useId: () => useId,
useInitialized: () => useInitialized,
useMotion: () => useMotion,
useParent: () => useParent,
useTouch: () => useTouch,
useVModel: () => useVModel,
useWindowSize: () => useWindowSize
});
module.exports = __toCommonJS(src_exports);
// src/useEventListener.ts
var import_vue2 = require("vue");
var import_shared = require("@varlet/shared");
// src/onSmartMounted.ts
var import_vue = require("vue");
function onSmartMounted(hook) {
let isMounted = false;
(0, import_vue.onMounted)(() => {
hook();
(0, import_vue.nextTick)(() => {
isMounted = true;
});
});
(0, import_vue.onActivated)(() => {
if (!isMounted) {
return;
}
hook();
});
}
// src/useEventListener.ts
function useEventListener(target, type, listener, options = {}) {
if (!(0, import_shared.inBrowser)()) {
return;
}
const { passive = false, capture = false } = options;
let listening = false;
let cleaned = false;
const getElement = (target2) => (0, import_shared.isFunction)(target2) ? target2() : (0, import_vue2.unref)(target2);
const add = (target2) => {
if (listening || cleaned) {
return;
}
const element = getElement(target2);
if (element) {
element.addEventListener(type, listener, {
passive,
capture
});
listening = true;
}
};
const remove = (target2) => {
if (!listening || cleaned) {
return;
}
const element = getElement(target2);
if (element) {
element.removeEventListener(type, listener, {
capture
});
listening = false;
}
};
let watchStopHandle;
if ((0, import_vue2.isRef)(target)) {
watchStopHandle = (0, import_vue2.watch)(
() => target.value,
(newValue, oldValue) => {
remove(oldValue);
add(newValue);
}
);
}
const cleanup = () => {
watchStopHandle == null ? void 0 : watchStopHandle();
remove(target);
cleaned = true;
};
onSmartMounted(() => {
add(target);
});
(0, import_vue2.onBeforeUnmount)(() => {
remove(target);
});
(0, import_vue2.onDeactivated)(() => {
remove(target);
});
return cleanup;
}
// src/useClickOutside.ts
var import_vue3 = require("vue");
var import_shared2 = require("@varlet/shared");
function useClickOutside(target, type, listener) {
if (!(0, import_shared2.inBrowser)()) {
return;
}
const handler = (event) => {
const element = (0, import_shared2.isFunction)(target) ? target() : (0, import_vue3.unref)(target);
if (element && !element.contains(event.target)) {
listener(event);
}
};
useEventListener(document, type, handler);
}
// src/onSmartUnmounted.ts
var import_vue4 = require("vue");
function onSmartUnmounted(hook) {
let keepalive = false;
(0, import_vue4.onDeactivated)(() => {
keepalive = true;
hook();
});
(0, import_vue4.onUnmounted)(() => {
if (keepalive) {
return;
}
hook();
});
}
// src/useParent.ts
var import_vue5 = require("vue");
function keyInProvides(key) {
const instance = (0, import_vue5.getCurrentInstance)();
return key in instance.provides;
}
function useParent(key) {
if (!keyInProvides(key)) {
return {
index: null,
parentProvider: null,
bindParent: null
};
}
const provider = (0, import_vue5.inject)(key);
const _a = provider, { childInstances, collect, clear } = _a, parentProvider = __objRest(_a, ["childInstances", "collect", "clear"]);
const childInstance = (0, import_vue5.getCurrentInstance)();
const index = (0, import_vue5.computed)(() => childInstances.indexOf(childInstance));
const bindParent = (childProvider) => {
(0, import_vue5.onMounted)(() => {
(0, import_vue5.nextTick)().then(() => {
collect(childInstance, childProvider);
});
});
(0, import_vue5.onBeforeUnmount)(() => {
(0, import_vue5.nextTick)().then(() => {
clear(childInstance, childProvider);
});
});
};
return {
index,
parentProvider,
bindParent
};
}
// src/useChildren.ts
var import_vue6 = require("vue");
var import_shared3 = require("@varlet/shared");
function flatVNodes(subTree) {
const vNodes = [];
const flat = (subTree2) => {
if (subTree2 == null ? void 0 : subTree2.component) {
flat(subTree2 == null ? void 0 : subTree2.component.subTree);
return;
}
if ((0, import_shared3.isArray)(subTree2 == null ? void 0 : subTree2.children)) {
subTree2.children.forEach((child) => {
if ((0, import_vue6.isVNode)(child)) {
vNodes.push(child);
flat(child);
}
});
}
};
flat(subTree);
return vNodes;
}
function useChildren(key) {
const parentInstance = (0, import_vue6.getCurrentInstance)();
const childInstances = (0, import_vue6.reactive)([]);
const childProviders = [];
const length = (0, import_vue6.computed)(() => childInstances.length);
const sortInstances = () => {
const vNodes = flatVNodes(parentInstance.subTree);
childInstances.sort((a, b) => vNodes.indexOf(a.vnode) - vNodes.indexOf(b.vnode));
};
const collect = (childInstance, childProvider) => {
childInstances.push(childInstance);
childProviders.push(childProvider);
sortInstances();
};
const clear = (childInstance, childProvider) => {
(0, import_shared3.removeItem)(childInstances, childInstance);
(0, import_shared3.removeItem)(childProviders, childProvider);
};
const bindChildren = (parentProvider) => {
(0, import_vue6.provide)(key, __spreadValues({
childInstances,
collect,
clear
}, parentProvider));
};
return {
length,
childProviders,
bindChildren
};
}
// src/onWindowResize.ts
function onWindowResize(listener) {
useEventListener(() => window, "resize", listener, { passive: true });
useEventListener(() => window, "orientationchange", listener, { passive: true });
}
// src/useInitialized.ts
var import_vue7 = require("vue");
function useInitialized(source, value) {
const initialized = (0, import_vue7.ref)(false);
(0, import_vue7.watch)(
source,
(newValue) => {
if (value === newValue) {
initialized.value = true;
}
},
{ immediate: true }
);
return initialized;
}
// src/useTouch.ts
var import_vue8 = require("vue");
var import_shared4 = require("@varlet/shared");
function getDirection(x, y) {
if (x > y) {
return "horizontal";
}
if (y > x) {
return "vertical";
}
}
function useTouch() {
const startX = (0, import_vue8.ref)(0);
const startY = (0, import_vue8.ref)(0);
const deltaX = (0, import_vue8.ref)(0);
const deltaY = (0, import_vue8.ref)(0);
const offsetX = (0, import_vue8.ref)(0);
const offsetY = (0, import_vue8.ref)(0);
const prevX = (0, import_vue8.ref)(0);
const prevY = (0, import_vue8.ref)(0);
const moveX = (0, import_vue8.ref)(0);
const moveY = (0, import_vue8.ref)(0);
const direction = (0, import_vue8.ref)();
const touching = (0, import_vue8.ref)(false);
const dragging = (0, import_vue8.ref)(false);
const startTime = (0, import_vue8.ref)(0);
const distance = (0, import_vue8.ref)(0);
let draggingAnimationFrame = null;
const resetTouch = () => {
startX.value = 0;
startY.value = 0;
deltaX.value = 0;
deltaY.value = 0;
offsetX.value = 0;
offsetY.value = 0;
prevX.value = 0;
prevY.value = 0;
moveX.value = 0;
moveY.value = 0;
direction.value = void 0;
touching.value = false;
dragging.value = false;
startTime.value = 0;
distance.value = 0;
};
const startTouch = (event) => {
resetTouch();
const { clientX: x, clientY: y } = event.touches[0];
startX.value = x;
startY.value = y;
prevX.value = x;
prevY.value = y;
touching.value = true;
startTime.value = performance.now();
dragging.value = false;
if (draggingAnimationFrame) {
window.cancelAnimationFrame(draggingAnimationFrame);
}
};
const moveTouch = (event) => {
const { clientX: x, clientY: y } = event.touches[0];
dragging.value = true;
deltaX.value = x - startX.value;
deltaY.value = y - startY.value;
offsetX.value = Math.abs(deltaX.value);
offsetY.value = Math.abs(deltaY.value);
distance.value = Math.sqrt(offsetX.value ** 2 + offsetY.value ** 2);
moveX.value = x - prevX.value;
moveY.value = y - prevY.value;
if (!direction.value) {
direction.value = getDirection(offsetX.value, offsetY.value);
}
prevX.value = x;
prevY.value = y;
};
const endTouch = () => {
touching.value = false;
draggingAnimationFrame = window.requestAnimationFrame(() => {
dragging.value = false;
});
};
const isReachTop = (element) => {
const scrollTop = (0, import_shared4.getScrollTop)(element);
return scrollTop === 0 && deltaY.value > 0;
};
const isReachBottom = (element, offset = 1) => {
const { scrollHeight, clientHeight, scrollTop } = element;
const offsetBottom = Math.abs(scrollHeight - scrollTop - clientHeight);
return deltaY.value < 0 && offsetBottom <= offset;
};
return {
startX,
startY,
deltaX,
deltaY,
offsetX,
offsetY,
prevX,
prevY,
moveX,
moveY,
direction,
touching,
dragging,
startTime,
distance,
resetTouch,
startTouch,
moveTouch,
endTouch,
isReachTop,
isReachBottom
};
}
// src/useId.ts
var import_vue9 = require("vue");
var import_shared5 = require("@varlet/shared");
function useId() {
const id = (0, import_vue9.ref)();
const instance = (0, import_vue9.getCurrentInstance)();
const name = (0, import_shared5.kebabCase)(instance.type.name);
id.value = process.env.NODE_ENV === "test" ? `${name}-mock-id` : `${name}-${instance.uid}`;
return id;
}
// src/useClientId.ts
var import_vue10 = require("vue");
var import_shared6 = require("@varlet/shared");
function useClientId() {
const instance = (0, import_vue10.getCurrentInstance)();
const name = (0, import_shared6.kebabCase)(instance.type.name);
const id = (0, import_vue10.ref)(process.env.NODE_ENV === "test" ? `${name}-mock-id` : void 0);
(0, import_vue10.onMounted)(() => {
if (process.env.NODE_ENV !== "test") {
id.value = `${name}-${instance.uid}`;
}
});
return id;
}
// src/useWindowSize.ts
var import_vue11 = require("vue");
var import_shared7 = require("@varlet/shared");
function useWindowSize(options = {}) {
const { initialWidth = 0, initialHeight = 0 } = options;
const width = (0, import_vue11.ref)(initialWidth);
const height = (0, import_vue11.ref)(initialHeight);
const update = () => {
if (!(0, import_shared7.inBrowser)()) {
return;
}
width.value = window.innerWidth;
height.value = window.innerHeight;
};
onSmartMounted(update);
onWindowResize(update);
return {
width,
height
};
}
// src/useVModel.ts
var import_vue12 = require("vue");
var import_shared8 = require("@varlet/shared");
function useVModel(props, key, options = {}) {
const { passive = true, eventName, defaultValue, emit } = options;
const event = eventName != null ? eventName : `onUpdate:${key.toString()}`;
const getValue = () => {
var _a;
return (_a = props[key]) != null ? _a : defaultValue;
};
if (!passive) {
return (0, import_vue12.computed)({
get() {
return getValue();
},
set(value) {
emit ? emit(event, value) : (0, import_shared8.call)(props[event], value);
}
});
}
const proxy = (0, import_vue12.ref)(getValue());
let shouldEmit = true;
(0, import_vue12.watch)(
() => props[key],
() => {
shouldEmit = false;
proxy.value = getValue();
(0, import_vue12.nextTick)(() => {
shouldEmit = true;
});
}
);
(0, import_vue12.watch)(
() => proxy.value,
(newValue) => {
if (!shouldEmit) {
return;
}
emit ? emit(event, newValue) : (0, import_shared8.call)(props[event], newValue);
}
);
return proxy;
}
// src/useMotion.ts
var import_vue13 = require("vue");
var import_shared9 = require("@varlet/shared");
function useMotion(options) {
const value = (0, import_vue13.ref)(getter(options.from));
const state = (0, import_vue13.ref)("pending");
let ctx = createMotionContext();
function getter(value2) {
return (0, import_shared9.isFunction)(value2) ? value2() : value2;
}
function reset() {
ctx.reset();
value.value = getter(options.from);
state.value = "pending";
ctx = createMotionContext();
}
function start() {
ctx.start();
}
function pause() {
ctx.pause();
}
function createMotionContext() {
return (0, import_shared9.motion)({
from: getter(options.from),
to: getter(options.to),
duration: options.duration ? getter(options.duration) : 300,
timingFunction: options.timingFunction,
onStateChange(newState) {
state.value = newState;
},
frame({ value: newValue, done }) {
var _a;
value.value = newValue;
if (done) {
(_a = options.onFinished) == null ? void 0 : _a.call(options, value.value);
}
}
});
}
return {
value,
state,
start,
pause,
reset
};
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
keyInProvides,
onSmartMounted,
onSmartUnmounted,
onWindowResize,
useChildren,
useClickOutside,
useClientId,
useEventListener,
useId,
useInitialized,
useMotion,
useParent,
useTouch,
useVModel,
useWindowSize
});