winbox-ui-next
Version:
We Design Vue 2.0: A Vue.js 3 UI Library
166 lines (165 loc) • 5.99 kB
JavaScript
var __defProp = Object.defineProperty;
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;
};
import { defineComponent, toRefs, ref, computed, watchEffect, resolveComponent, openBlock, createBlock, withCtx, createElementVNode, createElementBlock, normalizeStyle, createCommentVNode, normalizeClass, createVNode, renderSlot } from "vue";
import ResizeObserver from "../_components/resize-observer.js";
import { getPrefixCls } from "../_utils/global-config.js";
import { throttleByRaf } from "../_utils/throttle-by-raf.js";
import { isWindow, isUndefined } from "../_utils/is.js";
import { getElement, on, off } from "../_utils/dom.js";
import _export_sfc from "../_virtual/plugin-vue_export-helper";
function getTargetRect(target) {
return isWindow(target) ? {
top: 0,
bottom: window.innerHeight
} : target.getBoundingClientRect();
}
const _sfc_main = defineComponent({
name: "Affix",
components: {
ResizeObserver
},
props: {
offsetTop: {
type: Number,
default: 0
},
offsetBottom: {
type: Number
},
target: {
type: [String, Object, Function]
},
targetContainer: {
type: [String, Object, Function]
},
onChange: {
type: [Function, Array]
}
},
emits: [
"change"
],
setup(props, { emit }) {
const prefixCls = getPrefixCls("affix");
const { target, targetContainer } = toRefs(props);
const wrapperRef = ref();
const targetRef = ref();
const isFixed = ref(false);
const placeholderStyles = ref({});
const fixedStyles = ref({});
const classNames = computed(() => ({ [prefixCls]: isFixed.value }));
const updatePositionThrottle = throttleByRaf(() => {
if (!wrapperRef.value || !targetRef.value)
return;
const { offsetTop, offsetBottom } = props;
const offsetType = isUndefined(offsetBottom) ? "top" : "bottom";
const wrapperRect = wrapperRef.value.getBoundingClientRect();
const targetRect = getTargetRect(targetRef.value);
let newIsFixed = false;
let newFixedStyles = {};
const newPlaceholderStyles = {
width: `${wrapperRef.value.offsetWidth}px`,
height: `${wrapperRef.value.offsetHeight}px`
};
if (offsetType === "top") {
newIsFixed = wrapperRect.top - targetRect.top < (offsetTop || 0);
newFixedStyles = newIsFixed ? {
position: "fixed",
top: `${targetRect.top + (offsetTop || 0)}px`
} : {};
} else {
newIsFixed = targetRect.bottom - wrapperRect.bottom < (offsetBottom || 0);
newFixedStyles = newIsFixed ? {
position: "fixed",
bottom: `${window.innerHeight - targetRect.bottom + (offsetBottom || 0)}px`
} : {};
}
if (newIsFixed !== isFixed.value) {
isFixed.value = newIsFixed;
emit("change", newIsFixed);
}
placeholderStyles.value = newPlaceholderStyles;
fixedStyles.value = __spreadValues(__spreadValues({}, newFixedStyles), newIsFixed ? newPlaceholderStyles : {});
});
watchEffect((onInvalidate) => {
const element = target && target.value !== window && getElement(target.value) || window;
targetRef.value = element;
if (element) {
on(element, "scroll", updatePositionThrottle);
on(element, "resize", updatePositionThrottle);
onInvalidate(() => {
off(element, "scroll", updatePositionThrottle);
off(element, "resize", updatePositionThrottle);
});
}
});
watchEffect((onInvalidate) => {
if (!targetRef.value)
return;
const container = targetContainer && targetContainer.value !== window && getElement(targetContainer.value) || window;
if (container) {
on(container, "scroll", updatePositionThrottle);
on(container, "resize", updatePositionThrottle);
onInvalidate(() => {
off(container, "scroll", updatePositionThrottle);
off(container, "resize", updatePositionThrottle);
});
}
});
return {
wrapperRef,
isFixed,
classNames,
placeholderStyles,
fixedStyles,
updatePositionThrottle
};
},
methods: {
updatePosition() {
this.updatePositionThrottle();
}
}
});
const _hoisted_1 = { ref: "wrapperRef" };
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_ResizeObserver = resolveComponent("ResizeObserver");
return openBlock(), createBlock(_component_ResizeObserver, { onResize: _ctx.updatePositionThrottle }, {
default: withCtx(() => [
createElementVNode("div", _hoisted_1, [
_ctx.isFixed ? (openBlock(), createElementBlock("div", {
key: 0,
style: normalizeStyle(_ctx.placeholderStyles)
}, null, 4)) : createCommentVNode("v-if", true),
createElementVNode("div", {
class: normalizeClass(_ctx.classNames),
style: normalizeStyle(_ctx.fixedStyles)
}, [
createVNode(_component_ResizeObserver, { onResize: _ctx.updatePositionThrottle }, {
default: withCtx(() => [
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["onResize"])
], 6)
], 512)
]),
_: 3
}, 8, ["onResize"]);
}
var _Affix = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render]]);
export { _Affix as default };