{"version":3,"file":"index2.mjs","sources":["../../../../../src/components/ivue-scrollbar/index.vue"],"sourcesContent":["<template>\r\n  <div :class=\"prefixCls\" ref=\"scrollbar\">\r\n    <div\r\n      :class=\"wrapperClasses\"\r\n      :style=\"wrapperStyles\"\r\n      @scroll=\"handleScroll\"\r\n      ref=\"scrollbarWrapper\"\r\n    >\r\n      <component\r\n        :is=\"tag\"\r\n        :class=\"contentClasses\"\r\n        :style=\"contentStyle\"\r\n        ref=\"resize\"\r\n      >\r\n        <slot></slot>\r\n      </component>\r\n    </div>\r\n    <!-- 是否使用原生滚动条样式 -->\r\n    <template v-if=\"!native\">\r\n      <bar\r\n        :barHeight=\"data.barHeight\"\r\n        :barWidth=\"data.barWidth\"\r\n        :always=\"always\"\r\n        :ratioX=\"data.ratioX\"\r\n        :ratioY=\"data.ratioY\"\r\n        ref=\"bar\"\r\n      ></bar>\r\n    </template>\r\n  </div>\r\n</template>\r\n\r\n<script lang=\"ts\">\r\nimport {\r\n  computed,\r\n  defineComponent,\r\n  ref,\r\n  reactive,\r\n  onMounted,\r\n  nextTick,\r\n  onUpdated,\r\n  provide,\r\n  watch,\r\n} from 'vue';\r\nimport { useEventListener, useResizeObserver, isNumber } from '@vueuse/core';\r\n\r\nimport { addUnit, isValueNumber, isObject } from '../../utils/helpers';\r\nimport Bar from './bar.vue';\r\n\r\n// ts\r\nimport type { CSSProperties } from 'vue';\r\nimport {\r\n  BarInstance,\r\n  Props,\r\n  Data,\r\n  ScrollbarContextKey,\r\n} from './types/scrollbar';\r\n\r\n// top 2 + bottom 2\r\nconst GAP = 4;\r\n\r\nconst prefixCls = 'ivue-scrollbar';\r\n\r\nexport default defineComponent({\r\n  name: prefixCls,\r\n  emits: ['on-scroll'],\r\n  props: {\r\n    /**\r\n     * 包裹容器的自定义类名\r\n     *\r\n     * @type {String}\r\n     */\r\n    wrapperClass: {\r\n      type: String,\r\n      default: '',\r\n    },\r\n    /**\r\n     * 包裹容器的自定义样式\r\n     *\r\n     * @type {String | Object}\r\n     */\r\n    wrapperStyle: {\r\n      type: [String, Object],\r\n      default: '',\r\n    },\r\n    /**\r\n     * 视图的自定义类名\r\n     *\r\n     * @type {String}\r\n     */\r\n    contentClass: {\r\n      type: String,\r\n      default: '',\r\n    },\r\n    /**\r\n     * 视图的自定义样式\r\n     *\r\n     * @type {String | Object}\r\n     */\r\n    contentStyle: {\r\n      type: [String, Object],\r\n      default: '',\r\n    },\r\n    /**\r\n     * 是否使用原生滚动条样式\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    native: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 滚动条高度\r\n     *\r\n     * @type {String | Number}\r\n     */\r\n    height: {\r\n      type: [String, Number],\r\n      default: '',\r\n    },\r\n    /**\r\n     * 滚动条最大高度\r\n     *\r\n     * @type {String | Number}\r\n     */\r\n    maxHeight: {\r\n      type: [String, Number],\r\n      default: '',\r\n    },\r\n    /**\r\n     * 视图的元素标签\r\n     *\r\n     * @type {String}\r\n     */\r\n    tag: {\r\n      type: String,\r\n      default: 'div',\r\n    },\r\n    /**\r\n     * 滚动条总是显示\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    always: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 不响应容器尺寸变化，如果容器尺寸不会发生变化，最好设置它可以优化性能\r\n     *\r\n     * @type {Boolean}\r\n     */\r\n    noresize: {\r\n      type: Boolean,\r\n      default: false,\r\n    },\r\n    /**\r\n     * 自定义滚动条最小尺寸(开启 native 该属性不生效)\r\n     *\r\n     * @type {Number}\r\n     */\r\n    minBarSize: {\r\n      type: Number,\r\n      default: 20,\r\n    },\r\n  },\r\n  setup(props: Props, { emit }) {\r\n    // dom\r\n    const scrollbarWrapper = ref<HTMLDivElement>();\r\n    const scrollbar = ref<HTMLDivElement>();\r\n    const resize = ref<HTMLDivElement>();\r\n\r\n    const bar = ref<BarInstance>();\r\n\r\n    // data\r\n    const data = reactive<Data>({\r\n      /**\r\n       * 滚动条高度\r\n       *\r\n       * @type {String}\r\n       */\r\n      barHeight: '0',\r\n      /**\r\n       * 滚动条宽度\r\n       *\r\n       * @type {String}\r\n       */\r\n      barWidth: '0',\r\n      /**\r\n       * x轴滚动比率\r\n       *\r\n       * @type {Number}\r\n       */\r\n      ratioX: 1,\r\n      /**\r\n       * y轴滚动比率\r\n       *\r\n       * @type {Number}\r\n       */\r\n      ratioY: 1,\r\n    });\r\n\r\n    // computed\r\n\r\n    // 外层样式\r\n    const wrapperClasses = computed(() => {\r\n      return [\r\n        props.wrapperClass,\r\n        `${prefixCls}-wrapper`,\r\n        {\r\n          [`${prefixCls}-hidden-default`]: !props.native,\r\n        },\r\n      ];\r\n    });\r\n\r\n    // 外层样式\r\n    const wrapperStyles = computed(() => {\r\n      const style: CSSProperties = {};\r\n\r\n      // 滚动条高度\r\n      if (props.height) {\r\n        style.height = addUnit(props.height);\r\n      }\r\n\r\n      // 滚动条最大高度\r\n      if (props.maxHeight) {\r\n        style.maxHeight = addUnit(props.maxHeight);\r\n      }\r\n\r\n      return [props.wrapperStyle, style];\r\n    });\r\n\r\n    // 内容样式\r\n    const contentClasses = computed(() => {\r\n      return [props.contentClass, `${prefixCls}-content`];\r\n    });\r\n\r\n    // methods\r\n\r\n    // 滚动\r\n    const handleScroll = () => {\r\n      if (scrollbarWrapper.value) {\r\n        bar.value?.handleScroll(scrollbarWrapper.value);\r\n\r\n        emit('on-scroll', {\r\n          scrollTop: scrollbarWrapper.value.scrollTop,\r\n          scrollLeft: scrollbarWrapper.value.scrollLeft,\r\n        });\r\n      }\r\n    };\r\n\r\n    // 更新状态\r\n    const update = () => {\r\n      if (!scrollbarWrapper.value) {\r\n        return;\r\n      }\r\n\r\n      // 表格高度\r\n      const offsetHeight = scrollbarWrapper.value.offsetHeight - GAP;\r\n      // 可滚动高度\r\n      const originalHeight =\r\n        offsetHeight ** 2 / scrollbarWrapper.value.scrollHeight;\r\n      // 滚动条高度\r\n      const height = Math.max(originalHeight, props.minBarSize);\r\n      // 滚动条高度\r\n      data.barHeight = height + GAP < offsetHeight ? `${height}px` : '';\r\n\r\n      // 表格宽度\r\n      const offsetWidth = scrollbarWrapper.value.offsetWidth - GAP;\r\n      // 滚动条宽度\r\n      const originalWidth =\r\n        offsetWidth ** 2 / scrollbarWrapper.value.scrollWidth;\r\n\r\n      // 表格宽度\r\n      const width = Math.max(originalWidth, props.minBarSize);\r\n      // 滚动条宽度\r\n      data.barWidth = width + GAP < offsetWidth ? `${width}px` : '';\r\n\r\n      // x轴滚动比率\r\n      data.ratioX =\r\n        originalWidth /\r\n        (offsetWidth - originalWidth) /\r\n        (width / (offsetWidth - width));\r\n\r\n      // y轴滚动比率\r\n      data.ratioY =\r\n        originalHeight /\r\n        (offsetHeight - originalHeight) /\r\n        (height / (offsetHeight - height));\r\n    };\r\n\r\n    // 设置滚动高度\r\n    const setScrollTop = (value: number) => {\r\n      if (!isValueNumber(value)) {\r\n        return;\r\n      }\r\n\r\n      scrollbarWrapper.value.scrollTop = value;\r\n    };\r\n\r\n    // 设置滚动左右\r\n    const setScrollLeft = (value: number) => {\r\n      if (!isValueNumber(value)) {\r\n        return;\r\n      }\r\n\r\n      scrollbarWrapper.value.scrollLeft = value;\r\n    };\r\n\r\n    // 滚动到一组特定坐标\r\n    const scrollTo = (arg1: unknown, arg2?: number): void => {\r\n      // 对象\r\n      if (isObject(arg1)) {\r\n        scrollbarWrapper.value.scrollTo(arg1);\r\n      }\r\n      // 数字\r\n      else if (isNumber(arg1) && isNumber(arg2)) {\r\n        scrollbarWrapper.value.scrollTo(arg1, arg2);\r\n      }\r\n    };\r\n\r\n    // watch\r\n\r\n    // 滚动条高度\r\n    watch(\r\n      () => props.height,\r\n      () => {\r\n        if (!props.native) {\r\n          nextTick(() => {\r\n            update();\r\n\r\n            if (scrollbarWrapper.value) {\r\n              bar.value?.handleScroll(scrollbarWrapper.value);\r\n            }\r\n          });\r\n        }\r\n      }\r\n    );\r\n\r\n    // 不响应容器尺寸变化，如果容器尺寸不会发生变化，最好设置它可以优化性能\r\n    watch(\r\n      () => props.noresize,\r\n      (value) => {\r\n        // 不响应\r\n        if (!value) {\r\n          // 元素内容或边框尺寸的变化\r\n          useResizeObserver(resize.value, update);\r\n\r\n          // window resize\r\n          useEventListener('resize', update);\r\n        }\r\n      },\r\n      {\r\n        immediate: true,\r\n      }\r\n    );\r\n\r\n    // onMounted\r\n    onMounted(() => {\r\n      if (!props.native) {\r\n        nextTick(() => {\r\n          update();\r\n        });\r\n      }\r\n    });\r\n\r\n    // 数据更改导致的虚拟 DOM 重新渲染和更新完毕之后被调用\r\n    onUpdated(() => {\r\n      update();\r\n    });\r\n\r\n    // provide\r\n    provide(\r\n      ScrollbarContextKey,\r\n      reactive({\r\n        scrollbar: scrollbar,\r\n        scrollbarWrapper: scrollbarWrapper,\r\n      })\r\n    );\r\n\r\n    return {\r\n      prefixCls,\r\n      // dom\r\n      scrollbarWrapper,\r\n      scrollbar,\r\n      bar,\r\n      resize,\r\n\r\n      // data\r\n      data,\r\n      // computed\r\n      wrapperClasses,\r\n      wrapperStyles,\r\n      contentClasses,\r\n\r\n      // methods\r\n      handleScroll,\r\n      setScrollTop,\r\n      setScrollLeft,\r\n      update,\r\n      scrollTo,\r\n    };\r\n  },\r\n  components: {\r\n    Bar,\r\n  },\r\n});\r\n</script>\r\n"],"names":["_resolveComponent","_openBlock","_createElementBlock","_normalizeClass","_normalizeStyle","_createBlock","_resolveDynamicComponent","_createCommentVNode"],"mappings":";;;;;yBACEA,iBA2BM,KAAA,CAAA,CAAA;EA3BsB,OAAAC,SAAA,EAAW,EAAAC,kBAAA,CAAA,KAAA,EAAA;AAAA,IAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,SAAA,CAAA;AAAA,IACrC,GAAA,EAAA,WAAA;AAAA,GAAA,EAAA;AAAA,uBAEQ,KAAE,EAAA;AAAA,MACP,KAAA,EAAMA,cAAA,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,MACP,KAAA,EAAIC,cAAkB,CAAA,IAAA,CAAA,aAAA,CAAA;AAAA,MAAA,QAAA,EAAA,MAAA,CAAA,CAAA,CAAA,KAAA,MAAA,CAAA,CAAA,CAAA,GAAA,CAAA,GAAA,IAAA,KAAA,IAAA,CAAA,YAAA,IAAA,IAAA,CAAA,YAAA,CAAA,GAAA,IAAA,CAAA,CAAA;AAAA;;OAKdH,WAAA,EAAAI,WAAA,CAAEC,uBAAY,CAAA,IAAA,CAAA,GAAA,CAAA,EAAA;AAAA,QACpB,KAAA,EAAIH,cAAQ,CAAA,IAAA,CAAA,cAAA,CAAA;AAAA,QAAA,KAAA,EAAAC,cAAA,CAAA,IAAA,CAAA,YAAA,CAAA;AAAA;;;;;;OAKI,EAAA,CAAA,EAAA,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;AAAA,OACH,EAAM,CAAA;AAAA,IAAAG,mBACrB,sEAOO,CAAA;AAAA,IANK,CAAA,IAAA,CAAA,MAAA,IAAAN,SAAA,EAAA,EAAEI,YAAK,cAAS,EAAA;AAAA,MACzB,GAAA,EAAA,CAAA;AAAA,MACA,SAAA,EAAQ,KAAM,IAAA,CAAA,SAAA;AAAA,MACd,QAAA,EAAQ,KAAK,IAAA,CAAA,QAAA;AAAA,MACb,QAAQ,IAAA,CAAA,MAAA;AAAA,MACT,MAAA,EAAI,KAAK,IAAA,CAAA,MAAA;AAAA,MAAA,MAAA,EAAA,KAAA,IAAA,CAAA,MAAA;AAAA;;;;;;;;"}