overlayscrollbars-solid
Version: 
OverlayScrollbars for Solid.
1 lines • 11.8 kB
Source Map (JSON)
{"version":3,"file":"overlayscrollbars-solid.cjs","sources":["../src/createOverlayScrollbars.ts","../src/OverlayScrollbarsComponent.tsx"],"sourcesContent":["import { createRenderEffect, onCleanup } from 'solid-js';\r\nimport { OverlayScrollbars } from 'overlayscrollbars';\r\nimport type { Accessor } from 'solid-js';\r\nimport type { Store } from 'solid-js/store';\r\nimport type { InitializationTarget } from 'overlayscrollbars';\r\nimport type {\r\n  OverlayScrollbarsComponentProps,\r\n  OverlayScrollbarsComponentRef,\r\n} from './OverlayScrollbarsComponent';\r\n\r\ntype Defer = [\r\n  requestDefer: (callback: () => any, options?: OverlayScrollbarsComponentProps['defer']) => void,\r\n  cancelDefer: () => void\r\n];\r\n\r\nexport interface CreateOverlayScrollbarsParams {\r\n  /** OverlayScrollbars options. */\r\n  options?:\r\n    | OverlayScrollbarsComponentProps['options']\r\n    | Accessor<OverlayScrollbarsComponentProps['options']>;\r\n  /** OverlayScrollbars events. */\r\n  events?:\r\n    | OverlayScrollbarsComponentProps['events']\r\n    | Accessor<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?:\r\n    | OverlayScrollbarsComponentProps['defer']\r\n    | Accessor<OverlayScrollbarsComponentProps['defer']>;\r\n}\r\n\r\nexport type CreateOverlayScrollbarsInitialization = (target: InitializationTarget) => void;\r\n\r\nexport type CreateOverlayScrollbarsInstance = () => 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    // eslint-disable-next-line @typescript-eslint/no-empty-function\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\nconst isAccessor = (obj: any): obj is Accessor<any> => typeof obj === 'function';\r\nconst unwrapAccessor = <T>(obj: Accessor<T> | T): T => (isAccessor(obj) ? obj() : obj);\r\n\r\nexport const createOverlayScrollbars = (\r\n  params?:\r\n    | CreateOverlayScrollbarsParams\r\n    | Accessor<CreateOverlayScrollbarsParams | undefined>\r\n    | Store<CreateOverlayScrollbarsParams | undefined>\r\n): [CreateOverlayScrollbarsInitialization, CreateOverlayScrollbarsInstance] => {\r\n  let instance: OverlayScrollbars | null = null;\r\n  let options: OverlayScrollbarsComponentProps['options'];\r\n  let events: OverlayScrollbarsComponentProps['events'];\r\n  let defer: OverlayScrollbarsComponentProps['defer'];\r\n  const [requestDefer, clearDefer] = createDefer();\r\n\r\n  createRenderEffect(() => {\r\n    defer = unwrapAccessor(unwrapAccessor(params)?.defer);\r\n  });\r\n\r\n  createRenderEffect(() => {\r\n    options = unwrapAccessor(unwrapAccessor(params)?.options);\r\n\r\n    if (OverlayScrollbars.valid(instance)) {\r\n      instance.options(options || {}, true);\r\n    }\r\n  });\r\n\r\n  createRenderEffect(() => {\r\n    events = unwrapAccessor(unwrapAccessor(params)?.events);\r\n\r\n    if (OverlayScrollbars.valid(instance)) {\r\n      instance.on(events || {}, true);\r\n    }\r\n  });\r\n\r\n  onCleanup(() => {\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","import {\r\n  mergeProps,\r\n  splitProps,\r\n  children,\r\n  onCleanup,\r\n  createEffect,\r\n  createRenderEffect,\r\n  createSignal,\r\n} from 'solid-js';\r\nimport { Dynamic } from 'solid-js/web';\r\nimport type { JSX, ParentProps, ComponentProps, Ref, ValidComponent } from 'solid-js';\r\nimport type { OverlayScrollbars, PartialOptions, EventListeners } from 'overlayscrollbars';\r\nimport { createOverlayScrollbars } from './createOverlayScrollbars';\r\n\r\ntype InferGenericElement<T> = T extends keyof JSX.HTMLAttributes<infer G> ? G : HTMLElement;\r\n\r\nexport type OverlayScrollbarsComponentProps<T extends ValidComponent = 'div'> = Omit<\r\n  ComponentProps<T>,\r\n  'ref'\r\n> &\r\n  ParentProps<{\r\n    /** Tag of the root element. */\r\n    element?: T;\r\n    /** OverlayScrollbars options. */\r\n    options?: PartialOptions | false | null;\r\n    /** OverlayScrollbars events. */\r\n    events?: EventListeners | false | null;\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?: boolean | IdleRequestOptions;\r\n    /** OverlayScrollbarsComponent ref. */\r\n    ref?: Ref<OverlayScrollbarsComponentRef<T>>;\r\n  }>;\r\n\r\nexport interface OverlayScrollbarsComponentRef<T extends ValidComponent = 'div'> {\r\n  /** Returns the OverlayScrollbars instance or null if not initialized. */\r\n  osInstance(): OverlayScrollbars | null;\r\n  /** Returns the root element. */\r\n  getElement(): InferGenericElement<T> | null;\r\n}\r\n\r\nexport const OverlayScrollbarsComponent = <T extends ValidComponent = 'div'>(\r\n  props: OverlayScrollbarsComponentProps<T>\r\n) => {\r\n  const [finalProps, other] = splitProps(\r\n    mergeProps({ element: 'div' }, props as OverlayScrollbarsComponentProps),\r\n    ['element', 'options', 'events', 'defer', 'ref', 'children']\r\n  );\r\n  const [elementRef, setElementRef] = createSignal<HTMLDivElement | undefined>();\r\n  const [childrenRef, setChildrenRef] = createSignal<HTMLDivElement | undefined>();\r\n  const [initialize, instance] = createOverlayScrollbars(finalProps);\r\n  // https://github.com/KingSora/OverlayScrollbars/issues/700\r\n  // use the children helper outside of jsx: https://docs.solidjs.com/reference/component-apis/children\r\n  const resolvedChildren = children(() => finalProps.children);\r\n\r\n  createEffect(() => {\r\n    const target = elementRef();\r\n    const contentsElement = childrenRef();\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      finalProps.element === '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: contentsElement,\r\n              content: contentsElement,\r\n            },\r\n          }\r\n    );\r\n\r\n    onCleanup(() => {\r\n      instance()?.destroy();\r\n    });\r\n  });\r\n\r\n  createRenderEffect(() => {\r\n    const ref = {\r\n      osInstance: instance,\r\n      getElement: () =>\r\n        /* c8 ignore next */\r\n        elementRef() || null,\r\n    };\r\n\r\n    if (typeof finalProps.ref === 'function') {\r\n      finalProps.ref(ref);\r\n    } else {\r\n      finalProps.ref = ref;\r\n    }\r\n  });\r\n\r\n  return (\r\n    <Dynamic\r\n      component={finalProps.element}\r\n      data-overlayscrollbars-initialize=\"\"\r\n      ref={setElementRef}\r\n      {...other}\r\n    >\r\n      {finalProps.element === 'body' ? (\r\n        resolvedChildren()\r\n      ) : (\r\n        <div data-overlayscrollbars-contents=\"\" ref={setChildrenRef}>\r\n          {resolvedChildren()}\r\n        </div>\r\n      )}\r\n    </Dynamic>\r\n  );\r\n};\r\n"],"names":["createDefer","noop","idleId","rafId","wnd","idleSupported","rAF","cAF","rIdle","cIdle","clear","callback","options","isAccessor","obj","unwrapAccessor","createOverlayScrollbars","params","instance","events","defer","requestDefer","clearDefer","createRenderEffect","_a","OverlayScrollbars","onCleanup","target","init","OverlayScrollbarsComponent","props","finalProps","other","splitProps","mergeProps","element","elementRef","setElementRef","createSignal","childrenRef","setChildrenRef","initialize","resolvedChildren","children","createEffect","contentsElement","cancel","body","elements","viewport","content","destroy","ref","osInstance","getElement","_$createComponent","Dynamic","_$mergeProps","component","_$memo","_el$","_$getNextElement","_tmpl$","_$use","_$insert"],"mappings":"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"}