{"version":3,"file":"vue-scroller.mjs","names":[],"sources":["../src/composables/scroller.ts","../src/components/VScroller.tsx"],"sourcesContent":["import { onMounted, onBeforeUnmount, reactive, ref } from 'vue';\nimport {\n  Scroller,\n  ScrollerSetting,\n  ScrollerState,\n  ScrollAxis,\n  ScrollDirection,\n  ScrollXDirection,\n  ScrollYDirection,\n  ScrollerScrollOptions,\n  ScrollPosition,\n  ScrollToElementTarget,\n  ScrollerScrollToElementOptions,\n  ScrollToSideTargets,\n  ScrollStopper,\n  ScrollToElementAdditionalOffset,\n} from '@fastkit/scroller';\n\nexport type UseScrollerTarget = 'self' | 'body';\n\nexport interface UseScrollerSetting extends Omit<\n  Partial<ScrollerSetting>,\n  'el'\n> {\n  el?: UseScrollerTarget;\n}\n\nconst INITIAL_VALUE: any = null;\n\ntype UseScrollerState = {\n  containerHeight: number;\n  containerWidth: number;\n  isDestroyed: boolean;\n  isPending: boolean;\n  isReady: boolean;\n  isRunning: boolean;\n  lastAxis: ScrollAxis;\n  lastDirection: ScrollDirection;\n  lastXDirection: ScrollXDirection;\n  lastYDirection: ScrollYDirection;\n  nowScrolling: boolean;\n  scrollEnabled: boolean;\n  scrollHeight: number;\n  scrollWidth: number;\n  scrollableX: boolean;\n  scrollableY: boolean;\n  state: ScrollerState;\n  scrollBottom: number;\n  scrollLeft: number;\n  scrollRight: number;\n  scrollTop: number;\n};\n\nconst OBSERVER_READONLY_PROPS = [\n  'containerHeight',\n  'containerWidth',\n  'isDestroyed',\n  'isPending',\n  'isReady',\n  'isRunning',\n  'lastAxis',\n  'lastDirection',\n  'lastXDirection',\n  'lastYDirection',\n  'nowScrolling',\n  'scrollEnabled',\n  'scrollHeight',\n  'scrollWidth',\n  'scrollableX',\n  'scrollableY',\n  'state',\n] as const;\n\nconst OBSERVER_WRITABLE_PROPS = [\n  'scrollBottom',\n  'scrollLeft',\n  'scrollRight',\n  'scrollTop',\n] as const;\n\nconst OBSERVER_PROPS = [...OBSERVER_READONLY_PROPS, ...OBSERVER_WRITABLE_PROPS];\n\nfunction createDefaultState(): UseScrollerState {\n  return reactive(\n    Object.fromEntries(OBSERVER_PROPS.map((prop) => [prop, INITIAL_VALUE])),\n  ) as UseScrollerState;\n}\n\nexport function useScrollerControl(setting: UseScrollerSetting) {\n  const isSelf = setting.el === 'self';\n  const $target = isSelf ? null : undefined;\n  const state = createDefaultState();\n  const elementRef = ref<null | HTMLElement>(null);\n  const scroller = new Scroller({\n    ...setting,\n    el: $target,\n  });\n  scroller.observe(state);\n\n  const _scroller = {\n    get elementRef() {\n      return elementRef;\n    },\n    get scroller() {\n      return scroller;\n    },\n    get containerHeight() {\n      return state.containerHeight;\n    },\n    get containerWidth() {\n      return state.containerWidth;\n    },\n    get isDestroyed() {\n      return state.isDestroyed;\n    },\n    get isPending() {\n      return state.isPending;\n    },\n    get isReady() {\n      return state.isReady;\n    },\n    get isRunning() {\n      return state.isRunning;\n    },\n    get lastAxis() {\n      return state.lastAxis;\n    },\n    get lastDirection() {\n      return state.lastDirection;\n    },\n    get lastXDirection() {\n      return state.lastXDirection;\n    },\n    get lastYDirection() {\n      return state.lastYDirection;\n    },\n    get nowScrolling() {\n      return state.nowScrolling;\n    },\n    get scrollEnabled() {\n      return state.scrollEnabled;\n    },\n    get scrollHeight() {\n      return state.scrollHeight;\n    },\n    get scrollWidth() {\n      return state.scrollWidth;\n    },\n    get scrollableX() {\n      return state.scrollableX;\n    },\n    get scrollableY() {\n      return state.scrollableY;\n    },\n    get state() {\n      return state.state;\n    },\n    get scrollBottom() {\n      return state.scrollBottom;\n    },\n    set scrollBottom(scrollBottom) {\n      state.scrollBottom = scrollBottom;\n    },\n    get scrollLeft() {\n      return state.scrollLeft;\n    },\n    set scrollLeft(scrollLeft) {\n      state.scrollLeft = scrollLeft;\n    },\n    get scrollRight() {\n      return state.scrollRight;\n    },\n    set scrollRight(scrollRight) {\n      state.scrollRight = scrollRight;\n    },\n    get scrollTop() {\n      return state.scrollTop;\n    },\n    set scrollTop(scrollTop) {\n      state.scrollTop = scrollTop;\n    },\n\n    ready() {\n      return scroller.ready();\n    },\n\n    element() {\n      return elementRef.value;\n    },\n\n    start() {\n      return scroller.start();\n    },\n\n    stop(): void {\n      return scroller.stop();\n    },\n\n    destroy() {\n      return scroller.destroy();\n    },\n\n    update(): void {\n      return scroller.update();\n    },\n\n    toJSON() {\n      return scroller.toJSON();\n    },\n\n    toString(): string {\n      return scroller.toString();\n    },\n\n    cancel() {\n      return scroller.cancel();\n    },\n\n    by(diffX: number, diffY: number, options?: ScrollerScrollOptions) {\n      return scroller.by(diffX, diffY, options);\n    },\n\n    to(\n      scrollPosition: Partial<ScrollPosition>,\n      options?: ScrollerScrollOptions,\n    ) {\n      return scroller.to(scrollPosition, options);\n    },\n\n    toElement(\n      target: ScrollToElementTarget,\n      options?: ScrollerScrollToElementOptions,\n    ) {\n      return scroller.toElement(target, options);\n    },\n\n    toSide(targets: ScrollToSideTargets, options?: ScrollerScrollOptions) {\n      return scroller.toSide(targets, options);\n    },\n\n    toTop(options?: ScrollerScrollOptions) {\n      return scroller.toTop(options);\n    },\n\n    toRight(options?: ScrollerScrollOptions) {\n      return scroller.toRight(options);\n    },\n\n    toBottom(options?: ScrollerScrollOptions) {\n      return scroller.toBottom(options);\n    },\n\n    toLeft(options?: ScrollerScrollOptions) {\n      return scroller.toLeft(options);\n    },\n\n    toLeftTop(options?: ScrollerScrollOptions) {\n      return scroller.toLeftTop(options);\n    },\n\n    toLeftBottom(options?: ScrollerScrollOptions) {\n      return scroller.toLeftBottom(options);\n    },\n\n    toRightTop(options?: ScrollerScrollOptions) {\n      return scroller.toRightTop(options);\n    },\n\n    toRightBottom(options?: ScrollerScrollOptions) {\n      return scroller.toRightBottom(options);\n    },\n\n    pushScrollStopper(stopper: ScrollStopper) {\n      return scroller.pushScrollStopper(stopper);\n    },\n\n    removeScrollStopper(stopper: ScrollStopper) {\n      return scroller.removeScrollStopper(stopper);\n    },\n\n    setScrollToElementAdditionalOffset(\n      offset: ScrollToElementAdditionalOffset | undefined,\n    ) {\n      return scroller.setScrollToElementAdditionalOffset(offset);\n    },\n\n    deleteScrollToElementAdditionalOffset() {\n      return scroller.deleteScrollToElementAdditionalOffset();\n    },\n  };\n\n  if (isSelf) {\n    // const selfEl = ref<null | Element | ComponentPublicInstance>(null);\n    onMounted(() => {\n      let el = elementRef.value;\n      if (!el) return;\n      if (!(el instanceof Element)) {\n        el = (el as any).$el;\n      }\n      if (!(el instanceof Element)) return;\n      scroller.setElement(el);\n    });\n\n    onBeforeUnmount(() => {\n      _scroller.destroy();\n    });\n  }\n\n  return _scroller;\n}\n\nexport type UseScroller = ReturnType<typeof useScrollerControl>;\n\nlet _documentScroller: UseScroller | undefined;\n\nexport function getDocumentScroller(): UseScroller {\n  if (!_documentScroller) {\n    _documentScroller = useScrollerControl({ el: 'body' });\n  }\n  return _documentScroller;\n}\n\nexport type ScrollerControl = ReturnType<typeof useScrollerControl>;\n","import './VScroller.scss';\n\nimport { defineComponent, PropType, ExtractPropTypes, computed } from 'vue';\nimport { ExtractPropInput, defineTypedComponent } from '@fastkit/vue-utils';\nimport {\n  useScrollerControl,\n  UseScrollerSetting,\n  ScrollerControl,\n} from '../composables';\n\nexport interface VScrollerSettings extends UseScrollerSetting {}\n\nconst DEFAULT_GUIDE_OFFSET = 20;\n\nconst GuideTypes = ['top', 'right', 'bottom', 'left'] as const;\n\ntype VScrollerGuideType = (typeof GuideTypes)[number];\n\nexport const scrollerProps = {\n  settings: {\n    type: Object as PropType<VScrollerSettings | null>,\n    default: null,\n  },\n  /**\n   * スクロール可能な辺にガイドとして影を表示する場合に設定する\n   */\n  guide: [Boolean, Number],\n\n  /**\n   * スクロールするコンテナ要素のクラス名\n   */\n  containerClass: String,\n};\n\nexport type VScrollerProps = ExtractPropInput<typeof scrollerProps>;\n\nexport type VScrollerResolvedProps = ExtractPropTypes<typeof scrollerProps>;\n\n/** Scrollability in each direction */\nexport interface ScrollerScrollability {\n  /** Whether you can scroll to the left or not */\n  left: boolean;\n  /** Whether you can scroll to the right or not */\n  right: boolean;\n  /** Whether you can scroll to the top or not */\n  top: boolean;\n  /** Whether you can scroll to the bottom or not */\n  bottom: boolean;\n}\n\n/**\n * Combined Scrollability\n *\n * The information immediately below is marked as scrollable to account for the margin of the `guide` prop, so `false` may be marked even if the information is actually scrollable.\n * If you want to check strict scrollability, check the `strict` property.\n */\nexport interface ScrollerCombinedScrollability extends ScrollerScrollability {\n  /**\n   * Strict scrollability\n   *\n   * Scrollable more than 0px will be marked as valid\n   */\n  strict: ScrollerScrollability;\n}\n\nexport interface ScrollerAPI {\n  get scroller(): ScrollerControl;\n  /**\n   * Combined Scrollability\n   *\n   * @see {@link ScrollerCombinedScrollability}\n   */\n  get scrollable(): ScrollerCombinedScrollability;\n}\n\nexport const _ScrollerI = defineComponent({\n  name: 'VScroller',\n  props: scrollerProps,\n  setup(props, ctx) {\n    const settings = props.settings || {};\n    const scroller = useScrollerControl({\n      ...settings,\n      el: settings.el || 'self',\n    });\n\n    const guideOffsetRef = computed(() => {\n      const { guide } = props;\n      if (typeof guide === 'number') return guide;\n      if (guide === true) return DEFAULT_GUIDE_OFFSET;\n      return undefined;\n    });\n\n    const scrollability = computed<ScrollerCombinedScrollability>(() => {\n      const guideOffset = guideOffsetRef.value || DEFAULT_GUIDE_OFFSET;\n      const { scrollLeft, scrollTop, scrollRight, scrollBottom } = scroller;\n      return {\n        left: scrollLeft >= guideOffset,\n        right: scrollRight >= guideOffset,\n        top: scrollTop >= guideOffset,\n        bottom: scrollBottom >= guideOffset,\n        strict: {\n          left: scrollLeft > 0,\n          right: scrollRight > 0,\n          top: scrollTop > 0,\n          bottom: scrollBottom > 0,\n        },\n      };\n    });\n\n    const scrollerRef: ScrollerAPI = {\n      scroller,\n      get scrollable() {\n        return scrollability.value;\n      },\n    };\n\n    const guidesRef = computed<VScrollerGuideType[] | undefined>(() => {\n      const guideOffset = guideOffsetRef.value;\n      if (guideOffset === undefined) return;\n\n      const guides: VScrollerGuideType[] = [];\n\n      const scrollable = scrollability.value;\n\n      scrollable.left && guides.push('left');\n      scrollable.top && guides.push('top');\n      scrollable.right && guides.push('right');\n      scrollable.bottom && guides.push('bottom');\n\n      return guides;\n    });\n\n    ctx.expose(scrollerRef);\n\n    return () => {\n      const guides = guidesRef.value;\n      const { containerClass } = props;\n      const $guides =\n        guides &&\n        GuideTypes.map((type) => (\n          <div\n            class={[\n              'v-scroller__guide',\n              {\n                [`v-scroller__guide--${type}`]: true,\n                [`v-scroller__guide--active`]: guides.includes(type),\n              },\n            ]}\n            key={type}\n          />\n        ));\n\n      return (\n        <div class=\"v-scroller\">\n          <div\n            class={['v-scroller__container', containerClass]}\n            ref={scroller.elementRef}>\n            {ctx.slots.default?.()}\n          </div>\n          {$guides}\n        </div>\n      );\n    };\n  },\n});\n\nexport const VScroller =\n  defineTypedComponent(_ScrollerI).$expose<ScrollerAPI>();\n"],"mappings":"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"}