{"version":3,"file":"overlayscrollbars-vue.cjs","sources":["../src/useOverlayScrollbars.ts","../src/OverlayScrollbarsComponent.vue"],"sourcesContent":["import { onUnmounted, shallowRef, unref, watch } from 'vue';\r\nimport { OverlayScrollbars } from 'overlayscrollbars';\r\nimport type { Ref, UnwrapRef } from 'vue';\r\nimport type { InitializationTarget } from 'overlayscrollbars';\r\nimport type {\r\n  OverlayScrollbarsComponentProps,\r\n  OverlayScrollbarsComponentRef,\r\n} from './OverlayScrollbarsComponent.types';\r\n\r\ntype Defer = [\r\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\r\n  requestDefer: (callback: () => any, options?: OverlayScrollbarsComponentProps['defer']) => void,\r\n  cancelDefer: () => void,\r\n];\r\n\r\nexport interface UseOverlayScrollbarsParams {\r\n  /** OverlayScrollbars options. */\r\n  options?:\r\n    | OverlayScrollbarsComponentProps['options']\r\n    | Ref<OverlayScrollbarsComponentProps['options']>;\r\n  /** OverlayScrollbars events. */\r\n  events?:\r\n    | OverlayScrollbarsComponentProps['events']\r\n    | Ref<OverlayScrollbarsComponentProps['events']>;\r\n  /** Whether to defer the initialization to a point in time when the browser is idle. (or to the next frame if `window.requestIdleCallback` is not supported) */\r\n  defer?: OverlayScrollbarsComponentProps['defer'] | Ref<OverlayScrollbarsComponentProps['defer']>;\r\n}\r\n\r\nexport type UseOverlayScrollbarsInitialization = (target: InitializationTarget) => void;\r\n\r\nexport type UseOverlayScrollbarsInstance = () => ReturnType<\r\n  OverlayScrollbarsComponentRef['osInstance']\r\n>;\r\n\r\nconst createDefer = (): Defer => {\r\n  /* c8 ignore start */\r\n  if (typeof window === 'undefined') {\r\n    // mock ssr calls with \"noop\"\r\n\r\n    const noop = () => {};\r\n    return [noop, noop];\r\n  }\r\n  /* c8 ignore end */\r\n\r\n  let idleId: number;\r\n  let rafId: number;\r\n  const wnd = window;\r\n  const idleSupported = typeof wnd.requestIdleCallback === 'function';\r\n  const rAF = wnd.requestAnimationFrame;\r\n  const cAF = wnd.cancelAnimationFrame;\r\n  const rIdle = idleSupported ? wnd.requestIdleCallback : rAF;\r\n  const cIdle = idleSupported ? wnd.cancelIdleCallback : cAF;\r\n  const clear = () => {\r\n    cIdle(idleId);\r\n    cAF(rafId);\r\n  };\r\n\r\n  return [\r\n    (callback, options) => {\r\n      clear();\r\n      idleId = rIdle(\r\n        idleSupported\r\n          ? () => {\r\n              clear();\r\n              // inside idle its best practice to use rAF to change DOM for best performance\r\n              rafId = rAF(callback);\r\n            }\r\n          : callback,\r\n        typeof options === 'object' ? options : { timeout: 2233 }\r\n      );\r\n    },\r\n    clear,\r\n  ];\r\n};\r\n\r\n/**\r\n * Composable for advanced usage of OverlayScrollbars. (When the OverlayScrollbarsComponent is not enough)\r\n * @param params Parameters for customization.\r\n * @returns A tuple with two values:\r\n * The first value is the initialization function, it takes one argument which is the `InitializationTarget` and returns the OverlayScrollbars instance.\r\n * The second value is a function which returns the current OverlayScrollbars instance or `null` if not initialized.\r\n */\r\nexport const useOverlayScrollbars = (\r\n  params?: UseOverlayScrollbarsParams | Ref<UseOverlayScrollbarsParams | undefined>\r\n): [UseOverlayScrollbarsInitialization, UseOverlayScrollbarsInstance] => {\r\n  let instance: ReturnType<UseOverlayScrollbarsInstance> = null;\r\n  let options: UnwrapRef<UseOverlayScrollbarsParams['options']>;\r\n  let events: UnwrapRef<UseOverlayScrollbarsParams['events']>;\r\n  let defer: UnwrapRef<UseOverlayScrollbarsParams['defer']>;\r\n  const paramsRef = shallowRef(params || {});\r\n  const [requestDefer, clearDefer] = createDefer();\r\n\r\n  watch(\r\n    () => unref(paramsRef.value?.defer),\r\n    (currDefer) => {\r\n      defer = currDefer;\r\n    },\r\n    { deep: true, immediate: true }\r\n  );\r\n\r\n  watch(\r\n    () => unref(paramsRef.value?.options),\r\n    (currOptions) => {\r\n      options = currOptions;\r\n\r\n      if (OverlayScrollbars.valid(instance)) {\r\n        instance.options(options || {}, true);\r\n      }\r\n    },\r\n    { deep: true, immediate: true }\r\n  );\r\n\r\n  watch(\r\n    () => unref(paramsRef.value?.events),\r\n    (currEvents) => {\r\n      events = currEvents;\r\n\r\n      if (OverlayScrollbars.valid(instance)) {\r\n        instance.on(\r\n          /* c8 ignore next */\r\n          events || {},\r\n          true\r\n        );\r\n      }\r\n    },\r\n    { deep: true, immediate: true }\r\n  );\r\n\r\n  onUnmounted(() => {\r\n    clearDefer();\r\n    instance?.destroy();\r\n  });\r\n\r\n  return [\r\n    (target) => {\r\n      // if already initialized do nothing\r\n      if (OverlayScrollbars.valid(instance)) {\r\n        return instance;\r\n      }\r\n\r\n      const init = () => (instance = OverlayScrollbars(target, options || {}, events || {}));\r\n\r\n      if (defer) {\r\n        requestDefer(init, defer);\r\n      } else {\r\n        init();\r\n      }\r\n    },\r\n    () => instance,\r\n  ];\r\n};\r\n","<script setup lang=\"ts\">\r\nimport { ref, unref, shallowRef, toRefs, watch, watchPostEffect, type PropType } from 'vue';\r\nimport { useOverlayScrollbars } from './useOverlayScrollbars';\r\nimport type {\r\n  OverlayScrollbarsComponentProps,\r\n  OverlayScrollbarsComponentRef,\r\n} from './OverlayScrollbarsComponent.types';\r\nimport type { EventListeners, EventListenerArgs } from 'overlayscrollbars';\r\n\r\ntype EmitEventsMap = {\r\n  [N in keyof EventListenerArgs]: `os${Capitalize<N>}`;\r\n};\r\n\r\nconst emitEvents: EmitEventsMap = {\r\n  initialized: 'osInitialized',\r\n  updated: 'osUpdated',\r\n  destroyed: 'osDestroyed',\r\n  scroll: 'osScroll',\r\n};\r\nconst props = defineProps({\r\n  element: {\r\n    type: [String, Object] as PropType<Required<OverlayScrollbarsComponentProps>['element']>,\r\n    default: 'div',\r\n  },\r\n  options: { type: Object as PropType<OverlayScrollbarsComponentProps['options']> },\r\n  events: { type: Object as PropType<OverlayScrollbarsComponentProps['events']> },\r\n  defer: { type: [Boolean, Object] as PropType<OverlayScrollbarsComponentProps['defer']> },\r\n});\r\nconst emits = defineEmits<{\r\n  (name: 'osInitialized', ...args: EventListenerArgs['initialized']): void;\r\n  (name: 'osUpdated', ...args: EventListenerArgs['updated']): void;\r\n  (name: 'osDestroyed', ...args: EventListenerArgs['destroyed']): void;\r\n  (name: 'osScroll', ...args: EventListenerArgs['scroll']): void;\r\n}>();\r\n\r\nconst { element, options, events, defer } = toRefs(props);\r\nconst elementRef = shallowRef<HTMLElement | null>(null);\r\nconst slotRef = shallowRef<HTMLElement | null>(null);\r\nconst combinedEvents = ref<EventListeners>();\r\nconst [initialize, osInstance] = useOverlayScrollbars({ options, events: combinedEvents, defer });\r\n\r\nconst exposed: OverlayScrollbarsComponentRef = {\r\n  osInstance,\r\n  getElement: () => elementRef.value,\r\n};\r\n\r\ndefineExpose(exposed);\r\n\r\nwatchPostEffect((onCleanup) => {\r\n  const { value: target } = elementRef;\r\n  const { value: contentsElm } = slotRef;\r\n\r\n  /* c8 ignore start */\r\n  if (!target) {\r\n    return;\r\n  }\r\n  /* c8 ignore end */\r\n\r\n  initialize(\r\n    element.value === 'body'\r\n      ? {\r\n          target,\r\n          cancel: {\r\n            body: null,\r\n          },\r\n        }\r\n      : {\r\n          target,\r\n          elements: {\r\n            viewport: contentsElm,\r\n            content: contentsElm,\r\n          },\r\n        }\r\n  );\r\n\r\n  onCleanup(() => osInstance()?.destroy());\r\n});\r\n\r\nwatch(\r\n  () => unref(events),\r\n  (rawCurrEvents) => {\r\n    const currEvents = rawCurrEvents || {};\r\n    combinedEvents.value = (\r\n      Object.keys(emitEvents) as (keyof EventListeners)[]\r\n    ).reduce<EventListeners>(<N extends keyof EventListeners>(obj: EventListeners, name: N) => {\r\n      const eventListener = currEvents[name];\r\n      obj[name] = [\r\n        (...args: EventListenerArgs[N]) =>\r\n          emits(\r\n            emitEvents[name],\r\n            // @ts-ignore\r\n            ...args\r\n          ),\r\n        ...(Array.isArray(eventListener) ? eventListener : [eventListener]).filter(Boolean),\r\n      ];\r\n      return obj;\r\n    }, {});\r\n  },\r\n  { deep: true, immediate: true }\r\n);\r\n</script>\r\n\r\n<template>\r\n  <component data-overlayscrollbars-initialize=\"\" :is=\"element\" ref=\"elementRef\">\r\n    <slot v-if=\"element === 'body'\"></slot>\r\n    <div v-else data-overlayscrollbars-contents=\"\" ref=\"slotRef\">\r\n      <slot></slot>\r\n    </div>\r\n  </component>\r\n</template>\r\n"],"names":["createDefer","noop","idleId","rafId","wnd","idleSupported","rAF","cAF","rIdle","cIdle","clear","callback","options","useOverlayScrollbars","params","instance","events","defer","paramsRef","shallowRef","requestDefer","clearDefer","watch","unref","_a","currDefer","currOptions","OverlayScrollbars","currEvents","onUnmounted","target","init","emitEvents","element","toRefs","props","elementRef","slotRef","combinedEvents","ref","initialize","osInstance","expose","watchPostEffect","onCleanup","contentsElm","rawCurrEvents","obj","name","eventListener","args","emits"],"mappings":"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"}