@varlet/ui
Version:
A Vue3 component library based on Material Design 2 and 3, supporting mobile and desktop.
179 lines (178 loc) • 5.74 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, ref, watch } from "vue";
import { call, doubleRaf, getRect, raf, toNumber } from "@varlet/shared";
import { onSmartMounted, onSmartUnmounted, onWindowResize, useEventListener } from "@varlet/use";
import { createNamespace } from "../utils/components.mjs";
import { getParentScroller, toPxNum } from "../utils/elements.mjs";
import { props } from "./props.mjs";
const { name, n, classes } = createNamespace("sticky");
import { renderSlot as _renderSlot, normalizeClass as _normalizeClass, normalizeStyle as _normalizeStyle, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock } from "vue";
function __render__(_ctx, _cache) {
return _openBlock(), _createElementBlock(
"div",
{
ref: "stickyEl",
class: _normalizeClass(_ctx.classes(_ctx.n(), [_ctx.enableCSSMode, _ctx.n("--css-mode")])),
style: _normalizeStyle({
zIndex: _ctx.toNumber(_ctx.zIndex),
top: _ctx.enableCSSMode ? `${_ctx.offsetTop}px` : void 0,
width: _ctx.enableFixedMode ? _ctx.fixedWidth : void 0,
height: _ctx.enableFixedMode ? _ctx.fixedHeight : void 0
})
},
[
_createElementVNode(
"div",
{
ref: "wrapperEl",
class: _normalizeClass(_ctx.n("wrapper")),
style: _normalizeStyle({
zIndex: _ctx.toNumber(_ctx.zIndex),
position: _ctx.enableFixedMode ? "fixed" : void 0,
width: _ctx.enableFixedMode ? _ctx.fixedWrapperWidth : void 0,
height: _ctx.enableFixedMode ? _ctx.fixedWrapperHeight : void 0,
left: _ctx.enableFixedMode ? _ctx.fixedLeft : void 0,
top: _ctx.enableFixedMode ? _ctx.fixedTop : void 0
})
},
[
_renderSlot(_ctx.$slots, "default")
],
6
/* CLASS, STYLE */
)
],
6
/* CLASS, STYLE */
);
}
const __sfc__ = defineComponent({
name,
props,
setup(props2) {
const stickyEl = ref(null);
const wrapperEl = ref(null);
const isFixed = ref(false);
const fixedTop = ref("0px");
const fixedLeft = ref("0px");
const fixedWidth = ref("auto");
const fixedHeight = ref("auto");
const fixedWrapperWidth = ref("auto");
const fixedWrapperHeight = ref("auto");
const enableCSSMode = computed(() => !props2.disabled && props2.cssMode);
const enableFixedMode = computed(() => !props2.disabled && !props2.cssMode && isFixed.value);
const offsetTop = computed(() => toPxNum(props2.offsetTop));
let scroller;
watch(() => props2.disabled, resize);
onSmartMounted(() => __async(this, null, function* () {
yield doubleRaf();
setupScroller();
handleScroll();
}));
onSmartUnmounted(removeScrollListener);
onWindowResize(resize);
useEventListener(() => window, "scroll", handleScroll);
function computeFixedParams() {
const { cssMode, disabled } = props2;
if (disabled) {
return;
}
let scrollerTop = 0;
if (scroller && scroller !== window) {
const { top } = getRect(scroller);
scrollerTop = top;
}
const wrapper = wrapperEl.value;
const sticky = stickyEl.value;
const { top: stickyTop, left: stickyLeft } = getRect(sticky);
const currentOffsetTop = stickyTop - scrollerTop;
if (currentOffsetTop <= offsetTop.value) {
if (!cssMode) {
fixedWidth.value = `${sticky.offsetWidth}px`;
fixedHeight.value = `${sticky.offsetHeight}px`;
fixedTop.value = `${scrollerTop + offsetTop.value}px`;
fixedLeft.value = `${stickyLeft}px`;
fixedWrapperWidth.value = `${wrapper.offsetWidth}px`;
fixedWrapperHeight.value = `${wrapper.offsetHeight}px`;
isFixed.value = true;
}
return {
offsetTop: offsetTop.value,
isFixed: true
};
}
isFixed.value = false;
return {
offsetTop: currentOffsetTop,
isFixed: false
};
}
function setupScroller() {
scroller = getParentScroller(stickyEl.value);
if (scroller !== window) {
scroller.addEventListener("scroll", handleScroll);
}
}
function handleScroll() {
const fixedParams = computeFixedParams();
if (fixedParams) {
call(props2.onScroll, fixedParams.offsetTop, fixedParams.isFixed);
}
}
function removeScrollListener() {
if (!scroller || scroller === window) {
return;
}
scroller.removeEventListener("scroll", handleScroll);
}
function resize() {
return __async(this, null, function* () {
isFixed.value = false;
yield raf();
computeFixedParams();
});
}
return {
stickyEl,
wrapperEl,
isFixed,
offsetTop,
fixedTop,
fixedLeft,
fixedWidth,
fixedHeight,
fixedWrapperWidth,
fixedWrapperHeight,
enableCSSMode,
enableFixedMode,
n,
classes,
resize,
toNumber
};
}
});
__sfc__.render = __render__;
var stdin_default = __sfc__;
export {
stdin_default as default
};