quasar
Version:
Build high-performance VueJS user interfaces (SPA, PWA, SSR, Mobile and Desktop) in record time
120 lines (94 loc) • 2.68 kB
JavaScript
import { h, ref, computed, watch, onBeforeUnmount, getCurrentInstance, Transition } from 'vue'
import usePageSticky, { usePageStickyProps } from '../page-sticky/use-page-sticky.js'
import { getScrollTarget, setVerticalScrollPosition } from '../../utils/scroll/scroll.js'
import { createComponent } from '../../utils/private.create/create.js'
export default createComponent({
name: 'QPageScroller',
props: {
...usePageStickyProps,
scrollOffset: {
type: Number,
default: 1000
},
reverse: Boolean,
duration: {
type: Number,
default: 300
},
offset: {
...usePageStickyProps.offset,
default: () => [ 18, 18 ]
}
},
emits: [ 'click' ],
setup (props, { slots, emit }) {
const { proxy: { $q } } = getCurrentInstance()
const { $layout, getStickyContent } = usePageSticky()
const rootRef = ref(null)
let heightWatcher
const scrollHeight = computed(() => $layout.height.value - (
$layout.isContainer.value === true
? $layout.containerHeight.value
: $q.screen.height
))
function isVisible () {
return props.reverse === true
? scrollHeight.value - $layout.scroll.value.position > props.scrollOffset
: $layout.scroll.value.position > props.scrollOffset
}
const showing = ref(isVisible())
function updateVisibility () {
const newVal = isVisible()
if (showing.value !== newVal) {
showing.value = newVal
}
}
function updateReverse () {
if (props.reverse === true) {
if (heightWatcher === void 0) {
heightWatcher = watch(scrollHeight, updateVisibility)
}
}
else {
cleanup()
}
}
watch($layout.scroll, updateVisibility)
watch(() => props.reverse, updateReverse)
function cleanup () {
if (heightWatcher !== void 0) {
heightWatcher()
heightWatcher = void 0
}
}
function onClick (e) {
const target = getScrollTarget(
$layout.isContainer.value === true
? rootRef.value
: $layout.rootRef.value
)
setVerticalScrollPosition(
target,
props.reverse === true ? $layout.height.value : 0,
props.duration
)
emit('click', e)
}
function getContent () {
return showing.value === true
? h('div', {
ref: rootRef,
class: 'q-page-scroller',
onClick
}, getStickyContent(slots))
: null
}
updateReverse()
onBeforeUnmount(cleanup)
return () => h(
Transition,
{ name: 'q-transition--fade' },
getContent
)
}
})