element-plus
Version:
A Component Library for Vue 3
1 lines • 6.19 kB
Source Map (JSON)
{"version":3,"file":"scroll.mjs","names":[],"sources":["../../../../../packages/utils/dom/scroll.ts"],"sourcesContent":["import { isClient } from '../browser'\nimport { easeInOutCubic } from '../easings'\nimport { isFunction, isWindow } from '../types'\nimport { cAF, rAF } from '../raf'\nimport { getStyle } from './style'\nimport { isShadowRoot } from './aria'\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 if (isShadowRoot(parent)) {\n parent = parent.host as HTMLElement\n } else {\n parent = parent.parentNode as HTMLElement\n }\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 (isFunction(callback)) {\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"],"mappings":";;;;;;;;AAOA,MAAa,YAAY,IAAiB,eAAkC;AAC1E,KAAI,CAAC,SAAU,QAAO;CAEtB,MAAM,MACJ;EACE,WAAW;EACX,MAAM;EACN,OAAO;EACR,CACD,OAAO,WAAW;CACpB,MAAM,WAAW,SAAS,IAAI,IAAI;AAClC,QAAO;EAAC;EAAU;EAAQ;EAAU,CAAC,MAAM,MAAM,SAAS,SAAS,EAAE,CAAC;;AAGxE,MAAa,sBACX,IACA,eACqC;AACrC,KAAI,CAAC,SAAU;CAEf,IAAI,SAAsB;AAC1B,QAAO,QAAQ;AACb,MAAI;GAAC;GAAQ;GAAU,SAAS;GAAgB,CAAC,SAAS,OAAO,CAC/D,QAAO;AAET,MAAI,SAAS,QAAQ,WAAW,CAAE,QAAO;AAEzC,MAAI,aAAa,OAAO,CACtB,UAAS,OAAO;MAEhB,UAAS,OAAO;;AAIpB,QAAO;;AAGT,IAAI;AACJ,MAAa,qBAAqB,cAA8B;AAC9D,KAAI,CAAC,SAAU,QAAO;AACtB,KAAI,mBAAmB,OAAW,QAAO;CAEzC,MAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,OAAM,YAAY,GAAG,UAAU;AAC/B,OAAM,MAAM,aAAa;AACzB,OAAM,MAAM,QAAQ;AACpB,OAAM,MAAM,WAAW;AACvB,OAAM,MAAM,MAAM;AAClB,UAAS,KAAK,YAAY,MAAM;CAEhC,MAAM,gBAAgB,MAAM;AAC5B,OAAM,MAAM,WAAW;CAEvB,MAAM,QAAQ,SAAS,cAAc,MAAM;AAC3C,OAAM,MAAM,QAAQ;AACpB,OAAM,YAAY,MAAM;CAExB,MAAM,kBAAkB,MAAM;AAC9B,OAAM,YAAY,YAAY,MAAM;AACpC,kBAAiB,gBAAgB;AAEjC,QAAO;;;;;;AAOT,SAAgB,eACd,WACA,UACM;AACN,KAAI,CAAC,SAAU;AAEf,KAAI,CAAC,UAAU;AACb,YAAU,YAAY;AACtB;;CAGF,MAAM,gBAA+B,EAAE;CACvC,IAAI,UAAU,SAAS;AACvB,QACE,YAAY,QACZ,cAAc,WACd,UAAU,SAAS,QAAQ,EAC3B;AACA,gBAAc,KAAK,QAAuB;AAC1C,YAAW,QAAwB;;CAErC,MAAM,MACJ,SAAS,YACT,cAAc,QAAQ,MAAM,SAAS,OAAO,KAAK,WAAW,EAAE;CAChE,MAAM,SAAS,MAAM,SAAS;CAC9B,MAAM,cAAc,UAAU;CAC9B,MAAM,iBAAiB,cAAc,UAAU;AAE/C,KAAI,MAAM,YACR,WAAU,YAAY;UACb,SAAS,eAClB,WAAU,YAAY,SAAS,UAAU;;AAI7C,SAAgB,gBACd,WACA,MACA,IACA,UACA,UACA;CACA,MAAM,YAAY,KAAK,KAAK;CAE5B,IAAI;CACJ,MAAM,eAAe;EAEnB,MAAM,OADY,KAAK,KAAK,GACH;EACzB,MAAM,gBAAgB,eACpB,OAAO,WAAW,WAAW,MAC7B,MACA,IACA,SACD;AAED,MAAI,SAAS,UAAU,CACrB,WAAU,SAAS,OAAO,aAAa,cAAc;MAErD,WAAU,YAAY;AAExB,MAAI,OAAO,SACT,UAAS,IAAI,OAAO;WACX,WAAW,SAAS,CAC7B,WAAU;;AAId,SAAQ;AAER,cAAa;AACX,YAAU,IAAI,OAAO;;;AAIzB,MAAa,oBACX,QACA,cACG;AACH,KAAI,SAAS,UAAU,CACrB,QAAO,OAAO,cAAc;AAE9B,QAAO;;AAGT,MAAa,gBAAgB,cAAoC;AAC/D,KAAI,SAAS,UAAU,CACrB,QAAO,OAAO;AAEhB,QAAO,UAAU"}