import { computed, defineComponent, onBeforeUnmount, onMounted, type PropType, type Ref, ref, } from 'vue' import './scrollbar.scss' export default defineComponent({ name: 'ScrollBar', props: { onScroll: { type: Function as PropType<(position: number) => void>, required: true, }, scroll: { type: Number, required: true, }, type: { type: String as PropType<'vertical'|'horizontal'>, required: true, }, }, setup(props) { const rootElement: Ref = ref(undefined) const switchElement: Ref = ref(undefined) const isDragging = ref(false) const getSwitchOffset = () => Number(props.type === 'horizontal' ? switchElement.value?.offsetLeft : switchElement.value?.offsetTop) const clickHandler = (e: any) => { const offset = e.target.className === 'ark-ui-scrollbar-switch' ? getSwitchOffset() : 0 const clickPosition = props.type === 'horizontal' ? e.layerX : e.layerY const scrollbarLength = Number(props.type === 'horizontal' ? rootElement.value?.clientWidth : rootElement.value?.clientHeight) let result = ((offset + clickPosition) / scrollbarLength) * 100 if (result < 0) result = 0 if (result > 100) result = 100 if (props.onScroll) props.onScroll(result) } const mouseHandler = (e: any) => { if (!isDragging.value) return clickHandler(e) } const startDrag = (e: any) => { isDragging.value = true document.addEventListener('mousemove', mouseHandler) } const stopDrag = () => { isDragging.value = false document.addEventListener('mousemove', mouseHandler) } const switchStyle = computed(() => { const position = props.type === 'horizontal' ? ((Number(rootElement.value?.clientWidth) - Number(switchElement.value?.clientWidth)) * props.scroll) / 100 : ((Number(rootElement.value?.clientHeight) - Number(switchElement.value?.clientHeight)) * props.scroll) / 100 return props.type === 'vertical' ? `top: ${position}px;` : `left: ${position}px;` }) onMounted(() => { document.addEventListener('mouseup', stopDrag) }) onBeforeUnmount(() => { document.removeEventListener('mouseup', stopDrag) }) return () => (
) }, })