UNPKG

@ctsy/layui-vue

Version:

a component library for Vue 3 base on layui-vue

198 lines (197 loc) 7.02 kB
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, ref, shallowRef, computed, onMounted, onBeforeUnmount, withDirectives, openBlock, createElementBlock, normalizeClass, unref, normalizeStyle, withModifiers, renderSlot, createVNode, vShow } from "vue"; import "../icon/index.js"; import { _ as _sfc_main$2E } from "../icons-vue.es.js"; var index = ""; const _hoisted_1 = ["onClick"]; const __default__ = { name: "LayBacktop" }; const _sfc_main = /* @__PURE__ */ defineComponent(__spreadProps(__spreadValues({}, __default__), { props: { target: { default: "window" }, showHeight: { default: 200 }, disabled: { type: Boolean, default: false }, position: null, right: null, bottom: null, size: null, bgcolor: null, opacity: null, color: null, borderRadius: null, circle: { type: Boolean, default: false }, icon: { default: "layui-icon-top" }, iconSize: { default: 30 }, iconColor: null }, emits: ["click"], setup(__props, { emit }) { const props = __props; const backtopRef = ref(null); const scrollTarget = shallowRef(void 0); let visible = ref(props.showHeight === 0); const classBacktop = computed(() => { return { "layui-backtop-medium": props.size === "medium", "layui-backtop-small": props.size === "small" }; }); const borderRadius = computed(() => { if (props.circle) { return "50%"; } return typeof props.borderRadius === "number" ? `${props.borderRadius}px` : props.borderRadius; }); const styleBacktop = computed(() => { return { position: props.position, right: `${props.right}px`, bottom: `${props.bottom}px`, backgroundColor: props.bgcolor, opacity: props.opacity, color: props.color, borderRadius: borderRadius.value }; }); const easeInOut = (value) => { return value < 0.5 ? 2 * value * value : 1 - 2 * (value - 1) * (value - 1); }; const scrollToTop = () => { if (!scrollTarget.value) return; if (scrollTarget.value instanceof Window) { window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); } else { const previous = Date.now(); const scrollHeight = scrollTarget.value.scrollTop; const animationFunc = () => { if (!scrollTarget.value || scrollTarget.value instanceof Window) return; const elapsed = (Date.now() - previous) / 450; if (elapsed < 1) { scrollTarget.value.scrollTop = scrollHeight * (1 - easeInOut(elapsed)); window.requestAnimationFrame(animationFunc); } else { scrollTarget.value.scrollTop = 0; } }; window.requestAnimationFrame(animationFunc); } }; const handleScroll = () => { if (!scrollTarget.value) return; const scrollTop = scrollTarget.value instanceof Window ? window.pageYOffset : scrollTarget.value.scrollTop; visible.value = scrollTop >= props.showHeight; }; const handleClick = (event) => { if (!props.disabled) { scrollToTop(); } emit("click", event); }; const handlerMousedown = () => { backtopRef.value.style.opacity = "1"; }; const handlerMouseup = () => { backtopRef.value.style.opacity = "0.95"; }; const getScrollTarget = () => { if (props.target === "window") { return getScrollParent(backtopRef.value, false); } else { const targetElement = document.querySelector(props.target); if (!targetElement) { throw new Error(`target is not existed: ${props.target}`); } if (props.position === "absolute") { if (!targetElement.parentElement) { throw new Error(`target parent element is not existed: ${props.target}`); } targetElement.parentElement.style.position = "relative"; } return targetElement; } }; const getScrollParent = (element, includeHidden) => { let style = getComputedStyle(element); let excludeStaticParent = style.position === "absolute"; let overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/; for (let parent = element; parent = parent.parentElement; ) { style = getComputedStyle(parent); if (excludeStaticParent && style.position === "static") { continue; } if (overflowRegex.test(style.overflow + style.overflowY + style.overflowX)) { return parent; } } return document.documentElement || document.body || window; }; const throttle = (func, wait) => { var timer = null; return (...args) => { if (!timer) { timer = setTimeout(() => { timer = null; func.apply(this, args); }, wait); } }; }; onMounted(() => { if (!props.target) return; scrollTarget.value = getScrollTarget(); scrollTarget.value.addEventListener("scroll", throttle(handleScroll, 300)); }); onBeforeUnmount(() => { var _a; (_a = scrollTarget.value) == null ? void 0 : _a.removeEventListener("scroll", throttle(handleScroll, 300)); }); return (_ctx, _cache) => { return withDirectives((openBlock(), createElementBlock("div", { ref_key: "backtopRef", ref: backtopRef, class: normalizeClass(["layui-backtop", unref(classBacktop)]), style: normalizeStyle(__spreadValues({}, unref(styleBacktop))), onClick: withModifiers(handleClick, ["stop"]), onMousedown: handlerMousedown, onMouseup: handlerMouseup }, [ renderSlot(_ctx.$slots, "default", {}, () => [ createVNode(unref(_sfc_main$2E), { type: props.icon, size: `${props.iconSize}px`, color: props.iconColor }, null, 8, ["type", "size", "color"]) ]) ], 46, _hoisted_1)), [ [vShow, unref(visible)] ]); }; } })); _sfc_main.install = (app) => { app.component(_sfc_main.name, _sfc_main); }; export { _sfc_main as default };