import { useRect } from '@opentiny/vue-hooks'
import { useWindowSize } from '@opentiny/vue-hooks'
import { useEventListener } from '@opentiny/vue-hooks'
import { useScrollParent } from '@opentiny/utils'
import { computedRootStyle, computedStickyStyle, updateRoot, unitToPx, getRootRect, getTarget } from './index'
export const api = ['state']
export const renderless = (props, hooks, { vm, emit }) => {
const { reactive, computed, unref, ref, toRef, onMounted, watch } = hooks
const state = reactive({
root: null,
target: null,
windowHeight: 0,
windowWidth: 0,
rootHeight: 0,
rootWidth: 0,
rootTop: 0,
rootBottom: 0,
isFixed: false,
scrollTop: 0,
transform: 0,
scrollParent: null,
targetRect: null,
offset: 0,
rootStyle: computed(() => api.computedRootStyle()),
stickyStyle: computed(() => api.computedStickyStyle())
})
const api = {}
Object.assign(api, {
state,
computedRootStyle: computedRootStyle({ props, state }),
computedStickyStyle: computedStickyStyle({ props, state }),
updateRoot: updateRoot({ props, state, emit, api }),
getRootRect: getRootRect({ vm, state, api }),
getTarget: getTarget({ props, state, api }),
useEventListener: useEventListener(hooks),
useScrollParent: useScrollParent(hooks),
useWindowSize: useWindowSize(ref),
useRect: useRect(unref),
unitToPx: unitToPx()
})
watch(
() => state.isFixed,
(value) => {
emit('change', value)
}
)
watch(
() => props.offset,
(value) => {
state.offset = api.unitToPx(value)
api.updateRoot()
},
{ immediate: true }
)
const { width, height } = api.useWindowSize()
state.windowHeight = height
state.windowWidth = width
state.scrollParent = api.useScrollParent(toRef(state, 'root'))
api.useEventListener('scroll', api.updateRoot, { target: toRef(state, 'scrollParent'), passive: true })
onMounted(() => {
state.root = vm.$refs.root
setTimeout(() => {
api.getTarget()
api.getRootRect()
api.updateRoot()
})
})
return api
}