{"version":3,"file":"scroll.mjs","sources":["../../../../../packages/utils/dom/scroll.ts"],"sourcesContent":["import { isClient } from '../browser'\nimport { easeInOutCubic } from '../easings'\nimport { isWindow } from '../types'\nimport { cAF, rAF } from '../raf'\nimport { getStyle } from './style'\n\nexport const isScroll = (el: HTMLElement, isVertical?: boolean): boolean => {\n  if (!isClient) return false\n\n  const key = (\n    {\n      undefined: 'overflow',\n      true: 'overflow-y',\n      false: 'overflow-x',\n    } as const\n  )[String(isVertical)]!\n  const overflow = getStyle(el, key)\n  return ['scroll', 'auto', 'overlay'].some((s) => overflow.includes(s))\n}\n\nexport const getScrollContainer = (\n  el: HTMLElement,\n  isVertical?: boolean\n): Window | HTMLElement | undefined => {\n  if (!isClient) return\n\n  let parent: HTMLElement = el\n  while (parent) {\n    if ([window, document, document.documentElement].includes(parent))\n      return window\n\n    if (isScroll(parent, isVertical)) return parent\n\n    parent = parent.parentNode as HTMLElement\n  }\n\n  return parent\n}\n\nlet scrollBarWidth: number\nexport const getScrollBarWidth = (namespace: string): number => {\n  if (!isClient) return 0\n  if (scrollBarWidth !== undefined) return scrollBarWidth\n\n  const outer = document.createElement('div')\n  outer.className = `${namespace}-scrollbar__wrap`\n  outer.style.visibility = 'hidden'\n  outer.style.width = '100px'\n  outer.style.position = 'absolute'\n  outer.style.top = '-9999px'\n  document.body.appendChild(outer)\n\n  const widthNoScroll = outer.offsetWidth\n  outer.style.overflow = 'scroll'\n\n  const inner = document.createElement('div')\n  inner.style.width = '100%'\n  outer.appendChild(inner)\n\n  const widthWithScroll = inner.offsetWidth\n  outer.parentNode?.removeChild(outer)\n  scrollBarWidth = widthNoScroll - widthWithScroll\n\n  return scrollBarWidth\n}\n\n/**\n * Scroll with in the container element, positioning the **selected** element at the top\n * of the container\n */\nexport function scrollIntoView(\n  container: HTMLElement,\n  selected: HTMLElement\n): void {\n  if (!isClient) return\n\n  if (!selected) {\n    container.scrollTop = 0\n    return\n  }\n\n  const offsetParents: HTMLElement[] = []\n  let pointer = selected.offsetParent\n  while (\n    pointer !== null &&\n    container !== pointer &&\n    container.contains(pointer)\n  ) {\n    offsetParents.push(pointer as HTMLElement)\n    pointer = (pointer as HTMLElement).offsetParent\n  }\n  const top =\n    selected.offsetTop +\n    offsetParents.reduce((prev, curr) => prev + curr.offsetTop, 0)\n  const bottom = top + selected.offsetHeight\n  const viewRectTop = container.scrollTop\n  const viewRectBottom = viewRectTop + container.clientHeight\n\n  if (top < viewRectTop) {\n    container.scrollTop = top\n  } else if (bottom > viewRectBottom) {\n    container.scrollTop = bottom - container.clientHeight\n  }\n}\n\nexport function animateScrollTo(\n  container: HTMLElement | Window,\n  from: number,\n  to: number,\n  duration: number,\n  callback?: unknown\n) {\n  const startTime = Date.now()\n\n  let handle: number | undefined\n  const scroll = () => {\n    const timestamp = Date.now()\n    const time = timestamp - startTime\n    const nextScrollTop = easeInOutCubic(\n      time > duration ? duration : time,\n      from,\n      to,\n      duration\n    )\n\n    if (isWindow(container)) {\n      container.scrollTo(window.pageXOffset, nextScrollTop)\n    } else {\n      container.scrollTop = nextScrollTop\n    }\n    if (time < duration) {\n      handle = rAF(scroll)\n    } else if (typeof callback === 'function') {\n      callback()\n    }\n  }\n\n  scroll()\n\n  return () => {\n    handle && cAF(handle)\n  }\n}\n\nexport const getScrollElement = (\n  target: HTMLElement,\n  container: HTMLElement | Window\n) => {\n  if (isWindow(container)) {\n    return target.ownerDocument.documentElement\n  }\n  return container\n}\n\nexport const getScrollTop = (container: HTMLElement | Window) => {\n  if (isWindow(container)) {\n    return window.scrollY\n  }\n  return container.scrollTop\n}\n"],"names":["isScroll","t","e","c","n","undefined","true","false","String","o","h","some","l","includes","getScrollContainer","window","document","documentElement","parentNode","f","getScrollBarWidth","r","createElement","className","style","visibility","width","position","top","body","appendChild","offsetWidth","overflow","removeChild","scrollIntoView","scrollTop","offsetParent","contains","push","offsetTop","reduce","d","i","offsetHeight","s","m","clientHeight","animateScrollTo","Date","now","p","w","u","scrollTo","pageXOffset","a","T","getScrollElement","ownerDocument","getScrollTop","scrollY"],"mappings":"wOAA2M,MAACA,EAAS,CAACC,EAAEC,KAAK,IAAIC,EAAE,OAAM,EAAG,MAAMC,EAAE,CAACC,UAAU,WAAWC,KAAK,aAAaC,MAAM,cAAcC,OAAON,IAAIO,EAAEC,EAAET,EAAEG,GAAG,MAAM,CAAC,SAAS,OAAO,WAAWO,MAAKC,GAAGH,EAAEI,SAASD,MAAKE,EAAmB,CAACb,EAAEC,KAAK,IAAIC,EAAE,OAAO,IAAIC,EAAEH,EAAE,KAAKG,GAAG,CAAC,GAAG,CAACW,OAAOC,SAASA,SAASC,iBAAiBJ,SAAST,GAAG,OAAOW,OAAO,GAAGf,EAASI,EAAEF,GAAG,OAAOE,EAAEA,EAAEA,EAAEc,UAAU,CAAC,OAAOd,GAAG,IAAIe,EAAc,MAACC,EAAkBnB,IAAI,IAAIoB,EAAE,IAAIlB,EAAE,OAAO,EAAE,QAAO,IAAJgB,EAAW,OAAOA,EAAE,MAAMjB,EAAEc,SAASM,cAAc,OAAOpB,EAAEqB,UAAU,GAAGtB,oBAAoBC,EAAEsB,MAAMC,WAAW,SAASvB,EAAEsB,MAAME,MAAM,QAAQxB,EAAEsB,MAAMG,SAAS,WAAWzB,EAAEsB,MAAMI,IAAI,UAAUZ,SAASa,KAAKC,YAAY5B,GAAG,MAAME,EAAEF,EAAE6B,YAAY7B,EAAEsB,MAAMQ,SAAS,SAAS,MAAMvB,EAAEO,SAASM,cAAc,OAAOb,EAAEe,MAAME,MAAM,OAAOxB,EAAE4B,YAAYrB,GAAG,MAAMG,EAAEH,EAAEsB,YAAY,OAAwB,OAAjBV,EAAEnB,EAAEgB,aAAmBG,EAAEY,YAAY/B,GAAGiB,EAAEf,EAAEQ,EAAEO,GAAU,SAASe,EAAejC,EAAEC,GAAG,IAAIC,EAAE,OAAO,IAAID,EAAiB,YAAdD,EAAEkC,UAAU,GAAS,MAAM/B,EAAE,GAAG,IAAIK,EAAEP,EAAEkC,aAAa,KAAS,OAAJ3B,GAAUR,IAAIQ,GAAGR,EAAEoC,SAAS5B,IAAIL,EAAEkC,KAAK7B,GAAGA,EAAEA,EAAE2B,aAAa,MAAMxB,EAAEV,EAAEqC,UAAUnC,EAAEoC,QAAO,CAACC,EAAEC,IAAID,EAAEC,EAAEH,WAAU,GAAGlB,EAAET,EAAEV,EAAEyC,aAAaC,EAAE3C,EAAEkC,UAAUU,EAAED,EAAE3C,EAAE6C,aAAalC,EAAEgC,EAAE3C,EAAEkC,UAAUvB,EAAES,EAAEwB,IAAI5C,EAAEkC,UAAUd,EAAEpB,EAAE6C,aAAa,CAAQ,SAASC,EAAgB9C,EAAEC,EAAEE,EAAEK,EAAEG,GAAG,MAAMS,EAAE2B,KAAKC,MAAM,IAAIL,EAAE,MAAMC,EAAE,KAAK,MAAMH,EAAEM,KAAKC,MAAM5B,EAAE6B,EAAEC,EAAET,EAAEjC,EAAEA,EAAEiC,EAAExC,EAAEE,EAAEK,GAAG2C,EAAEnD,GAAGA,EAAEoD,SAAStC,OAAOuC,YAAYJ,GAAGjD,EAAEkC,UAAUe,EAAER,EAAEjC,EAAEmC,EAAEW,EAAEV,GAAa,mBAAHjC,GAAeA,KAAK,OAAOiC,IAAI,KAAKD,GAAGY,EAAEZ,GAAG,CAAa,MAACa,EAAiB,CAACxD,EAAEC,IAAIkD,EAAElD,GAAGD,EAAEyD,cAAczC,gBAAgBf,EAAEyD,EAAa1D,GAAGmD,EAAEnD,GAAGc,OAAO6C,QAAQ3D,EAAEkC"}