{"version":3,"file":"scrollbar.vue.mjs","sources":["../../../../../../packages/components/scrollbar/src/scrollbar.vue"],"sourcesContent":["<script lang=\"ts\">\n  import { computed, defineComponent, ref, onMounted } from 'vue'\n  import type { StyleValue } from 'vue'\n  import { getComponentNamespace, getNamespace } from '../../../utils/global-config'\n  import { isObject } from '../../../utils/is'\n  import ResizeObserver from '../../../shared/resize-observer'\n  import { scrollbarProps } from './scrollbar'\n  import { TRACK_SIZE } from './constant'\n  import Thumb from './thumb.vue'\n\n  import type { ThumbData } from './types'\n\n  export default defineComponent({\n    name: getComponentNamespace('Scrollbar'),\n    components: {\n      Thumb,\n      ResizeObserver\n    },\n    inheritAttrs: false,\n    props: scrollbarProps,\n    emits: ['scroll'],\n    setup(props, { emit }) {\n      const ns = getNamespace('scrollbar')\n      const cls = computed(() => [\n        ns,\n        props.outerClass,\n        isBoth.value && 'is-both',\n        `${ns}__${props.type}`\n      ])\n\n      const containerRef = ref<HTMLElement>()\n      const horizontalData = ref<ThumbData>()\n      const verticalData = ref<ThumbData>()\n      const horizontalThumbRef = ref()\n      const verticalThumbRef = ref()\n\n      const _hasHorizontalScrollbar = ref(false)\n      const _hasVerticalScrollbar = ref(false)\n      const hasHorizontalScrollbar = computed(\n        () => _hasHorizontalScrollbar.value && !props.disableHorizontal\n      )\n      const hasVerticalScrollbar = computed(\n        () => _hasVerticalScrollbar.value && !props.disableVertical\n      )\n\n      const isBoth = ref(false)\n\n      const getContainerSize = () => {\n        if (containerRef.value) {\n          const {\n            clientWidth,\n            clientHeight,\n            offsetWidth,\n            offsetHeight,\n            scrollWidth,\n            scrollHeight,\n            scrollTop,\n            scrollLeft\n          } = containerRef.value\n\n          _hasHorizontalScrollbar.value = scrollWidth > clientWidth\n          _hasVerticalScrollbar.value = scrollHeight > clientHeight\n\n          isBoth.value = hasHorizontalScrollbar.value && hasVerticalScrollbar.value\n          const horizontalTrackWidth =\n            props.type === 'embed' && isBoth.value ? offsetWidth - TRACK_SIZE : offsetWidth\n          const verticalTrackHeight =\n            props.type === 'embed' && isBoth.value ? offsetHeight - TRACK_SIZE : offsetHeight\n\n          const horizontalThumbWidth = Math.round(\n            horizontalTrackWidth / Math.min(scrollWidth / clientWidth, horizontalTrackWidth)\n          )\n          const maxHorizontalOffset = horizontalTrackWidth - horizontalThumbWidth\n          const horizontalRatio = (scrollWidth - clientWidth) / maxHorizontalOffset\n          const verticalThumbHeight = Math.round(\n            verticalTrackHeight / Math.min(scrollHeight / clientHeight, verticalTrackHeight)\n          )\n          const maxVerticalOffset = verticalTrackHeight - verticalThumbHeight\n          const verticalRatio = (scrollHeight - clientHeight) / maxVerticalOffset\n\n          horizontalData.value = {\n            ratio: horizontalRatio,\n            thumbSize: horizontalThumbWidth,\n            max: maxHorizontalOffset\n          }\n          verticalData.value = {\n            ratio: verticalRatio,\n            thumbSize: verticalThumbHeight,\n            max: maxVerticalOffset\n          }\n          if (scrollTop > 0) {\n            const verticalOffset = Math.round(scrollTop / (verticalData.value?.ratio ?? 1))\n            verticalThumbRef.value?.setOffset(verticalOffset)\n          }\n          if (scrollLeft > 0) {\n            const horizontalOffset = Math.round(scrollLeft / (verticalData.value?.ratio ?? 1))\n            horizontalThumbRef.value?.setOffset(horizontalOffset)\n          }\n        }\n      }\n\n      const handleResize = () => {\n        getContainerSize()\n      }\n\n      const handleVerticalScroll = (offset: number) => {\n        if (containerRef.value) {\n          containerRef.value.scrollTo({\n            top: offset * (verticalData.value?.ratio ?? 1)\n          })\n        }\n      }\n\n      const handleHorizontalScroll = (offset: number) => {\n        if (containerRef.value) {\n          containerRef.value.scrollTo({\n            left: offset * (horizontalData.value?.ratio ?? 1)\n          })\n        }\n      }\n\n      const style = computed(() => {\n        const style: StyleValue = {}\n        if (props.type === 'track') {\n          if (hasHorizontalScrollbar.value) {\n            style.paddingBottom = `${TRACK_SIZE}px`\n          }\n          if (hasVerticalScrollbar.value) {\n            style.paddingRight = `${TRACK_SIZE}px`\n          }\n        }\n        return [style, props.outerStyle ?? {}]\n      })\n\n      const handleScroll = (ev: Event) => {\n        if (containerRef.value) {\n          if (hasHorizontalScrollbar.value && !props.disableHorizontal) {\n            const horizontalOffset = Math.round(\n              containerRef.value.scrollLeft / (horizontalData.value?.ratio ?? 1)\n            )\n            horizontalThumbRef.value?.setOffset(horizontalOffset)\n          }\n          if (hasVerticalScrollbar.value && !props.disableVertical) {\n            const verticalOffset = Math.round(\n              containerRef.value.scrollTop / (verticalData.value?.ratio ?? 1)\n            )\n            verticalThumbRef.value?.setOffset(verticalOffset)\n          }\n        }\n        emit('scroll', ev)\n      }\n\n      onMounted(() => {\n        getContainerSize()\n      })\n\n      return {\n        ns,\n        cls,\n        style,\n        containerRef,\n        horizontalThumbRef,\n        verticalThumbRef,\n        horizontalData,\n        verticalData,\n        isBoth,\n        hasHorizontalScrollbar,\n        hasVerticalScrollbar,\n        handleScroll,\n        handleHorizontalScroll,\n        handleVerticalScroll,\n        handleResize\n      }\n    },\n    methods: {\n      scrollTo(\n        options?:\n          | number\n          | {\n              left?: number\n              top?: number\n            },\n        y?: number\n      ) {\n        if (isObject(options)) {\n          ;(this.$refs.containerRef as HTMLElement)?.scrollTo(options)\n        } else if (options || y) {\n          ;(this.$refs.containerRef as HTMLElement)?.scrollTo(options as number, y as number)\n        }\n      },\n      scrollTop(top: number) {\n        ;(this.$refs.containerRef as HTMLElement)?.scrollTo({\n          top\n        })\n      },\n      scrollLeft(left: number) {\n        ;(this.$refs.containerRef as HTMLElement)?.scrollTo({\n          left\n        })\n      }\n    }\n  })\n</script>\n\n<template>\n  <div :class=\"cls\" :style=\"style\">\n    <div ref=\"containerRef\" :class=\"`${ns}__container`\" v-bind=\"$attrs\" @scroll=\"handleScroll\">\n      <ResizeObserver @resize=\"handleResize\">\n        <slot></slot>\n      </ResizeObserver>\n    </div>\n\n    <Thumb\n      v-if=\"!hide && hasHorizontalScrollbar\"\n      ref=\"horizontalThumbRef\"\n      :data=\"horizontalData\"\n      direction=\"horizontal\"\n      :both=\"isBoth\"\n      @scroll=\"handleHorizontalScroll\"\n    />\n    <Thumb\n      v-if=\"!hide && hasVerticalScrollbar\"\n      ref=\"verticalThumbRef\"\n      :data=\"verticalData\"\n      direction=\"vertical\"\n      :both=\"isBoth\"\n      @scroll=\"handleVerticalScroll\"\n    />\n  </div>\n</template>\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_mergeProps","$attrs","handleResize","_withCtx","hasHorizontalScrollbar","_createBlock","isBoth","handleHorizontalScroll","hide","hasVerticalScrollbar","_createCommentVNode","handleVerticalScroll"],"mappings":";;;;;;2BA6MEA,iBAuBM,OAAA,CAAA,CAAA;AAvBkB,EAAA,OAAAC,WAAA,EAAAC,kBAAA;AAAA,IAAO,KAAA;AAAA,IAAA;AAAA,MAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,GAAA,CAAA;AAAA,MAC7B,KAAA,EAAAC,cAIM,CAAA,IAAA,CAJN,KAAA,CAAA;AAAA,KAAA;AAAA;;QAAqC,KAAA;AAAA,QAAAC,UAAA,CAAA;AAAA,UAAuBC,GAAAA,EAAAA,cAAAA;AAAAA,UAAS,KAAA,EAAM,GAAA,IAAA,CAAA,EAAA,CAAA,WAAA,CAAA;AAAA,SAAA,EAAA,KAAA,MAAA,EAAA;AAAA,UACzE,QAEiB,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,OAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAFM,IAAEC,CAAAA,YAAAA,IAAY,IAAA,CAAA,YAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA,SAAA,CAAA;AAAA;sBACnC,yBAAa,EAAA,EAAA,QAAA,EAAA,IAAA,CAAA,cAAA,EAAA;AAAA,YAAA,OAAA,EAAAC,QAAA,MAAA;AAAA;;;;WAKAC,EAAAA,CAAAA,EAAAA,CAAAA,UAAAA,CAAAA,CAAAA;AAAAA,SAAAA;AAAAA;;OADjB;AAAA,MAAA,CAAA,KAAA,IAAA,IAAA,IAAA,CAAA,0BAAAR,SAEM,EAAA,EAAoBS,YAAA,gBAAA,EAAA;AAAA,QACvB,GAAI,EAAA,CAAA;AAAA,QACL,GAAA,EAAA,oBAAA;AAAA,QACC,MAAMC,IAAAA,CAAAA,cAAAA;AAAAA,QACN,SAAQC,EAAAA,YAAAA;AAAAA,QAAAA,MAAAA,IAAAA,CAAAA,MAAAA;AAAAA;OAGFC,EAAI,IAAA,EAAA,CAAA,EAAIC,CAAoB,MAAA,EAAA,MAAA,EAAA,UAAA,CAAA,CAAA,IAAAC,kBADrC,CAAA,MAAA,EAOE,IAAA,CAAA;AAAA,MAAA,CAAA,KAAA,IAAA,IAAA,IAAA,CAAA,wBAAAd,SALI,EAAA,EAAkBS,YAAA,gBAAA,EAAA;AAAA,QACrB,GAAI,EAAA,CAAA;AAAA,QACL,GAAA,EAAA,kBAAA;AAAA,QACC,MAAMC,IAAAA,CAAAA,YAAAA;AAAAA,QACN,SAAQK,EAAAA,UAAAA;AAAAA,QAAAA,MAAAA,IAAAA,CAAAA,MAAAA;AAAAA;;;;;;;;;;;"}