@meve/ui
Version:
Argon design system components library
145 lines (132 loc) • 4.6 kB
JavaScript
import { createNamespace } from '../utils/create';
import { getParentScroller, toPxNum } from '../utils/elements';
import { props } from './props';
import { toNumber } from '../utils/shared';
var _createNamespace = createNamespace('sticky'),
createComponent = _createNamespace.createComponent,
namespace = _createNamespace.namespace;
var StickyPlugin = createComponent({
props: props,
data: function data() {
return {
isFixed: false,
fixedTop: '0px',
fixedLeft: '0px',
fixedWidth: 'auto',
fixedHeight: 'auto',
fixedWrapperWidth: 'auto',
fixedWrapperHeight: 'auto',
scroller: null
};
},
watch: {
disabled: function disabled() {
this.handleScroll();
}
},
activated: function activated() {
this.addScrollListener();
},
deactivated: function deactivated() {
this.removeScrollListener();
},
mounted: function mounted() {
this.addScrollListener();
},
beforeDestroy: function beforeDestroy() {
this.removeScrollListener();
},
computed: {
enableCSSMode: function enableCSSMode() {
return !this.disabled && this.cssMode;
},
enableFixedMode: function enableFixedMode() {
return !this.disabled && this.isFixed;
},
offsetTopNum: function offsetTopNum() {
return toPxNum(this.offsetTop);
}
},
methods: {
handleScroll: function handleScroll() {
var cssMode = this.cssMode,
disabled = this.disabled;
if (disabled) {
return;
}
var scrollerTop = 0;
if (this.scroller !== window) {
var _this$scroller$getBou = this.scroller.getBoundingClientRect(),
top = _this$scroller$getBou.top;
scrollerTop = top;
}
var wrapper = this.$refs.wrapper;
var sticky = this.$refs.sticky;
var _sticky$getBoundingCl = sticky.getBoundingClientRect(),
stickyTop = _sticky$getBoundingCl.top,
stickyLeft = _sticky$getBoundingCl.left;
var currentOffsetTop = stickyTop - scrollerTop;
if (currentOffsetTop <= this.offsetTopNum) {
if (!cssMode) {
this.fixedWidth = sticky.offsetWidth + "px";
this.fixedHeight = sticky.offsetHeight + "px";
this.fixedTop = scrollerTop + this.offsetTopNum + "px";
this.fixedLeft = stickyLeft + "px";
this.fixedWrapperWidth = wrapper.offsetWidth + "px";
this.fixedWrapperHeight = wrapper.offsetHeight + "px";
this.isFixed = true;
}
this.$emit('scroll', this.offsetTopNum, true);
} else {
this.isFixed = false;
this.$emit('scroll', currentOffsetTop, false);
}
},
addScrollListener: function addScrollListener() {
this.scroller = getParentScroller(this.$refs.sticky);
this.scroller !== window && this.scroller.addEventListener('scroll', this.handleScroll);
window.addEventListener('scroll', this.handleScroll);
this.handleScroll();
},
removeScrollListener: function removeScrollListener() {
this.scroller !== window && this.scroller.removeEventListener('scroll', this.handleScroll);
window.removeEventListener('scroll', this.handleScroll);
}
},
render: function render() {
var h = arguments[0];
var enableCSSMode = this.enableCSSMode,
enableFixedMode = this.enableFixedMode,
fixedWrapperWidth = this.fixedWrapperWidth,
fixedWrapperHeight = this.fixedWrapperHeight,
fixedLeft = this.fixedLeft,
fixedTop = this.fixedTop,
zIndex = this.zIndex,
offsetTopNum = this.offsetTopNum,
fixedWidth = this.fixedWidth,
fixedHeight = this.fixedHeight;
return h("div", {
"ref": "sticky",
"class": [namespace(), enableCSSMode ? namespace('--css-mode') : null],
"style": {
zIndex: toNumber(zIndex),
top: enableCSSMode ? offsetTopNum + "px" : undefined,
width: enableFixedMode ? fixedWidth : undefined,
height: enableFixedMode ? fixedHeight : undefined
}
}, [h("div", {
"ref": "wrapper",
"class": namespace('__wrapper'),
"style": {
zIndex: toNumber(zIndex),
position: enableFixedMode ? 'fixed' : undefined,
width: enableFixedMode ? fixedWrapperWidth : undefined,
height: enableFixedMode ? fixedWrapperHeight : undefined,
left: enableFixedMode ? fixedLeft : undefined,
top: enableFixedMode ? fixedTop : undefined
}
}, [this.slots()])]);
}
});
export var _StickyComponent = StickyPlugin;
export default StickyPlugin;