@melt-ui/svelte
Advanced tools
Comparing version 0.7.0 to 0.7.1
@@ -15,1 +15,3 @@ export * from './array'; | ||
export * from './debounce'; | ||
export * from './platform'; | ||
export * from './scroll'; |
@@ -15,1 +15,3 @@ export * from './array'; | ||
export * from './debounce'; | ||
export * from './platform'; | ||
export * from './scroll'; |
@@ -1,1 +0,1 @@ | ||
export declare function removeScroll(): () => void; | ||
export declare function removeScroll(_document?: Document): (() => void) | undefined; |
@@ -1,10 +0,74 @@ | ||
export function removeScroll() { | ||
const initialPaddingRight = getComputedStyle(document.body).paddingRight; | ||
const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth; | ||
document.documentElement.style.overflowY = 'hidden'; | ||
document.documentElement.style.paddingRight = `calc(${scrollbarWidth}px + ${initialPaddingRight})`; | ||
// Modified from @zag-js/remove-scroll v0.10.2 (2023-06-10) | ||
// Source: https://github.com/chakra-ui/zag | ||
// https://github.com/chakra-ui/zag/blob/main/packages/utilities/remove-scroll/src/index.ts | ||
import { isIos } from './platform'; | ||
const LOCK_CLASSNAME = 'data-melt-scroll-lock'; | ||
function assignStyle(el, style) { | ||
if (!el) | ||
return; | ||
const previousStyle = el.style.cssText; | ||
Object.assign(el.style, style); | ||
return () => { | ||
document.documentElement.style.overflowY = 'auto'; | ||
document.documentElement.style.paddingRight = '0'; | ||
el.style.cssText = previousStyle; | ||
}; | ||
} | ||
function setCSSProperty(el, property, value) { | ||
if (!el) | ||
return; | ||
const previousValue = el.style.getPropertyValue(property); | ||
el.style.setProperty(property, value); | ||
return () => { | ||
if (previousValue) { | ||
el.style.setProperty(property, previousValue); | ||
} | ||
else { | ||
el.style.removeProperty(property); | ||
} | ||
}; | ||
} | ||
function getPaddingProperty(documentElement) { | ||
// RTL <body> scrollbar | ||
const documentLeft = documentElement.getBoundingClientRect().left; | ||
const scrollbarX = Math.round(documentLeft) + documentElement.scrollLeft; | ||
return scrollbarX ? 'paddingLeft' : 'paddingRight'; | ||
} | ||
export function removeScroll(_document) { | ||
const doc = _document ?? document; | ||
const win = doc.defaultView ?? window; | ||
const { documentElement, body } = doc; | ||
const locked = body.hasAttribute(LOCK_CLASSNAME); | ||
if (locked) | ||
return; | ||
body.setAttribute(LOCK_CLASSNAME, ''); | ||
const scrollbarWidth = win.innerWidth - documentElement.clientWidth; | ||
const setScrollbarWidthProperty = () => setCSSProperty(documentElement, '--scrollbar-width', `${scrollbarWidth}px`); | ||
const paddingProperty = getPaddingProperty(documentElement); | ||
const setStyle = () => assignStyle(body, { | ||
overflow: 'hidden', | ||
[paddingProperty]: `${scrollbarWidth}px`, | ||
}); | ||
// Only iOS doesn't respect `overflow: hidden` on document.body | ||
const setIOSStyle = () => { | ||
const { scrollX, scrollY, visualViewport } = win; | ||
// iOS 12 does not support `visuaViewport`. | ||
const offsetLeft = visualViewport?.offsetLeft ?? 0; | ||
const offsetTop = visualViewport?.offsetTop ?? 0; | ||
const restoreStyle = assignStyle(body, { | ||
position: 'fixed', | ||
overflow: 'hidden', | ||
top: `${-(scrollY - Math.floor(offsetTop))}px`, | ||
left: `${-(scrollX - Math.floor(offsetLeft))}px`, | ||
right: '0', | ||
[paddingProperty]: `${scrollbarWidth}px`, | ||
}); | ||
return () => { | ||
restoreStyle?.(); | ||
win.scrollTo(scrollX, scrollY); | ||
}; | ||
}; | ||
const cleanups = [setScrollbarWidthProperty(), isIos() ? setIOSStyle() : setStyle()]; | ||
return () => { | ||
cleanups.forEach((fn) => fn?.()); | ||
body.removeAttribute(LOCK_CLASSNAME); | ||
}; | ||
} |
{ | ||
"name": "@melt-ui/svelte", | ||
"version": "0.7.0", | ||
"version": "0.7.1", | ||
"license": "MIT", | ||
@@ -5,0 +5,0 @@ "exports": { |
119437
97
3098